55using System . Collections . Generic ;
66using System . Linq ;
77using System . Text ;
8+ using System . Collections . Immutable ;
89#pragma warning disable CS8602 // Dereference of a possibly null reference.
910
1011namespace Fantasy . SourceGenerator . Generators
@@ -18,54 +19,166 @@ public partial class EntitySystemGenerator : IIncrementalGenerator
1819 {
1920 public void Initialize ( IncrementalGeneratorInitializationContext context )
2021 {
21- // 查找所有实现了 IEntitySystem 相关接口的类
22+ // 查找所有 System 类
2223 var systemTypes = context . SyntaxProvider
2324 . CreateSyntaxProvider (
2425 predicate : static ( node , _ ) => IsSystemClass ( node ) ,
25- transform : static ( ctx , _ ) => GetSystemTypeInfo ( ctx ) )
26- . Where ( static info => info != null )
26+ transform : static ( ctx , _ ) => GetSystemSymbol ( ctx ) )
27+ . Where ( static symbol => symbol != null )
2728 . Collect ( ) ;
28- // 组合编译信息和找到的类型
29- var compilationAndTypes = context . CompilationProvider . Combine ( systemTypes ) ;
30- // 注册源代码输出
31- context . RegisterSourceOutput ( compilationAndTypes , static ( spc , source ) =>
29+
30+ // 查找代码中所有使用到的闭合泛型 Entity
31+ var usedClosedGenericEntities = context . SyntaxProvider
32+ . CreateSyntaxProvider (
33+ predicate : static ( node , _ ) => IsGenericEntityUsage ( node ) ,
34+ transform : static ( ctx , _ ) => GetClosedEntitySymbol ( ctx ) )
35+ . Where ( static symbol => symbol != null )
36+ . Collect ( )
37+ . Select ( static ( types , _ ) => types . Distinct < INamedTypeSymbol > ( SymbolEqualityComparer . Default ) . ToImmutableArray ( ) ) ;
38+
39+ // 根据 闭合Entity 处理 System
40+ var finalSystemInfos = systemTypes . Combine ( usedClosedGenericEntities )
41+ . Select ( ( tuple , _ ) =>
3242 {
33- if ( CompilationHelper . IsSourceGeneratorDisabled ( source . Left ) )
34- {
35- return ;
36- }
37-
38- if ( ! CompilationHelper . HasFantasyDefine ( source . Left ) )
39- {
40- return ;
41- }
42-
43- if ( source . Left . GetTypeByMetadataName ( "Fantasy.Assembly.IEntitySystemRegistrar" ) == null )
43+ var systems = tuple . Left ;
44+ var usedEntities = tuple . Right ;
45+ var result = new List < EntitySystemTypeInfo > ( ) ;
46+
47+ foreach ( var systemSymbol in systems )
4448 {
45- return ;
49+ // 泛型System
50+ if ( systemSymbol ! . IsOpenGeneric ( ) )
51+ {
52+ foreach ( var entitySymbol in usedEntities )
53+ {
54+ // 尝试为 闭合Entity 构造 闭合System
55+ if ( TryCreateClosedSystemInfo ( systemSymbol ! , entitySymbol ! , out var info ) )
56+ {
57+ result . Add ( info ! ) ;
58+ }
59+ }
60+ }
61+ else // 普通 System
62+ {
63+ var info = CreateInfoFromSymbol ( systemSymbol ! ) ;
64+ if ( info != null )
65+ {
66+ result . Add ( info ) ;
67+ }
68+ }
4669 }
70+ return result ;
71+ } ) ;
4772
48- GenerateRegistrationCode ( spc , source . Left , source . Right ! ) ;
73+ //组合编译信息输出
74+ var source = context . CompilationProvider . Combine ( finalSystemInfos ) ;
75+ context . RegisterSourceOutput ( source , ( spc , source ) =>
76+ {
77+ if ( CompilationHelper . IsSourceGeneratorDisabled ( source . Left ) ) return ;
78+ if ( ! CompilationHelper . HasFantasyDefine ( source . Left ) ) return ;
79+ if ( source . Left . GetTypeByMetadataName ( "Fantasy.Assembly.IEntitySystemRegistrar" ) == null ) return ;
80+
81+ GenerateRegistrationCode ( spc , source . Left , source . Right ) ;
4982 } ) ;
5083 }
51-
52- private static EntitySystemTypeInfo ? GetSystemTypeInfo ( GeneratorSyntaxContext context )
84+
85+
86+ #region Predicate & Transform
87+
88+ private static INamedTypeSymbol ? GetSystemSymbol ( GeneratorSyntaxContext context )
5389 {
5490 var classDecl = ( ClassDeclarationSyntax ) context . Node ;
91+ var symbol = context . SemanticModel . GetDeclaredSymbol ( classDecl ) as INamedTypeSymbol ;
92+ if ( symbol == null || symbol . IsAbstract ) return null ; // 忽略抽象类
5593
56- if ( context . SemanticModel . GetDeclaredSymbol ( classDecl ) is not INamedTypeSymbol symbol || ! symbol . IsInstantiable ( ) )
57- {
94+ // 目标实体不能是闭合泛型
95+ var targetEntityArg = GetSystemTargetEntityArg ( symbol ! ) ;
96+ if ( targetEntityArg == null ) return null ;
97+ if ( targetEntityArg . IsGenericType && ! targetEntityArg . IsOpenGeneric ( ) ) return null ;
98+
99+ return symbol ;
100+ }
101+
102+ // 判断代码中使用到的闭合泛型 Entity
103+ private static bool IsGenericEntityUsage ( SyntaxNode node ) => node is GenericNameSyntax ;
104+
105+ private static INamedTypeSymbol ? GetClosedEntitySymbol ( GeneratorSyntaxContext context )
106+ {
107+ if ( context . Node is not GenericNameSyntax genericName ) return null ;
108+
109+ var symbolInfo = context . SemanticModel . GetSymbolInfo ( genericName ) ;
110+ var symbol = symbolInfo . Symbol as INamedTypeSymbol ;
111+
112+ if ( symbol == null ) return null ;
113+ if ( symbol . IsOpenGeneric ( ) ) return null ; // 确保是闭合泛型
114+
115+ // 检查继承自 Entity
116+ if ( ! EntityTypeCollectionGenerator . InheritsFromEntitySymbol ( symbol ) ) return null ;
117+
118+ return symbol ;
119+ }
120+
121+ #endregion
122+
123+ #region Generic Analysis
124+
125+ /// <summary>
126+ /// 获取System类的目标实体参数
127+ /// </summary>
128+ private static INamedTypeSymbol ? GetSystemTargetEntityArg ( INamedTypeSymbol systemSymbol ) {
129+ var baseType = systemSymbol . BaseType ;
130+
131+ if ( ! baseType . IsGenericType )
58132 return null ;
59- }
60-
61- var baseType = symbol . BaseType ;
62133
63- if ( ! baseType . IsGenericType )
134+ return baseType . TypeArguments . FirstOrDefault ( ) as INamedTypeSymbol ;
135+ }
136+
137+ ///<summary>
138+ /// NOTE : 需要提高完备性
139+ /// 尝试将一个 开放泛型System 和一个 闭合泛型Entity 进行匹配,
140+ /// 并生成闭合的 System 信息。
141+ ///</summary>
142+ private static bool TryCreateClosedSystemInfo ( INamedTypeSymbol systemSymbol , INamedTypeSymbol entitySymbol , out EntitySystemTypeInfo ? info )
143+ {
144+ // 1. 获取 System 关注的实体基类型 (从 AwakeSystem<T> 中提取 T)
145+ var targetEntityArg = GetSystemTargetEntityArg ( systemSymbol ) ;
146+ info = null ;
147+
148+ // 2. 检查 Entity 是否匹配 System 的定义
149+
150+ // 比如 泛型System 的参数结构 AGenericEntity<T1, T2> 与对应的实体 AGenericEntity<EnumA, EnumB>,
151+ // 它们的 ConstructedFrom 必须吻合
152+
153+ if ( ! SymbolEqualityComparer . Default . Equals ( targetEntityArg . ConstructedFrom , entitySymbol . ConstructedFrom ) )
154+ return false ;
155+
156+ // 3. 检查参数数量是否相等
157+ var systemTypeArgs = entitySymbol . TypeArguments . ToArray ( ) ;
158+ if ( systemTypeArgs . Length != systemSymbol . TypeParameters . Length ) return false ;
159+
160+ // 4. 构造闭合的 System 类型
161+ // 使用 Entity 的泛型参数 (EnumA, EnumB) 来填充 System 的泛型参数
162+ try
64163 {
65- return null ;
164+ var constructedSystemSymbol = systemSymbol . Construct ( systemTypeArgs ) ;
165+ info = CreateInfoFromSymbol ( constructedSystemSymbol ) ;
166+ return info != null ;
167+ }
168+ catch
169+ {
170+ return false ;
66171 }
67-
68- return baseType . Name switch
172+ }
173+
174+ private static EntitySystemTypeInfo ? CreateInfoFromSymbol ( INamedTypeSymbol symbol )
175+ {
176+ var baseType = symbol . BaseType ;
177+ if ( baseType == null ) return null ;
178+
179+ var typeName = baseType . ConstructedFrom . Name ;
180+
181+ return typeName switch
69182 {
70183 "AwakeSystem" => EntitySystemTypeInfo . Create ( EntitySystemType . AwakeSystem , symbol ) ,
71184 "UpdateSystem" => EntitySystemTypeInfo . Create ( EntitySystemType . UpdateSystem , symbol ) ,
@@ -75,7 +188,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
75188 _ => null
76189 } ;
77190 }
78-
191+
192+ #endregion
193+
79194 private static void GenerateRegistrationCode (
80195 SourceProductionContext context ,
81196 Compilation compilation ,
@@ -218,16 +333,12 @@ private static void GenerateSystemCode(SourceCodeBuilder builder, string defineC
218333 private static bool IsSystemClass ( SyntaxNode node )
219334 {
220335 if ( node is not ClassDeclarationSyntax classDecl )
221- {
222336 return false ;
223- }
224337
225338 // 必须有基类型列表(继承抽象类)
226339 if ( classDecl . BaseList == null || classDecl . BaseList . Types . Count == 0 )
227- {
228340 return false ;
229- }
230-
341+
231342 // 快速检查是否包含可能的 EntitySystem 基类名称
232343 var baseListText = classDecl . BaseList . ToString ( ) ;
233344 return baseListText . Contains ( "AwakeSystem" ) ||
@@ -275,7 +386,7 @@ private EntitySystemTypeInfo(
275386 public static EntitySystemTypeInfo Create ( EntitySystemType entitySystemType , INamedTypeSymbol symbol )
276387 {
277388 // 获取泛型参数 T (例如:AwakeSystem<T> 中的 T)
278- var entityType = symbol . BaseType ? . TypeArguments . FirstOrDefault ( ) ;
389+ var entityType = GetSystemTargetEntityArg ( symbol ) ;
279390 var entityTypeFullName = entityType ? . GetFullName ( false ) ?? "Unknown" ;
280391
281392 // // 使用与运行时相同的算法计算哈希值
0 commit comments