Exemple #1
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");
    }
Exemple #2
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);
        }
    }