@@ -554,22 +554,50 @@ extension SourceKitServer {
554
554
index: IndexStoreDB
555
555
) async throws -> CrossLanguageName ? {
556
556
let definitions = index. occurrences ( ofUSR: usr, roles: [ . definition] )
557
- guard let definitionSymbol = definitions. only else {
558
- if definitions. isEmpty {
559
- logger. error ( " no definitions for \( usr) found " )
560
- } else {
561
- logger. error ( " Multiple definitions for \( usr) found " )
562
- }
557
+ if definitions. isEmpty {
558
+ logger. error ( " no definitions for \( usr) found " )
563
559
return nil
564
560
}
561
+ if definitions. count > 1 {
562
+ logger. log ( " Multiple definitions for \( usr) found " )
563
+ }
564
+ // There might be multiple definitions of the same symbol eg. in different `#if` branches. In this case pick any of
565
+ // them because with very high likelihood they all translate to the same clang and Swift name. Sort the entries to
566
+ // ensure that we deterministically pick the same entry every time.
567
+ for definitionOccurrence in definitions. sorted ( ) {
568
+ do {
569
+ return try await getCrossLanguageName (
570
+ forDefinitionOccurrence: definitionOccurrence,
571
+ overrideName: overrideName,
572
+ workspace: workspace,
573
+ index: index
574
+ )
575
+ } catch {
576
+ // If getting the cross-language name fails for this occurrence, try the next definition, if there are multiple.
577
+ logger. log (
578
+ " Getting cross-language name for occurrence at \( definitionOccurrence. location) failed. \( error. forLogging) "
579
+ )
580
+ }
581
+ }
582
+ return nil
583
+ }
584
+
585
+ private func getCrossLanguageName(
586
+ forDefinitionOccurrence definitionOccurrence: SymbolOccurrence ,
587
+ overrideName: String ? = nil ,
588
+ workspace: Workspace ,
589
+ index: IndexStoreDB
590
+ ) async throws -> CrossLanguageName {
591
+ let definitionSymbol = definitionOccurrence. symbol
592
+ let usr = definitionSymbol. usr
565
593
let definitionLanguage : Language =
566
- switch definitionSymbol. symbol . language {
594
+ switch definitionSymbol. language {
567
595
case . c: . c
568
596
case . cxx: . cpp
569
597
case . objc: . objective_c
570
598
case . swift: . swift
571
599
}
572
- let definitionDocumentUri = DocumentURI ( URL ( fileURLWithPath: definitionSymbol . location. path) )
600
+ let definitionDocumentUri = DocumentURI ( URL ( fileURLWithPath: definitionOccurrence . location. path) )
573
601
574
602
guard
575
603
let definitionLanguageService = await self . languageService (
@@ -578,25 +606,24 @@ extension SourceKitServer {
578
606
in: workspace
579
607
)
580
608
else {
581
- logger. fault ( " Failed to get language service for the document defining \( usr) " )
582
- return nil
609
+ throw ResponseError . unknown ( " Failed to get language service for the document defining \( usr) " )
583
610
}
584
611
585
- let definitionName = overrideName ?? definitionSymbol. symbol . name
612
+ let definitionName = overrideName ?? definitionSymbol. name
586
613
587
614
switch definitionLanguageService {
588
615
case is ClangLanguageServerShim :
589
616
let swiftName : String ?
590
617
if let swiftReference = await getReferenceFromSwift ( usr: usr, index: index, workspace: workspace) {
591
- let isObjectiveCSelector = definitionLanguage == . objective_c && definitionSymbol. symbol . kind. isMethod
618
+ let isObjectiveCSelector = definitionLanguage == . objective_c && definitionSymbol. kind. isMethod
592
619
swiftName = try await swiftReference. languageServer. translateClangNameToSwift (
593
620
at: swiftReference. location,
594
621
in: swiftReference. snapshot,
595
622
isObjectiveCSelector: isObjectiveCSelector,
596
623
name: definitionName
597
624
)
598
625
} else {
599
- logger. debug ( " Not translating \( usr ) to Swift because it is not referenced from Swift " )
626
+ logger. debug ( " Not translating \( definitionSymbol ) to Swift because it is not referenced from Swift " )
600
627
swiftName = nil
601
628
}
602
629
return CrossLanguageName ( clangName: definitionName, swiftName: swiftName, definitionLanguage: definitionLanguage)
@@ -610,7 +637,7 @@ extension SourceKitServer {
610
637
let clangName : String ?
611
638
if hasReferenceFromClang {
612
639
clangName = try await swiftLanguageServer. translateSwiftNameToClang (
613
- at: definitionSymbol . location,
640
+ at: definitionOccurrence . location,
614
641
in: definitionDocumentUri,
615
642
name: CompoundDeclName ( definitionName)
616
643
)
0 commit comments