1
- using System ;
2
- using System . Collections . Immutable ;
1
+ using System . Collections . Immutable ;
3
2
using System . Linq ;
4
- using System . Reflection . Metadata . Ecma335 ;
5
3
using Microsoft . CodeAnalysis ;
6
4
using Microsoft . CodeAnalysis . CSharp ;
7
5
using Microsoft . CodeAnalysis . CSharp . Syntax ;
10
8
namespace ET . Analyzer
11
9
{
12
10
[ DiagnosticAnalyzer ( LanguageNames . CSharp ) ]
13
- public class EntityFiledAccessAnalyzer : DiagnosticAnalyzer
11
+ public class EntityFiledAccessAnalyzer : DiagnosticAnalyzer
14
12
{
15
13
private const string Title = "实体字段访问错误" ;
16
-
14
+
17
15
private const string MessageFormat = "实体: {0} 字段: {1} 只能在实体类生命周期组件或友元类(含有FriendClassAttribute)中访问" ;
18
-
16
+
19
17
private const string Description = "请使用实体类属性或方法访问其他实体字段." ;
20
-
18
+
21
19
private const string EntityType = "ET.Entity" ;
22
-
20
+
23
21
private const string ObjectSystemAttribute = "ET.ObjectSystemAttribute" ;
24
-
22
+
25
23
private const string ISystemType = "ET.ISystemType" ;
26
24
27
25
private const string FriendClassAttribute = "ET.FriendClassAttribute" ;
@@ -31,37 +29,37 @@ public class EntityFiledAccessAnalyzer : DiagnosticAnalyzer
31
29
MessageFormat ,
32
30
DiagnosticCategories . Hotfix ,
33
31
DiagnosticSeverity . Error , true , Description ) ;
34
-
32
+
35
33
public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics => ImmutableArray . Create ( Rule ) ;
36
-
37
-
34
+
38
35
public override void Initialize ( AnalysisContext context )
39
36
{
40
37
if ( ! AnalyzerGlobalSetting . EnableAnalyzer )
41
38
{
42
39
return ;
43
40
}
41
+
44
42
context . ConfigureGeneratedCodeAnalysis ( GeneratedCodeAnalysisFlags . None ) ;
45
43
context . EnableConcurrentExecution ( ) ;
46
44
context . RegisterSyntaxNodeAction ( this . AnalyzeMemberAccessExpression , SyntaxKind . SimpleMemberAccessExpression ) ;
47
45
}
48
46
49
47
private void AnalyzeMemberAccessExpression ( SyntaxNodeAnalysisContext context )
50
48
{
51
- if ( ! AnalyzerHelper . IsAssemblyNeedAnalyze ( context . Compilation . AssemblyName , AnalyzeAssembly . AllHotfix ) )
49
+ if ( ! AnalyzerHelper . IsAssemblyNeedAnalyze ( context . Compilation . AssemblyName , AnalyzeAssembly . AllHotfix ) )
52
50
{
53
51
return ;
54
52
}
55
-
53
+
56
54
if ( ! ( context . Node is MemberAccessExpressionSyntax memberAccessExpressionSyntax ) )
57
55
{
58
56
return ;
59
57
}
60
-
58
+
61
59
// -----筛选出实体类的字段symbol-----
62
-
63
- var filedSymbol = context . SemanticModel . GetSymbolInfo ( memberAccessExpressionSyntax ) . Symbol ;
64
- if ( filedSymbol == null || ! ( filedSymbol is IFieldSymbol ) )
60
+
61
+ ISymbol ? filedSymbol = context . SemanticModel . GetSymbolInfo ( memberAccessExpressionSyntax ) . Symbol ;
62
+ if ( filedSymbol == null || ! ( filedSymbol is IFieldSymbol ) )
65
63
{
66
64
return ;
67
65
}
@@ -71,20 +69,21 @@ private void AnalyzeMemberAccessExpression(SyntaxNodeAnalysisContext context)
71
69
return ;
72
70
}
73
71
74
- if ( filedSymbol . ContainingType . BaseType ? . ToString ( ) != EntityType )
72
+ if ( filedSymbol . ContainingType . BaseType ? . ToString ( ) != EntityType )
75
73
{
76
74
return ;
77
75
}
78
-
76
+
79
77
// -----筛选出在实体类和实体System外部字段访问-----
80
78
// 实体System包括awakeSystem updateSystem等生命周期类和 componentSystem静态方法类
81
79
82
- var accessFieldClassDeclaretion = memberAccessExpressionSyntax . GetParentClassDeclaration ( ) ;
83
- if ( accessFieldClassDeclaretion == null )
80
+ ClassDeclarationSyntax ? accessFieldClassDeclaretion = memberAccessExpressionSyntax . GetParentClassDeclaration ( ) ;
81
+ if ( accessFieldClassDeclaretion == null )
84
82
{
85
83
return ;
86
84
}
87
- var accessFieldClassSymbol = context . SemanticModel . GetDeclaredSymbol ( accessFieldClassDeclaretion ) ;
85
+
86
+ INamedTypeSymbol ? accessFieldClassSymbol = context . SemanticModel . GetDeclaredSymbol ( accessFieldClassDeclaretion ) ;
88
87
89
88
if ( accessFieldClassSymbol == null )
90
89
{
@@ -96,51 +95,55 @@ private void AnalyzeMemberAccessExpression(SyntaxNodeAnalysisContext context)
96
95
{
97
96
return ;
98
97
}
99
-
98
+
100
99
//判断是否在实体类生命周期System中
101
- if ( CheckIsEntityLifecycleSystem ( accessFieldClassSymbol , filedSymbol . ContainingType ) )
100
+ if ( this . CheckIsEntityLifecycleSystem ( accessFieldClassSymbol , filedSymbol . ContainingType ) )
102
101
{
103
102
return ;
104
103
}
105
104
106
105
//判断是否在实体类的友元类中
107
- if ( CheckIsEntityFriendClass ( accessFieldClassSymbol , filedSymbol . ContainingType ) )
106
+ if ( this . CheckIsEntityFriendClass ( accessFieldClassSymbol , filedSymbol . ContainingType ) )
108
107
{
109
108
return ;
110
109
}
111
-
112
- Diagnostic diagnostic = Diagnostic . Create ( Rule , memberAccessExpressionSyntax . GetLocation ( ) , filedSymbol . ContainingType . Name , filedSymbol . Name ) ;
110
+
111
+ Diagnostic diagnostic = Diagnostic . Create ( Rule , memberAccessExpressionSyntax . GetLocation ( ) , filedSymbol . ContainingType . Name ,
112
+ filedSymbol . Name ) ;
113
113
context . ReportDiagnostic ( diagnostic ) ;
114
114
}
115
-
115
+
116
116
private bool CheckIsEntityLifecycleSystem ( INamedTypeSymbol accessFieldClassSymbol , INamedTypeSymbol entityTypeSymbol )
117
117
{
118
- if ( accessFieldClassSymbol . BaseType == null || ! accessFieldClassSymbol . BaseType . IsGenericType )
118
+ if ( accessFieldClassSymbol . BaseType == null || ! accessFieldClassSymbol . BaseType . IsGenericType )
119
119
{
120
120
return false ;
121
121
}
122
+
122
123
// 判断是否含有 ObjectSystem Attribute 且继承了接口 ISystemType
123
124
if ( accessFieldClassSymbol . BaseType . HasAttribute ( ObjectSystemAttribute ) && accessFieldClassSymbol . HasInterface ( ISystemType ) )
124
125
{
125
126
// 获取 accessFieldClassSymbol 父类的实体类型参数
126
- var entityTypeArgumentSymbol = accessFieldClassSymbol . BaseType . TypeArguments . FirstOrDefault ( ) ;
127
+ ITypeSymbol ? entityTypeArgumentSymbol = accessFieldClassSymbol . BaseType . TypeArguments . FirstOrDefault ( ) ;
127
128
if ( entityTypeArgumentSymbol == null )
128
129
{
129
130
return false ;
130
131
}
131
- // 判断 accessFieldClassSymbol 父类的实体类型参数是否为 entityTypeSymbol
132
- if ( entityTypeArgumentSymbol . ToString ( ) == entityTypeSymbol . ToString ( ) )
133
- {
134
- return true ;
135
- }
132
+
133
+ // 判断 accessFieldClassSymbol 父类的实体类型参数是否为 entityTypeSymbol
134
+ if ( entityTypeArgumentSymbol . ToString ( ) == entityTypeSymbol . ToString ( ) )
135
+ {
136
+ return true ;
137
+ }
136
138
}
139
+
137
140
return false ;
138
141
}
139
142
140
143
private bool CheckIsEntityFriendClass ( INamedTypeSymbol accessFieldTypeSymbol , INamedTypeSymbol entityTypeSymbol )
141
144
{
142
145
var attributes = accessFieldTypeSymbol . GetAttributes ( ) ;
143
- foreach ( var attributeData in attributes )
146
+ foreach ( AttributeData ? attributeData in attributes )
144
147
{
145
148
if ( attributeData . AttributeClass ? . ToString ( ) != FriendClassAttribute )
146
149
{
0 commit comments