ReferencesFinder(INode symbol, IAbstractSyntaxTree ast, ResolverContextStack ctxt) { this.ast = ast; this.symbol = symbol; searchId = symbol.Name; this.ctxt = ctxt; }
public EditorPathbarProvider(Document doc, object tag) { this.document = doc; this.tag = ((D_Parser.Dom.INode)tag).Parent; var ast = document.ParsedDocument as ParsedDModule; if (ast != null) syntaxTree = ast.DDom; Reset (); }
public static TypeReferencesResult Scan(IAbstractSyntaxTree ast, ParseCacheList pcl) { var typeRefFinder = new TypeReferenceFinder(pcl); typeRefFinder.ast = ast; // Enum all identifiers typeRefFinder.S(ast); // Crawl through all remaining expressions by evaluating their types and check if they're actual type references. typeRefFinder.queueCount = typeRefFinder.q.Count; typeRefFinder.ResolveAllIdentifiers(); return typeRefFinder.result; }
public void Add(string rootDirectory, IAbstractSyntaxTree ast) { // Handle module packages var relativeDirectory = Path.GetDirectoryName(ast.FileName.Substring(rootDirectory.Length)); var modulePackage = relativeDirectory.Replace(Path.DirectorySeparatorChar, '.'); if (!ModulePackageNames.ContainsKey(modulePackage)) ModulePackageNames.Add(modulePackage, Path.GetDirectoryName(ast.FileName)); // Overwrite its module name ast.ModuleName = DModule.GetModuleName(rootDirectory,ast); Add(ast, modulePackage); }
/// <summary> /// </summary> /// <param name="ast">The syntax tree to scan</param> /// <param name="symbol">Might not be a child symbol of ast</param> /// <param name="ctxt">The context required to search for symbols</param> /// <returns></returns> public static IEnumerable<ISyntaxRegion> Scan(IAbstractSyntaxTree ast, INode symbol, ResolverContextStack ctxt) { if (ast == null || symbol == null || ctxt == null) return null; ctxt.PushNewScope(ast); var f = new ReferencesFinder(symbol, ast, ctxt); f.S(ast); ctxt.Pop(); return f.l; }
public void CacheModuleMethods(IAbstractSyntaxTree ast, ResolverContextStack ctxt) { foreach (var m in ast) if (m is DMethod) { var dm = (DMethod)m; if (dm.Parameters == null || dm.Parameters.Count == 0 || dm.Parameters[0].Type == null) continue; ctxt.PushNewScope(dm); var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); ctxt.Pop(); if (firstArg_result != null && firstArg_result.Length != 0) lock (CachedMethods) CachedMethods[dm] = firstArg_result[0]; } }
public void Add(IAbstractSyntaxTree ast, string modulePackage=null) { if (modulePackage == null) { int lastDot=ast.ModuleName.LastIndexOf('.'); if (lastDot < 0) modulePackage = ""; else modulePackage = ast.ModuleName.Substring(0, lastDot); } Modules[ast.ModuleName] = ast; // Handle its package origin List<IAbstractSyntaxTree> modPackageList = null; if (!ModulePackages.TryGetValue(modulePackage, out modPackageList)) ModulePackages[modulePackage] = new List<IAbstractSyntaxTree> { ast }; else modPackageList.Add(ast); // Put public root symbols to the types/globalsymbols dictionaries HandleDictEntries(ast); }
//INode typeNode; //IEnumerable<IAbstractSyntaxTree> moduleCache; public DDebugSymbolWrapper(DebugScopedSymbol sym, DDebugSupport support) : base(sym) { this.supp = support; try { /*var ci=CoreManager.DebugManagement.Engine.Symbols.GetPointerTarget(sym.Offset); object mo = null; IntPtr moPtr = new IntPtr(); var raw = CoreManager.DebugManagement.Engine.Memory.ReadVirtual(ci, 4); Marshal.StructureToPtr(raw, moPtr, false); mo = Marshal.PtrToStructure(moPtr, typeof(DObject));*/ } catch { } // Search currently scoped module string file = ""; uint line = 0; CoreManager.DebugManagement.Engine.Symbols.GetLineByOffset(CoreManager.DebugManagement.Engine.CurrentInstructionOffset,out file,out line); codeLine = (int)line; if (string.IsNullOrWhiteSpace(file)) return; // If file name found, get syntax tree, as far as possible DProject ownerPrj=null; module = DLanguageBinding.GetFileSyntaxTree(file,out ownerPrj); // If syntax tree built, search the variable location if (module != null) { IStatement stmt = null; var block = DResolver.SearchBlockAt(module, new CodeLocation(0, codeLine),out stmt); var ctxt=ResolutionContext.Create(null, null, block); var res = TypeDeclarationResolver.ResolveIdentifier(Symbol.Name,ctxt, null); if (res!=null && res.Length > 0 && res[0] is DSymbol) { variableNode = ((DSymbol)res[0]).Definition; //moduleCache = DCodeCompletionSupport.Instance.EnumAvailableModules(ownerPrj); } } // Set type string _typeString= base.TypeString; if (variableNode != null) { var t = variableNode.Type; if (t != null) _typeString= t.ToString(); } // Set value string if (_typeString.StartsWith("class ")) { _valueString = base.ValueString; //CodeInjection.WriteObjectVariable(supp.hProcess, supp.varAddr, (uint)sym.Offset); //_valueString = CodeInjection.EvaluateObjectString(supp.hProcess, supp.toStringFunc, supp.varAddr, (uint)sym.Offset); /* var th = CodeInjection.BeginExecuteMethod(supp.hProcess, supp.toStringFunc); CoreManager.DebugManagement.Engine.Execute("~2 g"); CoreManager.DebugManagement.Engine.WaitForEvent(); CodeInjection.WaitForExecutionEnd(th); */ //_valueString = CodeInjection.ReadDString(supp.hProcess, supp.varAddr); } else { _valueString=base.ValueString; if (variableNode != null) { ITypeDeclaration curValueType = variableNode.Type; if (curValueType != null) { if (!IsBasicType(curValueType)) { if (TypeString == "string") //TODO: Replace this by searching the alias definition in the cache curValueType = new ArrayDecl() { InnerDeclaration = new DTokenDeclaration(DTokens.Char) }; else if (TypeString == "wstring") curValueType = new ArrayDecl() { InnerDeclaration = new DTokenDeclaration(DTokens.Wchar) }; else if (TypeString == "dstring") curValueType = new ArrayDecl() { InnerDeclaration = new DTokenDeclaration(DTokens.Dchar) }; if (IsArray(curValueType)) { var clampDecl = curValueType as ArrayDecl; var valueType = clampDecl.InnerDeclaration; if (valueType is DTokenDeclaration) { bool IsString = false; uint elsz = 0; var realType = DetermineArrayType((valueType as DTokenDeclaration).Token, out elsz, out IsString); var arr = CoreManager.DebugManagement.Engine.Symbols.ReadArray(sym.Offset, realType, elsz); if (arr != null) _valueString = BuildArrayContentString(arr, IsString); } } else { //TODO: call an object's toString method somehow to obtain its representing string manually } } } } } }
/// <summary> /// Adds a module (name stub) to the completion data /// </summary> /// <param name="ModuleName"></param> /// <param name="AssocModule"></param> public void Add(string ModuleName, IAbstractSyntaxTree Module = null, string PathOverride = null) { expansions += ModuleName + "\n"; }
public void Process(IAbstractSyntaxTree ast) { int value = this.ValueOf(Option<Expression>.AsOption(ast)); Console.WriteLine("Expression value is {0}", value); }
/// <summary> /// Scans the syntax tree for all kinds of identifier declarations, /// tries to resolve them, /// adds them to a dictionary. If not found, /// they will be added to a second, special array. /// /// Note: For performance reasons, it's recommended to disable 'ResolveAliases' in the ResolverContext parameter /// </summary> /// <param name="lastResCtxt"></param> /// <param name="SyntaxTree"></param> /// <returns></returns> public static CodeScanResult ScanSymbols(ResolverContext lastResCtxt,IAbstractSyntaxTree SyntaxTree) { var csr = new CodeScanResult(); var compDict = new Dictionary<string, ResolveResult>(); // Step 1: Enum all existing type id's that shall become resolved'n displayed var typeObjects = CodeScanner.ScanForTypeIdentifiers(SyntaxTree); foreach (var o in typeObjects) { if (o == null) continue; #region Identifier Declarations if (o is IdentifierDeclaration) { HandleIdDeclaration(o as IdentifierDeclaration, lastResCtxt, SyntaxTree, csr, compDict); } #endregion /* #region Method call check else if (o is PostfixExpression_MethodCall) { var mc=o as PostfixExpression_MethodCall; int argc = mc.ArgumentCount; var methodOverloads=HandleIdDeclaration(mc.ExpressionTypeRepresentation as IdentifierDeclaration, lastResCtxt, SyntaxTree, csr, compDict); // Important: Also check template parameters and arguments! IExpression[] TemplateArguments=null; if (mc.PostfixForeExpression is TemplateInstanceExpression) TemplateArguments = (mc.PostfixForeExpression as TemplateInstanceExpression).Arguments; int TemplateArgCount = TemplateArguments == null ? 0 : TemplateArguments.Length; // Note: If no method members were found, we already show the semantic error as a generically missing symbol if (methodOverloads != null) { var l1 = new List<DMethod>(); var l2 = new List<DMethod>(); #region First add all available method overloads foreach (var rr_ in methodOverloads) { // Like every time, remove unnecessary aliasing var rr = DResolver.TryRemoveAliasesFromResult(rr_); // Can be either 1) a normal method OR 2) a type related opCall // 1) if (rr is MemberResult) { var mr = rr as MemberResult; //FIXME: What about delegate aliases'n stuff? if (!(mr.ResolvedMember is DMethod)) continue; var dm = mr.ResolvedMember as DMethod; // Even before checking argument types etc, pre-select possibly chosen overloads // by comparing the method's parameter count with the call's argument count if (dm.Parameters.Count == argc && (dm.TemplateParameters==null?true: dm.TemplateParameters.Length==TemplateArgCount)) l1.Add(dm); } // 2) else if (rr is TypeResult) { var tr = rr as TypeResult; // Scan the type for opCall members var opCalls=DResolver.ScanNodeForIdentifier(tr.ResolvedTypeDefinition, "opCall", lastResCtxt); if (opCalls != null) foreach (var n in opCalls) { var dm = n as DMethod; // Also pre-filter opCall members by param count comparison if (dm!=null && dm.Parameters.Count == argc && (dm.TemplateParameters == null ? true : dm.TemplateParameters.Length == TemplateArgCount)) l1.Add(dm); } } } #endregion // Must be a semantic error - no method fits in any way if(l1.Count<1) { csr.ParameterActions.Add(o as IExpression, null); continue; } // Compare template arguments first } } #endregion */ } return csr; }
static ResolveResult[] HandleIdDeclaration(IdentifierDeclaration typeId, ResolverContext lastResCtxt, IAbstractSyntaxTree SyntaxTree, CodeScanResult csr, Dictionary<string, ResolveResult> compDict) { var typeString = typeId.ToString(); bool WasAlreadyResolved = false; ResolveResult[] allCurrentResults = null; ResolveResult rr = null; /* * string,wstring,dstring are highlighted by the editor's syntax definition automatically.. * Anyway, allow to resolve e.g. "object.string" */ if (typeString == "" || typeString == "string" || typeString == "wstring" || typeString == "dstring") return null; lastResCtxt.ScopedBlock = DResolver.SearchBlockAt(SyntaxTree, typeId.Location, out lastResCtxt.ScopedStatement); if (typeString == "th" && typeId.Location.Line == 114) { } if (!(WasAlreadyResolved = compDict.TryGetValue(typeString, out rr))) { allCurrentResults = DResolver.ResolveType(typeId, lastResCtxt); if (allCurrentResults != null && allCurrentResults.Length > 0) rr = allCurrentResults[0]; } if (rr == null) { if (typeId is IdentifierDeclaration) csr.UnresolvedIdentifiers.Add(typeId as IdentifierDeclaration); } else { /* * Note: It is of course possible to highlight more than one type in one type declaration! * So, we scan down the result hierarchy for TypeResults and highlight all of them later. */ var curRes = rr; /* * Note: Since we want to use results multiple times, * we at least have to 'update' their type declarations * to ensure that the second, third, fourth etc. occurence of this result * are also highlit (and won't(!) cause an Already-Added-Exception of our finalDict-Array) */ var curTypeDeclBase = typeId as ITypeDeclaration; while (curRes != null) { if (curRes is MemberResult) { var mr = curRes as MemberResult; // If curRes is an alias or a template parameter, highlight it if (mr.ResolvedMember is TemplateParameterNode || (mr.ResolvedMember is DVariable && (mr.ResolvedMember as DVariable).IsAlias)) { try { csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes); } catch { } // See performance reasons //if (curRes != rr && !WasAlreadyResolved && !) compDict.Add(curTypeDeclBase.ToString(), curRes); } } else if (curRes is TypeResult) { // Yeah, in quite all cases we do identify a class via its name ;-) if (curTypeDeclBase is IdentifierDeclaration && !(curTypeDeclBase is DTokenDeclaration) && !csr.ResolvedIdentifiers.ContainsKey(curTypeDeclBase as IdentifierDeclaration)) { csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes); // See performance reasons //if (curRes != rr && !WasAlreadyResolved) compDict.Add(curTypeDeclBase.ToString(), curRes); } } else if (curRes is ModuleResult) { if (curTypeDeclBase is IdentifierDeclaration && !csr.ResolvedIdentifiers.ContainsKey(curTypeDeclBase as IdentifierDeclaration)) csr.ResolvedIdentifiers.Add(curTypeDeclBase as IdentifierDeclaration, curRes); } curRes = curRes.ResultBase; curTypeDeclBase = curTypeDeclBase.InnerDeclaration; } } return allCurrentResults; }
public void Process(IAbstractSyntaxTree ast) { string expression = ToString(Option<Expression>.AsOption(ast)); Console.WriteLine("Formatted expression: {0}", expression); }
public static bool IsPhobosModule(IAbstractSyntaxTree Module) { return Module.FileName.Contains (Path.DirectorySeparatorChar + "phobos" + Path.DirectorySeparatorChar) || Module.FileName.Contains (Path.DirectorySeparatorChar + "druntime" + Path.DirectorySeparatorChar + "import" + Path.DirectorySeparatorChar); }
/// <summary> /// Parses the module again /// </summary> /// <param name="Module"></param> public static void UpdateModule(IAbstractSyntaxTree Module) { var m = DParser.ParseFile(Module.FileName); Module.ParseErrors = m.ParseErrors; Module.AssignFrom(m); }
void PrepareQueue(IAbstractSyntaxTree module) { if (module != null) foreach (var n in module) { var dm = n as DMethod; // UFCS only allows free function that contain at least one parameter if (dm == null || dm.Parameters.Count == 0 || dm.Parameters[0].Type == null) continue; queue.Push(dm); } }
/// <summary> /// Cleans the cache from items related to the passed syntax tree. /// Used for incremental update. /// </summary> public void RemoveModuleItems(IAbstractSyntaxTree ast) { if (IsProcessing) return; var remList = new List<DMethod>(); foreach (var kv in CachedMethods) if (kv.Key.NodeRoot == ast) remList.Add(kv.Key); foreach (var i in remList) lock (CachedMethods) CachedMethods.Remove(i); }
protected void HandleDictEntries(IAbstractSyntaxTree ast) { foreach (var def in ast) { if (def != null && !HandleTypeEntry(def)) HandleGlobalMemberEntry(def); } }
public static void UpdateModuleFromText(IAbstractSyntaxTree Module, string Code) { var m = DParser.ParseString(Code); Module.ParseErrors = m.ParseErrors; Module.AssignFrom(m); }
/// <summary> /// Returns a package-module name-combination (like std.stdio) in dependency of its base directory (e.g. C:\dmd2\src\phobos) /// </summary> public static string GetModuleName(string baseDirectory, IAbstractSyntaxTree ast) { return GetModuleName(baseDirectory, ast.FileName); }