public static AbstractType[] HandleNodeMatches( IEnumerable <INode> matches, ResolverContextStack ctxt, AbstractType resultBase = null, object TypeDeclaration = null) { // Abbreviate a foreach-loop + List alloc var ll = matches as IList <INode>; if (ll != null && ll.Count == 1) { return new[] { ll[0] == null ? null : HandleNodeMatch(ll[0], ctxt, resultBase, TypeDeclaration) } } ; var rl = new List <AbstractType>(); if (matches != null) { foreach (var m in matches) { if (m == null) { continue; } var res = HandleNodeMatch(m, ctxt, resultBase, TypeDeclaration); if (res != null) { rl.Add(res); } } } return(rl.ToArray()); }
ReferencesFinder(INode symbol, IAbstractSyntaxTree ast, ResolverContextStack ctxt) { this.ast = ast; this.symbol = symbol; searchId = symbol.Name; this.ctxt = ctxt; }
public static AssocArrayType Resolve(ArrayDecl ad, ResolverContextStack ctxt) { var valueTypes = Resolve(ad.ValueType, ctxt); ctxt.CheckForSingleResult(valueTypes, ad); AbstractType valueType = null; AbstractType keyType = null; int fixedArrayLength = -1; if (valueTypes == null || valueTypes.Length == 0) { return(null); } valueType = valueTypes[0]; ISymbolValue val; keyType = ResolveKey(ad, out fixedArrayLength, out val, ctxt); if (keyType == null || (keyType is PrimitiveType && ((PrimitiveType)keyType).TypeToken == DTokens.Int)) { return(fixedArrayLength == -1 ? new ArrayType(valueType, ad) : new ArrayType(valueType, fixedArrayLength, ad)); } return(new AssocArrayType(valueType, keyType, ad)); }
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 IEnumerable<DMethod> FindFitting(ResolverContextStack ctxt, CodeLocation currentLocation, ISemantic firstArgument, string nameFilter = null) { if (IsProcessing) return null; var preMatchList = new List<DMethod>(); bool dontUseNameFilter = nameFilter == null; lock(CachedMethods) foreach (var kv in CachedMethods) { // First test if arg is matching the parameter if ((dontUseNameFilter || kv.Key.Name == nameFilter) && ResultComparer.IsImplicitlyConvertible(firstArgument, kv.Value, ctxt)) preMatchList.Add(kv.Key); } // Then filter out methods which cannot be accessed in the current context // (like when the method is defined in a module that has not been imported) var mv = new MatchFilterVisitor<DMethod>(ctxt, preMatchList); mv.IterateThroughScopeLayers(currentLocation); return mv.filteredList; }
public IEnumerable <DMethod> FindFitting(ResolverContextStack ctxt, CodeLocation currentLocation, ISemantic firstArgument, string nameFilter = null) { if (IsProcessing) { return(null); } var preMatchList = new List <DMethod>(); bool dontUseNameFilter = nameFilter == null; lock (CachedMethods) foreach (var kv in CachedMethods) { // First test if arg is matching the parameter if ((dontUseNameFilter || kv.Key.Name == nameFilter) && ResultComparer.IsImplicitlyConvertible(firstArgument, kv.Value, ctxt)) { preMatchList.Add(kv.Key); } } // Then filter out methods which cannot be accessed in the current context // (like when the method is defined in a module that has not been imported) var mv = new MatchFilterVisitor <DMethod>(ctxt, preMatchList); mv.IterateThroughScopeLayers(currentLocation); return(mv.filteredList); }
void parseThread(object pcl_shared) { DMethod dm = null; var pcl = (ParseCacheList)pcl_shared; var ctxt = new ResolverContextStack(pcl, new ResolverContext()); ctxt.ContextIndependentOptions |= ResolutionOptions.StopAfterFirstOverloads; while (queue.Count != 0) { lock (queue) { if (queue.Count == 0) { return; } dm = queue.Pop(); } ctxt.CurrentContext.ScopedBlock = dm; var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); if (firstArg_result != null && firstArg_result.Length != 0) { lock (CachedMethods) CachedMethods[dm] = firstArg_result[0]; } } }
public static ArrayType GetStringType(ResolverContextStack ctxt, LiteralSubformat fmt = LiteralSubformat.Utf8) { ArrayType _t = null; if (ctxt != null) { var obj = ctxt.ParseCache.LookupModuleName("object").First(); string strType = fmt == LiteralSubformat.Utf32 ? "dstring" : fmt == LiteralSubformat.Utf16 ? "wstring" : "string"; var strNode = obj[strType]; if(strNode!=null && strNode.Count != 0) _t = DResolver.StripAliasSymbol(TypeDeclarationResolver.HandleNodeMatch(strNode[0], ctxt)) as ArrayType; } if (_t == null) { var ch = fmt == LiteralSubformat.Utf32 ? DTokens.Dchar : fmt == LiteralSubformat.Utf16 ? DTokens.Wchar : DTokens.Char; _t = new ArrayType(new PrimitiveType(ch, DTokens.Immutable), new ArrayDecl { ValueType = new MemberFunctionAttributeDecl(DTokens.Immutable) { InnerType = new DTokenDeclaration(ch) } }); } return _t; }
public static AbstractTooltipContent[] BuildToolTip(IEditorData Editor) { try { var ctxt = ResolverContextStack.Create(Editor); // In the case we've got a method or something, don't return its base type, only the reference to it ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly; var rr = DResolver.ResolveType(Editor, ctxt, DResolver.AstReparseOptions.AlsoParseBeyondCaret); if (rr.Length < 1) { return(null); } var l = new List <AbstractTooltipContent>(rr.Length); foreach (var res in rr) { l.Add(BuildTooltipContent(res)); } return(l.ToArray()); } catch { } return(null); }
public static AbstractType[] GetOverloads(IdentifierExpression id, ResolverContextStack ctxt) { var raw = TypeDeclarationResolver.ResolveIdentifier(id.Value as string, ctxt, id, id.ModuleScoped); var f = DResolver.FilterOutByResultPriority(ctxt, raw); return(f == null ? null : f.ToArray()); }
public static AbstractType getStringType(ResolverContextStack ctxt) { var str = new IdentifierDeclaration("string"); var sType = TypeDeclarationResolver.Resolve(str, ctxt); ctxt.CheckForSingleResult(sType, str); return sType != null && sType.Length != 0 ? sType[0] : null; }
public static AbstractType ResolveSingle(string id, ResolverContextStack ctxt, object idObject, bool ModuleScope = false) { var r = ResolveIdentifier(id, ctxt, idObject, ModuleScope); ctxt.CheckForSingleResult(r, idObject as ISyntaxRegion); return(r != null && r.Length != 0 ? r[0] : null); }
public static AbstractType ResolveSingle(IdentifierDeclaration id, ResolverContextStack ctxt, AbstractType[] resultBases = null, bool filterForTemplateArgs = true) { var r = Resolve(id, ctxt, resultBases, filterForTemplateArgs); ctxt.CheckForSingleResult(r, id); return(r != null && r.Length != 0 ? r[0] : null); }
public static IEnumerable <INode> SearchMatchesAlongNodeHierarchy(ResolverContextStack ctxt, CodeLocation caret, string name) { var scan = new NameScan(ctxt) { filterId = name }; scan.IterateThroughScopeLayers(caret); return(scan.Matches); }
public static IEnumerable<INode> EnumAllAvailableMembers( ResolverContextStack ctxt, CodeLocation Caret, MemberFilter VisibleMembers) { var en = new ItemEnumeration(ctxt); en.IterateThroughScopeLayers(Caret, VisibleMembers); return en.Nodes.Count <1 ? null : en.Nodes; }
public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolverContextStack ctxt, IEnumerable<AbstractType> resultBases = null, bool deduceParameters = true) { AbstractType[] res = null; if (resultBases == null) res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix, tix.TemplateIdentifier.ModuleScoped); else res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdentifier.Id, resultBases, ctxt, tix); return !ctxt.Options.HasFlag(ResolutionOptions.NoTemplateParameterDeduction) && deduceParameters ? TemplateInstanceHandler.EvalAndFilterOverloads(res, tix, ctxt) : res; }
public static AbstractType[] GetResolvedConstructorOverloads(TokenExpression tk, ResolverContextStack ctxt) { if (tk.Token == DTokens.This || tk.Token == DTokens.Super) { var classRef = EvaluateType(tk, ctxt) as TemplateIntermediateType; if (classRef != null) return D_Parser.Resolver.TypeResolution.TypeDeclarationResolver.HandleNodeMatches(GetConstructors(classRef), ctxt, classRef, tk); } return null; }
public static IEnumerable <INode> EnumAllAvailableMembers( ResolverContextStack ctxt, CodeLocation Caret, MemberFilter VisibleMembers) { var en = new ItemEnumeration(ctxt); en.IterateThroughScopeLayers(Caret, VisibleMembers); return(en.Nodes.Count < 1 ? null : en.Nodes); }
public static void Generate(ISemantic rr, ResolverContextStack ctxt, IEditorData ed, ICompletionDataGenerator gen) { if(ed.ParseCache!=null) foreach (var pc in ed.ParseCache) if (pc != null && pc.UfcsCache != null && pc.UfcsCache.CachedMethods != null && pc.UfcsCache.CachedMethods.Count != 0) { var r=pc.UfcsCache.FindFitting(ctxt, ed.CaretLocation, rr); if(r!=null) foreach (var m in r) gen.Add(m); } }
public static AbstractType[] ResolveHoveredCode( out ResolverContextStack ResolverContext, MonoDevelop.Ide.Gui.Document doc=null) { var edData = GetEditorData(doc); ResolverContext = ResolverContextStack.Create(edData); ResolverContext.ContextIndependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly; // Resolve the hovered piece of code return DResolver.ResolveType(edData, ResolverContext, DResolver.AstReparseOptions.AlsoParseBeyondCaret | DResolver.AstReparseOptions.OnlyAssumeIdentifierList); }
/// <summary> /// Uses the standard value provider for expression value evaluation /// </summary> public static ISymbolValue EvaluateValue(IExpression x, ResolverContextStack ctxt) { try { return EvaluateValue(x, new StandardValueProvider(ctxt)); } catch { //TODO Redirect evaluation exception to some outer logging service } return null; }
public static DelegateType Resolve(DelegateDeclaration dg, ResolverContextStack ctxt) { var returnTypes = Resolve(dg.ReturnType, ctxt); ctxt.CheckForSingleResult(returnTypes, dg.ReturnType); if (returnTypes != null && returnTypes.Length != 0) { return(new DelegateType(returnTypes[0], dg)); // Parameter types will be resolved later on } return(null); }
public static bool TryGetImplicitProperty(TemplateType template, ResolverContextStack ctxt, out AbstractType[] matchingChild) { // Check if there are only children that are named as the parent template. // That's the requirement for the special treatment. matchingChild = null; if (!ContainsEquallyNamedChildrenOnly(template.Definition)) { return(false); } // Prepare a new context bool pop = !ctxt.NodeIsInCurrentScopeHierarchy(template.Definition); if (pop) { ctxt.PushNewScope(template.Definition); } // Introduce the deduced params to the current resolution context ctxt.CurrentContext.IntroduceTemplateParameterTypes(template); // Get actual overloads, var overloads = template.Definition[template.Name]; // resolve them var resolvedOverloads = TypeDeclarationResolver.HandleNodeMatches(overloads, ctxt, null, template.DeclarationOrExpressionBase); // and deduce their parameters whereas this time, the parent's parameter are given already, in the case it's e.g. // needed as return type or in a declaration condition: // Furthermore, pass all the arguments that have been passed to the super template, to the child, // so these arguments may be used again for some inner parameters. var args = new List <ISemantic>(template.DeducedTypes.Count); foreach (var kv in template.DeducedTypes) { args.Add((ISemantic)kv.Value.ParameterValue ?? kv.Value.Base); } matchingChild = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(resolvedOverloads, args, true, ctxt); // Undo context-related changes if (pop) { ctxt.Pop(); } else { ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(template); } return(matchingChild != null && matchingChild.Length == 1 && matchingChild[0] != null); }
public static PointerType Resolve(PointerDecl pd, ResolverContextStack ctxt) { var ptrBaseTypes = Resolve(pd.InnerDeclaration, ctxt); ctxt.CheckForSingleResult(ptrBaseTypes, pd); if (ptrBaseTypes == null || ptrBaseTypes.Length == 0) { return(null); } return(new PointerType(ptrBaseTypes[0], pd)); }
public static List<ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolverContextStack ctxt) { // Resolve given argument expressions var templateArguments = new List<ISemantic>(); if (tix != null && tix.Arguments!=null) foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt); if (ctxt.CheckForSingleResult(res, tde.Declaration) || res != null) { var mr = res[0] as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch(System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval==null ? (ISemantic)mr : eval); } else templateArguments.Add(res[0]); } } else templateArguments.Add(Evaluation.EvaluateValue(arg, ctxt)); } return templateArguments; }
public static AbstractType[] ResolveIdentifier(string id, ResolverContextStack ctxt, object idObject, bool ModuleScope = false) { var loc = idObject is ISyntaxRegion ? ((ISyntaxRegion)idObject).Location:CodeLocation.Empty; if (ModuleScope) { ctxt.PushNewScope(ctxt.ScopedBlock.NodeRoot as IAbstractSyntaxTree); } // If there are symbols that must be preferred, take them instead of scanning the ast else { var tstk = new Stack <ResolverContext>(); D_Parser.Resolver.Templates.TemplateParameterSymbol dedTemplateParam = null; while (!ctxt.CurrentContext.DeducedTemplateParameters.TryGetValue(id, out dedTemplateParam)) { if (ctxt.PrevContextIsInSameHierarchy) { tstk.Push(ctxt.Pop()); } else { break; } } while (tstk.Count > 0) { ctxt.Push(tstk.Pop()); } if (dedTemplateParam != null) { return new[] { dedTemplateParam } } ; } var matches = NameScan.SearchMatchesAlongNodeHierarchy(ctxt, loc, id); var res = HandleNodeMatches(matches, ctxt, null, idObject); if (ModuleScope) { ctxt.Pop(); } return(res); }
public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolverContextStack ctxt, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true) { AbstractType[] res = null; if (resultBases == null) { res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix, tix.TemplateIdentifier.ModuleScoped); } else { res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdentifier.Id, resultBases, ctxt, tix); } return(!ctxt.Options.HasFlag(ResolutionOptions.NoTemplateParameterDeduction) && deduceParameters? TemplateInstanceHandler.DeduceParamsAndFilterOverloads(res, tix, ctxt) : res); }
/// <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 static AbstractType[] Resolve(ITypeDeclaration declaration, ResolverContextStack ctxt) { if (declaration is IdentifierDeclaration) { return(Resolve((IdentifierDeclaration)declaration, ctxt)); } else if (declaration is TemplateInstanceExpression) { return(Evaluation.GetOverloads((TemplateInstanceExpression)declaration, ctxt)); } var t = ResolveSingle(declaration, ctxt); return(t == null ? null : new[] { t }); }
public static AbstractType Resolve(MemberFunctionAttributeDecl attrDecl, ResolverContextStack ctxt) { if (attrDecl != null) { var ret = Resolve(attrDecl.InnerType, ctxt); ctxt.CheckForSingleResult(ret, attrDecl.InnerType); if (ret != null && ret.Length != 0 && ret[0] != null) { ret[0].Modifier = attrDecl.Modifier; return(ret[0]); } } return(null); }
/// <summary> /// Associates the given arguments with the template parameters specified in the type/method declarations /// and filters out unmatching overloads. /// </summary> /// <param name="rawOverloadList">Can be either type results or method results</param> /// <param name="givenTemplateArguments">A list of already resolved arguments passed explicitly /// in the !(...) section of a template instantiation /// or call arguments given in the (...) appendix /// that follows a method identifier</param> /// <param name="isMethodCall">If true, arguments that exceed the expected parameter count will be ignored as far as all parameters could be satisfied.</param> /// <param name="ctxt"></param> /// <returns>A filtered list of overloads which mostly fit to the specified arguments. /// Usually contains only 1 element. /// The 'TemplateParameters' property of the results will be also filled for further usage regarding smart completion etc.</returns> public static AbstractType[] EvalAndFilterOverloads(IEnumerable<AbstractType> rawOverloadList, IEnumerable<ISemantic> givenTemplateArguments, bool isMethodCall, ResolverContextStack ctxt) { if (rawOverloadList == null) return null; var filteredOverloads = DeduceOverloads(rawOverloadList, givenTemplateArguments, isMethodCall, ctxt); // If there are >1 overloads, filter from most to least specialized template param if (filteredOverloads.Count > 1) return SpecializationOrdering.FilterFromMostToLeastSpecialized(filteredOverloads, ctxt); else if (filteredOverloads.Count == 1) return filteredOverloads.ToArray(); return null; }
public static MemberSymbol FillMethodReturnType(MemberSymbol mr, ResolverContextStack ctxt) { if (mr == null || ctxt == null) return mr; var dm = mr.Definition as DMethod; ctxt.CurrentContext.IntroduceTemplateParameterTypes(mr); if (dm != null) { var returnType=GetMethodReturnType(dm, ctxt); mr = new MemberSymbol(dm, returnType, mr.DeclarationOrExpressionBase); } ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(mr); return mr; }
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 static string GetReferenceUrl(AbstractType result, ResolverContextStack ctxt, CodeLocation caret) { if (result != null) { var n = DResolver.GetResultMember (result); if (n != null && n.NodeRoot is IAbstractSyntaxTree) { if (IsPhobosModule (n.NodeRoot as IAbstractSyntaxTree)) { var phobos_url = "phobos/" + (n.NodeRoot as IAbstractSyntaxTree).ModuleName.Replace ('.', '_') + ".html"; if (!(n is IAbstractSyntaxTree)) phobos_url += "#" + n.Name; return phobos_url; } } else if (result is PrimitiveType || result is DelegateType || result is AssocArrayType) { if (result.DeclarationOrExpressionBase is ITypeDeclaration) return GetRefUrlFor ((ITypeDeclaration)result.DeclarationOrExpressionBase); else if (result.DeclarationOrExpressionBase is IExpression) return GetRefUrlFor ((IExpression)result.DeclarationOrExpressionBase); } } if (ctxt.ScopedStatement != null) { return GetRefUrlFor (ctxt.ScopedStatement, caret); } else if (ctxt.ScopedBlock is DClassLike) { var dc = ctxt.ScopedBlock as DClassLike; if (dc.ClassType == DTokens.Class) return "class.html"; else if (dc.ClassType == DTokens.Interface) return "interface.html"; else if (dc.ClassType == DTokens.Struct || dc.ClassType == DTokens.Union) return "struct.html"; else if (dc.ClassType == DTokens.Template) return "template.html"; } else if (ctxt.ScopedBlock is DEnum) return "enum.html"; return null; }
public static AbstractType[] FilterFromMostToLeastSpecialized( List<AbstractType> templateOverloads, ResolverContextStack ctxt) { if (templateOverloads == null) return null; var so = new SpecializationOrdering { ctxt = ctxt }; /* * Note: If there are functions that are specialized equally, like * void foo(T) (T t) {} and * void foo(T) (T t, int a) {}, * both functions have to be returned - because foo!string matches both overloads. * Later on, in the parameter-argument-comparison, these overloads will be filtered a second time - only then, * two overloads would be illegal. */ var lastEquallySpecializedOverloads = new List<AbstractType>(); var currentlyMostSpecialized = templateOverloads[0]; lastEquallySpecializedOverloads.Add(currentlyMostSpecialized); for (int i = 1; i < templateOverloads.Count; i++) { var evenMoreSpecialized = so.GetTheMoreSpecialized(currentlyMostSpecialized, templateOverloads[i]); if (evenMoreSpecialized == null) lastEquallySpecializedOverloads.Add(templateOverloads[i]); else { currentlyMostSpecialized = evenMoreSpecialized; lastEquallySpecializedOverloads.Clear(); lastEquallySpecializedOverloads.Add(currentlyMostSpecialized); } } return lastEquallySpecializedOverloads.ToArray(); }
public static MemberSymbol[] TryResolveUFCS( ISemantic firstArgument, PostfixExpression_Access acc, ResolverContextStack ctxt) { if (ctxt == null) return null; var name=""; if (acc.AccessExpression is IdentifierExpression) name = ((IdentifierExpression)acc.AccessExpression).Value as string; else if (acc.AccessExpression is TemplateInstanceExpression) name = ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdentifier.Id; else return null; var methodMatches = new List<MemberSymbol>(); if(ctxt.ParseCache!=null) foreach (var pc in ctxt.ParseCache) { var tempResults=pc.UfcsCache.FindFitting(ctxt, acc.Location, firstArgument, name); if (tempResults != null) foreach (var m in tempResults) { var mr = TypeDeclarationResolver.HandleNodeMatch(m, ctxt, TypeDeclarationResolver.Convert(firstArgument), acc) as MemberSymbol; if (mr!=null) { mr.IsUFCSResult = true; methodMatches.Add(mr); } } } return methodMatches.Count == 0 ? null : methodMatches.ToArray(); }
static void HandleNewExpression(NewExpression nex, ArgumentsResolutionResult res, IEditorData Editor, ResolverContextStack ctxt, IBlockNode curBlock) { res.MethodIdentifier = nex; CalculateCurrentArgument(nex, res, Editor.CaretLocation, ctxt); var type = TypeDeclarationResolver.ResolveSingle(nex.Type, ctxt) as ClassType; //TODO: Inform the user that only classes can be instantiated if (type != null) { var constructors = new List<DMethod>(); bool explicitCtorFound = false; foreach (var member in type.Definition) { var dm = member as DMethod; if (dm != null && dm.SpecialType == DMethod.MethodType.Constructor) { explicitCtorFound = true; if (!dm.IsPublic) { var curNode = curBlock; bool pass = false; do { if (curNode == type.Definition) { pass = true; break; } } while ((curNode = curNode.Parent as IBlockNode) != curNode); if (!pass) continue; } constructors.Add(dm); } } if (constructors.Count == 0) { if (explicitCtorFound) { // TODO: Somehow inform the user that the current class can't be instantiated } else { // Introduce default constructor constructors.Add(new DMethod(DMethod.MethodType.Constructor) { Description = "Default constructor for " + type.Name, Parent = type.Definition }); } } // Wrapp all ctor members in MemberSymbols var _ctors = new List<AbstractType>(); foreach (var ctor in constructors) _ctors.Add(new MemberSymbol(ctor, type, nex.Type)); res.ResolvedTypesOrMethods = _ctors.ToArray(); //TODO: Probably pre-select the current ctor by handling previously typed arguments etc. } }
static void CalculateCurrentArgument(NewExpression nex, ArgumentsResolutionResult res, CodeLocation caretLocation, ResolverContextStack ctxt, IEnumerable<AbstractType> resultBases=null) { if (nex.Arguments != null) { int i = 0; foreach (var arg in nex.Arguments) { if (caretLocation >= arg.Location && caretLocation <= arg.EndLocation) { res.CurrentlyTypedArgumentIndex = i; break; } i++; } } }
public StandardValueProvider(ResolverContextStack ctxt) { ResolutionContext = ctxt; }
public bool Run(DProject project,INode targetMember, string newName=null) { if(!CanRename(targetMember) || Ide.IdeApp.Workbench.ActiveDocument ==null) return false; n = targetMember; // Request new name if (newName == null) newName = MessageService.GetTextResponse("Enter a new name", "Symbol rename", n.Name); if (newName == null || newName==n.Name) return false; // Validate new name if (string.IsNullOrWhiteSpace(newName)) { MessageService.ShowError("Symbol name must not be empty!"); return false; } foreach (var c in newName) if (!D_Parser.Completion.CtrlSpaceCompletionProvider.IsIdentifierChar(c)) { MessageService.ShowError("Character '" + c + "' in " + newName + " not allowed as identifier character!"); return false; } // Setup locals var parseCache = project != null ? project.ParseCache : ParseCacheList.Create(DCompilerService.Instance.GetDefaultCompiler().ParseCache); var modules = project == null ? (IEnumerable<IAbstractSyntaxTree>) new[] { (Ide.IdeApp.Workbench.ActiveDocument.ParsedDocument as MonoDevelop.D.Parser.ParsedDModule).DDom } : project.LocalFileCache; foundReferences = new Dictionary<string, List<CodeLocation>>(); var ctxt = new ResolverContextStack(parseCache, new ResolverContext()); // Enumerate references foreach (var mod in modules) { if (mod == null) continue; var references = D_Parser.Refactoring.ReferencesFinder.Scan(mod, n, ctxt).ToList(); if ((n.NodeRoot as IAbstractSyntaxTree).FileName == mod.FileName) references.Insert(0, new IdentifierDeclaration(n.Name) { Location = n.NameLocation }); if (references.Count < 1) continue; references.Sort(new ReferenceFinding.IdLocationComparer(true)); if (!foundReferences.ContainsKey(mod.FileName)) foundReferences.Add(mod.FileName, new List<CodeLocation>()); var moduleRefList = foundReferences[mod.FileName]; foreach (var reference in references) { moduleRefList.Add(reference.Location); } } if (foundReferences.Count < 1) return false; // Replace occurences foreach (var kv1 in foundReferences) { var doc = TextFileProvider.Instance.GetEditableTextFile(new FilePath(kv1.Key)); if (doc != null) { foreach (var kv2 in kv1.Value) { int offset = doc.GetPositionFromLineColumn(kv2.Line, kv2.Column); doc.DeleteText(offset, n.Name.Length); doc.InsertText(offset, newName); } // If project file not open for editing, reparse it if (project != null && !IdeApp.Workbench.Documents.Any((Ide.Gui.Document d) => { if (d.IsFile && d.FileName == kv1.Key) return true; return false; })) project.ReparseModule(kv1.Key); } } // Assign new name to the node n.Name = newName; /* // Prepare current editor (setup textlinks and anchors) var doc = Ide.IdeApp.Workbench.ActiveDocument; if (doc == null || !doc.IsFile || !foundReferences.ContainsKey(doc.FileName)) return false; var editor = doc.Editor; var localReferences = foundReferences[doc.FileName]; List<TextLink> links = new List<TextLink>(); TextLink link = new TextLink("name"); int baseOffset = Int32.MaxValue; foreach (var r in localReferences) { baseOffset = Math.Min(baseOffset, editor.Document.LocationToOffset(r.Line, r.Column)); } foreach (var r in localReferences) { var segment = new Segment(editor.Document.LocationToOffset(r.Line, r.Column) - baseOffset, n.Name.Length); if (segment.Offset <= editor.Caret.Offset - baseOffset && editor.Caret.Offset - baseOffset <= segment.EndOffset) { link.Links.Insert(0, segment); } else { link.AddLink(segment); } } links.Add(link); if (editor.CurrentMode is TextLinkEditMode) ((TextLinkEditMode)editor.CurrentMode).ExitTextLinkMode(); var tle = new TextLinkEditMode(editor.Parent, baseOffset, links); tle.SetCaretPosition = false; tle.SelectPrimaryLink = true; // Show rename helper popup if (tle.ShouldStartTextLinkMode) { var helpWindow = new ModeHelpWindow(); helpWindow.TransientFor = IdeApp.Workbench.RootWindow; helpWindow.TitleText = "<b>Renaming " + (n as AbstractNode).ToString(false) + "</b>"; helpWindow.Items.Add(new KeyValuePair<string, string>(GettextCatalog.GetString("<b>Key</b>"), GettextCatalog.GetString("<b>Behavior</b>"))); helpWindow.Items.Add(new KeyValuePair<string, string>(GettextCatalog.GetString("<b>Return</b>"), GettextCatalog.GetString("<b>Accept</b> this refactoring."))); helpWindow.Items.Add(new KeyValuePair<string, string>(GettextCatalog.GetString("<b>Esc</b>"), GettextCatalog.GetString("<b>Cancel</b> this refactoring."))); tle.HelpWindow = helpWindow; tle.Cancel += delegate { if (tle.HasChangedText) editor.Document.Undo(); }; helpWindow.Destroyed += (object o, EventArgs e) => { if (tle.HasChangedText) { } }; tle.OldMode = editor.CurrentMode; tle.StartMode(); editor.CurrentMode = tle; } else return false; */ return true; }
public AbstractVisitor(ResolverContextStack context) { ctxt=context; }
/// <summary> /// Tries to resolve a static property's name. /// Returns a result describing the theoretical member (".init"-%gt;MemberResult; ".typeof"->TypeResult etc). /// Returns null if nothing was found. /// </summary> /// <param name="InitialResult"></param> /// <returns></returns> public static MemberSymbol TryResolveStaticProperties( ISemantic InitialResult, string propertyIdentifier, ResolverContextStack ctxt = null, bool Evaluate = false, IdentifierDeclaration idContainter = null) { // If a pointer'ed type is given, take its base type if (InitialResult is PointerType) InitialResult = ((PointerType)InitialResult).Base; if (InitialResult == null || InitialResult is ModuleSymbol) return null; INode relatedNode = null; if (InitialResult is DSymbol) relatedNode = ((DSymbol)InitialResult).Definition; #region init if (propertyIdentifier == "init") { var prop_Init = new DVariable { Name = "init", Description = "Initializer" }; if (relatedNode != null) { if (!(relatedNode is DVariable)) { prop_Init.Parent = relatedNode.Parent; prop_Init.Type = new IdentifierDeclaration(relatedNode.Name); } else { prop_Init.Parent = relatedNode; prop_Init.Initializer = (relatedNode as DVariable).Initializer; prop_Init.Type = relatedNode.Type; } } return new MemberSymbol(prop_Init, DResolver.StripAliasSymbol(AbstractType.Get(InitialResult)), idContainter); } #endregion #region sizeof if (propertyIdentifier == "sizeof") return new MemberSymbol(new DVariable { Name = "sizeof", Type = new DTokenDeclaration(DTokens.Int), Initializer = new IdentifierExpression(4), Description = "Size in bytes (equivalent to C's sizeof(type))" }, new PrimitiveType(DTokens.Int), idContainter); #endregion #region alignof if (propertyIdentifier == "alignof") return new MemberSymbol(new DVariable { Name = "alignof", Type = new DTokenDeclaration(DTokens.Int), Description = "Alignment size" }, new PrimitiveType(DTokens.Int),idContainter); #endregion #region mangleof if (propertyIdentifier == "mangleof") return new MemberSymbol(new DVariable { Name = "mangleof", Type = new IdentifierDeclaration("string"), Description = "String representing the ‘mangled’ representation of the type" }, getStringType(ctxt) , idContainter); #endregion #region stringof if (propertyIdentifier == "stringof") return new MemberSymbol(new DVariable { Name = "stringof", Type = new IdentifierDeclaration("string"), Description = "String representing the source representation of the type" }, getStringType(ctxt), idContainter); #endregion #region classinfo else if (propertyIdentifier == "classinfo") { var tr = DResolver.StripMemberSymbols(AbstractType.Get(InitialResult)) as TemplateIntermediateType; if (tr is ClassType || tr is InterfaceType) { var ci=new IdentifierDeclaration("TypeInfo_Class") { InnerDeclaration = new IdentifierDeclaration("object"), ExpressesVariableAccess = true, }; var ti = TypeDeclarationResolver.Resolve(ci, ctxt); ctxt.CheckForSingleResult(ti, ci); return new MemberSymbol(new DVariable { Name = "classinfo", Type = ci }, ti!=null && ti.Length!=0?ti[0]:null, idContainter); } } #endregion //TODO: Resolve the types of type-specific properties (floats, ints, arrays, assocarrays etc.) return null; }
protected ItemEnumeration(ResolverContextStack ctxt) : base(ctxt) { }
/// <summary> /// Returns false if cache is already updating. /// </summary> public bool Update(ParseCacheList pcList, ParseCache subCacheToUpdate = null) { if (IsProcessing) return false; try { IsProcessing = true; var ctxt = new ResolverContextStack(pcList, new ResolverContext()) { ContextIndependentOptions = ResolutionOptions.StopAfterFirstOverloads }; queue.Clear(); // Prepare queue if (subCacheToUpdate != null) foreach (var module in subCacheToUpdate) PrepareQueue(module); else foreach (var pc in pcList) foreach (var module in pc) PrepareQueue(module); var sw = new Stopwatch(); sw.Start(); var threads = new Thread[ThreadedDirectoryParser.numThreads]; for (int i = 0; i < ThreadedDirectoryParser.numThreads; i++) { var th = threads[i] = new Thread(parseThread) { IsBackground = true, Priority = ThreadPriority.Lowest, Name = "UFCS Analysis thread #" + i }; th.Start(pcList); } for (int i = 0; i < ThreadedDirectoryParser.numThreads; i++) if (threads[i].IsAlive) threads[i].Join(10000); sw.Stop(); CachingDuration = sw.Elapsed; } finally { IsProcessing = false; } return true; }
void parseThread(object pcl_shared) { DMethod dm = null; var pcl = (ParseCacheList)pcl_shared; var ctxt = new ResolverContextStack(pcl, new ResolverContext()); ctxt.ContextIndependentOptions |= ResolutionOptions.StopAfterFirstOverloads; while (queue.Count != 0) { lock (queue) { if (queue.Count == 0) return; dm = queue.Pop(); } ctxt.CurrentContext.ScopedBlock = dm; var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); if (firstArg_result != null && firstArg_result.Length != 0) lock (CachedMethods) CachedMethods[dm] = firstArg_result[0]; } }
/// <summary> /// Reparses the given method's fucntion body until the cursor position, /// searches the last occurring method call or template instantiation, /// counts its already typed arguments /// and returns a wrapper containing all the information. /// </summary> public static ArgumentsResolutionResult ResolveArgumentContext( IEditorData Editor, ResolverContextStack ctxt) { ParserTrackerVariables trackVars = null; IStatement curStmt = null; IExpression lastParamExpression = null; // Get the currently scoped block var curBlock = DResolver.SearchBlockAt(Editor.SyntaxTree, Editor.CaretLocation, out curStmt); if (curBlock == null) return null; // Get an updated abstract view on the module's code var parsedStmtBlock = CtrlSpaceCompletionProvider.FindCurrentCaretContext( Editor.ModuleCode, curBlock ,Editor.CaretOffset, Editor.CaretLocation, out trackVars) as StatementContainingStatement; if (parsedStmtBlock == null) return null; // Search the returned statement block (i.e. function body) for the current statement var exStmt = BlockStatement.SearchBlockStatement(parsedStmtBlock, Editor.CaretLocation) as IExpressionContainingStatement; lastParamExpression = ExpressionHelper.SearchForMethodCallsOrTemplateInstances(exStmt, Editor.CaretLocation); if (lastParamExpression == null) { // Give it a last chance by handling the lastly parsed object // - which is a TemplateInstanceExpression in quite all cases lastParamExpression = trackVars.LastParsedObject as IExpression; } /* * Then handle the lastly found expression regarding the following points: * * 1) foo( -- normal arguments only * 2) foo!(...)( -- normal arguments + template args * 3) foo!( -- template args only * 4) new myclass( -- ctor call * 5) new myclass!( -- ditto * 6) new myclass!(...)( * 7) mystruct( -- opCall call */ var res = new ArgumentsResolutionResult() { ParsedExpression = lastParamExpression }; // 1), 2) if (lastParamExpression is PostfixExpression_MethodCall) { res.IsMethodArguments = true; var call = (PostfixExpression_MethodCall) lastParamExpression; res.MethodIdentifier = call.PostfixForeExpression; res.ResolvedTypesOrMethods = Evaluation.TryGetUnfilteredMethodOverloads(call.PostfixForeExpression, ctxt, call); if (call.Arguments != null) { int i = 0; foreach (var arg in call.Arguments) { if (Editor.CaretLocation >= arg.Location && Editor.CaretLocation <= arg.EndLocation) { res.CurrentlyTypedArgumentIndex = i; break; } i++; } } } // 3) else if (lastParamExpression is TemplateInstanceExpression) { var templ = (TemplateInstanceExpression)lastParamExpression; res.IsTemplateInstanceArguments = true; res.MethodIdentifier = templ; res.ResolvedTypesOrMethods = Evaluation.GetOverloads(templ, ctxt, null, false); if (templ.Arguments != null) { int i = 0; foreach (var arg in templ.Arguments) { if (Editor.CaretLocation >= arg.Location && Editor.CaretLocation <= arg.EndLocation) { res.CurrentlyTypedArgumentIndex = i; break; } i++; } } } else if (lastParamExpression is PostfixExpression_Access) { var acc = (PostfixExpression_Access)lastParamExpression; res.MethodIdentifier = acc.PostfixForeExpression; res.ResolvedTypesOrMethods = Evaluation.TryGetUnfilteredMethodOverloads(acc.PostfixForeExpression, ctxt, acc); if (res.ResolvedTypesOrMethods == null) return res; if (acc.AccessExpression is NewExpression) CalculateCurrentArgument(acc.AccessExpression as NewExpression, res, Editor.CaretLocation, ctxt, res.ResolvedTypesOrMethods); } else if (lastParamExpression is NewExpression) HandleNewExpression((NewExpression)lastParamExpression,res,Editor,ctxt,curBlock); /* * alias int function(int a, bool b) myDeleg; * alias myDeleg myDeleg2; * * myDeleg dg; * * dg( -- it's not needed to have myDeleg but the base type for what it stands for * * ISSUE: * myDeleg( -- not allowed though * myDeleg2( -- allowed neither! */ if (res.ResolvedTypesOrMethods != null) res.ResolvedTypesOrMethods = DResolver.StripAliasSymbols(res.ResolvedTypesOrMethods); return res; }
public TemplateParameterDeduction(DeducedTypeDictionary DeducedParameters, ResolverContextStack ctxt) { this.ctxt = ctxt; this.TargetDictionary = DeducedParameters; }
public static IEnumerable<ISyntaxRegion> Scan(INode symbol, ResolverContextStack ctxt) { return Scan(symbol.NodeRoot as IAbstractSyntaxTree, symbol, ctxt); }