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());
        }
示例#2
0
 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));
        }
示例#4
0
        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];
                    }
                }
            }
        }
示例#5
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;
        }
示例#6
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);
        }
示例#7
0
 ReferencesFinder(INode symbol, IAbstractSyntaxTree ast, ResolverContextStack ctxt)
 {
     this.ast    = ast;
     this.symbol = symbol;
     searchId    = symbol.Name;
     this.ctxt   = ctxt;
 }
示例#8
0
        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);
        }
示例#11
0
        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);
        }
示例#15
0
        public static IEnumerable <INode> SearchMatchesAlongNodeHierarchy(ResolverContextStack ctxt, CodeLocation caret, string name)
        {
            var scan = new NameScan(ctxt)
            {
                filterId = name
            };

            scan.IterateThroughScopeLayers(caret);

            return(scan.Matches);
        }
示例#16
0
        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;
        }
示例#18
0
        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;
        }
示例#19
0
        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);
             }
 }
示例#21
0
        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);
        }
示例#22
0
 /// <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);
        }
示例#24
0
        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);
        }
示例#28
0
        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);
        }
示例#29
0
        /// <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;
        }
示例#34
0
        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();
        }
示例#37
0
        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++;
                }
            }
        }
示例#40
0
 public StandardValueProvider(ResolverContextStack ctxt)
 {
     ResolutionContext = ctxt;
 }
示例#41
0
        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;
        }
示例#42
0
 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"-&gt;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;
        }
示例#44
0
 protected ItemEnumeration(ResolverContextStack ctxt)
     : base(ctxt)
 {
 }
示例#45
0
        /// <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;
        }
示例#46
0
        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;
 }
示例#49
0
 public static IEnumerable<ISyntaxRegion> Scan(INode symbol, ResolverContextStack ctxt)
 {
     return Scan(symbol.NodeRoot as IAbstractSyntaxTree, symbol, ctxt);
 }