private void AnalyzeMemberAccessExpression(SyntaxNodeAnalysisContext context) { if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.All)) { return; } if (!(context.Node is MemberAccessExpressionSyntax memberAccessExpressionSyntax)) { return; } // 筛选出 Component函数syntax string methodName = memberAccessExpressionSyntax.Name.Identifier.Text; if (!Definition.ComponentMethod.Contains(methodName)) { return; } if (!(memberAccessExpressionSyntax?.Parent is InvocationExpressionSyntax invocationExpressionSyntax) || !(context.SemanticModel.GetSymbolInfo(invocationExpressionSyntax).Symbol is IMethodSymbol addComponentMethodSymbol)) { return; } // 获取AComponent函数的调用者类型 ITypeSymbol?parentTypeSymbol = memberAccessExpressionSyntax.GetMemberAccessSyntaxParentType(context.SemanticModel); if (parentTypeSymbol == null) { return; } // 对于Entity基类会报错 除非标记了EnableAccessEntiyChild if (parentTypeSymbol.ToString() == Definition.EntityType) { HandleAcessEntityChild(context); return; } // 非Entity的子类 跳过 if (parentTypeSymbol.BaseType?.ToString() != Definition.EntityType) { return; } // 获取 component实体类型 ISymbol?componentTypeSymbol = null; // Component为泛型调用 if (addComponentMethodSymbol.IsGenericMethod) { GenericNameSyntax?genericNameSyntax = memberAccessExpressionSyntax?.GetFirstChild <GenericNameSyntax>(); TypeArgumentListSyntax?typeArgumentList = genericNameSyntax?.GetFirstChild <TypeArgumentListSyntax>(); var componentTypeSyntax = typeArgumentList?.Arguments.First(); if (componentTypeSyntax == null) { Diagnostic diagnostic = Diagnostic.Create(EntityComponentAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation()); context.ReportDiagnostic(diagnostic); throw new Exception("componentTypeSyntax==null"); } componentTypeSymbol = context.SemanticModel.GetSymbolInfo(componentTypeSyntax).Symbol; } //Component为非泛型调用 else { SyntaxNode?firstArgumentSyntax = invocationExpressionSyntax.GetFirstChild <ArgumentListSyntax>()?.GetFirstChild <ArgumentSyntax>() ?.ChildNodes().First(); if (firstArgumentSyntax == null) { Diagnostic diagnostic = Diagnostic.Create(EntityComponentAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation()); context.ReportDiagnostic(diagnostic); return; } // 参数为typeOf时 提取Type类型 if (firstArgumentSyntax is TypeOfExpressionSyntax typeOfExpressionSyntax) { firstArgumentSyntax = typeOfExpressionSyntax.Type; } ISymbol?firstArgumentSymbol = context.SemanticModel.GetSymbolInfo(firstArgumentSyntax).Symbol; if (firstArgumentSymbol is ILocalSymbol childLocalSymbol) { componentTypeSymbol = childLocalSymbol.Type; } else if (firstArgumentSymbol is IParameterSymbol childParamaterSymbol) { componentTypeSymbol = childParamaterSymbol.Type; } else if (firstArgumentSymbol is IMethodSymbol methodSymbol) { componentTypeSymbol = methodSymbol.ReturnType; } else if (firstArgumentSymbol is IFieldSymbol fieldSymbol) { componentTypeSymbol = fieldSymbol.Type; } else if (firstArgumentSymbol is IPropertySymbol propertySymbol) { componentTypeSymbol = propertySymbol.Type; } else if (firstArgumentSymbol is INamedTypeSymbol namedTypeSymbol) { componentTypeSymbol = namedTypeSymbol; } else if (firstArgumentSymbol is ITypeParameterSymbol) { // 忽略typeof(T)参数类型 return; } else if (firstArgumentSymbol != null) { Diagnostic diagnostic = Diagnostic.Create(EntityComponentAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), firstArgumentSymbol.Name, parentTypeSymbol.Name); context.ReportDiagnostic(diagnostic); return; } else { Diagnostic diagnostic = Diagnostic.Create(EntityComponentAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), firstArgumentSyntax.GetText(), parentTypeSymbol.Name); context.ReportDiagnostic(diagnostic); return; } } if (componentTypeSymbol == null) { return; } // 忽略 component类型为泛型类型 if (componentTypeSymbol is ITypeParameterSymbol typeParameterSymbol) { return; } // 忽略 Type参数 if (componentTypeSymbol.ToString() == "System.Type") { return; } // 组件类型为Entity时 忽略检查 if (componentTypeSymbol.ToString() == Definition.EntityType) { return; } // 判断component类型是否属于约束类型 //获取component类的parentType标记数据 INamedTypeSymbol?availableParentTypeSymbol = null; bool hasParentTypeAttribute = false; foreach (AttributeData?attributeData in componentTypeSymbol.GetAttributes()) { if (attributeData.AttributeClass?.ToString() == Definition.ComponentOfAttribute) { hasParentTypeAttribute = true; if (attributeData.ConstructorArguments[0].Value is INamedTypeSymbol typeSymbol) { availableParentTypeSymbol = typeSymbol; break; } } } if (hasParentTypeAttribute && availableParentTypeSymbol == null) { return; } // 符合约束条件 通过检查 if (availableParentTypeSymbol != null && availableParentTypeSymbol.ToString() == parentTypeSymbol.ToString()) { return; } { Diagnostic diagnostic = Diagnostic.Create(EntityComponentAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), componentTypeSymbol?.Name, parentTypeSymbol?.Name); context.ReportDiagnostic(diagnostic); } }
private void AnalyzeMemberAccessExpression(SyntaxNodeAnalysisContext context) { if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.AllHotfix)) { return; } if (!(context.Node is MemberAccessExpressionSyntax memberAccessExpressionSyntax)) { return; } // 筛选出 AddChild函数syntax string methodName = memberAccessExpressionSyntax.Name.Identifier.Text; if (!AddChildMethods.Contains(methodName)) { return; } if (!(memberAccessExpressionSyntax?.Parent is InvocationExpressionSyntax invocationExpressionSyntax) || !(context.SemanticModel.GetSymbolInfo(invocationExpressionSyntax).Symbol is IMethodSymbol addChildMethodSymbol)) { return; } // 获取AddChild函数的调用者类型 ITypeSymbol?parentTypeSymbol = memberAccessExpressionSyntax.GetMemberAccessSyntaxParentType(context.SemanticModel); if (parentTypeSymbol == null) { return; } // 只检查Entity的子类 if (parentTypeSymbol.BaseType?.ToString() != EntityType) { return; } // 获取实体类 ChildType标签的约束类型 INamedTypeSymbol?availableChildTypeSymbol = null; bool hasChildTypeAttribute = false; foreach (AttributeData?attributeData in parentTypeSymbol.GetAttributes()) { if (attributeData.AttributeClass?.Name == "ChildTypeAttribute") { hasChildTypeAttribute = true; if (!(attributeData.ConstructorArguments[0].Value is INamedTypeSymbol s)) { continue; } availableChildTypeSymbol = s; } } if (hasChildTypeAttribute && (availableChildTypeSymbol == null)) { return; } // 获取 child实体类型 ISymbol?childTypeSymbol = null; // addChild为泛型调用 if (addChildMethodSymbol.IsGenericMethod) { GenericNameSyntax?genericNameSyntax = memberAccessExpressionSyntax?.GetFirstChild <GenericNameSyntax>(); TypeArgumentListSyntax?typeArgumentList = genericNameSyntax?.GetFirstChild <TypeArgumentListSyntax>(); IdentifierNameSyntax?childTypeSyntax = typeArgumentList?.GetFirstChild <IdentifierNameSyntax>(); if (childTypeSyntax == null) { Diagnostic diagnostic = Diagnostic.Create(Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation()); context.ReportDiagnostic(diagnostic); throw new Exception("childTypeSyntax==null"); } childTypeSymbol = context.SemanticModel.GetSymbolInfo(childTypeSyntax).Symbol; } // addChild为非泛型调用 else { SyntaxNode?firstArgumentSyntax = invocationExpressionSyntax.GetFirstChild <ArgumentListSyntax>()?.GetFirstChild <ArgumentSyntax>() ?.ChildNodes().First(); if (firstArgumentSyntax == null) { Diagnostic diagnostic = Diagnostic.Create(Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation()); context.ReportDiagnostic(diagnostic); return; } ISymbol?firstArgumentSymbol = context.SemanticModel.GetSymbolInfo(firstArgumentSyntax).Symbol; if (firstArgumentSymbol is ILocalSymbol childLocalSymbol) { childTypeSymbol = childLocalSymbol.Type; } else if (firstArgumentSymbol is IParameterSymbol childParamaterSymbol) { childTypeSymbol = childParamaterSymbol.Type; } else if (firstArgumentSymbol is IMethodSymbol methodSymbol) { childTypeSymbol = methodSymbol.ReturnType; } else if (firstArgumentSymbol is IFieldSymbol fieldSymbol) { childTypeSymbol = fieldSymbol.Type; } else if (firstArgumentSymbol is IPropertySymbol propertySymbol) { childTypeSymbol = propertySymbol.Type; } else if (firstArgumentSymbol != null) { Diagnostic diagnostic = Diagnostic.Create(Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), firstArgumentSymbol.Name, parentTypeSymbol.Name); context.ReportDiagnostic(diagnostic); return; } else { Diagnostic diagnostic = Diagnostic.Create(Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), firstArgumentSyntax.GetText(), parentTypeSymbol.Name); context.ReportDiagnostic(diagnostic); return; } } if (childTypeSymbol == null) { return; } // 判断child类型是否属于约束类型 if (availableChildTypeSymbol?.ToString() == childTypeSymbol.ToString()) { return; } { Diagnostic diagnostic = Diagnostic.Create(Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), childTypeSymbol?.Name, parentTypeSymbol?.Name); context.ReportDiagnostic(diagnostic); } }
private void AnalyzeMemberAccessExpression(SyntaxNodeAnalysisContext context) { if (!AnalyzerHelper.IsAssemblyNeedAnalyze(context.Compilation.AssemblyName, AnalyzeAssembly.All)) { return; } if (!(context.Node is MemberAccessExpressionSyntax memberAccessExpressionSyntax)) { return; } // 筛选出 AddChild函数syntax string methodName = memberAccessExpressionSyntax.Name.Identifier.Text; if (!Definition.AddChildMethods.Contains(methodName)) { return; } if (!(memberAccessExpressionSyntax?.Parent is InvocationExpressionSyntax invocationExpressionSyntax) || !(context.SemanticModel.GetSymbolInfo(invocationExpressionSyntax).Symbol is IMethodSymbol addChildMethodSymbol)) { return; } // 获取AddChild函数的调用者类型 ITypeSymbol?parentTypeSymbol = memberAccessExpressionSyntax.GetMemberAccessSyntaxParentType(context.SemanticModel); if (parentTypeSymbol == null) { return; } // 对于Entity基类会报错 除非标记了EnableAccessEntiyChild if (parentTypeSymbol.ToString() == Definition.EntityType) { HandleAcessEntityChild(context); return; } // 非Entity的子类 跳过 if (parentTypeSymbol.BaseType?.ToString() != Definition.EntityType) { return; } // 获取 child实体类型 ISymbol?childTypeSymbol = null; // addChild为泛型调用 if (addChildMethodSymbol.IsGenericMethod) { GenericNameSyntax?genericNameSyntax = memberAccessExpressionSyntax?.GetFirstChild <GenericNameSyntax>(); TypeArgumentListSyntax?typeArgumentList = genericNameSyntax?.GetFirstChild <TypeArgumentListSyntax>(); var childTypeSyntax = typeArgumentList?.Arguments.First(); if (childTypeSyntax == null) { Diagnostic diagnostic = Diagnostic.Create(AddChildTypeAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation()); context.ReportDiagnostic(diagnostic); throw new Exception("childTypeSyntax==null"); } childTypeSymbol = context.SemanticModel.GetSymbolInfo(childTypeSyntax).Symbol; } // addChild为非泛型调用 else { SyntaxNode?firstArgumentSyntax = invocationExpressionSyntax.GetFirstChild <ArgumentListSyntax>()?.GetFirstChild <ArgumentSyntax>() ?.ChildNodes().First(); if (firstArgumentSyntax == null) { Diagnostic diagnostic = Diagnostic.Create(AddChildTypeAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation()); context.ReportDiagnostic(diagnostic); return; } ISymbol?firstArgumentSymbol = context.SemanticModel.GetSymbolInfo(firstArgumentSyntax).Symbol; if (firstArgumentSymbol is ILocalSymbol childLocalSymbol) { childTypeSymbol = childLocalSymbol.Type; } else if (firstArgumentSymbol is IParameterSymbol childParamaterSymbol) { childTypeSymbol = childParamaterSymbol.Type; } else if (firstArgumentSymbol is IMethodSymbol methodSymbol) { childTypeSymbol = methodSymbol.ReturnType; } else if (firstArgumentSymbol is IFieldSymbol fieldSymbol) { childTypeSymbol = fieldSymbol.Type; } else if (firstArgumentSymbol is IPropertySymbol propertySymbol) { childTypeSymbol = propertySymbol.Type; } else if (firstArgumentSymbol != null) { Diagnostic diagnostic = Diagnostic.Create(AddChildTypeAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), firstArgumentSymbol.Name, parentTypeSymbol.Name); context.ReportDiagnostic(diagnostic); return; } else { Diagnostic diagnostic = Diagnostic.Create(AddChildTypeAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), firstArgumentSyntax.GetText(), parentTypeSymbol.Name); context.ReportDiagnostic(diagnostic); return; } } if (childTypeSymbol == null) { return; } // 忽略 child类型为泛型类型 if (childTypeSymbol is ITypeParameterSymbol typeParameterSymbol) { return; } // 获取ChildOf标签的约束类型 if (!(childTypeSymbol is ITypeSymbol childType)) { throw new Exception($"{childTypeSymbol} 不是typeSymbol"); } INamedTypeSymbol?availableParentType = null; bool hasAttribute = false; foreach (AttributeData?attributeData in childType.GetAttributes()) { if (attributeData.AttributeClass?.ToString() == Definition.ChildOfAttribute) { hasAttribute = true; availableParentType = attributeData.ConstructorArguments[0].Value as INamedTypeSymbol; break; } } if (hasAttribute && availableParentType == null) { return; } // 判断父级类型是否属于child约束的父级类型 if (availableParentType?.ToString() == parentTypeSymbol.ToString()) { return; } { Diagnostic diagnostic = Diagnostic.Create(AddChildTypeAnalyzerRule.Rule, memberAccessExpressionSyntax?.Name.Identifier.GetLocation(), childTypeSymbol?.Name, parentTypeSymbol?.Name); context.ReportDiagnostic(diagnostic); } }