protected override string Process(EditorData editorData, string tok) { var originalCaretLocation = editorData.CaretLocation; var idx = originalCaretLocation.Column - 1; // step back to beginning of identifier while (editorData.CaretOffset > 0 && Lexer.IsIdentifierPart(editorData.ModuleCode[editorData.CaretOffset - 1])) { editorData.CaretOffset--; if (idx > 0) { idx--; } } editorData.CaretLocation = new CodeLocation(idx + 1, originalCaretLocation.Line); char triggerChar = string.IsNullOrEmpty(tok) ? '\0' : tok[0]; var cdgen = new VDServerCompletionDataGenerator(tok); CodeCompletion.GenerateCompletionData(editorData, cdgen, triggerChar); return(cdgen.expansions.ToString()); }
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())); }
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())); }