Example #1
0
        void CreateDeeperLevelCache(IBlockNode bn)
        {
            var dd = TypeCache[bn] = new Dictionary <string, INode>();

            // Set the parent to null to crawl through current level only. Imports/Mixins etc. will be handled though.
            var parentBackup = bn.Parent;

            bn.Parent = null;

            sharedCtxt.CurrentContext.ScopedBlock = bn;
            var vis = ItemEnumeration.EnumAllAvailableMembers(sharedCtxt, bn.EndLocation, MemberFilter.Types);

            if (vis != null)
            {
                foreach (var n in vis)
                {
                    if (!string.IsNullOrEmpty(n.Name))
                    {
                        dd[n.Name] = n;
                    }
                }
            }

            bn.Parent = parentBackup;
        }
Example #2
0
        /// <summary>
        /// Used for caching available types.
        /// </summary>
        protected override void OnScopedBlockChanged(IBlockNode bn)
        {
            Dictionary <int, byte> dd = null;

            foreach (var n in ItemEnumeration.EnumScopedBlockChildren(ctxt, MemberFilter.Types | MemberFilter.Enums))
            {
                if (n.NameHash != 0)
                {
                    if (dd == null && !TypeCache.TryGetValue(bn, out dd))
                    {
                        TypeCache [bn] = dd = new Dictionary <int, byte> ();
                    }

                    byte type = 0;

                    if (n is DClassLike)
                    {
                        type = (n as DClassLike).ClassType;
                    }
                    else if (n is DEnum)
                    {
                        type = DTokens.Enum;
                    }
                    else if (n is TemplateParameter.Node)
                    {
                        type = DTokens.Not;                         // Only needed for highlighting and thus just a convention question
                    }
                    dd[n.NameHash] = type;
                }
            }
        }
Example #3
0
        static IEnumerable <AbstractType> GetStructMembers(StructType t, ResolutionContext ctxt)
        {
            if (lastStructMembersEnlisted == null ||
                lastStructHandled != t.Definition)
            {
                lastStructHandled = t.Definition;
                var children = ItemEnumeration.EnumChildren(t, ctxt, MemberFilter.Variables);
                lastStructMembersEnlisted = TypeDeclarationResolver.HandleNodeMatches(children, ctxt, t);
            }

            return(lastStructMembersEnlisted);
        }
Example #4
0
        /// <summary>
        /// Used for caching available types.
        /// </summary>
        protected override void OnScopedBlockChanged(IBlockNode bn)
        {
            HashSet <int> dd = null;

            foreach (var n in ItemEnumeration.EnumScopedBlockChildren(ctxt, MemberFilter.Types))
            {
                if (n.NameHash != 0)
                {
                    if (dd == null && !TypeCache.TryGetValue(bn, out dd))
                    {
                        TypeCache [bn] = dd = new HashSet <int> ();
                    }
                    dd.Add(n.NameHash);
                }
            }
        }
Example #5
0
        void CreateDeeperLevelCache(IBlockNode bn)
        {
            var dd = TypeCache[bn] = new Dictionary <int, INode>();

            // Set the parent to null to crawl through current level only. Imports/Mixins etc. will be handled though.
            var parentBackup = bn.Parent;

            bn.Parent = null;

            sharedCtxt.CurrentContext.Set(bn);
            foreach (var n in ItemEnumeration.EnumScopedBlockChildren(sharedCtxt, MemberFilter.Types))
            {
                if (n.NameHash != 0)
                {
                    dd[n.NameHash] = n;
                }
            }

            bn.Parent = parentBackup;
        }
Example #6
0
        /// <summary>
        /// Used for caching available types.
        /// </summary>
        protected override void OnScopedBlockChanged(IBlockNode bn)
        {
            Dictionary <int, byte> dd = null;

            if (ctxt.CancelOperation)
            {
                return;
            }
            foreach (var n in ItemEnumeration.EnumScopedBlockChildren(ctxt, MemberFilter.Types | MemberFilter.Enums | MemberFilter.TypeParameters | MemberFilter.Variables))
            {
                if (n.NameHash != 0)
                {
                    if (dd == null && !TypeCache.TryGetValue(bn, out dd))
                    {
                        TypeCache [bn] = dd = new Dictionary <int, byte> ();
                    }

                    dd[n.NameHash] = n.Accept(TypeDet);
                }
            }
        }
        protected override void BuildCompletionDataInternal(IEditorData Editor, string EnteredText)
        {
            IEnumerable <INode> listedItems = null;
            var visibleMembers = MemberFilter.All;

            IStatement curStmt = null;

            if (curBlock == null)
            {
                curBlock = D_Parser.Resolver.TypeResolution.DResolver.SearchBlockAt(Editor.SyntaxTree, Editor.CaretLocation, out curStmt);
            }

            if (curBlock == null)
            {
                return;
            }

            // 1) Get current context the caret is at
            if (parsedBlock == null)
            {
                parsedBlock = FindCurrentCaretContext(
                    Editor.ModuleCode,
                    curBlock,
                    Editor.CaretOffset,
                    Editor.CaretLocation,
                    out trackVars);
            }

            // 2) If in declaration and if node identifier is expected, do not show any data
            if (trackVars == null)
            {
                // --> Happens if no actual declaration syntax given --> Show types/imports/keywords anyway
                visibleMembers = MemberFilter.Imports | MemberFilter.Types | MemberFilter.Keywords;

                listedItems = ItemEnumeration.EnumAllAvailableMembers(curBlock, null, Editor.CaretLocation, Editor.ParseCache, visibleMembers);
            }
            else
            {
                var n  = trackVars.LastParsedObject as INode;
                var dv = n as DVariable;
                if (dv != null && dv.IsAlias && dv.Type == null && trackVars.ExpectingIdentifier)
                {
                    // Show completion because no aliased type has been entered yet
                }
                else if (n != null && string.IsNullOrEmpty(n.Name) && trackVars.ExpectingIdentifier)
                {
                    return;
                }

                else if (trackVars.LastParsedObject is TokenExpression &&
                         DTokens.BasicTypes[(trackVars.LastParsedObject as TokenExpression).Token] &&
                         !string.IsNullOrEmpty(EnteredText) &&
                         IsIdentifierChar(EnteredText[0]))
                {
                    return;
                }

                if (trackVars.LastParsedObject is DAttribute)
                {
                    var attr = trackVars.LastParsedObject as DAttribute;

                    if (attr.IsStorageClass && attr.Token != DTokens.Abstract)
                    {
                        return;
                    }
                }

                if (trackVars.LastParsedObject is ImportStatement)
                {
                    visibleMembers = MemberFilter.Imports;
                }
                else if ((trackVars.LastParsedObject is NewExpression && trackVars.IsParsingInitializer) ||
                         trackVars.LastParsedObject is TemplateInstanceExpression && ((TemplateInstanceExpression)trackVars.LastParsedObject).Arguments == null)
                {
                    visibleMembers = MemberFilter.Imports | MemberFilter.Types;
                }
                else if (EnteredText == " ")
                {
                    return;
                }
                // In class bodies, do not show variables
                else if (!(parsedBlock is BlockStatement || trackVars.IsParsingInitializer))
                {
                    visibleMembers = MemberFilter.Imports | MemberFilter.Types | MemberFilter.Keywords;
                }

                /*
                 * Handle module-scoped things:
                 * When typing a dot without anything following, trigger completion and show types, methods and vars that are located in the module & import scope
                 */
                else if (trackVars.LastParsedObject is TokenExpression &&
                         ((TokenExpression)trackVars.LastParsedObject).Token == DTokens.Dot)
                {
                    visibleMembers = MemberFilter.Methods | MemberFilter.Types | MemberFilter.Variables;
                    curBlock       = Editor.SyntaxTree;
                    curStmt        = null;
                }

                // In a method, parse from the method's start until the actual caret position to get an updated insight
                if (visibleMembers.HasFlag(MemberFilter.Variables) &&
                    curBlock is DMethod &&
                    parsedBlock is BlockStatement)
                {
                    var bs = parsedBlock as BlockStatement;

                    // Insert the updated locals insight.
                    // Do not take the caret location anymore because of the limited parsing of our code.
                    curStmt = bs.SearchStatementDeeply(bs.EndLocation);
                }
                else
                {
                    curStmt = null;
                }



                if (visibleMembers != MemberFilter.Imports)                 // Do not pass the curStmt because we already inserted all updated locals a few lines before!
                {
                    listedItems = ItemEnumeration.EnumAllAvailableMembers(curBlock, curStmt, Editor.CaretLocation, Editor.ParseCache, visibleMembers);
                }
            }

            // Add all found items to the referenced list
            if (listedItems != null)
            {
                foreach (var i in listedItems)
                {
                    if (i is IAbstractSyntaxTree)                     // Modules and stuff will be added later on
                    {
                        continue;
                    }

                    if (CanItemBeShownGenerally(i))
                    {
                        CompletionDataGenerator.Add(i);
                    }
                }
            }

            //TODO: Split the keywords into such that are allowed within block statements and non-block statements
            // Insert typable keywords
            if (visibleMembers.HasFlag(MemberFilter.Keywords))
            {
                foreach (var kv in DTokens.Keywords)
                {
                    CompletionDataGenerator.Add(kv.Key);
                }
            }

            else if (visibleMembers.HasFlag(MemberFilter.Types))
            {
                foreach (var kv in DTokens.BasicTypes_Array)
                {
                    CompletionDataGenerator.Add(kv);
                }
            }

            #region Add module name stubs of importable modules
            if (visibleMembers.HasFlag(MemberFilter.Imports))
            {
                var nameStubs    = new Dictionary <string, string>();
                var availModules = new List <IAbstractSyntaxTree>();

                foreach (var sstmt in Editor.SyntaxTree.StaticStatements)
                {
                    if (sstmt is ImportStatement)
                    {
                        var impStmt = (ImportStatement)sstmt;

                        foreach (var imp in impStmt.Imports)
                        {
                            if (string.IsNullOrEmpty(imp.ModuleAlias))
                            {
                                var id = imp.ModuleIdentifier.ToString();

                                IAbstractSyntaxTree mod = null;
                                foreach (var m in Editor.ParseCache.LookupModuleName(id))
                                {
                                    mod = m;
                                    break;
                                }

                                if (mod == null || string.IsNullOrEmpty(mod.ModuleName))
                                {
                                    continue;
                                }

                                var stub = imp.ModuleIdentifier.InnerMost.ToString();

                                if (!nameStubs.ContainsKey(stub) && !availModules.Contains(mod))
                                {
                                    if (stub == mod.ModuleName)
                                    {
                                        availModules.Add(mod);
                                    }
                                    else
                                    {
                                        nameStubs.Add(stub, GetModulePath(mod.FileName, id.Split('.').Length, 1));
                                    }
                                }
                            }
                        }
                    }
                }

                foreach (var kv in nameStubs)
                {
                    CompletionDataGenerator.Add(kv.Key, null, kv.Value);
                }

                foreach (var mod in availModules)
                {
                    CompletionDataGenerator.Add(mod.ModuleName, mod);
                }
            }
            #endregion
        }