Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
            }
        }