Ejemplo n.º 1
0
        public AbstractData GetNodeData(SyntaxNode node,
                                        bool create = false,
                                        NamespaceData namespaceData   = null,
                                        TypeData typeData             = null,
                                        BaseMethodData baseMethodData = null)
        {
            FunctionData  functionData = null;
            PropertyData  propertyData = null;
            BaseFieldData fieldData    = null;
            FieldVariableDeclaratorData fieldVariableData = null;
            SyntaxNode endNode;

            if (baseMethodData != null)
            {
                endNode = baseMethodData.GetNode();
            }
            else if (typeData != null)
            {
                endNode = typeData.Node;
            }
            else if (namespaceData != null)
            {
                endNode = namespaceData.Node;
            }
            else
            {
                endNode = Node;
            }

            foreach (var n in node.AncestorsAndSelf()
                     .TakeWhile(o => !ReferenceEquals(o, endNode))
                     .Where(IsValid)
                     .Reverse())
            {
                switch (n.Kind())
                {
                case SyntaxKind.ParenthesizedLambdaExpression:
                case SyntaxKind.AnonymousMethodExpression:
                case SyntaxKind.SimpleLambdaExpression:
                case SyntaxKind.LocalFunctionStatement:
                    if (baseMethodData == null)
                    {
                        // ParenthesizedLambda, AnonymousMethod and SimpleLambda can be also defined inside a type
                        if (!n.IsKind(SyntaxKind.LocalFunctionStatement))
                        {
                            if (typeData != null)
                            {
                                return(null);                                        // TODO: A type can have one or many FuncionData so we need to register them
                            }
                        }
                        throw new InvalidOperationException($"Anonymous function {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    functionData = functionData != null
                                                        ? functionData.GetChildFunction(n, SemanticModel, create)
                                                        : baseMethodData.GetChildFunction(n, SemanticModel, create);

                    if (functionData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.MethodDeclaration:
                    if (typeData == null)
                    {
                        throw new InvalidOperationException($"Method {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    var methodNode = (MethodDeclarationSyntax)n;
                    baseMethodData = typeData.GetMethodData(methodNode, SemanticModel, create);
                    if (baseMethodData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.DestructorDeclaration:
                case SyntaxKind.ConstructorDeclaration:
                case SyntaxKind.OperatorDeclaration:
                case SyntaxKind.ConversionOperatorDeclaration:
                    if (typeData == null)
                    {
                        throw new InvalidOperationException($"Method {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    var baseMethodNode = (BaseMethodDeclarationSyntax)n;
                    baseMethodData = typeData.GetSpecialMethodData(baseMethodNode, SemanticModel, create);
                    if (baseMethodData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.ArrowExpressionClause:
                    if (propertyData == null)
                    {
                        continue;
                    }
                    functionData = propertyData.GetAccessorData;
                    break;

                case SyntaxKind.GetAccessorDeclaration:
                    if (propertyData == null)
                    {
                        throw new InvalidOperationException($"Get accessor property {n} is declared outside a {nameof(PropertyDeclarationSyntax)}");
                    }
                    functionData = propertyData.GetAccessorData;
                    if (functionData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.SetAccessorDeclaration:
                    if (propertyData == null)
                    {
                        throw new InvalidOperationException($"Set accessor property {n} is declared outside a {nameof(PropertyDeclarationSyntax)}");
                    }
                    functionData = propertyData.SetAccessorData;
                    if (functionData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.PropertyDeclaration:
                    if (typeData == null)
                    {
                        throw new InvalidOperationException($"Property {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    var propertyNode = (PropertyDeclarationSyntax)n;
                    propertyData = typeData.GetPropertyData(propertyNode, SemanticModel, create);
                    if (propertyData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.FieldDeclaration:
                case SyntaxKind.EventFieldDeclaration:
                    if (typeData == null)
                    {
                        throw new InvalidOperationException($"Field {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    var fieldNode = (BaseFieldDeclarationSyntax)n;
                    fieldData = typeData.GetBaseFieldData(fieldNode, SemanticModel, create);
                    if (fieldData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.VariableDeclarator:
                    if (fieldData == null)
                    {
                        throw new InvalidOperationException($"Field {n} is declared outside a {nameof(BaseFieldDeclarationSyntax)}");
                    }
                    var variableNode = (VariableDeclaratorSyntax)n;
                    fieldVariableData = fieldData.GetVariableDeclaratorData(variableNode, SemanticModel);
                    if (fieldVariableData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.InterfaceDeclaration:
                case SyntaxKind.StructDeclaration:
                    if (namespaceData == null)
                    {
                        namespaceData = GlobalNamespace;
                    }
                    var typeNode = (TypeDeclarationSyntax)n;
                    typeData = typeData != null
                                                        ? typeData.GetNestedTypeData(typeNode, SemanticModel, create)
                                                        : namespaceData.GetTypeData(typeNode, SemanticModel, create);

                    if (typeData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.NamespaceDeclaration:
                    var namespaceNode = (NamespaceDeclarationSyntax)n;
                    namespaceData = namespaceData != null
                                                        ? namespaceData.GetNestedNamespaceData(namespaceNode, SemanticModel, create)
                                                        : GetNamespaceData(namespaceNode, create);

                    if (namespaceData == null)
                    {
                        return(null);
                    }
                    break;
                }
            }

            switch (node.Kind())
            {
            case SyntaxKind.ParenthesizedLambdaExpression:
            case SyntaxKind.AnonymousMethodExpression:
            case SyntaxKind.SimpleLambdaExpression:
            case SyntaxKind.LocalFunctionStatement:
            case SyntaxKind.GetAccessorDeclaration:                     // Property getter
            case SyntaxKind.SetAccessorDeclaration:                     // Property setter
                return(functionData);

            case SyntaxKind.MethodDeclaration:
            case SyntaxKind.DestructorDeclaration:
            case SyntaxKind.ConstructorDeclaration:
            case SyntaxKind.OperatorDeclaration:
            case SyntaxKind.ConversionOperatorDeclaration:
                return(baseMethodData);

            case SyntaxKind.ClassDeclaration:
            case SyntaxKind.InterfaceDeclaration:
            case SyntaxKind.StructDeclaration:
                return(typeData);

            case SyntaxKind.NamespaceDeclaration:
                return(namespaceData);

            case SyntaxKind.PropertyDeclaration:
                return(propertyData);

            case SyntaxKind.FieldDeclaration:
            case SyntaxKind.EventFieldDeclaration:
                return(fieldData);

            case SyntaxKind.VariableDeclarator:
                return(fieldVariableData);

            case SyntaxKind.ArrowExpressionClause:                     // Arrow expression of a property getter or method
                return(functionData ?? baseMethodData);

            default:
                throw new InvalidOperationException($"Invalid node kind {Enum.GetName(typeof(SyntaxKind), node.Kind())}");
            }
        }
Ejemplo n.º 2
0
 public AccessorData(PropertyData propertyData, IMethodSymbol symbol, SyntaxNode node) : base(propertyData?.TypeData, symbol, node)
 {
     PropertyData = propertyData ?? throw new ArgumentNullException(nameof(propertyData));
     Node         = node ?? throw new ArgumentNullException(nameof(node));
 }