public void GetDefinition(string filename, int startLine, int startIndex, int endLine, int endIndex) { filename = normalizePath(filename); var ast = GetModule(filename); if (ast == null) { throw new COMException("module not found", 1); } _tipStart = new CodeLocation(startIndex + 1, startLine); _tipEnd = new CodeLocation(endIndex + 1, endLine); _tipText.Clear(); _setupEditorData(); _editorData.CaretLocation = _tipEnd; _editorData.SyntaxTree = ast as DModule; _editorData.ModuleCode = _sources[filename]; // codeOffset+1 because otherwise it does not work on the first character _editorData.CaretOffset = getCodeOffset(_editorData.ModuleCode, _tipStart) + 2; ISyntaxRegion sr = DResolver.GetScopedCodeObject(_editorData); LooseResolution.NodeResolutionAttempt attempt; var rr = sr != null?LooseResolution.ResolveTypeLoosely(_editorData, sr, out attempt, true) : null; _tipText.Clear(); if (rr != null) { var n = DResolver.GetResultMember(rr, true); if (n == null) { return; } bool decl = false; var mthd = n as DMethod; if (mthd != null) { decl = mthd.Body == null; } else if (n.ContainsAttribute(DTokens.Extern)) { decl = true; } if (decl) { _tipText.Append("EXTERN:"); } _tipStart = n.Location; _tipEnd = n.EndLocation; INode node = n.NodeRoot; if (node is DModule) { _tipText.Append((node as DModule).FileName); } } }
protected override string Process(EditorData editorData, bool moduleOnly) { var sr = DResolver.GetScopedCodeObject(editorData); var rr = sr != null?LooseResolution.ResolveTypeLoosely(editorData, sr, out _, true) : null; var refs = new StringBuilder(); if (rr != null) { var n = ExpressionTypeEvaluation.GetResultMember(rr); if (n != null) { var ctxt = ResolutionContext.Create(editorData, true); if (moduleOnly || n.ContainsAnyAttribute(DTokens.Private) || (n is DVariable variable && variable.IsLocal)) { GetReferencesInModule(editorData.SyntaxTree, refs, n, ctxt); } else { foreach (var rootPackage in editorData.ParseCache.EnumRootPackagesSurroundingModule(editorData.SyntaxTree)) { foreach (var module in rootPackage) { GetReferencesInModule(module, refs, n, ctxt); } } } } //var res = TypeReferenceFinder.Scan(_editorData, System.Threading.CancellationToken.None, null); }
public void GetReferences(string filename, string tok, uint line, uint idx, string expr) { filename = normalizePath(filename); var ast = GetModule(filename); if (ast == null) { throw new COMException("module not found", 1); } _request = Request.References; _result = "__pending__"; Action dg = () => { _setupEditorData(); CodeLocation loc = new CodeLocation((int)idx + 1, (int)line); _editorData.CaretLocation = loc; _editorData.SyntaxTree = ast as DModule; _editorData.ModuleCode = _sources[filename]; _editorData.CaretOffset = getCodeOffset(_editorData.ModuleCode, loc); ISyntaxRegion sr = DResolver.GetScopedCodeObject(_editorData); LooseResolution.NodeResolutionAttempt attempt; var rr = sr != null?LooseResolution.ResolveTypeLoosely(_editorData, sr, out attempt, true) : null; StringBuilder refs = new StringBuilder(); if (rr != null) { var n = DResolver.GetResultMember(rr, true); if (n != null) { var ctxt = ResolutionContext.Create(_editorData, true); if (n.ContainsAttribute(DTokens.Private) || ((n is DVariable) && (n as DVariable).IsLocal)) { GetReferencesInModule(ast, refs, n, ctxt); } else { foreach (var basePath in _imports.Split(nlSeparator, StringSplitOptions.RemoveEmptyEntries)) { foreach (var mod in GlobalParseCache.EnumModulesRecursively(basePath)) { GetReferencesInModule(mod, refs, n, ctxt); } } } } //var res = TypeReferenceFinder.Scan(_editorData, System.Threading.CancellationToken.None, null); } if (!_editorData.CancelToken.IsCancellationRequested && _request == Request.References) { _result = refs.ToString(); } }; }
public static AbstractType[] ResolveHoveredCodeLoosely(out IEditorData ed, out LooseResolution.NodeResolutionAttempt resolutionAttempt, out ISyntaxRegion sr, Document doc = null) { ed = CreateEditorData(doc); if (ed == null) { sr = null; resolutionAttempt = LooseResolution.NodeResolutionAttempt.Normal; return(null); } //return DResolver.ResolveTypeLoosely(ed, out resolutionAttempt, ctxt); return(AmbiguousType.TryDissolve(LooseResolution.ResolveTypeLoosely(ed, out resolutionAttempt, out sr, true)).ToArray()); }
public override TooltipItem GetItem(TextEditor editor, int offset) { // Note: Normally, the document already should be open var doc = IdeApp.Workbench.GetDocument(editor.Document.FileName); if (doc == null) { return(null); } var ast = doc.GetDAst(); // Due the first note, the AST already should exist if (ast == null) { return(null); } // Get code cache var codeCache = DResolverWrapper.CreateParseCacheView(doc); // Create editor context var line = editor.GetLineByOffset(offset); var ed = new EditorData { CaretOffset = offset, CaretLocation = new CodeLocation(offset - line.Offset, editor.OffsetToLineNumber(offset)), ModuleCode = editor.Text, ParseCache = codeCache, SyntaxTree = ast }; // Let the engine build all contents LooseResolution.NodeResolutionAttempt att; ISyntaxRegion sr; var rr = LooseResolution.ResolveTypeLoosely(ed, out att, out sr, true); // Create tool tip item if (rr != null) { return(new TooltipItem(new TTI { t = rr, sr = sr }, offset, 1)); } return(null); }
public override Task <Hover> Handle(HoverParams request, CancellationToken cancellationToken) { var editorData = DResolverWrapper.CreateEditorData(request, cancellationToken); var resolvedHoveredTypes = LooseResolution.ResolveTypeLoosely(editorData, out LooseResolution.NodeResolutionAttempt resolutionAttempt, out ISyntaxRegion syntaxRegion, true); var markup = string.Join(Environment.NewLine + Environment.NewLine, AmbiguousType.TryDissolve(resolvedHoveredTypes) .Where(t => t != null) .Select(t => TooltipMarkupGen.CreateSignatureMarkdown(t))); return(Task.FromResult(new Hover { Contents = new MarkedStringsOrMarkupContent(new MarkupContent { Kind = MarkupKind.Markdown, Value = markup }), Range = syntaxRegion.ToRange() })); }
protected override Tuple <CodeLocation, CodeLocation, string> Process( EditorData editorData, bool evaluateUnderneathExpression) { // codeOffset+1 because otherwise it does not work on the first character editorData.CaretOffset++; var sr = DResolver.GetScopedCodeObject(editorData); if (sr == null) { return(Tuple.Create(CodeLocation.Empty, CodeLocation.Empty, String.Empty)); } var types = LooseResolution.ResolveTypeLoosely(editorData, sr, out _, true); if (editorData.CancelToken.IsCancellationRequested) { return(Tuple.Create(CodeLocation.Empty, CodeLocation.Empty, String.Empty)); } if (types == null) { return(Tuple.Create(sr.Location, sr.EndLocation, String.Empty)); } var tipText = new StringBuilder(); DNode dn = null; foreach (var t in AmbiguousType.TryDissolve(types)) { var dt = t; if (dt is AliasedType at) { // jump to original definition if it is not renamed or the caret is on the import var isRenamed = (at.Definition as ImportSymbolAlias)?.ImportBinding?.Alias != null; if (!isRenamed || at.Definition.Location == sr.Location) { dt = at.Base; } } tipText.Append(NodeToolTipContentGen.Instance.GenTooltipSignature(dt)); if (dt is DSymbol symbol) { dn = symbol.Definition; } tipText.Append("\a"); } while (tipText.Length > 0 && tipText[tipText.Length - 1] == '\a') { tipText.Length--; } if (evaluateUnderneathExpression) { var ctxt = editorData.GetLooseResolutionContext(LooseResolution.NodeResolutionAttempt.Normal); ctxt.Push(editorData); try { ISymbolValue v = null; if (dn is DVariable var && var.Initializer != null && var.IsConst) { v = Evaluation.EvaluateValue(var.Initializer, ctxt); } if (v == null && sr is IExpression expression) { v = Evaluation.EvaluateValue(expression, ctxt); } if (v != null && !(v is ErrorValue)) { var valueStr = " = " + v; if (tipText.Length > valueStr.Length && tipText.ToString(tipText.Length - valueStr.Length, valueStr.Length) != valueStr) { tipText.Append(valueStr); } } } catch (Exception e) { tipText.Append("\aException during evaluation = ").Append(e.Message); } ctxt.Pop(); } if (dn != null) { VDServerCompletionDataGenerator.GenerateNodeTooltipBody(dn, tipText); } while (tipText.Length > 0 && tipText[tipText.Length - 1] == '\a') { tipText.Length--; } return(Tuple.Create(sr.Location, sr.EndLocation, tipText.ToString())); }
public void GetDefinition(string filename, int startLine, int startIndex, int endLine, int endIndex) { filename = normalizePath(filename); var ast = GetModule(filename); if (ast == null) { throw new COMException("module not found", 1); } _tipStart = new CodeLocation(startIndex + 1, startLine); _tipEnd = new CodeLocation(endIndex + 1, endLine); _request = Request.Definition; _result = "__pending__"; Action dg = () => { _setupEditorData(); _editorData.CaretLocation = _tipEnd; _editorData.SyntaxTree = ast as DModule; _editorData.ModuleCode = _sources[filename]; // codeOffset+1 because otherwise it does not work on the first character _editorData.CaretOffset = getCodeOffset(_editorData.ModuleCode, _tipStart) + 2; ISyntaxRegion sr = DResolver.GetScopedCodeObject(_editorData); LooseResolution.NodeResolutionAttempt attempt; var rr = sr != null?LooseResolution.ResolveTypeLoosely(_editorData, sr, out attempt, true) : null; StringBuilder tipText = new StringBuilder(); if (rr != null) { DNode n = null; foreach (var t in AmbiguousType.TryDissolve(rr)) { n = DResolver.GetResultMember(t, true); if (n != null) { break; } } if (n != null) { if (tipText.Length > 0) { tipText.Append("\n"); } bool decl = false; var mthd = n as DMethod; if (mthd != null) { decl = mthd.Body == null; } else if (n.ContainsAttribute(DTokens.Extern)) { decl = true; } if (decl) { tipText.Append("EXTERN:"); } _tipStart = n.Location; _tipEnd = n.EndLocation; INode node = n.NodeRoot; if (node is DModule) { tipText.Append((node as DModule).FileName); } } } if (!_editorData.CancelToken.IsCancellationRequested && _request == Request.Definition) { _result = tipText.ToString(); } }; runAsync(dg); }
public void GetTip(string filename, int startLine, int startIndex, int endLine, int endIndex) { filename = normalizePath(filename); var ast = GetModule(filename); if (ast == null) { throw new COMException("module not found", 1); } _tipStart = new CodeLocation(startIndex + 1, startLine); _tipEnd = new CodeLocation(startIndex + 2, startLine); _request = Request.Tip; _result = "__pending__"; Action dg = () => { _setupEditorData(); _editorData.CaretLocation = _tipStart; _editorData.SyntaxTree = ast as DModule; _editorData.ModuleCode = _sources[filename]; // codeOffset+1 because otherwise it does not work on the first character _editorData.CaretOffset = getCodeOffset(_editorData.ModuleCode, _tipStart) + 1; ISyntaxRegion sr = DResolver.GetScopedCodeObject(_editorData); LooseResolution.NodeResolutionAttempt attempt; AbstractType types = sr != null?LooseResolution.ResolveTypeLoosely(_editorData, sr, out attempt, true) : null; if (_editorData.CancelToken.IsCancellationRequested) { return; } StringBuilder tipText = new StringBuilder(); if (types != null) { if (sr != null) { _tipStart = sr.Location; _tipEnd = sr.EndLocation; } DNode dn = null; foreach (var t in AmbiguousType.TryDissolve(types)) { tipText.Append(NodeToolTipContentGen.Instance.GenTooltipSignature(t)).Append("\a"); if (t is DSymbol) { dn = (t as DSymbol).Definition; } } while (tipText.Length > 0 && tipText[tipText.Length - 1] == '\a') { tipText.Length--; } if (dn != null) { VDServerCompletionDataGenerator.GenerateNodeTooltipBody(dn, tipText); } while (tipText.Length > 0 && tipText[tipText.Length - 1] == '\a') { tipText.Length--; } } if (_request == Request.Tip) { _result = tipText.ToString(); } }; runAsync(dg); }
protected override Tuple <CodeLocation, CodeLocation, string> Process(EditorData editorData, int flags) { bool evaluateUnderneathExpression = (flags & 1) != 0; bool quoteCode = (flags & 2) != 0; bool overloads = (flags & 4) != 0; // codeOffset+1 because otherwise it does not work on the first character // editorData.CaretOffset++; var sr = DResolver.GetScopedCodeObject(editorData); if (sr == null) { return(Tuple.Create(CodeLocation.Empty, CodeLocation.Empty, String.Empty)); } ArgumentsResolutionResult res = null; if (overloads) { res = ParameterInsightResolution.ResolveArgumentContext(editorData); } else { var types = LooseResolution.ResolveTypeLoosely(editorData, sr, out _, true); if (types != null) { res = new ArgumentsResolutionResult(); res.ResolvedTypesOrMethods = new AbstractType[1] { types }; } } if (editorData.CancelToken.IsCancellationRequested) { return(Tuple.Create(CodeLocation.Empty, CodeLocation.Empty, String.Empty)); } if (res == null || res.ResolvedTypesOrMethods == null) { return(Tuple.Create(sr.Location, sr.EndLocation, String.Empty)); } DNode dn = null; var tips = new List <Tuple <string, string> >(); foreach (var types in res.ResolvedTypesOrMethods) { foreach (var t in AmbiguousType.TryDissolve(types)) { var tipText = new StringBuilder(); var dt = t; if (dt is AliasedType at) { // jump to original definition if it is not renamed or the caret is on the import var isRenamed = (at.Definition as ImportSymbolAlias)?.ImportBinding?.Alias != null; if (!isRenamed || at.Definition.Location == sr.Location) { dt = at.Base; } } tipText.Append(NodeToolTipContentGen.Instance.GenTooltipSignature(dt, false, -1, quoteCode)); if (dt is DSymbol symbol) { dn = symbol.Definition; } if (evaluateUnderneathExpression) { var ctxt = editorData.GetLooseResolutionContext(LooseResolution.NodeResolutionAttempt.Normal); ctxt.Push(editorData); try { ISymbolValue v = null; if (dn is DVariable var && var.Initializer != null && var.IsConst) { v = Evaluation.EvaluateValue(var.Initializer, ctxt); } if (v == null && sr is IExpression expression) { v = Evaluation.EvaluateValue(expression, ctxt); } if (v != null && !(v is ErrorValue)) { var valueStr = " = " + v; if (tipText.Length > valueStr.Length && tipText.ToString(tipText.Length - valueStr.Length, valueStr.Length) != valueStr) { tipText.Append(valueStr); } } } catch (Exception e) { tipText.Append(" (Exception during evaluation: ").Append(e.Message).Append(")"); } ctxt.Pop(); } var docText = new StringBuilder(); if (dn != null) { VDServerCompletionDataGenerator.GenerateNodeTooltipBody(dn, docText); } tips.Add(Tuple.Create(tipText.ToString(), docText.ToString())); } } var text = new StringBuilder(); string prevDoc = ""; bool first = true; foreach (var tip in tips) { // do not emit the same doc twice if (overloads || (tip.Item2 != "ditto" && tip.Item2 != prevDoc)) { if (!string.IsNullOrEmpty(prevDoc)) { text.Append("\n").Append(prevDoc); } } if (!first) { text.Append("\a"); } first = false; text.Append(tip.Item1); if (tip.Item2 != "ditto") { prevDoc = tip.Item2; } } if (!string.IsNullOrEmpty(prevDoc)) { text.Append("\n").Append(prevDoc); } return(Tuple.Create(sr.Location, sr.EndLocation, text.ToString())); }
public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol) { DSymbol ds = null; mightBeLegalUnresolvableSymbol = false; if (string.IsNullOrWhiteSpace(symName)) { return(null); } // Try to handle a probably mangled string or C function. if (symName.StartsWith("_")) { try{ ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol; }catch {} } // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[]) if (ds == null && Lexer.IsIdentifierPart((int)symName[0])) { mightBeLegalUnresolvableSymbol = true; ITypeDeclaration q; var method = DParser.ParseMethodDeclarationHeader(symName, out q); q = Demangler.RemoveNestedTemplateRefsFromQualifier(q); AbstractType[] overloads = null; D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => { try { overloads = AmbiguousType.TryDissolve(LooseResolution.LookupIdRawly(ctxt.ParseCache, q, ctxt.ScopedBlock.NodeRoot as DModule)).ToArray(); } catch (Exception ex) { MonoDevelop.Core.LoggingService.LogWarning("Error during trace.log symbol resolution of " + q.ToString(), ex); } }); if (overloads == null || overloads.Length == 0) { return(null); } else if (overloads.Length == 1) { ds = overloads[0] as DSymbol; } else { method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type); var methodType = TypeDeclarationResolver.GetMethodReturnType(method, ctxt); var methodParameters = new List <AbstractType>(); D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => { if (method.Parameters != null && method.Parameters.Count != 0) { foreach (var parm in method.Parameters) { methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt)); } } }); foreach (var o in overloads) { ds = o as DSymbol; if (ds == null || !(ds.Definition is DMethod)) { continue; } var dm = ds.Definition as DMethod; // Compare return types if (dm.Type != null) { if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base)) { continue; } } else if (dm.Type == null && methodType != null) { return(null); } // Compare parameters if (methodParameters.Count != dm.Parameters.Count) { continue; } for (int i = 0; i < methodParameters.Count; i++) { if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt))) { continue; } } } } } return(ds != null ? ds.Definition : null); }
protected override Tuple <CodeLocation, CodeLocation, string> Process(EditorData editorData, CodeLocation tipEnd) { var tipStart = editorData.CaretLocation; editorData.CaretOffset += 2; editorData.CaretLocation = tipEnd; var sr = DResolver.GetScopedCodeObject(editorData); var rr = sr != null?LooseResolution.ResolveTypeLoosely(editorData, sr, out _, true) : null; var definitionSourceFilename = new StringBuilder(); if (rr != null) { if (rr is AliasedType at) { // jump to original definition if it is not renamed or the caret is on the import var isRenamed = (at.Definition as ImportSymbolAlias)?.ImportBinding?.Alias != null; if (!isRenamed || at.Definition.Location == sr.Location) { rr = at.Base; } } DNode n = null; foreach (var t in AmbiguousType.TryDissolve(rr)) { n = ExpressionTypeEvaluation.GetResultMember(t); if (n != null) { break; } } if (n != null) { if (definitionSourceFilename.Length > 0) { definitionSourceFilename.Append("\n"); } bool decl = false; if (n is DMethod method) { decl = method.Body == null; } else if (n.ContainsAnyAttribute(DTokens.Extern)) { decl = true; } if (decl) { definitionSourceFilename.Append("EXTERN:"); } tipStart = n.Location; tipEnd = n.EndLocation; if (n.NodeRoot is DModule module) { definitionSourceFilename.Append(module.FileName); } } } return(Tuple.Create(tipStart, tipEnd, definitionSourceFilename.ToString())); }
public static AbstractType[] ResolveHoveredCodeLoosely(IEditorData ed, out LooseResolution.NodeResolutionAttempt resolutionAttempt, out ISyntaxRegion sr) { return(AmbiguousType.TryDissolve(LooseResolution.ResolveTypeLoosely(ed, out resolutionAttempt, out sr, true)).ToArray()); }