-
Notifications
You must be signed in to change notification settings - Fork 314
Show overriden functions when performing jump-to-definition on a dynamic call #977
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
Conversation
@swift-ci Please test |
5e89ed3
to
a3f7f11
Compare
@swift-ci Please test |
@swift-ci Please test Windows |
logger.info("performing indexed jump-to-def with usr \(usr)") | ||
var occurs = index.occurrences(ofUSR: usr, roles: [.definition]) | ||
if occurs.isEmpty { | ||
occurs = index.occurrences(ofUSR: usr, roles: [.declaration]) | ||
} | ||
if symbolDetails.isDynamic { | ||
occurs += occurs.flatMap { | ||
index.occurrences(relatedToUSR: $0.symbol.usr, roles: .overrideOf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we should filter by receivers here, ie.
- Get the set of types to filter (receivers + their subtypes)
- For each override check if it's a child of one of the types in the filter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a filter by receiver types.
@@ -1725,12 +1725,18 @@ extension SourceKitServer { | |||
} | |||
|
|||
let resolved = self.extractIndexedOccurrences(symbols: symbols, index: index, useLocalFallback: true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could just skip this if the symbol isn't dynamic - the index will be at most up to date as the location in the module, or worse. Though that would change if background indexing was added (or preparation, if we go that route instead).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I just noticed this is on SourceKitServer and not the language service. Would still be nice to skip for Swift IMO. As for clangd not returning dynamic, that's something we could change (the request we're using is one we specifically added for this use case - https://reviews.llvm.org/D54799). But in the meantime, I'd default to returning overrides if isDynamic
isn't set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed it so that we don’t do an index lookup if SymbolRequest
returns a location.
a3f7f11
to
1ccccc3
Compare
@swift-ci Please test |
…mic call Fixes swiftlang#809 rdar://114864256
`extractIndexedOccurences` mostly dealt with how to create a fallback value and we didn’t support fallback values in 3/4 cases. Remove it, simplifying the callers of `extractIndexedOccurances` along the way.
9aa0257
to
84fdea9
Compare
@swift-ci Please test |
@swift-ci Please test Windows |
return [] | ||
} | ||
|
||
if let symbol = symbols.first, let bestLocalDeclaration = symbol.bestLocalDeclaration, !(symbol.isDynamic ?? false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we default isDynamic
to true
so that it's always doing an index lookup (this would be the clang case)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you’re right. I added a test case for this.
guard let symbol = symbols.first else { | ||
return [] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize the old code only handled a single result, but is there any reason not to just handle multiple for all of these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is not. I thought we had an issue for this but looks like we don’t. Filed rdar://119163908
// if first resolved location is in `.swiftinterface` file. Use moduleName to return | ||
// textual interface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "first" here mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it used to refer to the fact that everything was based on symbols.first
. Rephrased the comment slightly.
do { | ||
return try await languageService.definition(req) | ||
} catch {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we ignoring the error here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to orLog
and added the following comment:
We are on only calling the language service's
definition
function if your index-based lookup failed. If this fallback request fails, its error is usually not very enlightening. For example theSwiftLanguageServer
will always respond withunsupported method
. Thus, only log such a failure instead of returning it to the client.
// Only contain overrides that are children of one of the receiver types or their subtypes. | ||
return overrides.filter { override in | ||
override.relations.contains(where: { | ||
$0.roles.contains(.childOf) && transitiveReceiverUsrs.contains($0.symbol.usr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$0.roles.contains(.childOf) && transitiveReceiverUsrs.contains($0.symbol.usr) | |
$0.roles.contains(.childOf) && (transitiveReceiverUsrs.isEmpty || transitiveReceiverUsrs.contains($0.symbol.usr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed that as well. Changed it slightly so that transitiveReceiverUsrs
is nil
if not receivers were passed.
@swift-ci Please test |
1 similar comment
@swift-ci Please test |
Fixes #809
rdar://114864256