@@ -4,59 +4,100 @@ namespace GodotSharp.SourceGenerators;
44
55public static class CompilationExtensions
66{
7- public static string GetFullName ( this Compilation compilation , string type , string hint = "" )
7+ // TODO: Cache?
8+ public static string GetValidType ( this Compilation compilation , string type )
89 {
9- return ResolveDuplicates ( compilation . GetSymbolsWithName ( type , SymbolFilter . Type ) ) ? . GlobalName ( ) ;
10+ return SearchCurrentCompilation ( )
11+ ?? SearchReferencedAssemblies ( ) ;
1012
11- ISymbol ResolveDuplicates ( IEnumerable < ISymbol > symbols )
13+ string SearchCurrentCompilation ( )
14+ => compilation . ContainsSymbolsWithName ( type , SymbolFilter . Type ) ? type : null ;
15+
16+ string SearchReferencedAssemblies ( )
1217 {
13- if ( symbols . Skip ( 1 ) . Any ( ) )
14- {
15- symbols = symbols // Ignore generics
16- . Where ( x => x . MetadataName == type ) ;
18+ var refs = compilation . GetUsedAssemblyReferences ( )
19+ . Select ( compilation . GetAssemblyOrModuleSymbol )
20+ . Cast < IAssemblySymbol > ( )
21+ . OrderByDescending ( asm => asm . Name is "GodotSharp" ) ;
1722
18- if ( symbols . Skip ( 1 ) . Any ( ) )
23+ foreach ( var asm in refs )
24+ {
25+ if ( asm . Name is "GodotSharp" )
1926 {
20- // Differentiate by path
21- symbols = symbols . Where ( x => x . Locations . Select ( x => x . GetLineSpan ( ) . Path . Replace ( "\\ " , "/" ) ) . Any ( x => x . EndsWith ( hint ) ) ) ;
22-
23- if ( symbols . Skip ( 1 ) . Any ( ) )
24- Log . Warn ( $ "Choosing first from multiple candidates [Type: { type } , Namespaces: { string . Join ( "|" , symbols . Select ( x => x . Namespace ( ) ) ) } ]") ;
27+ // Some names in Godot have mismatched case (mostly 2d/2D & 3d,3D)
28+ var csType = asm . TypeNames . FirstOrDefault ( x => x . Equals ( type , StringComparison . OrdinalIgnoreCase ) ) ;
29+ if ( csType is not null ) return csType ;
2530 }
31+
32+ Log . Debug ( $ "*** Searching for { type } in { asm . Name } ") ;
33+
34+ if ( asm . TypeNames . Contains ( type ) )
35+ return type ;
2636 }
2737
28- return symbols . FirstOrDefault ( ) ;
38+ return null ;
2939 }
3040 }
3141
32- public static string GetValidType ( this Compilation compilation , string type )
42+ // TODO: Cache?
43+ public static string GetFullName ( this Compilation compilation , string type )
3344 {
3445 return SearchCurrentCompilation ( )
3546 ?? SearchReferencedAssemblies ( ) ;
3647
37- string SearchCurrentCompilation ( )
38- => compilation . ContainsSymbolsWithName ( type , SymbolFilter . Type ) ? type : null ;
48+ string SearchCurrentCompilation ( ) => compilation
49+ . GetSymbolsWithName ( type , SymbolFilter . Type )
50+ . FirstOrDefault ( ) ? . FullName ( ) ; // TODO: Resolve duplicates with hint if required (eg, ns/filepath)
3951
4052 string SearchReferencedAssemblies ( )
4153 {
4254 var refs = compilation . GetUsedAssemblyReferences ( )
4355 . Select ( compilation . GetAssemblyOrModuleSymbol )
44- . Cast < IAssemblySymbol > ( ) ;
56+ . Cast < IAssemblySymbol > ( )
57+ . OrderByDescending ( asm => asm . Name is "GodotSharp" ) ;
4558
4659 foreach ( var asm in refs )
4760 {
48- if ( asm . Name . StartsWith ( "GodotSharp" ) )
61+ if ( asm . Name is "GodotSharp" )
4962 {
5063 // Some names in Godot have mismatched case (mostly 2d/2D & 3d,3D)
5164 var csType = asm . TypeNames . FirstOrDefault ( x => x . Equals ( type , StringComparison . OrdinalIgnoreCase ) ) ;
52- if ( csType is not null ) return csType ;
65+ if ( csType is not null ) return $ "Godot. { csType } " ;
5366 }
5467
68+ Log . Debug ( $ "*** Searching for { type } in { asm . Name } ") ;
69+
5570 if ( asm . TypeNames . Contains ( type ) )
56- return type ;
71+ return type ; // TODO: Walk namspace/type symbols if required
5772 }
5873
5974 return null ;
6075 }
6176 }
77+
78+ // Old
79+ public static string GetFullName ( this Compilation compilation , string type , string hint )
80+ {
81+ return ResolveDuplicates ( compilation . GetSymbolsWithName ( type , SymbolFilter . Type ) ) ? . GlobalName ( ) ;
82+
83+ ISymbol ResolveDuplicates ( IEnumerable < ISymbol > symbols )
84+ {
85+ if ( symbols . Skip ( 1 ) . Any ( ) )
86+ {
87+ symbols = symbols // Ignore generics
88+ . Where ( x => x . MetadataName == type ) ;
89+
90+ if ( symbols . Skip ( 1 ) . Any ( ) )
91+ {
92+ // Differentiate by path
93+ symbols = symbols . Where ( x => x . Locations . Select ( x => x . GetLineSpan ( ) . Path . Replace ( "\\ " , "/" ) ) . Any ( x => x . EndsWith ( hint ) ) ) ;
94+
95+ if ( symbols . Skip ( 1 ) . Any ( ) )
96+ Log . Warn ( $ "Choosing first from multiple candidates [Type: { type } , Namespaces: { string . Join ( "|" , symbols . Select ( x => x . Namespace ( ) ) ) } ]") ;
97+ }
98+ }
99+
100+ return symbols . FirstOrDefault ( ) ;
101+ }
102+ }
62103}
0 commit comments