Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose more structural information about function declarations #82

Closed
tjarratt opened this issue Nov 3, 2015 · 7 comments
Closed

Expose more structural information about function declarations #82

tjarratt opened this issue Nov 3, 2015 · 7 comments

Comments

@tjarratt
Copy link

tjarratt commented Nov 3, 2015

Hey SourceKitten crew, I've been having some fun creating an Xcode plugin that generates classes implementing swift protocols. I'm using SourceKitten to parse source files and generate an AST-level representation of the file, which I then use to determine what methods are in a given protocol.

When I get the structure back for a given file, I get some high level information about the protocol, the functions inside of it, but a lot of type information is missing (especially the local name and types of arguments, and the return value's type).

For example, I've got a contrived protocol like this for testing

protocol MySpecialProtocol {
    func thisIsATest(receives: Int, someArgs: Array<String>) -> String
}

What I get back from SourceKitten is an XPCDictionary that looks a bit like this (some keys omitted for brevity)

{
  "key.substructure" : [
    {
      "key.kind" : "source.lang.swift.decl.protocol",
      "key.substructure" : [
        {
          "key.kind" : "source.lang.swift.decl.function.method.instance",
          "key.accessibility" : "source.lang.swift.accessibility.internal",
          "key.substructure" : [],
          "key.name" : "thisIsATest(_:someArgs:)"
        }
      ],
      "key.name" : "MySpecialProtocol",
      "key.runtime_name" : "_TtP8__main__17MySpecialProtocol_",
    }
  ]
}

As you can see, all of the substructure for thisIsATest is missing. In File.swift, the resultant XPCDictionary is stripped of any nested elements that are not comments or declarations (excluding parameter declarations). I believe the information I am looking for is mainly in the parameter declarations.

Is there a particular reason why parameter declarations are filtered out of this? I would personally find it incredibly useful.

I'd be more than happy to submit a pull request for this, given that we can reach an understanding of which parameter declarations should be ignored, if any. My current feeling is that none should be ignored, but perhaps I'm being a bit naive?

Thank you for your time and contributions. SourceKitten has really been a boon to my personal project.

@tjarratt tjarratt changed the title Expose local parameter name type of function declarations Expose more structural information about function declarations Nov 3, 2015
@segiddins
Copy link
Collaborator

I'm guessing this is a limitation in sourcekit, rather than something SourceKitten is actively doing?

@tjarratt
Copy link
Author

tjarratt commented Nov 3, 2015

Sorry, Sam, but I'm fairly certain that SourceKitten is filtering it out.

Prior to that filter step, here's a snippet of what we get back from sourcekit for a function declaration

["key.kind": "source.lang.swift.decl.function.method.instance",
                          "key.accessibility": "source.lang.swift.accessibility.internal",
                          "key.substructure": [["key.kind": "source.lang.swift.decl.var.parameter",
                                                "key.offset": 124,
                                                "key.nameoffset": 0,
                                                "key.namelength": 0,
                                                "key.length": 8,
                                                "key.typename": "Int",
                                                "key.name": "receives"],
                                               ["key.kind": "source.lang.swift.decl.var.parameter",
                                                "key.offset": 139,
                                                "key.nameoffset": 139,
                                                "key.namelength": 13,
                                                "key.length": 13,
                                                "key.typename": "RandomTestStruct",
                                                "key.name": "somethingHere"]],
                          "key.name": "thisIsATest(_:somethingHere:)"]

The substructure for each source.lang.swift.decl.function.method.instance is always stripped out by SourceKitten.

@jpsim
Copy link
Owner

jpsim commented Nov 3, 2015

Hi @tjarratt you're right that we're "cleaning up" the result from structure calls. This is only really done for historical reasons, because there was a lot of useless messy information in there but it looks super clean in Xcode 7.

I'll take a look at what it would take to stop filtering those results. Hang tight!

@jpsim
Copy link
Owner

jpsim commented Nov 3, 2015

FYI, this is what SourceKit itself can provide us from your protocol sample:

[
  {
    "key.kind": "source.lang.swift.decl.protocol",
    "key.accessibility": "source.lang.swift.accessibility.internal",
    "key.name": "MySpecialProtocol",
    "key.offset": 0,
    "key.length": 97,
    "key.runtime_name": "_TtP8__main__17MySpecialProtocol_",
    "key.nameoffset": 9,
    "key.namelength": 17,
    "key.bodyoffset": 28,
    "key.bodylength": 68,
    "key.substructure": [
      {
        "key.kind": "source.lang.swift.decl.function.method.instance",
        "key.accessibility": "source.lang.swift.accessibility.internal",
        "key.name": "thisIsATest(_:someArgs:)",
        "key.offset": 29,
        "key.length": 66,
        "key.nameoffset": 34,
        "key.namelength": 51,
        "key.substructure": [
          {
            "key.kind": "source.lang.swift.decl.var.parameter",
            "key.name": "receives",
            "key.offset": 46,
            "key.length": 8,
            "key.typename": "Int",
            "key.nameoffset": 0,
            "key.namelength": 0
          },
          {
            "key.kind": "source.lang.swift.decl.var.parameter",
            "key.name": "someArgs",
            "key.offset": 61,
            "key.length": 8,
            "key.typename": "Array<String>",
            "key.nameoffset": 61,
            "key.namelength": 8
          }
        ]
      }
    ]
  }
]

@jpsim
Copy link
Owner

jpsim commented Nov 3, 2015

That was easy. Fixed in #83.

@jpsim jpsim closed this as completed in #83 Nov 3, 2015
@tjarratt
Copy link
Author

tjarratt commented Nov 4, 2015

Aww thanks @jpsim. I was real excited to submit a pull request, since it seemed easy, but I guess I can be content knowing I helped improve the product in a small fashion.

Thanks so much for the quick response. I'm very excited to try it out!

Sent From A Very Small Keyboard

On Nov 3, 2015, at 12:02, JP Simard [email protected] wrote:

Closed #82 via #83.


Reply to this email directly or view it on GitHub.

@jpsim
Copy link
Owner

jpsim commented Nov 4, 2015

Haha, sorry to steal your opportunity to contribute! There's no shortage of other issues to fix, however 😉.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants