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; }
/// <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; } } }
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); }
/// <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); } } }
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; }
/// <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 }