bool Handle(TemplateTypeParameter p, ISemantic arg)
        {
            // if no argument given, try to handle default arguments
            if (arg == null)
            {
                return(TryAssignDefaultType(p));
            }

            // If no spezialization given, assign argument immediately
            if (p.Specialization == null)
            {
                return(Set(p, arg, 0));
            }

            bool handleResult = HandleDecl(null, p.Specialization, arg);

            if (!handleResult)
            {
                return(false);
            }

            // Apply the entire argument to parameter p if there hasn't been no explicit association yet
            TemplateParameterSymbol tps;

            if (!TargetDictionary.TryGetValue(p, out tps) || tps == null)
            {
                TargetDictionary[p] = new TemplateParameterSymbol(p, arg);
            }

            return(true);
        }
        /// <summary>
        /// Returns false if the item has already been set before and if the already set item is not equal to 'r'.
        /// Inserts 'r' into the target dictionary and returns true otherwise.
        /// </summary>
        bool Set(ITemplateParameter p, ISemantic r, string name = null)
        {
            if (string.IsNullOrEmpty(name))
            {
                name = p.Name;
            }

            TemplateParameterSymbol rl = null;

            if (!TargetDictionary.TryGetValue(name, out rl) || rl == null)
            {
                TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner);
                return(true);
            }
            else
            {
                if (rl != null)
                {
                    if (ResultComparer.IsEqual(rl.Base, r))
                    {
                        return(true);
                    }
                    else
                    {
                        // Error: Ambiguous assignment
                    }
                }

                TargetDictionary[name] = new TemplateParameterSymbol(p, r, null, TargetDictionary.ParameterOwner);

                return(false);
            }
        }
        public bool HandleDecl(TemplateTypeParameter p, ITypeDeclaration td, ISemantic rr)
        {
            if (td is IdentifierDeclaration)
            {
                return(HandleDecl(p, (IdentifierDeclaration)td, rr));
            }

            if (TemplateInstanceHandler.IsNonFinalArgument(rr))
            {
                foreach (var tp in this.TargetDictionary.Keys.ToList())
                {
                    if (TargetDictionary[tp] == null)
                    {
                        TargetDictionary[tp] = new TemplateParameterSymbol(tp, null);
                    }
                }

                return(true);
            }

            //HACK Ensure that no information gets lost by using this function
            // -- getting a value but requiring an abstract type and just extract it from the value - is this correct behaviour?
            var at = AbstractType.Get(rr);

            if (td is ArrayDecl)
            {
                return(HandleDecl(p, (ArrayDecl)td, DResolver.StripMemberSymbols(at) as AssocArrayType));
            }
            else if (td is DTokenDeclaration)
            {
                return(HandleDecl((DTokenDeclaration)td, at));
            }
            else if (td is DelegateDeclaration)
            {
                return(HandleDecl(p, (DelegateDeclaration)td, DResolver.StripMemberSymbols(at) as DelegateType));
            }
            else if (td is PointerDecl)
            {
                return(HandleDecl(p, (PointerDecl)td, DResolver.StripMemberSymbols(at) as PointerType));
            }
            else if (td is MemberFunctionAttributeDecl)
            {
                return(HandleDecl(p, (MemberFunctionAttributeDecl)td, at));
            }
            else if (td is TypeOfDeclaration)
            {
                return(HandleDecl((TypeOfDeclaration)td, at));
            }
            else if (td is VectorDeclaration)
            {
                return(HandleDecl((VectorDeclaration)td, at));
            }
            else if (td is TemplateInstanceExpression)
            {
                return(HandleDecl(p, (TemplateInstanceExpression)td, at));
            }

            return(false);
        }
Exemple #4
0
        /// <summary>
        /// Returns false if the item has already been set before and if the already set item is not equal to 'r'.
        /// Inserts 'r' into the target dictionary and returns true otherwise.
        /// </summary>
        bool Set(TemplateParameter p, ISemantic r, int nameHash)
        {
            if (p == null)
            {
                if (nameHash != 0 && TargetDictionary.ExpectedParameters != null)
                {
                    foreach (var tpar in TargetDictionary.ExpectedParameters)
                    {
                        if (tpar.NameHash == nameHash)
                        {
                            p = tpar;
                            break;
                        }
                    }
                }
            }

            if (p == null)
            {
                ctxt.LogError(null, "no fitting template parameter found!");
                return(false);
            }

            // void call(T)(T t) {}
            // call(myA) -- T is *not* myA but A, so only assign myA's type to T.
            if (p is TemplateTypeParameter)
            {
                var newR = Resolver.TypeResolution.DResolver.StripMemberSymbols(AbstractType.Get(r));
                if (newR != null)
                {
                    r = newR;
                }
            }

            TemplateParameterSymbol rl;

            if (!TargetDictionary.TryGetValue(p, out rl) || rl == null)
            {
                TargetDictionary[p] = new TemplateParameterSymbol(p, r);
                return(true);
            }
            else
            {
                if (ResultComparer.IsEqual(rl.Base, r))
                {
                    TargetDictionary[p] = new TemplateParameterSymbol(p, r);
                    return(true);
                }
                else if (rl == null)
                {
                    TargetDictionary[p] = new TemplateParameterSymbol(p, r);
                }

                // Error: Ambiguous assignment

                return(false);
            }
        }
        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);
        }