public SyntaxTreeNode_Base FindChildByName(params string[] name)
    {
        SyntaxTreeNode_Base result = this;

        foreach (var n in name)
        {
            var node = result as SyntaxTreeNode_Rule;
            if (node == null)
            {
                return(null);
            }

            var children = node.nodes;
            result = null;
            for (var i = 0; i < node.NumValidNodes; i++)
            {
                var child = children[i];
                if (child.ParseNode != null && child.ParseNode.ToString() == n)
                {
                    result = child;
                    break;
                }
            }
            if (result == null)
            {
                return(null);
            }
        }
        return(result);
    }
Пример #2
0
    public override TypeDefinitionBase ReturnType()
    {
        if (returnType == null)
        {
            if (kind == SymbolKind.Constructor)
            {
                return(parentSymbol as TypeDefinitionBase ?? unknownType);
            }

            if (declarations != null)
            {
                SyntaxTreeNode_Base refNode = null;
                switch (declarations[0].parseTreeNode.RuleName)
                {
                case "methodDeclaration":
                case "interfaceMethodDeclaration":
                    refNode = declarations[0].parseTreeNode.FindPreviousNode();
                    break;

                default:
                    refNode = declarations[0].parseTreeNode.Parent.Parent.ChildAt(declarations[0].parseTreeNode.Parent.m_iChildIndex - 1);
                    break;
                }
                if (refNode == null)
                {
                    Debug.LogError("Could not find method return type from node: " + declarations[0].parseTreeNode);
                }
                returnType = refNode != null ? new SymbolReference(refNode) : null;
            }
        }

        return(returnType == null ? unknownType : returnType.Definition as TypeDefinitionBase ?? unknownType);
    }
Пример #3
0
    public static void GetCompletions(IdentifierCompletionsType completionTypes, SyntaxTreeNode_Base parseTreeNode, HashSet <SymbolDefinition> completionSymbols, string assetPath)
    {
#if false
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        GetCompletions_Profiled(completionTypes, parseTreeNode, completionSymbols, assetPath);
        stopwatch.Stop();
        Debug.Log("GetCompletions: " + stopwatch.ElapsedMilliseconds + "ms");
    }
Пример #4
0
    public static SymbolDefinition GetResolvedSymbol(SyntaxTreeNode_Base baseNode)
    {
#if false
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var result = GetResolvedSymbol_Internal(baseNode);
        stopwatch.Stop();
        Debug.Log("GetResolvedSymbol: " + stopwatch.ElapsedMilliseconds + "ms");
        return(result);
    }
Пример #5
0
 public bool IsAncestorOf(SyntaxTreeNode_Base node)
 {
     while (node != null)
     {
         if (node.Parent == this)
         {
             return(true);
         }
         else
         {
             node = node.Parent;
         }
     }
     return(false);
 }
    public override void Resolve(SyntaxTreeNode_Leaf leaf, int numTypeArgs, bool asTypeOnly)
    {
        leaf.ResolvedSymbol = null;
        if (numTypeArgs == 0 && !asTypeOnly)
        {
            SyntaxTreeNode_Base target = null;

            if (leaf.m_iChildIndex == 0 && leaf.Parent != null && leaf.Parent.Parent == parseTreeNode)
            {
                var node = parseTreeNode
                           .Parent
                           .Parent
                           .Parent;
                if (node.RuleName == "objectCreationExpression")
                {
                    target = node.Parent.NodeAt(1);
                }
                else
                {
                    target = node.LeafAt(0);
                }

                if (target != null)
                {
                    var targetSymbol = target.ResolvedSymbol;
                    if (targetSymbol != null)
                    {
                        targetSymbol = targetSymbol.TypeOf();
                    }
                    else
                    {
                        targetSymbol = SymbolDefinition.ResolveNode(target, parentScope);
                    }

                    if (targetSymbol != null)
                    {
                        targetSymbol.ResolveMember(leaf, parentScope, 0, false);
                    }
                    return;
                }
            }
        }

        base.Resolve(leaf, numTypeArgs, asTypeOnly);
    }
    public override void GetCompletionData(Dictionary <string, SymbolDefinition> data, bool fromInstance, SD_Assembly assembly)
    {
        var baseNode = completionNode;

        if (baseNode.Parent != null && (baseNode.Parent == parseTreeNode || baseNode.m_iChildIndex == 0 && baseNode.Parent.Parent == parseTreeNode))
        {
            SymbolDefinition    target     = null;
            SyntaxTreeNode_Base targetNode = null;

            var node = parseTreeNode
                       .Parent
                       .Parent
                       .Parent;
            if (node.RuleName == "objectCreationExpression")
            {
                targetNode = node.Parent;
                target     = SymbolDefinition.ResolveNode(targetNode);
                var targetAsType = target as TypeDefinitionBase;
                if (targetAsType != null)
                {
                    target = targetAsType.GetThisInstance();
                }
            }
            else
            {
                targetNode = node.Parent.LeafAt(0);
                target     = SymbolDefinition.ResolveNode(node.Parent.LeafAt(0));
            }

            if (target != null)
            {
                HashSet <SymbolDefinition> completions = new HashSet <SymbolDefinition>();
                SymbolResolver.GetCompletions(IdentifierCompletionsType.Member, targetNode, completions, completionAssetPath);
                foreach (var symbol in completions)
                {
                    data.Add(symbol.name, symbol);
                }
            }
        }
        else
        {
            base.GetCompletionData(data, fromInstance, assembly);
        }
    }
Пример #8
0
    private static void GetMemberCompletions(SymbolDefinition targetDef, SyntaxTreeNode_Base parseTreeNode,
                                             SD_Assembly assemblyDefinition, Dictionary <string, SymbolDefinition> d, bool includeExtensionMethods)
    {
        if (targetDef != null)
        {
            var typeOf = targetDef.TypeOf();
            var flags  = BindingFlags.Instance | BindingFlags.Static;
            switch (targetDef.kind)
            {
            case SymbolKind.None:
            case SymbolKind.Error:
                break;

            case SymbolKind.Namespace:
            case SymbolKind.Interface:
            case SymbolKind.Struct:
            case SymbolKind.Class:
            case SymbolKind.TypeParameter:
            case SymbolKind.Delegate:
                flags = BindingFlags.Static;
                break;

            case SymbolKind.Enum:
                flags = BindingFlags.Static;
                break;

            case SymbolKind.Field:
            case SymbolKind.ConstantField:
            case SymbolKind.LocalConstant:
            case SymbolKind.Property:
            case SymbolKind.Event:
            case SymbolKind.Indexer:
            case SymbolKind.Method:
            case SymbolKind.MethodGroup:
            case SymbolKind.Constructor:
            case SymbolKind.Destructor:
            case SymbolKind.Operator:
            case SymbolKind.Accessor:
            case SymbolKind.Parameter:
            case SymbolKind.CatchParameter:
            case SymbolKind.Variable:
            case SymbolKind.ForEachVariable:
            case SymbolKind.FromClauseVariable:
            case SymbolKind.EnumMember:
                flags = BindingFlags.Instance;
                break;

            case SymbolKind.BaseTypesList:
            case SymbolKind.TypeParameterConstraintList:
                flags = BindingFlags.Static;
                break;

            case SymbolKind.Instance:
                flags = BindingFlags.Instance;
                break;

            case SymbolKind.Null:
                return;

            default:
                throw new ArgumentOutOfRangeException();
            }
            //targetDef.kind = targetDef is TypeDefinitionBase && targetDef.kind != SymbolKind.Enum ? BindingFlags.Static : targetDef is InstanceDefinition ? BindingFlags.Instance : 0;

            TypeDefinitionBase contextType = null;
            for (var n = parseTreeNode as SyntaxTreeNode_Rule ?? parseTreeNode.Parent; n != null; n = n.Parent)
            {
                var s = n.scope as Scope_SymbolDeclaration;
                if (s != null)
                {
                    contextType = s.declaration.definition as TypeDefinitionBase;
                    if (contextType != null)
                    {
                        break;
                    }
                }
            }

            AccessLevelMask mask =
                typeOf == contextType || typeOf.IsSameOrParentOf(contextType) ? AccessLevelMask.Private | AccessLevelMask.Protected | AccessLevelMask.Internal | AccessLevelMask.Public :
                contextType != null && contextType.DerivesFrom(typeOf as TypeDefinitionBase) ? AccessLevelMask.Protected | AccessLevelMask.Internal | AccessLevelMask.Public :
                AccessLevelMask.Internal | AccessLevelMask.Public;

            if (typeOf.Assembly == null || !typeOf.Assembly.InternalsVisibleIn(assemblyDefinition))
            {
                mask &= ~AccessLevelMask.Internal;
            }

            typeOf.GetMembersCompletionData(d, flags, mask, assemblyDefinition);

            if (includeExtensionMethods && flags == BindingFlags.Instance &&
                (typeOf.kind == SymbolKind.Class || typeOf.kind == SymbolKind.Struct || typeOf.kind == SymbolKind.Interface || typeOf.kind == SymbolKind.Enum))
            {
                var enclosingScopeNode = parseTreeNode as SyntaxTreeNode_Rule ?? parseTreeNode.Parent;
                while (enclosingScopeNode != null && enclosingScopeNode.scope == null)
                {
                    enclosingScopeNode = enclosingScopeNode.Parent;
                }
                var enclosingScope = enclosingScopeNode != null ? enclosingScopeNode.scope : null;

                if (enclosingScope != null)
                {
                    enclosingScope.GetExtensionMethodsCompletionData(typeOf as TypeDefinitionBase, d);
                }
            }
        }
    }
Пример #9
0
    public static void GetCompletions_Profiled(IdentifierCompletionsType completionTypes, ParseTree.BaseNode parseTreeNode, HashSet <SymbolDefinition> completionSymbols, string assetPath)
    {
#endif
        try
        {
            var d = new Dictionary <string, SymbolDefinition>();
            var assemblyDefinition = SD_Assembly.FromAssetPath(assetPath);

            if ((completionTypes & IdentifierCompletionsType.MemberName) != 0)
            {
                SyntaxTreeNode_Base targetNode = null;

                var node = parseTreeNode.Parent;
                if (node.RuleName != "objectOrCollectionInitializer")
                {
                    if (node.RuleName != "objectInitializer")
                    {
                        if (node.RuleName == "memberInitializerList")
                        {
                            node = node.Parent; // objectInitializer
                        }
                    }
                    node = node.Parent; // objectOrCollectionInitializer
                }
                node = node.Parent;
                if (node.RuleName == "objectCreationExpression")
                {
                    targetNode = node.Parent;
                }
                else // node is memberInitializer
                {
                    targetNode = node.LeafAt(0);
                }

                var targetDef = targetNode != null?SymbolDefinition.ResolveNode(targetNode) : null;

                if (targetDef != null)
                {
                    GetMemberCompletions(targetDef, parseTreeNode, assemblyDefinition, d, false);

                    var filteredData = new Dictionary <string, SymbolDefinition>();
                    foreach (var kv in d)
                    {
                        var symbol = kv.Value;
                        if (symbol.kind == SymbolKind.Field && (symbol.modifiers & Modifiers.ReadOnly) == 0 ||
                            symbol.kind == SymbolKind.Property && symbol.FindName("set", 0, false) != null)
                        {
                            filteredData[kv.Key] = symbol;
                        }
                    }
                    d = filteredData;
                }

                var targetType = targetDef != null?targetDef.TypeOf() as TypeDefinitionBase : null;

                if (targetType == null || !targetType.DerivesFrom(SymbolDefinition.builtInTypes_IEnumerable))
                {
                    completionSymbols.Clear();
                    completionSymbols.UnionWith(d.Values);
                    return;
                }
            }

            if ((completionTypes & IdentifierCompletionsType.Member) != 0)
            {
                var target = parseTreeNode.FindPreviousNode();
                if (target != null)
                {
                    var targetAsNode = target as SyntaxTreeNode_Rule;
                    if (targetAsNode != null && targetAsNode.RuleName == "primaryExpressionPart")
                    {
                        var node0 = targetAsNode.NodeAt(0);
                        if (node0 != null && node0.RuleName == "arguments")
                        {
                            target       = target.FindPreviousNode();
                            targetAsNode = target as SyntaxTreeNode_Rule;
                        }
                    }
                    //Debug.Log(targetAsNode ?? target.parent);
                    ResolveNode(targetAsNode ?? target.Parent);
                    var targetDef = GetResolvedSymbol(targetAsNode ?? target.Parent);

                    GetMemberCompletions(targetDef, parseTreeNode, assemblyDefinition, d, true);
                }
            }
            else if (parseTreeNode == null)
            {
#if SI3_WARNINGS
                Debug.LogWarning(completionTypes);
#endif
            }
            else
            {
                Scope_Base.completionNode      = parseTreeNode;
                Scope_Base.completionAssetPath = assetPath;

                if (parseTreeNode.IsLit("=>"))
                {
                    parseTreeNode = parseTreeNode.Parent.NodeAt(parseTreeNode.m_iChildIndex + 1) ?? parseTreeNode;
                }
                if (parseTreeNode.IsLit("]") && parseTreeNode.Parent.RuleName == "attributes")
                {
                    parseTreeNode = parseTreeNode.Parent.Parent.NodeAt(parseTreeNode.Parent.m_iChildIndex + 1);
                }

                var enclosingScopeNode = parseTreeNode as SyntaxTreeNode_Rule ?? parseTreeNode.Parent;
                if (enclosingScopeNode != null && (enclosingScopeNode.scope is Scope_SymbolDeclaration) &&
                    (parseTreeNode.IsLit(";") || parseTreeNode.IsLit("}")) &&
                    enclosingScopeNode.GetLastLeaf() == parseTreeNode)
                {
                    enclosingScopeNode = enclosingScopeNode.Parent;
                }
                while (enclosingScopeNode != null && enclosingScopeNode.scope == null)
                {
                    enclosingScopeNode = enclosingScopeNode.Parent;
                }
                if (enclosingScopeNode != null)
                {
                    var lastLeaf = parseTreeNode as SyntaxTreeNode_Leaf ??
                                   ((SyntaxTreeNode_Rule)parseTreeNode).GetLastLeaf() ??
                                   ((SyntaxTreeNode_Rule)parseTreeNode).FindPreviousLeaf();
                    Scope_Base.completionAtLine       = lastLeaf != null ? lastLeaf.Line : 0;
                    Scope_Base.completionAtTokenIndex = lastLeaf != null ? lastLeaf.TokenIndex : 0;

                    enclosingScopeNode.scope.GetCompletionData(d, true, assemblyDefinition);
                }
            }

            completionSymbols.UnionWith(d.Values);
        }
        catch (Exception e)
        {
            Debug.LogException(e);
        }
    }
 public SymbolReference(SyntaxTreeNode_Base node)
 {
     parseTreeNode = node;
 }
 public void ImportNamespace(string namespaceToImport, SyntaxTreeNode_Base declaringNode)
 {
     throw new NotImplementedException();
 }
Пример #12
0
    public override SymbolDefinition TypeOf()
    {
        if (_resolvingTypeOf)
        {
            return(unknownType);
        }
        _resolvingTypeOf = true;

        if (type != null && (type.Definition == null || !type.Definition.IsValid()))
        {
            type = null;
        }

        if (type != null && type.Definition.kind == SymbolKind.Error)
        {
            type = null;
        }

        if (type == null)
        {
            {
                SymbolDeclaration decl = declarations != null?declarations.FirstOrDefault() : null;

                if (decl != null)
                {
                    SyntaxTreeNode_Base typeNode = null;
                    switch (decl.kind)
                    {
                    case SymbolKind.Parameter:
                        if (decl.parseTreeNode.RuleName == "implicitAnonymousFunctionParameter")
                        {
                            type = TypeOfImplicitParameter(decl);
                        }
                        else
                        {
                            typeNode = decl.parseTreeNode.FindChildByName("type");
                            type     = typeNode != null ? new SymbolReference(typeNode) : null;//"System.Object" };
                        }
                        break;

                    case SymbolKind.Field:
                        typeNode = decl.parseTreeNode.Parent.Parent.Parent.FindChildByName("type");
                        type     = typeNode != null ? new SymbolReference(typeNode) : null;//"System.Object" };
                        break;

                    case SymbolKind.EnumMember:
                        type = new SymbolReference(parentSymbol);
                        break;

                    case SymbolKind.ConstantField:
                    case SymbolKind.LocalConstant:
                        //typeNode = decl.parseTreeNode.parent.parent.ChildAt(1);
                        //break;
                        switch (decl.parseTreeNode.Parent.Parent.RuleName)
                        {
                        case "constantDeclaration":
                        case "localDeclaration_Constant":
                            typeNode = decl.parseTreeNode.Parent.Parent.ChildAt(1);
                            break;

                        default:
                            typeNode = decl.parseTreeNode.Parent.Parent.Parent.FindChildByName("IDENTIFIER");
                            break;
                        }
                        type = typeNode != null ? new SymbolReference(typeNode) : null;
                        break;

                    case SymbolKind.Property:
                    case SymbolKind.Indexer:
                        typeNode = decl.parseTreeNode.Parent.FindChildByName("type");
                        type     = typeNode != null ? new SymbolReference(typeNode) : null;
                        break;

                    case SymbolKind.Event:
                        typeNode = decl.parseTreeNode.FindParentByName("eventDeclaration").ChildAt(1);
                        type     = typeNode != null ? new SymbolReference(typeNode) : null;
                        break;

                    case SymbolKind.Variable:
                        if (decl.parseTreeNode != null && decl.parseTreeNode.Parent != null && decl.parseTreeNode.Parent.Parent != null)
                        {
                            typeNode = decl.parseTreeNode.Parent.Parent.FindChildByName("localVariableType");
                        }
                        type = typeNode != null ? new SymbolReference(typeNode) : null;
                        break;

                    case SymbolKind.ForEachVariable:
                        if (decl.parseTreeNode != null)
                        {
                            typeNode = decl.parseTreeNode.FindChildByName("localVariableType");
                        }
                        type = typeNode != null ? new SymbolReference(typeNode) : null;
                        break;

                    case SymbolKind.FromClauseVariable:
                        type = null;
                        if (decl.parseTreeNode != null)
                        {
                            typeNode = decl.parseTreeNode.FindChildByName("type");
                            type     = typeNode != null
                                    ? new SymbolReference(typeNode)
                                    : new SymbolReference(EnumerableElementType(decl.parseTreeNode.NodeAt(-1)));
                        }
                        break;

                    case SymbolKind.CatchParameter:
                        if (decl.parseTreeNode != null)
                        {
                            typeNode = decl.parseTreeNode.Parent.FindChildByName("exceptionClassType");
                        }
                        type = typeNode != null ? new SymbolReference(typeNode) : null;
                        break;

                    default:
                        Debug.LogError(decl.kind);
                        break;
                    }
                }
            }
        }

        var result = type != null ? type.Definition : unknownType;

        _resolvingTypeOf = false;
        return(result);
    }
    public SyntaxTreeNode_Base NameNode()
    {
        if (parseTreeNode == null || parseTreeNode.NumValidNodes == 0)
        {
            return(null);
        }

        SyntaxTreeNode_Base nameNode = null;

        switch (parseTreeNode.RuleName)
        {
        case "Declaration_Namespace":
            nameNode = parseTreeNode.ChildAt(1);
            var nameNodeAsNode = nameNode as SyntaxTreeNode_Rule;
            if (nameNodeAsNode != null && nameNodeAsNode.NumValidNodes != 0)
            {
                nameNode = nameNodeAsNode.ChildAt(-1) ?? nameNode;
            }
            break;

        case "Directive_UsingAlias":
            nameNode = parseTreeNode.ChildAt(0);
            break;

        case "interfaceDeclaration":
        case "structDeclaration":
        case "classDeclaration":
        case "enumDeclaration":
            nameNode = parseTreeNode.ChildAt(1);
            break;

        case "delegateDeclaration":
            nameNode = parseTreeNode.ChildAt(2);
            break;

        case "eventDeclarator":
        case "eventWithAccessorsDeclaration":
        case "propertyDeclaration":
        case "interfacePropertyDeclaration":
        case "variableDeclarator":
        case "localVariableDeclarator":
        case "constantDeclarator":
        case "interfaceMethodDeclaration":
        case "catchExceptionIdentifier":
            nameNode = parseTreeNode.ChildAt(0);
            break;

        case "methodDeclaration":
        case "constructorDeclaration":
            var methodHeaderNode = parseTreeNode.NodeAt(0);
            if (methodHeaderNode != null && methodHeaderNode.NumValidNodes > 0)
            {
                nameNode = methodHeaderNode.ChildAt(0);
            }
            break;

        case "methodHeader":
        case "constructorDeclarator":
            nameNode = parseTreeNode.ChildAt(0);
            break;

        case "destructorDeclarator":
            nameNode = parseTreeNode.FindChildByName("IDENTIFIER");
            break;

        case "fixedParameter":
        case "operatorParameter":
        case "parameterArray":
        case "explicitAnonymousFunctionParameter":
            nameNode = parseTreeNode.FindChildByName("NAME");
            break;

        case "implicitAnonymousFunctionParameter":
            nameNode = parseTreeNode.ChildAt(0);
            break;

        case "typeParameter":
            nameNode = parseTreeNode.ChildAt(0);
            break;

        case "enumMemberDeclaration":
            if (parseTreeNode.ChildAt(0) is SyntaxTreeNode_Rule)
            {
                nameNode = parseTreeNode.ChildAt(1);
            }
            else
            {
                nameNode = parseTreeNode.ChildAt(0);
            }
            break;

        case "statementList":
            return(null);

        case "lambdaExpression":
        case "anonymousMethodExpression":
            return(parseTreeNode);

        case "interfaceTypeList":
            nameNode = parseTreeNode.ChildAt(0);
            break;

        case "foreachStatement":
        case "fromClause":
            nameNode = parseTreeNode.FindChildByName("NAME");
            break;

        case "getAccessorDeclaration":
        case "interfaceGetAccessorDeclaration":
        case "setAccessorDeclaration":
        case "interfaceSetAccessorDeclaration":
        case "addAccessorDeclaration":
        case "removeAccessorDeclaration":
            nameNode = parseTreeNode.FindChildByName("IDENTIFIER");
            break;

        case "indexerDeclaration":
        case "interfaceIndexerDeclaration":
        case "labeledStatement":
            return(parseTreeNode.ChildAt(0));

        case "conversionOperatorDeclarator":
        case "operatorDeclarator":
        case "Directive_UsingNamespace":
        case "typeParameterConstraintsClause":
            return(null);

        default:
            Debug.LogWarning("Don't know how to extract symbol name from: " + parseTreeNode);
            return(null);
        }
        return(nameNode);
    }
Пример #14
0
 public abstract IdentifierCompletionsType GetCompletionTypes(SyntaxTreeNode_Base afterNode);