public string ResolveExpression(TextEditorData ed, Document doc, int offset, out int startOffset) { startOffset = offset; var editorData = DResolverWrapper.CreateEditorData(doc); if (editorData == null) { return(null); } editorData.CaretOffset = offset; var edLoc = ed.OffsetToLocation(offset); editorData.CaretLocation = new CodeLocation(edLoc.Column, edLoc.Line); var o = DResolver.GetScopedCodeObject(editorData); if (o != null) { startOffset = ed.LocationToOffset(o.Location.Line, o.Location.Column); if (o is INode) { return((o as INode).Name); } return(o.ToString()); } return(null); }
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 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); } } }
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 override TooltipItem GetItem(Mono.TextEditor.TextEditor editor, int offset) { if (offset >= editor.Document.TextLength) { return(null); } if (!DebuggingService.IsDebugging || DebuggingService.IsRunning) { return(null); } var frame = DebuggingService.CurrentFrame; if (frame == null) { return(null); } var ed = (ExtensibleTextEditor)editor; string expression = null; int startOffset = 0, length = 0; if (ed.IsSomethingSelected && offset >= ed.SelectionRange.Offset && offset <= ed.SelectionRange.EndOffset) { // This should be handled by the MD-internal Debug value tooltip provider already expression = ed.SelectedText; startOffset = ed.SelectionRange.Offset; length = ed.SelectionRange.Length; } else { var doc = Ide.IdeApp.Workbench.GetDocument(ed.FileName); if (doc == null) { return(null); } var editorData = DResolverWrapper.CreateEditorData(doc); editorData.CaretOffset = offset; var edLoc = ed.OffsetToLocation(offset); editorData.CaretLocation = new D_Parser.Dom.CodeLocation(edLoc.Column, edLoc.Line); var ctxt = ResolutionContext.Create(editorData); var o = DResolver.GetScopedCodeObject(editorData, ctxt, DResolver.AstReparseOptions.AlsoParseBeyondCaret | DResolver.AstReparseOptions.OnlyAssumeIdentifierList); if (o != null) { expression = o.ToString(); } } if (string.IsNullOrEmpty(expression)) { return(null); } ObjectValue val; if (!cachedValues.TryGetValue(expression, out val)) { val = frame.GetExpressionValue(expression, true); cachedValues [expression] = val; } if (val == null || val.IsUnknown || val.IsNotSupported) { return(null); } val.Name = expression; return(new TooltipItem(val, startOffset, length)); }
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); }
public static INode[] TryFindingSelectedIdImportIndependently(IEditorData ed, out bool importRequired, bool tryResolveNormally = true) { importRequired = false; var l = new List <INode>(); var ctxt = new ResolverContextStack(ed.ParseCache, new ResolverContext()) { ContextIndependentOptions = ResolutionOptions.ReturnMethodReferencesOnly | ResolutionOptions.DontResolveBaseTypes | ResolutionOptions.DontResolveAliases | ResolutionOptions.NoTemplateParameterDeduction }; ctxt.ScopedBlock = DResolver.SearchBlockAt(ed.SyntaxTree, ed.CaretLocation, out ctxt.CurrentContext.ScopedStatement); // Get scoped object. var o = DResolver.GetScopedCodeObject(ed, ctxt, DResolver.AstReparseOptions.AlsoParseBeyondCaret); if (o == null) { throw new Exception("No identifier selected"); } // Try to resolve it using the usual (strictly filtered) way. if (tryResolveNormally) { AbstractType[] t = null; if (o is IExpression) { t = new[] { Evaluation.EvaluateType((IExpression)o, ctxt) } } ; else if (o is ITypeDeclaration) { t = TypeDeclarationResolver.Resolve((ITypeDeclaration)o, ctxt); } if (t != null && t.Length != 0 && t[0] != null) { foreach (var at in t) { if (at is DSymbol) { l.Add(((DSymbol)at).Definition); } } return(l.ToArray()); } } // If no results: // Extract a concrete id from that syntax object. (If access expression/nested decl, use the inner-most one) string id = null; chkAgain: if (o is ITypeDeclaration) { var td = ((ITypeDeclaration)o).InnerMost; if (td is IdentifierDeclaration) { id = ((IdentifierDeclaration)td).Id; } else if (td is TemplateInstanceExpression) { id = ((TemplateInstanceExpression)td).TemplateIdentifier.Id; } } else if (o is IExpression) { var x = (IExpression)o; while (x is PostfixExpression) { x = ((PostfixExpression)x).PostfixForeExpression; } if (x is IdentifierExpression && ((IdentifierExpression)x).IsIdentifier) { id = (string)((IdentifierExpression)x).Value; } else if (x is TemplateInstanceExpression) { id = ((TemplateInstanceExpression)x).TemplateIdentifier.Id; } else if (x is NewExpression) { o = ((NewExpression)x).Type; goto chkAgain; } } if (string.IsNullOrEmpty(id)) { throw new Exception("No extractable identifier found"); } // Rawly scan through all modules' roots of the parse cache to find that id. foreach (var pc in ed.ParseCache) { foreach (var mod in pc) { if (mod.Name == id) { l.Add(mod); } var ch = mod[id]; if (ch != null) { foreach (var c in ch) { var dn = c as DNode; if (dn == null || !dn.ContainsAttribute(DTokens.Package, DTokens.Private, DTokens.Protected)) { l.Add(c); } } } //TODO: Mixins } } importRequired = true; return(l.ToArray()); }
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())); }
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())); }