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

[SourceKit] Add CollectVariableType request #37867

Merged
merged 5 commits into from
Jun 24, 2021

Conversation

fwcd
Copy link
Member

@fwcd fwcd commented Jun 10, 2021

To provide accurate support for inlay type hints in SourceKit-LSP (see swiftlang/sourcekit-lsp#406 for details), this PR introduces a new request called CollectVariableType. Although similar to CollectExpressionType, the new request provides types for variable declarations and closure parameters specifically, together with the identifiers' ranges and a flag stating whether there already exists an explicit type annotation.

Example

let x: Int = 3
var y = "test"

yields the following response:

<VariableTypes>
(4, 5): Int (explicit type: 1)
(19, 20): String (explicit type: 0)
</VariableTypes>

Additions to the SourceKit protocol

The request looks like this:

{
    <key.request>:            (UID)     <source.request.variable.type>,
    <key.sourcefile>:         (string)  // Absolute path to the file.
    <key.compilerargs>:       [string*] // Array of zero or more strings for the compiler arguments,
                                        // e.g ["-sdk", "/path/to/sdk"]. If key.sourcefile is provided,
                                        // these must include the path to that file.
    [opt] <key.offset>:       (int64)   // Offset of the requested range. Defaults to zero.
    [opt] <key.length>:       (int64)   // Length of the requested range. Defaults to the entire file.
}

The response looks like this:

{
    <key.variable_type_list>: (array) [var-type-info*]   // A list of variable declarations and types
}

var-type-info ::=
{
    <key.variable_offset>:       (int64)    // Offset of a variable identifier in the source file
    <key.variable_length>:       (int64)    // Length of a variable identifier an expression in the source file
    <key.variable_type>:         (string)   // Printed type of the variable declaration
    <key.variable_type_explicit> (bool)     // Whether the declaration has an explicit type annotation
}

Implementation Progress

  • Add VariableTypeCollector that traverses AST and collects variable type information
  • Implement the new request handler
  • Add tests verifying basic use-cases (local variables, fields, parameters, declarations with and without type annotations)
  • Add support for ranged requests (key.offset, key.length)

@fwcd fwcd marked this pull request as ready for review June 10, 2021 21:14
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looking good to me. I’ve added some questions and comments inline.

lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
include/swift/Sema/IDETypeChecking.h Outdated Show resolved Hide resolved
tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
tools/SourceKit/include/SourceKit/Core/LangSupport.h Outdated Show resolved Hide resolved
include/swift/Sema/IDETypeChecking.h Outdated Show resolved Hide resolved
@fwcd
Copy link
Member Author

fwcd commented Jun 14, 2021

Thanks for the feedback, I've followed the implementation of ExpressionTypeInfo pretty closely for now, but I will make sure to address these issues.

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, I only now managed to look through the code. Unfortunately, after looking at the implementation of the new TypeVariableArray, I remembered why we needed the approach with the output stream + offsets in ExpressionTypeArrayBuilder and I think it’s also necessary for VariableTypeArray 😬. Sorry for the back and forth about this.

lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
test/SourceKit/VariableType/ranged.swift Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
tools/SourceKit/include/SourceKit/Core/LangSupport.h Outdated Show resolved Hide resolved
tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp Outdated Show resolved Hide resolved
tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp Outdated Show resolved Hide resolved
tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp Outdated Show resolved Hide resolved
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I’ve got some more comments inline.

include/swift/Sema/IDETypeChecking.h Outdated Show resolved Hide resolved
include/swift/Sema/IDETypeChecking.h Outdated Show resolved Hide resolved
include/swift/Sema/IDETypeChecking.h Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
@fwcd
Copy link
Member Author

fwcd commented Jun 21, 2021

I have updated the implementation to use SourceRanges as suggested and will now rebase the branch on main to resolve the merge conflict and squash related commits.

fwcd added 3 commits June 21, 2021 19:28
- Add VariableTypeCollector
  This new SourceEntityWalker collects types from variable declarations.
- Add SwiftLangSupport::collectVariableTypes
- Implement CollectVariableType request
- Provide information about explicit types in CollectVarType
- Fix HasExplicitType in VariableTypeArray
- Fix typo
- Implement ranged CollectVariableTypes requests
- Use offset/length params for CollectVariableType in sourcekitd-test
- Address a bunch of PR suggestions
- Remove CanonicalType from VariableTypeCollector
  This turned out not to be needed (for now).
- Improve doc comment on VariableTypeCollector::getTypeOffsets
- Remove unused CanonicalTy variable
- Remove out-of-date comment
- Run clang-format on the CollectVariableType implementation
- Fix some minor style issues
- Use emplace_back while collecting variable infos
- Pass CollectVariableType range to VariableTypeCollector
- Use capitalized variable names in VariableTypeArray
  ...as recommended by the LLVM coding standards
- Use PrintOptions for type printing in VariableTypeCollector
- Return void for collectVariableType
  This seems to be cleaner stylistically.
- Avoid visiting subranges of invalid range in VariableTypeCollector
- Use std::string for type buffer in VariableTypeCollectorASTConsumer
- Use plural for PrintedType in VariableTypeArray
- Remove unused fields in VariableTypeArrayBuilder
- Add suggested doc comments to VariableTypeArray
- Remove unused VariableTypeInfo.TypeLength
- Fix typo of ostream in VariableTypeCollectorASTConsumer
- Fix typo
- Document Offset and Length semantics in collectVariableTypes
- Add CollectVariableType test for function/closure parameters
- Test ranged CollectVariableType request
- Add separate test for ranged CollectVariableType
- Use line:col positions in sourcekitd-test for var types
- Add test case for CollectVariableType and inout params
- Update ranged CollectVariableType test
  ...as per the PR suggestions.
- Fix style issue
- Add SourceRange::contains and SourceRange::overlaps
- Use SourceRange in VariableTypeCollector
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve got some minor comments regarding variable names and doc comments again. Other than that, it’s looking great. Can’t wait to try this out with the editor.

include/swift/Sema/IDETypeChecking.h Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
lib/IDE/IDETypeChecking.cpp Outdated Show resolved Hide resolved
fwcd added 2 commits June 22, 2021 15:02
Also add a test to verify that error types get ignored (as intended).
Rename VariableTypeCollector::getTypeOffsets to ::getTypeOffset and only
return the start offset, since the end offset is no longer needed (the
string is null-terminated).

Also improve variable naming slightly.
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Let’s get this 🚢ed.

@ahoppen
Copy link
Member

ahoppen commented Jun 22, 2021

@swift-ci Please smoke test

@ahoppen ahoppen merged commit ba910cc into swiftlang:main Jun 24, 2021
@fwcd fwcd deleted the sourcekit-var-types branch June 24, 2021 09:46
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

Successfully merging this pull request may close these issues.

2 participants