Skip to content

[IDE] Implement completion-like cursor info for ValueDecls #62362

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

Merged
merged 5 commits into from
Dec 12, 2022

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Dec 2, 2022

This brings up the ability to compute cursor info results using the completion-like type checking paradigm, which an reuse ASTContexts and doesn’t need to type check the entire file.

For now, the new implementation only supports cursor info on ValueDecls (not on references) because they were easiest to implement. More cursor info kinds are coming soon.

At the moment, we only run the new implementation in a verification mode: It is only invoked in assert toolchains and when run, we check that the results are equivalent to the old implementation. Once more cursor info kinds are implemented and if the SourceKit stress tester doesn’t find any verification issues, we can enable the new implementation, falling back to the old implementation if the new one didn’t produce any results.

@ahoppen ahoppen requested a review from rintaro December 2, 2022 11:42
@ahoppen ahoppen force-pushed the ahoppen/completion-like-cursor-info branch 2 times, most recently from 99ca5d0 to 66ae9bd Compare December 6, 2022 12:03
@ahoppen
Copy link
Member Author

ahoppen commented Dec 6, 2022

@swift-ci Please smoke test macOS

@ahoppen
Copy link
Member Author

ahoppen commented Dec 6, 2022

@swift-ci Please SourceKit stress test

@ahoppen ahoppen force-pushed the ahoppen/completion-like-cursor-info branch from 66ae9bd to 2820645 Compare December 6, 2022 23:26
@ahoppen
Copy link
Member Author

ahoppen commented Dec 7, 2022

@swift-ci Please smoke test macOS

@ahoppen
Copy link
Member Author

ahoppen commented Dec 7, 2022

@swift-ci Please SourceKit stress test

Comment on lines -655 to +656
return Impl.getMemoryBuffer(Filename, FileSystem, Error);
return Impl.getFileContent(Filename, /*IsPrimary=*/false, FileSystem, Error)
.Buffer;
Copy link
Member

Choose a reason for hiding this comment

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

Implementation has both getMemoryBuffer and getFileContent, but the public interface only has getMemoryBuffer and it calls Implementation::getFileContent. How confusing 😬

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I know. But 🤷


/// Walks the AST, looking for a node at \c LocToResolves. While walking the
/// AST, also gathers information about shorthand shadows.
class NodeFinder : ASTWalker {
Copy link
Member

Choose a reason for hiding this comment

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

I feel we have too many similar "finder" like this. E.g. ContextFinder in Refactoring.cpp. It'd be great we can consolidate them. But that doesn't block this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I’ll see what I can do in a follow-up PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, IMO ideally we'd do what Clang does here - ie. build up a hierarchy to the deepest node and pass that around everywhere we need it (rather than continually performing the same ASTWalk skipping outside-of-loc ranges in basically every refactoring + cursor info).

Copy link
Member Author

Choose a reason for hiding this comment

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

I filed rdar://103178329 so we don’t forget about it and hope that I’ll get to it at some point.

@@ -794,3 +794,70 @@ void swift::ide::CompletionInstance::conformingMethodList(
Callback);
});
}

void swift::ide::CompletionInstance::cursorInfo(
Copy link
Contributor

Choose a reason for hiding this comment

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

Little weird it's a part of CompletionInstance 😅.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we should rename CompletionInstance. But I didn’t know how else to name it.


/// Walks the AST, looking for a node at \c LocToResolves. While walking the
/// AST, also gathers information about shorthand shadows.
class NodeFinder : ASTWalker {
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, IMO ideally we'd do what Clang does here - ie. build up a hierarchy to the deepest node and pass that around everywhere we need it (rather than continually performing the same ASTWalk skipping outside-of-loc ranges in basically every refactoring + cursor info).

let xxx = "hello"
#endif
}
// TODO: Once we switch to use the solver-based cursor info implementation, we also receive results for the int case
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it handle unparsed #if regions?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it just fell out of the implementation that it does. I think we just type check whatever decl the cursor info points to. I’m not entirely sure how well it works if the decl you invoke cursor info on references other variables in a #if though.

// RUN: %{python} %utils/split_file.py -o %t/split %s
// RUN: %empty-directory(%t/build)
// RUN: %target-swift-frontend -emit-module -module-name MyModule -emit-module-path %t/build/MyModule.swiftmodule -emit-module-source-info-path %t/build/MyModule.swiftsourceinfo %t/split/Action.swift
// RUN: %sourcekitd-test -req=cursor -req-opts=retrieve_symbol_graph=1 -pos=5:14 %t/split/test.swift -- %t/split/test.swift -I %t/build | %FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason to include the symbol graph here rather than just doing cursor info on Action and checking the file/line/col? I would have thought we have a check for that already though, do we really not?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because AFAICT symbol graph causes REFERENCED DECLS to be returned and that’s what references the source file from .swiftsourceinfo.

Copy link
Contributor

Choose a reason for hiding this comment

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

Doing a cursor info on Action should also end up using the .swiftsourceinfo. REFERENCED DECLS does as well because the decl is actually the type of the decl you're doing cursor info on. But as I said, I'm very surprised we don't already have a test for that.

Copy link
Member Author

Choose a reason for hiding this comment

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

For reasons I don’t fully understand (I haven’t really done any investigation though) we report the correct source location of Action even when we’re not using .swiftsourceinfo.

This brings up the ability to compute cursor info results using the completion-like type checking paradigm, which an reuse ASTContexts and doesn’t need to type check the entire file.

For now, the new implementation only supports cursor info on `ValueDecl`s (not on references) because they were easiest to implement. More cursor info kinds are coming soon.

At the moment, we only run the new implementation in a verification mode: It is only invoked in assert toolchains and when run, we check that the results are equivalent to the old implementation. Once more cursor info kinds are implemented and if the SourceKit stress tester doesn’t find any verification issues, we can enable the new implementation, falling back to the old implementation if the new one didn’t produce any results.
…ming the second code completion pass

Otherwise, the closure discriminator will be incremented by one when the closure witht he code completion token is parsed a second time during the second pass, and thus it would receive a different discriminator during the second pass.
Cursor infor needs source info for referenced decls.
@ahoppen
Copy link
Member Author

ahoppen commented Dec 8, 2022

Note to self: The stress tester failure at offset 300 of modification concurrent-359 of rows/MovieRow.swift has the following reduce reproducer:

// RUN: %sourcekitd-test -req=cursor -req-opts=retrieve_symbol_graph=1 -pos=5:12 %s -- %s

let formatter: DateFormatter = {
  struct MovieRow {
    struct Props

The solver-based implementation reports Props as conforming to Sendable in symbol graph, the AST-based implementation does not report this. I think this change is acceptable and I’ll just mark this discrepancy as an XFail in the stress tester.

@ahoppen ahoppen force-pushed the ahoppen/completion-like-cursor-info branch from 3b52924 to e777d37 Compare December 8, 2022 14:40
@ahoppen
Copy link
Member Author

ahoppen commented Dec 8, 2022

@swift-ci Please SourceKit stress test

1 similar comment
@ahoppen
Copy link
Member Author

ahoppen commented Dec 9, 2022

@swift-ci Please SourceKit stress test

@ahoppen
Copy link
Member Author

ahoppen commented Dec 9, 2022

@swift-ci Please smoke test

@ahoppen
Copy link
Member Author

ahoppen commented Dec 9, 2022

@swift-ci Please smoke test macOS

…ursorInfo

The lexer will be responsible for knowing whether we have a code completion token, everything else will also work for other IDE inspection features.

The changes start to really make sense once I rename CodeCompletion -> IDEInspection in a lot of places.
@ahoppen ahoppen force-pushed the ahoppen/completion-like-cursor-info branch from 2e9ebf9 to 9a0a772 Compare December 10, 2022 11:19
@ahoppen
Copy link
Member Author

ahoppen commented Dec 10, 2022

@swift-ci Please SourceKit stress test

@ahoppen
Copy link
Member Author

ahoppen commented Dec 10, 2022

@swift-ci Please smoke test

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.

3 participants