@@ -24,7 +24,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
24
24
25
25
var vtablesToAddFromClassTypes = context . SyntaxProvider . CreateSyntaxProvider (
26
26
static ( n , _ ) => NeedVtableAttribute ( n ) ,
27
- static ( n , _ ) => GetVtableAttributeToAdd ( n )
27
+ static ( n , _ ) => GetVtableAttributeToAdd ( n , false )
28
28
) . Where ( static vtableAttribute => vtableAttribute != default ) ;
29
29
30
30
var vtableAttributesToAdd = vtablesToAddFromClassTypes . Select ( static ( vtable , _ ) => vtable . Item1 ) ;
@@ -36,7 +36,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
36
36
// that will already be generated by the component generator.
37
37
var vtablesFromComponentTypes = context . SyntaxProvider . CreateSyntaxProvider (
38
38
static ( n , _ ) => IsComponentType ( n ) ,
39
- static ( n , _ ) => GetVtableAttributeToAdd ( n )
39
+ static ( n , _ ) => GetVtableAttributeToAdd ( n , true )
40
40
) . Where ( static vtableAttribute => vtableAttribute != default ) . Collect ( ) . Combine ( properties ) .
41
41
// Get component types if only authoring scenario
42
42
SelectMany ( static ( ( ImmutableArray < ( VtableAttribute vtableAttribute , EquatableArray < VtableAttribute > adapterTypes ) > classTypes , ( bool , bool isCsWinRTComponent , bool ) properties ) value , CancellationToken _ ) =>
@@ -45,7 +45,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
45
45
var instantiatedTypesToAddOnLookupTable = context . SyntaxProvider . CreateSyntaxProvider (
46
46
static ( n , _ ) => NeedVtableOnLookupTable ( n ) ,
47
47
static ( n , _ ) => GetVtableAttributesToAddOnLookupTable ( n )
48
- ) . SelectMany ( static ( vtable , _ ) => vtable ) .
48
+ ) . Combine ( properties )
49
+ // Get component types if only authoring scenario
50
+ . Select ( static ( ( ( EquatableArray < VtableAttribute > lookupTable , EquatableArray < VtableAttribute > componentLookupTable ) vtableAttributes , ( bool , bool isCsWinRTComponent , bool ) properties ) value , CancellationToken _ ) =>
51
+ value . properties . isCsWinRTComponent ? value . vtableAttributes . componentLookupTable : value . vtableAttributes . lookupTable )
52
+ . SelectMany ( static ( vtable , _ ) => vtable ) .
49
53
Where ( static vtableAttribute => vtableAttribute != null ) ;
50
54
51
55
var instantiatedTaskAdapters = context . SyntaxProvider . CreateSyntaxProvider (
@@ -108,16 +112,19 @@ private static bool IsComponentType(SyntaxNode node)
108
112
! GeneratorHelper . IsWinRTType ( declaration ) ; // Making sure it isn't an RCW we are projecting.
109
113
}
110
114
111
- private static ( VtableAttribute , EquatableArray < VtableAttribute > ) GetVtableAttributeToAdd ( GeneratorSyntaxContext context )
115
+ private static ( VtableAttribute , EquatableArray < VtableAttribute > ) GetVtableAttributeToAdd ( GeneratorSyntaxContext context , bool checkForComponentTypes )
112
116
{
117
+ var isWinRTTypeFunc = checkForComponentTypes ?
118
+ GeneratorHelper . IsWinRTTypeWithPotentialAuthoringComponentTypesFunc ( context . SemanticModel . Compilation ) :
119
+ GeneratorHelper . IsWinRTType ;
113
120
var symbol = context . SemanticModel . GetDeclaredSymbol ( context . Node as ClassDeclarationSyntax ) ;
114
- var vtableAttribute = GetVtableAttributeToAdd ( symbol , GeneratorHelper . IsWinRTType , context . SemanticModel . Compilation , false ) ;
121
+ var vtableAttribute = GetVtableAttributeToAdd ( symbol , isWinRTTypeFunc , context . SemanticModel . Compilation , false ) ;
115
122
if ( vtableAttribute != default )
116
123
{
117
124
HashSet < VtableAttribute > vtableAttributesForLookupTable = [ ] ;
118
125
// Add any adapter types which may be needed if certain functions
119
126
// from some known interfaces are called.
120
- AddVtableAdapterTypeForKnownInterface ( symbol , context . SemanticModel . Compilation , GeneratorHelper . IsWinRTType , vtableAttributesForLookupTable ) ;
127
+ AddVtableAdapterTypeForKnownInterface ( symbol , context . SemanticModel . Compilation , isWinRTTypeFunc , vtableAttributesForLookupTable ) ;
121
128
return ( vtableAttribute , vtableAttributesForLookupTable . ToImmutableArray ( ) ) ;
122
129
}
123
130
@@ -194,19 +201,13 @@ private static (VtableAttribute, VtableAttribute) GetVtableAttributesForTaskAdap
194
201
{
195
202
var constructedAdapterType = adpaterType . Construct ( [ .. symbol . TypeArguments ] ) ;
196
203
return ( GetVtableAttributeToAdd ( constructedAdapterType , GeneratorHelper . IsWinRTType , context . SemanticModel . Compilation , false ) ,
197
- GetVtableAttributeToAdd ( constructedAdapterType , IsWinRTTypeWithPotentialAuthoringComponentTypes , context . SemanticModel . Compilation , false ) ) ;
204
+ GetVtableAttributeToAdd ( constructedAdapterType , GeneratorHelper . IsWinRTTypeWithPotentialAuthoringComponentTypesFunc ( context . SemanticModel . Compilation ) , context . SemanticModel . Compilation , false ) ) ;
198
205
}
199
206
}
200
207
}
201
208
}
202
209
203
210
return default ;
204
-
205
- bool IsWinRTTypeWithPotentialAuthoringComponentTypes ( ISymbol type )
206
- {
207
- var winrtTypeAttribute = context . SemanticModel . Compilation . GetTypeByMetadataName ( "WinRT.WindowsRuntimeTypeAttribute" ) ;
208
- return GeneratorHelper . IsWinRTType ( type , winrtTypeAttribute , true , context . SemanticModel . Compilation . Assembly ) ;
209
- }
210
211
}
211
212
212
213
private static string ToFullyQualifiedString ( ISymbol symbol )
@@ -836,7 +837,18 @@ node is VariableDeclarationSyntax ||
836
837
node is ReturnStatementSyntax ;
837
838
}
838
839
839
- private static EquatableArray < VtableAttribute > GetVtableAttributesToAddOnLookupTable ( GeneratorSyntaxContext context )
840
+ private static ( EquatableArray < VtableAttribute > , EquatableArray < VtableAttribute > ) GetVtableAttributesToAddOnLookupTable ( GeneratorSyntaxContext context )
841
+ {
842
+ // Get the lookup table as if we are running in an authoring component scenario and as if we are not
843
+ // and then use the properties later on when we have access to it to check if we are to choose the right one.
844
+ // Otherwise we will end up generating lookup tables which don't have vtable entries for authoring types.
845
+ return ( GetVtableAttributesToAddOnLookupTable ( context , GeneratorHelper . IsWinRTType ) ,
846
+ GetVtableAttributesToAddOnLookupTable ( context , GeneratorHelper . IsWinRTTypeWithPotentialAuthoringComponentTypesFunc ( context . SemanticModel . Compilation ) ) ) ;
847
+ }
848
+
849
+ private static EquatableArray < VtableAttribute > GetVtableAttributesToAddOnLookupTable (
850
+ GeneratorSyntaxContext context ,
851
+ Func < ISymbol , bool > isWinRTType )
840
852
{
841
853
HashSet < ITypeSymbol > visitedTypes = new ( SymbolEqualityComparer . Default ) ;
842
854
HashSet < VtableAttribute > vtableAttributes = new ( ) ;
@@ -850,7 +862,7 @@ private static EquatableArray<VtableAttribute> GetVtableAttributesToAddOnLookupT
850
862
// and end up calling a projection function (i.e. ones generated by XAML compiler)
851
863
// In theory, another library can also be called which can call a projected function
852
864
// but not handling those scenarios for now.
853
- ( GeneratorHelper . IsWinRTType ( methodSymbol . ContainingSymbol ) ||
865
+ ( isWinRTType ( methodSymbol . ContainingSymbol ) ||
854
866
SymbolEqualityComparer . Default . Equals ( methodSymbol . ContainingAssembly , context . SemanticModel . Compilation . Assembly ) ) )
855
867
{
856
868
// Get the concrete types directly from the argument rather than
@@ -879,13 +891,13 @@ private static EquatableArray<VtableAttribute> GetVtableAttributesToAddOnLookupT
879
891
{
880
892
var leftSymbol = context . SemanticModel . GetSymbolInfo ( assignment . Left ) . Symbol ;
881
893
if ( leftSymbol is IPropertySymbol propertySymbol &&
882
- ( GeneratorHelper . IsWinRTType ( propertySymbol . ContainingSymbol ) ||
894
+ ( isWinRTType ( propertySymbol . ContainingSymbol ) ||
883
895
SymbolEqualityComparer . Default . Equals ( propertySymbol . ContainingAssembly , context . SemanticModel . Compilation . Assembly ) ) )
884
896
{
885
897
AddVtableAttributesForType ( context . SemanticModel . GetTypeInfo ( assignment . Right ) , propertySymbol . Type ) ;
886
898
}
887
899
else if ( leftSymbol is IFieldSymbol fieldSymbol &&
888
- ( GeneratorHelper . IsWinRTType ( fieldSymbol . ContainingSymbol ) ||
900
+ ( isWinRTType ( fieldSymbol . ContainingSymbol ) ||
889
901
SymbolEqualityComparer . Default . Equals ( fieldSymbol . ContainingAssembly , context . SemanticModel . Compilation . Assembly ) ) )
890
902
{
891
903
AddVtableAttributesForType ( context . SemanticModel . GetTypeInfo ( assignment . Right ) , fieldSymbol . Type ) ;
@@ -953,14 +965,14 @@ void AddVtableAttributesForType(Microsoft.CodeAnalysis.TypeInfo instantiatedType
953
965
}
954
966
visitedTypes . Add ( arrayType ) ;
955
967
956
- var vtableAtribute = GetVtableAttributeToAdd ( arrayType , GeneratorHelper . IsWinRTType , context . SemanticModel . Compilation , false ) ;
968
+ var vtableAtribute = GetVtableAttributeToAdd ( arrayType , isWinRTType , context . SemanticModel . Compilation , false ) ;
957
969
if ( vtableAtribute != default )
958
970
{
959
971
vtableAttributes . Add ( vtableAtribute ) ;
960
972
}
961
973
962
974
// Also add the enumerator type to the lookup table as the native caller can call it.
963
- AddEnumeratorAdapterForType ( arrayType . ElementType , context . SemanticModel . Compilation , GeneratorHelper . IsWinRTType , vtableAttributes ) ;
975
+ AddEnumeratorAdapterForType ( arrayType . ElementType , context . SemanticModel . Compilation , isWinRTType , vtableAttributes ) ;
964
976
}
965
977
}
966
978
else if ( instantiatedType . Type is not null || instantiatedType . ConvertedType is not null )
@@ -982,11 +994,11 @@ void AddVtableAttributesForType(Microsoft.CodeAnalysis.TypeInfo instantiatedType
982
994
// information is available.
983
995
if ( instantiatedTypeSymbol . TypeKind == TypeKind . Delegate &&
984
996
instantiatedTypeSymbol . MetadataName . Contains ( "`" ) &&
985
- GeneratorHelper . IsWinRTType ( instantiatedTypeSymbol ) &&
997
+ isWinRTType ( instantiatedTypeSymbol ) &&
986
998
convertedToTypeSymbol . SpecialType == SpecialType . System_Object )
987
999
{
988
1000
var argumentClassNamedTypeSymbol = instantiatedTypeSymbol as INamedTypeSymbol ;
989
- vtableAttributes . Add ( GetVtableAttributeToAdd ( instantiatedTypeSymbol , GeneratorHelper . IsWinRTType , context . SemanticModel . Compilation , false ) ) ;
1001
+ vtableAttributes . Add ( GetVtableAttributeToAdd ( instantiatedTypeSymbol , isWinRTType , context . SemanticModel . Compilation , false ) ) ;
990
1002
}
991
1003
992
1004
// This handles the case where the source generator wasn't able to run
@@ -998,21 +1010,21 @@ void AddVtableAttributesForType(Microsoft.CodeAnalysis.TypeInfo instantiatedType
998
1010
// library which happened to not run the AOT optimizer. So as a best effort,
999
1011
// we handle it here.
1000
1012
if ( instantiatedTypeSymbol . TypeKind == TypeKind . Class &&
1001
- ( instantiatedTypeSymbol . MetadataName . Contains ( "`" ) || ! GeneratorHelper . IsWinRTType ( instantiatedTypeSymbol ) ) &&
1013
+ ( instantiatedTypeSymbol . MetadataName . Contains ( "`" ) || ! isWinRTType ( instantiatedTypeSymbol ) ) &&
1002
1014
! GeneratorHelper . HasWinRTExposedTypeAttribute ( instantiatedTypeSymbol ) &&
1003
1015
// If the type is defined in the same assembly as what the source generator is running on,
1004
1016
// we let the WinRTExposedType attribute generator handle it.
1005
1017
! SymbolEqualityComparer . Default . Equals ( instantiatedTypeSymbol . ContainingAssembly , context . SemanticModel . Compilation . Assembly ) &&
1006
1018
// Make sure the type we are passing is being boxed or cast to another interface.
1007
1019
! SymbolEqualityComparer . Default . Equals ( instantiatedTypeSymbol , convertedToTypeSymbol ) )
1008
1020
{
1009
- var vtableAtribute = GetVtableAttributeToAdd ( instantiatedTypeSymbol , GeneratorHelper . IsWinRTType , context . SemanticModel . Compilation , false ) ;
1021
+ var vtableAtribute = GetVtableAttributeToAdd ( instantiatedTypeSymbol , isWinRTType , context . SemanticModel . Compilation , false ) ;
1010
1022
if ( vtableAtribute != default )
1011
1023
{
1012
1024
vtableAttributes . Add ( vtableAtribute ) ;
1013
1025
}
1014
1026
1015
- AddVtableAdapterTypeForKnownInterface ( instantiatedTypeSymbol , context . SemanticModel . Compilation , GeneratorHelper . IsWinRTType , vtableAttributes ) ;
1027
+ AddVtableAdapterTypeForKnownInterface ( instantiatedTypeSymbol , context . SemanticModel . Compilation , isWinRTType , vtableAttributes ) ;
1016
1028
}
1017
1029
}
1018
1030
}
0 commit comments