jpsim / jpsim/SourceKitten

Swift API generated from Objective-C code doesn't resolve forward declarations

Open
#731 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Swift
Stars
2.4k
Forks
237
PR merge metrics
No merged PRs in 30d

Description

We noticed that there are issues with the listing of Swift name and declaration in the SourceKitten output for Objective-C API that includes forward declarations.
When using a forward declaration of e.g. a protocol, the Swift name/declaration is missing completely.

Consider the following two files in a project, and an umbrella header importing both of those:

PSPDFProtocol.h
#import <Foundation/Foundation.h>

@protocol PSPDFProtocol
@end
PSPDFClass.h
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@protocol PSPDFProtocol;

@interface PSPDFClass

- (id<PSPDFProtocol>)protocolAPI;

@end

NS_ASSUME_NONNULL_END

The SourceKitten doc command results in the following output:

PSPDFKit.json
[
  {
    "PSPDFClass.h" : {
      "key.diagnostic_stage" : "",
      "key.substructure" : [
        {
          "key.always_deprecated" : false,
          "key.always_unavailable" : false,
          "key.deprecation_message" : "",
          "key.doc.column" : 12,
          "key.doc.file" : "PSPDFClass.h",
          "key.doc.line" : 7,
          "key.filepath" : "PSPDFClass.h",
          "key.kind" : "sourcekitten.source.lang.objc.decl.class",
          "key.name" : "PSPDFClass",
          "key.parsed_declaration" : "@interface PSPDFClass\n\n- (id<PSPDFProtocol>)protocolAPI;\n\n@end",
          "key.parsed_scope.end" : 11,
          "key.parsed_scope.start" : 7,
          "key.substructure" : [
            {
              "key.always_deprecated" : false,
              "key.always_unavailable" : false,
              "key.deprecation_message" : "",
              "key.doc.column" : 22,
              "key.doc.file" : "PSPDFClass.h",
              "key.doc.line" : 9,
              "key.filepath" : "PSPDFClass.h",
              "key.kind" : "sourcekitten.source.lang.objc.decl.method.instance",
              "key.name" : "-protocolAPI",
              "key.parsed_declaration" : "- (id<PSPDFProtocol>)protocolAPI;",
              "key.parsed_scope.end" : 9,
              "key.parsed_scope.start" : 9,
              "key.unavailable_message" : "",
              "key.usr" : "c:objc(cs)PSPDFClass(im)protocolAPI"
            }
          ],
          "key.swift_declaration" : "class PSPDFClass",
          "key.swift_name" : "PSPDFClass",
          "key.unavailable_message" : "",
          "key.usr" : "c:objc(cs)PSPDFClass"
        }
      ]
    }
  },
  {
    "PSPDFProtocol.h" : {
      "key.diagnostic_stage" : "",
      "key.substructure" : [
        {
          "key.always_deprecated" : false,
          "key.always_unavailable" : false,
          "key.deprecation_message" : "",
          "key.doc.column" : 11,
          "key.doc.file" : "PSPDFProtocol.h",
          "key.doc.line" : 3,
          "key.filepath" : "PSPDFProtocol.h",
          "key.kind" : "sourcekitten.source.lang.objc.decl.protocol",
          "key.name" : "PSPDFProtocol",
          "key.parsed_declaration" : "@protocol PSPDFProtocol\n@end",
          "key.parsed_scope.end" : 4,
          "key.parsed_scope.start" : 3,
          "key.swift_declaration" : "protocol PSPDFProtocol",
          "key.swift_name" : "PSPDFProtocol",
          "key.unavailable_message" : "",
          "key.usr" : "c:objc(pl)PSPDFProtocol"
        }
      ]
    }
  }
]

Note that the swift_name and swift_declaration are missing from the protocolAPI symbol.


One solution to this would be to replace the forward declaration with an actual import of the file that includes the protocol, but in some cases this is not a viable solution as it results in circular dependencies.

Is there any way that the Swift API for this could be generated correctly?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the report with PSPDFProtocol.h, PSPDFClass.h, and the umbrella header, then run SourceKitten’s doc command and compare the protocolAPI output. Read the generated JSON and the SourceKitten path handling Objective-C declarations; done means the forward-declared protocol method includes the expected swift_name and swift_declaration fields without introducing a circular import.

Written by the indexing model from the issue text.

Assessment

Tech stack
objective-c, swift
Domain
compilers, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.