public static AbstractType[] ResolveHoveredCodeLoosely(out ResolutionContext ctxt, out IEditorData ed, out DResolver.NodeResolutionAttempt resolutionAttempt, Document doc = null) { ed = CreateEditorData(doc); if (ed == null) { resolutionAttempt = DResolver.NodeResolutionAttempt.Normal; ctxt = null; return(null); } ctxt = ResolutionContext.Create(ed, false); //return DResolver.ResolveTypeLoosely(ed, out resolutionAttempt, ctxt); return(AmbiguousType.TryDissolve(DResolver.ResolveTypeLoosely(ed, out resolutionAttempt, ctxt)).ToArray()); }
public static AbstractType[] ResolveHoveredCode( out ResolutionContext ResolverContext, out IEditorData edData, Document doc = null) { edData = CreateEditorData(doc); if (edData == null) { ResolverContext = null; return(null); } ResolverContext = ResolutionContext.Create(edData, false); // Resolve the hovered piece of code return(AmbiguousType.TryDissolve(DResolver.ResolveType(edData, ctxt: ResolverContext)).ToArray()); }
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 Window CreateTooltipWindow(TextEditor editor, int offset, Gdk.ModifierType modifierState, TooltipItem item) { var doc = IdeApp.Workbench.ActiveDocument; if (doc == null) { return(null); } var titem = item.Item as AbstractType; if (titem == null) { return(null); } var result = new TooltipInformationWindow(); result.ShowArrow = true; foreach (var i in AmbiguousType.TryDissolve(titem)) { if (i == null) { continue; } var tooltipInformation = TooltipInfoGen.Create(i, editor.ColorStyle); if (tooltipInformation != null && !string.IsNullOrEmpty(tooltipInformation.SignatureMarkup)) { result.AddOverload(tooltipInformation); } } if (result.Overloads < 1) { result.Dispose(); return(null); } result.RepositionWindow(); return(result); }
static IEnumerable <DModule> TryGetGenericImportingPackageForSymbol(DNode nodeToTestImportabilityFor) { if (nodeToTestImportabilityFor == null) { yield break; } var moduleContainingPackage = GlobalParseCache.GetPackage(nodeToTestImportabilityFor.NodeRoot as DModule); while (moduleContainingPackage != null) { // Search for package.d-Modules; var packageModule = (moduleContainingPackage.Parent ?? moduleContainingPackage).GetModule(moduleContainingPackage.NameHash); if (packageModule == null) { moduleContainingPackage = moduleContainingPackage.Parent; continue; } // Try to get from found package module to destination node var ctxt = new ResolutionContext(new LegacyParseCacheView(new[] { moduleContainingPackage.Root }), null, packageModule); ctxt.CurrentContext.ContextDependentOptions = ResolutionOptions.ReturnMethodReferencesOnly | ResolutionOptions.DontResolveBaseTypes; var td = D_Parser.Parser.DParser.ParseBasicType(DNode.GetNodePath(nodeToTestImportabilityFor, true)); var res = TypeDeclarationResolver.ResolveSingle(td, ctxt, false); foreach (var ov in AmbiguousType.TryDissolve(res)) { if (ov is DSymbol && (ov as DSymbol).Definition == nodeToTestImportabilityFor) { yield return(packageModule); break; } } moduleContainingPackage = moduleContainingPackage.Parent; } }
void HandleIndexSliceExpression(PostfixExpression x) { res.IsMethodArguments = true; res.ParsedExpression = x; var overloads = new List <AbstractType>(); if (x.PostfixForeExpression == null) { return; } var b = ExpressionTypeEvaluation.EvaluateType(x.PostfixForeExpression, ctxt); var bases = AmbiguousType.TryDissolve(b); var ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpSliceIdHash, bases, ctxt, x, false); if (ov != null) { overloads.AddRange(ov); } ov = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(ExpressionTypeEvaluation.OpIndexIdHash, bases, ctxt, x, false); if (ov != null) { overloads.AddRange(ov); } if (overloads.Count == 0) { b = DResolver.StripMemberSymbols(b); var toTypeDecl = new DTypeToTypeDeclVisitor(); var aa = b as AssocArrayType; if (aa != null) { var retType = aa.ValueType != null?aa.ValueType.Accept(toTypeDecl) : null; var dm = new DMethod { Name = "opIndex", Type = retType }; dm.Parameters.Add(new DVariable { Name = "index", Type = aa.KeyType != null ? aa.KeyType.Accept(toTypeDecl) : null }); overloads.Add(new MemberSymbol(dm, aa.ValueType, x)); if ((aa is ArrayType) && !(aa as ArrayType).IsStaticArray) { dm = new DMethod { Name = "opSlice", Type = retType }; overloads.Add(new MemberSymbol(dm, aa.ValueType, x)); } } else if (b is PointerType) { b = (b as PointerType).Base; var dm = new DMethod { Name = "opIndex", Type = b != null?b.Accept(toTypeDecl) : null }; dm.Parameters.Add(new DVariable { Name = "index", Type = new IdentifierDeclaration("size_t") }); overloads.Add(new MemberSymbol(dm, b, x)); } } res.ResolvedTypesOrMethods = overloads.ToArray(); }
/// <summary> /// Returns either all unfiltered and undeduced overloads of a member of a base type/value (like b from type a if the expression is a.b). /// if <param name="EvalAndFilterOverloads"></param> is false. /// If true, all overloads will be deduced, filtered and evaluated, so that (in most cases,) a one-item large array gets returned /// which stores the return value of the property function b that is executed without arguments. /// Also handles UFCS - so if filtering is wanted, the function becom /// </summary> public static R[] EvalPostfixAccessExpression <R>(ExpressionVisitor <R> vis, ResolutionContext ctxt, PostfixExpression_Access acc, ISemantic resultBase = null, bool EvalAndFilterOverloads = true, bool ResolveImmediateBaseType = true, AbstractSymbolValueProvider ValueProvider = null) where R : class, ISemantic { if (acc == null) { return(null); } var baseExpression = resultBase ?? (acc.PostfixForeExpression != null ? acc.PostfixForeExpression.Accept(vis) as ISemantic : null); if (acc.AccessExpression is NewExpression) { /* * This can be both a normal new-Expression as well as an anonymous class declaration! */ //TODO! return(null); } AbstractType[] overloads; var optBackup = ctxt.CurrentContext.ContextDependentOptions; if (acc.AccessExpression is TemplateInstanceExpression) { if (!ResolveImmediateBaseType) { ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes; } var tix = (TemplateInstanceExpression)acc.AccessExpression; // Do not deduce and filter if superior expression is a method call since call arguments' types also count as template arguments! overloads = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, new[] { AbstractType.Get(baseExpression) }, EvalAndFilterOverloads); if (!ResolveImmediateBaseType) { ctxt.CurrentContext.ContextDependentOptions = optBackup; } } else if (acc.AccessExpression is IdentifierExpression) { var id = acc.AccessExpression as IdentifierExpression; if (ValueProvider != null && EvalAndFilterOverloads && baseExpression != null) { var staticPropResult = StaticProperties.TryEvalPropertyValue(ValueProvider, baseExpression, id.ValueStringHash); if (staticPropResult != null) { return new[] { (R)staticPropResult } } ; } if (!ResolveImmediateBaseType) { ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes; } overloads = ExpressionTypeEvaluation.GetOverloads(id, ctxt, AmbiguousType.TryDissolve(AbstractType.Get(baseExpression)), EvalAndFilterOverloads); if (!ResolveImmediateBaseType) { ctxt.CurrentContext.ContextDependentOptions = optBackup; } } else { /* * if (eval){ * EvalError(acc, "Invalid access expression"); * return null; * }*/ ctxt.LogError(acc, "Invalid post-dot expression"); return(null); } // If evaluation active and the access expression is stand-alone, return a single item only. if (EvalAndFilterOverloads && ValueProvider != null) { return new[] { (R) new Evaluation(ValueProvider).TryDoCTFEOrGetValueRefs(AmbiguousType.Get(overloads, acc.AccessExpression), acc.AccessExpression) } } ; return(overloads as R[]); } ISymbolValue EvalForeExpression(PostfixExpression ex) { return(ex.PostfixForeExpression != null?ex.PostfixForeExpression.Accept(this) : null); }
public AbstractType Visit(PostfixExpression_Slice x) { var foreExpression = EvalForeExpression(x); // myArray[0]; myArray[0..5]; if (foreExpression is MemberSymbol) { foreExpression = DResolver.StripMemberSymbols(foreExpression); } var udt = foreExpression as UserDefinedType; if (udt == null) { return(foreExpression); } AbstractType[] sliceArgs; if (x.FromExpression == null && x.ToExpression == null) { sliceArgs = null; } else { sliceArgs = new AbstractType[2]; if (x.FromExpression != null) { sliceArgs[0] = x.FromExpression.Accept(this); } if (x.ToExpression != null) { sliceArgs[1] = x.ToExpression.Accept(this); } } ctxt.CurrentContext.IntroduceTemplateParameterTypes(udt); var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(OpSliceIdHash, AmbiguousType.TryDissolve(foreExpression), ctxt, x, false); overloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(overloads, sliceArgs, true, ctxt); ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt); return(TryPretendMethodExecution(AmbiguousType.Get(overloads, x), x, sliceArgs) ?? foreExpression); }
public AbstractType Visit(PostfixExpression_Index x) { var foreExpression = EvalForeExpression(x); // myArray[0]; myArray[0..5]; // opIndex/opSlice ? if (foreExpression is MemberSymbol) { foreExpression = DResolver.StripMemberSymbols(foreExpression); } var udt = foreExpression as UserDefinedType; if (udt != null) { ctxt.CurrentContext.IntroduceTemplateParameterTypes(udt); var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(OpIndexIdHash, AmbiguousType.TryDissolve(foreExpression), ctxt, x, false); if (overloads != null && overloads.Length > 0) { var indexArgs = x.Arguments != null ? new AbstractType[x.Arguments.Length] : null; for (int i = 0; i < indexArgs.Length; i++) { if (x.Arguments[i] != null) { indexArgs[i] = x.Arguments[i].Accept(this); } } overloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(overloads, indexArgs, true, ctxt); ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt); return(TryPretendMethodExecution(AmbiguousType.Get(overloads, x), x, indexArgs)); } ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt); if (foreExpression is TemplateIntermediateType) { //TODO: Proper resolution of alias this declarations var tit = foreExpression as TemplateIntermediateType; var ch = tit.Definition[DVariable.AliasThisIdentifierHash]; if (ch != null) { foreach (DVariable aliasThis in ch) { foreExpression = TypeDeclarationResolver.HandleNodeMatch(aliasThis, ctxt, foreExpression); if (foreExpression != null) { break; // HACK: Just omit other alias this' to have a quick run-through } } } if (foreExpression == null) { return(tit); } } } foreExpression = DResolver.StripMemberSymbols(foreExpression); if (foreExpression is AssocArrayType) { var ar = foreExpression as AssocArrayType; /* * myType_Array[0] -- returns TypeResult myType * return the value type of a given array result */ //TODO: Handle opIndex overloads if (ar.ValueType != null) { ar.ValueType.NonStaticAccess = true; } return(new ArrayAccessSymbol(x, ar.ValueType)); } /* * int* a = new int[10]; * * a[0] = 12; */ else if (foreExpression is PointerType) { var b = (foreExpression as PointerType).Base; if (b != null) { b.NonStaticAccess = true; } return(b); } //return new ArrayAccessSymbol(x,((PointerType)foreExpression).Base); else if (foreExpression is DTuple) { var tt = foreExpression as DTuple; if (x.Arguments != null && x.Arguments.Length != 0) { var idx = Evaluation.EvaluateValue(x.Arguments[0], ctxt) as PrimitiveValue; if (tt.Items == null) { ctxt.LogError(tt.DeclarationOrExpressionBase, "No items in Type tuple"); } else if (idx == null || !DTokens.IsBasicType_Integral(idx.BaseTypeToken)) { ctxt.LogError(x.Arguments[0], "Index expression must evaluate to integer value"); } else if (idx.Value > (decimal)Int32.MaxValue || (int)idx.Value >= tt.Items.Length || idx.Value < 0m) { ctxt.LogError(x.Arguments[0], "Index number must be a value between 0 and " + tt.Items.Length); } else { return(AbstractType.Get(tt.Items[(int)idx.Value])); } } } ctxt.LogError(x, "No matching base type for indexing operation"); return(null); }
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 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 void GetTip(string filename, int startLine, int startIndex, int endLine, int endIndex) { 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); _tipText.Clear(); _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.NodeResolutionAttempt attempt; var types = DResolver.ResolveTypeLoosely(_editorData, out attempt, out sr); _tipText.Clear(); 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--; } } }
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 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 static AbstractType[] ResolveHoveredCodeLoosely(IEditorData ed, out LooseResolution.NodeResolutionAttempt resolutionAttempt, out ISyntaxRegion sr) { return(AmbiguousType.TryDissolve(LooseResolution.ResolveTypeLoosely(ed, out resolutionAttempt, out sr, true)).ToArray()); }