-
Notifications
You must be signed in to change notification settings - Fork 320
Fix module definition jumping in Swift interface files #2233
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
base: main
Are you sure you want to change the base?
Changes from 9 commits
4058ac6
dd7de19
62334c0
d0e544e
f509987
e147601
67e5f17
82cc691
d143d8d
8dfcbfa
c9a943e
b372182
05d8d02
6f4ee70
36a5f83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1850,10 +1850,24 @@ extension SourceKitLSPServer { | |
languageService: LanguageService | ||
) async throws -> [Location] { | ||
// If this symbol is a module then generate a textual interface | ||
if symbol.kind == .module, let name = symbol.name { | ||
if symbol.kind == .module { | ||
// For module symbols, prefer using systemModule information if available | ||
let moduleName: String | ||
let groupName: String? | ||
|
||
if let systemModule = symbol.systemModule { | ||
moduleName = systemModule.moduleName | ||
groupName = systemModule.groupName | ||
} else if let name = symbol.name { | ||
moduleName = name | ||
groupName = nil | ||
} else { | ||
return [] | ||
} | ||
|
||
let interfaceLocation = try await self.definitionInInterface( | ||
moduleName: name, | ||
groupName: nil, | ||
moduleName: moduleName, | ||
groupName: groupName, | ||
symbolUSR: nil, | ||
originatorUri: uri, | ||
languageService: languageService | ||
|
@@ -2051,9 +2065,34 @@ extension SourceKitLSPServer { | |
originatorUri: DocumentURI, | ||
languageService: LanguageService | ||
) async throws -> Location { | ||
// Check if we're already in the target interface with the same module/group/symbol | ||
if case .generatedInterface(let interfaceData) = try? ReferenceDocumentURL(from: originatorUri), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment still applies here: #2233 |
||
interfaceData.moduleName == moduleName && interfaceData.groupName == groupName { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly to my other comments about the build settings, we need to check here that we are using build settings from the same original file. But I think as long as we pass along the same build settings file, this shouldn’t cause any issues. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ahoppen Thanks for the comment without this change, here would happen if I open defination of Cause:
this makes the logic quite complicated
I think we could assume the interface is the same if the interface was originally opened from a same then we could simplify the originalUri as
the benefits are
Untitled.movThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, IMO when doing a jump to definition from within an interface, the
|
||
// If we have a specific symbol USR, try to find its position in the current interface | ||
if let symbolUSR = symbolUSR, | ||
let swiftLanguageService = languageService as? SwiftLanguageService { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m currently trying to unravel the dependency of the What are the challenges of always going through
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. adding a group might be a good idea i imagine there could be different versions of swiftinterface which are used by different modules/files i think the challenge is how to determine it in the beginning instead of a uuid |
||
do { | ||
let position = try await swiftLanguageService.generatedInterfaceManager.position( | ||
ofUsr: symbolUSR, | ||
in: interfaceData | ||
) | ||
return Location(uri: originatorUri, range: Range(position)) | ||
} catch { | ||
// If we can't find the symbol, just return the top of the current interface | ||
return Location(uri: originatorUri, range: Range(Position(line: 0, utf16index: 0))) | ||
} | ||
} else { | ||
// No specific symbol, just return the current interface location | ||
return Location(uri: originatorUri, range: Range(Position(line: 0, utf16index: 0))) | ||
} | ||
} | ||
|
||
// If the originator URI is already a generated interface, use its primary file for build settings | ||
let documentForBuildSettings = originatorUri.primaryFile ?? originatorUri | ||
|
||
guard | ||
let interfaceDetails = try await languageService.openGeneratedInterface( | ||
document: originatorUri, | ||
document: documentForBuildSettings, | ||
moduleName: moduleName, | ||
groupName: groupName, | ||
symbolUSR: symbolUSR | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,14 +122,22 @@ package enum ReferenceDocumentURL { | |
var buildSettingsFile: DocumentURI { | ||
switch self { | ||
case .macroExpansion(let data): return data.primaryFile | ||
case .generatedInterface(let data): return data.buildSettingsFrom | ||
case .generatedInterface(let data): | ||
if let referenceDocumentURL = try? ReferenceDocumentURL(from: data.buildSettingsFrom) { | ||
return referenceDocumentURL.buildSettingsFile | ||
} | ||
return data.buildSettingsFrom | ||
} | ||
} | ||
|
||
var primaryFile: DocumentURI? { | ||
switch self { | ||
case .macroExpansion(let data): return data.primaryFile | ||
case .generatedInterface(let data): return data.buildSettingsFrom.primaryFile | ||
case .generatedInterface(let data): | ||
if let referenceDocumentURL = try? ReferenceDocumentURL(from: data.buildSettingsFrom) { | ||
return referenceDocumentURL.primaryFile | ||
} | ||
return data.buildSettingsFrom.primaryFile | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
} | ||
} | ||
|
@@ -170,8 +178,4 @@ extension DocumentURI { | |
|
||
package struct ReferenceDocumentURLError: Error, CustomStringConvertible { | ||
package var description: String | ||
|
||
init(description: String) { | ||
self.description = description | ||
} | ||
} |
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.
Similar to my other comment about the
.swiftinterface
extension, I don’t think we need this here, do we? This only applies to tests and I don’t think we open any.swiftinterface
files in tests.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 deleted but please check the tests about
swiftinterface