예제 #1
0
        ISemantic E(TemplateInstanceExpression tix, bool ImplicitlyExecute = true)
        {
            var o = DResolver.StripAliasSymbols(GetOverloads(tix, ctxt));

            if (eval)
            {
                return(TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute));
            }
            else
            {
                ctxt.CheckForSingleResult(o, tix);
                if (o != null)
                {
                    if (o.Length == 1)
                    {
                        return(o[0]);
                    }
                    else if (o.Length > 1)
                    {
                        return(new InternalOverloadValue(o, tix));
                    }
                }
                return(null);
            }
        }
예제 #2
0
        DNode[] ResolveTemplateInstanceId(TemplateInstanceExpression tix)
        {
            /*
             * Again a very unclear/buggy situation:
             * When having a cascaded tix as parameter, it uses the left-most part (i.e. the inner most) of the typedeclaration construct.
             *
             * class C(A!X.SubClass, X) {} can be instantiated via C!(A!int), but not via C!(A!int.SubClass) - totally confusing
             * (dmd v2.060)
             */
            if (tix.InnerDeclaration != null)
            {
                if (tix.InnerMost is TemplateInstanceExpression)
                {
                    tix = (TemplateInstanceExpression)tix.InnerMost;
                }
                else
                {
                    return(new DNode[0]);
                }
            }

            var optBackup = ctxt.CurrentContext.ContextDependentOptions;

            ctxt.CurrentContext.ContextDependentOptions = ResolutionOptions.DontResolveBaseClasses | ResolutionOptions.DontResolveBaseTypes | ResolutionOptions.StopAfterFirstOverloads;

            var initialResults = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix);
            var l = _handleResStep(initialResults);

            ctxt.CurrentContext.ContextDependentOptions = optBackup;

            return(l.ToArray());
        }
예제 #3
0
        public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable<AbstractType> rawOverloadList,
			TemplateInstanceExpression templateInstanceExpr,
			ResolutionContext ctxt, bool isMethodCall = false)
        {
            bool hasUndeterminedArgs;
            var args = PreResolveTemplateArgs(templateInstanceExpr, ctxt, out hasUndeterminedArgs);
            return DeduceParamsAndFilterOverloads(rawOverloadList, args, isMethodCall, ctxt, hasUndeterminedArgs);
        }
예제 #4
0
        public ISymbolValue Visit(TemplateInstanceExpression tix)
        {
            var ImplicitlyExecute = this.ImplicitlyExecute;

            this.ImplicitlyExecute = true;

            return(TryDoCTFEOrGetValueRefs(AmbiguousType.Get(ExpressionTypeEvaluation.GetOverloads(tix, ctxt), tix), tix, ImplicitlyExecute));
        }
예제 #5
0
        public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable <AbstractType> rawOverloadList,
                                                                    TemplateInstanceExpression templateInstanceExpr,
                                                                    ResolutionContext ctxt, bool isMethodCall = false)
        {
            var args = PreResolveTemplateArgs(templateInstanceExpr, ctxt);

            return(DeduceParamsAndFilterOverloads(rawOverloadList, args, isMethodCall, ctxt));
        }
예제 #6
0
        public override void Visit(TemplateInstanceExpression x)
        {
            if (DoPrimaryIdCheck(x.TemplateIdHash))
            {
                AddResult(x);
            }

            base.Visit(x);
        }
예제 #7
0
        public ISymbolValue Visit(TemplateInstanceExpression tix)
        {
            var ImplicitlyExecute = this.ImplicitlyExecute;
            this.ImplicitlyExecute = true;

            var o = DResolver.StripAliasSymbols(ExpressionTypeEvaluation.GetOverloads(tix, ctxt));

            return TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute);
        }
예제 #8
0
        ITypeDeclaration QualifiedName()
        {
            ITypeDeclaration td = null;
            int n;

            while (PeekIsDecNumber)
            {
                // Read number of either the first LName or TemplateInstanceName
                n = (int)Number();
                sb.Clear();
                if ((char)r.Peek() == '_')
                {
                    r.Read();
                    sb.Append('_');
                    if ((char)r.Peek() == '_')
                    {
                        r.Read();
                        sb.Append('_');
                        if ((char)r.Peek() == 'T')
                        {
                            r.Read();
                            // We've got to handle a Template instance:
                            // Number __T LName TemplateArgs Z
                            var tpi = new TemplateInstanceExpression(new IdentifierDeclaration(LName()));

                            tpi.InnerDeclaration = td;
                            td = tpi;

                            var xx = new List <IExpression>();
                            while (r.Peek() != -1)
                            {
                                var arg = TemplateArg();
                                if (arg == null)
                                {
                                    break;
                                }
                                xx.Add(arg);
                            }
                            tpi.Arguments = xx.ToArray();
                            continue;
                        }
                    }
                }

                // Just an LName
                if (n > sb.Length)
                {
                    sb.Append(LName(n - sb.Length));
                }

                var ttd = new IdentifierDeclaration(sb.ToString());
                ttd.InnerDeclaration = td;
                td = ttd;
            }

            return(td);
        }
예제 #9
0
        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);
        }
예제 #10
0
        public ISymbolValue Visit(TemplateInstanceExpression tix)
        {
            var ImplicitlyExecute = this.ImplicitlyExecute;

            this.ImplicitlyExecute = true;

            var o = DResolver.StripAliasSymbols(ExpressionTypeEvaluation.GetOverloads(tix, ctxt));

            return(TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute));
        }
예제 #11
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.EvalAndFilterOverloads(res, tix, ctxt) : res;
        }
예제 #12
0
        public override void Visit(TemplateInstanceExpression x)
        {
            byte type;

            if (DoPrimaryIdCheck(x.TemplateIdHash, out type))
            {
                AddResult(x, type);
            }

            base.Visit(x);
        }
예제 #13
0
 public override void Visit(TemplateInstanceExpression id)
 {
     if (id.TemplateIdHash == searchHash)
     {
         ctxt.CurrentContext.Set(id.Location);
         if (TryAdd(ExpressionTypeEvaluation.EvaluateType(id, ctxt, false), id))
         {
             return;
         }
     }
 }
예제 #14
0
        ISemantic E(TemplateInstanceExpression tix, bool ImplicitlyExecute = true)
        {
            var o = DResolver.StripAliasSymbols(GetOverloads(tix, ctxt));

            if (eval)
                return TryDoCTFEOrGetValueRefs(o, tix, ImplicitlyExecute);
            else
            {
                ctxt.CheckForSingleResult(o, tix);
                if (o != null && o.Length == 1)
                    return o[0];
                return null;
            }
        }
예제 #15
0
        public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolutionContext ctxt, IEnumerable<AbstractType> resultBases = null, bool deduceParameters = true)
        {
            if(resultBases == null && tix.InnerDeclaration != null)
                resultBases = TypeDeclarationResolver.Resolve(tix.InnerDeclaration, ctxt);

            AbstractType[] res;
            if (resultBases == null)
                res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdHash, ctxt, tix, tix.ModuleScopedIdentifier);
            else
                res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdHash, resultBases, ctxt, tix);

            return (ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0 && deduceParameters ?
                TemplateInstanceHandler.DeduceParamsAndFilterOverloads(res, tix, ctxt) : res;
        }
예제 #16
0
        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;
        }
예제 #17
0
        public virtual void Visit(TemplateInstanceExpression x)
        {
            if (x.Identifier != null)
            {
                x.Identifier.Accept(this);
            }

            if (x.Arguments != null)
            {
                foreach (var arg in x.Arguments)
                {
                    arg.Accept(this);
                }
            }
        }
예제 #18
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);
        }
예제 #19
0
        ITypeDeclaration VisitDSymbol(DSymbol t)
        {
            var def             = t.Definition;
            ITypeDeclaration td = new IdentifierDeclaration(def != null ? def.NameHash : 0);

            if (def != null && t.DeducedTypes != null && def.TemplateParameters != null)
            {
                var args = new List <IExpression>();
                foreach (var tp in def.TemplateParameters)
                {
                    IExpression argEx = null;
                    foreach (var tps in t.DeducedTypes)
                    {
                        if (tps != null && tps.Parameter == tp)
                        {
                            if (tps.ParameterValue != null)
                            {
                                //TODO: Convert ISymbolValues back to IExpression
                            }
                            else
                            {
                                argEx = new TypeDeclarationExpression(AcceptType(tps));
                            }
                            break;
                        }
                    }

                    args.Add(argEx ?? new IdentifierExpression(tp.NameHash));
                }

                td = new TemplateInstanceExpression(td)
                {
                    Arguments = args.ToArray()
                };
            }

            var ret = td;

            while (def != null && def != (def = def.Parent as DNode) &&
                   def != null && !(def is DModule))
            {
                td = td.InnerDeclaration = new IdentifierDeclaration(def.NameHash);
            }

            return(ret);
        }
예제 #20
0
        public void Visit(TemplateInstanceExpression tix)
        {
            res.IsTemplateInstanceArguments = true;

            res.MethodIdentifier           = tix;
            ctxt.ContextIndependentOptions = ResolutionOptions.NoTemplateParameterDeduction;
            res.ResolvedTypesOrMethods     = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, null, false);

            if (tix.Arguments != null)
            {
                res.CurrentlyTypedArgumentIndex = tix.Arguments.Length;
            }
            else
            {
                res.CurrentlyTypedArgumentIndex = 0;
            }
        }
예제 #21
0
        public AbstractType Visit(TemplateInstanceExpression tix)
        {
            var o = DResolver.StripAliasSymbols(GetOverloads(tix, ctxt));

            ctxt.CheckForSingleResult(o, tix);
            if (o != null)
            {
                if (o.Length == 1)
                {
                    return(o[0]);
                }
                else if (o.Length > 1)
                {
                    return(new AmbiguousType(o));
                }
            }
            return(null);
        }
예제 #22
0
        public override void Visit(TemplateInstanceExpression tix)
        {
            var resolvedSymbol = TryPopPFAStack();

            if (tix.TemplateIdHash == searchHash)
            {
                if (resolvedSymbol == null)
                {
                    resolvedSymbol = Evaluation.EvaluateType(tix, ctxt) as DSymbol;
                }

                if (resolvedSymbol != null && resolvedSymbol.Definition == symbol)
                {
                    l.Add(tix);
                    return;
                }
            }
            base.Visit(tix);
        }
예제 #23
0
        void GetRawCallOverloads(ResolutionContext ctxt, IExpression callForeExpression,
                                 out AbstractType[] baseExpression,
                                 out TemplateInstanceExpression tix)
        {
            tix = null;

            if (callForeExpression is PostfixExpression_Access)
            {
                var pac = (PostfixExpression_Access)callForeExpression;
                tix = pac.AccessExpression as TemplateInstanceExpression;

                baseExpression = Evaluation.EvalPostfixAccessExpression(this, ctxt, pac, null, false, false);
            }
            else
            {
                // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one
                var optBackup = ctxt.CurrentContext.ContextDependentOptions;
                ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;

                if (callForeExpression is TokenExpression)
                {
                    baseExpression = ExpressionTypeEvaluation.GetResolvedConstructorOverloads((TokenExpression)callForeExpression, ctxt);
                }
                else
                {
                    if (callForeExpression is TemplateInstanceExpression)
                    {
                        baseExpression = ExpressionTypeEvaluation.GetOverloads(tix = (TemplateInstanceExpression)callForeExpression, ctxt, null, false);
                    }
                    else if (callForeExpression is IdentifierExpression)
                    {
                        baseExpression = ExpressionTypeEvaluation.GetOverloads(callForeExpression as IdentifierExpression, ctxt, deduceParameters: false);
                    }
                    else
                    {
                        baseExpression = new[] { callForeExpression != null?AbstractType.Get(callForeExpression.Accept(this)) : null }
                    };
                }

                ctxt.CurrentContext.ContextDependentOptions = optBackup;
            }
        }
예제 #24
0
        public static AbstractType[] GetOverloads(TemplateInstanceExpression tix, ResolutionContext ctxt, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true)
        {
            if (resultBases == null && tix.InnerDeclaration != null)
            {
                resultBases = TypeDeclarationResolver.Resolve(tix.InnerDeclaration, ctxt);
            }

            AbstractType[] res;
            if (resultBases == null)
            {
                res = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdHash, ctxt, tix, tix.ModuleScopedIdentifier);
            }
            else
            {
                res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(tix.TemplateIdHash, resultBases, ctxt, tix);
            }

            return((ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0 && deduceParameters?
                   TemplateInstanceHandler.DeduceParamsAndFilterOverloads(res, tix, ctxt) : res);
        }
예제 #25
0
        static void HandleTemplateInstance(TemplateInstanceExpression tix,
                                           ArgumentsResolutionResult res,
                                           IEditorData Editor,
                                           ResolutionContext ctxt,
                                           IBlockNode curBlock,
                                           IEnumerable <AbstractType> resultBases = null)
        {
            res.IsTemplateInstanceArguments = true;

            res.MethodIdentifier       = tix;
            res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, resultBases, false);

            if (tix.Arguments != null)
            {
                res.CurrentlyTypedArgumentIndex = tix.Arguments.Length;
            }
            else
            {
                res.CurrentlyTypedArgumentIndex = 0;
            }
        }
예제 #26
0
        public TemplateInstanceExpression TemplateInstance()
        {
            if (!Expect(Identifier))
                return null;

            var td = new TemplateInstanceExpression() {
                TemplateIdentifier = new IdentifierDeclaration(t.Value)
                {
                    Location=t.Location,
                    EndLocation=t.EndLocation
                },
                Location = t.Location
            };
            LastParsedObject = td;

            var args = new List<IExpression>();

            if (!Expect(Not))
                return td;

            if (laKind == (OpenParenthesis))
            {
                Step();
                if (laKind != CloseParenthesis)
                {
                    bool init = true;
                    while (init || laKind == (Comma))
                    {
                        if (!init) Step();
                        init = false;

                        if (IsAssignExpression())
                            args.Add(AssignExpression());
                        else
                            args.Add(new TypeDeclarationExpression(Type()));
                    }
                }
                Expect(CloseParenthesis);
            }
            else
            {
                Step();
                if (t.Kind == Literal)
                    args.Add(new IdentifierExpression(t.LiteralValue, LiteralFormat.Scalar));
                else if (t.Kind == Identifier)
                    args.Add(new IdentifierExpression(t.Value));
                else
                    args.Add(new TokenExpression(t.Kind));
            }
            td.Arguments = args.ToArray();
            td.EndLocation = t.EndLocation;
            return td;
        }
        bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r)
        {
            /*
             * TODO: Scan down r for having at least one templateinstanceexpression as declaration base.
             * If a tix was found, check if the definition of the respective result base level
             * and the un-aliased identifier of the 'tix' parameter match.
             * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes),
             * it is only important that the definition is inside this bundle.
             * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t!
             *
             * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME
             */
            var paramTix_TemplateMatchPossibilities       = ResolveTemplateInstanceId(tix);
            TemplateIntermediateType tixBasedArgumentType = null;
            var r_ = r as DSymbol;

            while (r_ != null)
            {
                if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression)
                {
                    var tit = r_ as TemplateIntermediateType;
                    if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition))
                    {
                        tixBasedArgumentType = tit;
                        break;
                    }
                }

                r_ = r_.Base as DSymbol;
            }

            /*
             * This part is very tricky:
             * I still dunno what is allowed over here--
             *
             * class Foo(T:Bar!E[],E) {}
             * ...
             * Foo!(Bar!string[]) f; -- E will be 'string' then
             *
             * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar
             *		obviously is not a template instance expression - it's a normal identifier only.
             */
            if (tixBasedArgumentType != null)
            {
                var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator();

                foreach (var p in tix.Arguments)
                {
                    if (!argEnum_given.MoveNext() || argEnum_given.Current == null)
                    {
                        return(false);
                    }

                    // Convert p to type declaration
                    var param_Expected = ConvertToTypeDeclarationRoughly(p);

                    if (param_Expected == null)
                    {
                        return(false);
                    }

                    var result_Given = ExpressionTypeEvaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt);

                    if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given))
                    {
                        return(false);
                    }
                }

                // Too many params passed..
                if (argEnum_given.MoveNext())
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
예제 #28
0
		public override void Visit (TemplateInstanceExpression id)
		{
			if (id.TemplateIdHash == searchHash)
			{
				ctxt.CurrentContext.Set(id.Location);
				if (TryAdd(ExpressionTypeEvaluation.EvaluateType(id, ctxt, false), id))
					return;
			}
		}
예제 #29
0
        public TemplateInstanceExpression TemplateInstance()
        {
            if (!Expect(Identifier))
                return null;

            var td = new TemplateInstanceExpression() {
                TemplateIdentifier = new IdentifierDeclaration(t.Value)
                {
                    Location=t.Location,
                    EndLocation=t.EndLocation
                },
                Location = t.Location
            };
            LastParsedObject = td;

            var args = new List<IExpression>();

            if (!Expect(Not))
                return td;

            if (laKind == (OpenParenthesis))
            {
                Step();

                if (laKind != CloseParenthesis)
                {
                    bool init = true;
                    while (laKind == Comma || init)
                    {
                        if (!init) Step();
                        init = false;

                        if (IsEOF)
                        {
                            args.Add(new TokenExpression(DTokens.INVALID) { Location= la.Location, EndLocation=la.EndLocation });
                            break;
                        }

                        var la_Backup = la;

                        bool wp = AllowWeakTypeParsing;
                        AllowWeakTypeParsing = true;

                        var typeArg = Type();

                        AllowWeakTypeParsing = wp;

                        if (typeArg != null && (laKind == CloseParenthesis || laKind==Comma))
                            args.Add(new TypeDeclarationExpression(typeArg));
                        else
                        {
                            la = la_Backup;
                            Peek(1);

                            args.Add(AssignExpression());
                        }
                    }
                }
                Expect(CloseParenthesis);
            }
            else
            {
                Step();

                /*
                 * TemplateSingleArgument:
                 *		Identifier
                 *		BasicTypeX
                 *		CharacterLiteral
                 *		StringLiteral
                 *		IntegerLiteral
                 *		FloatLiteral
                 *		true
                 *		false
                 *		null
                 *		__FILE__
                 *		__LINE__
                 */

                IExpression arg= null;

                if (t.Kind == Literal)
                    arg = new IdentifierExpression(t.LiteralValue, LiteralFormat.Scalar)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };
                else if (t.Kind == Identifier)
                    arg = new IdentifierExpression(t.Value)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };
                else if (BasicTypes[t.Kind])
                    arg = new TypeDeclarationExpression(new DTokenDeclaration(t.Kind)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    });
                else if (
                    t.Kind == True ||
                    t.Kind == False ||
                    t.Kind == Null ||
                    t.Kind == __FILE__ ||
                    t.Kind == __LINE__)
                    arg = new TokenExpression(t.Kind)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };
                else if (IsEOF)
                {
                    ExpectingIdentifier = false;
                    return td;
                }

                args.Add(arg);
            }
            td.Arguments = args.ToArray();
            td.EndLocation = t.EndLocation;
            return td;
        }
        void GetRawCallOverloads(ResolutionContext ctxt, PostfixExpression_MethodCall call,
                                 out AbstractType[] baseExpression,
                                 out ISymbolValue baseValue,
                                 out TemplateInstanceExpression tix)
        {
            baseValue = null;
            tix       = null;

            if (call.PostfixForeExpression is PostfixExpression_Access)
            {
                var pac = (PostfixExpression_Access)call.PostfixForeExpression;
                tix = pac.AccessExpression as TemplateInstanceExpression;

                var vs = EvalPostfixAccessExpression(this, ctxt, pac, null, false, false);

                baseExpression = TypeDeclarationResolver.Convert(vs);
            }
            else
            {
                // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one
                var optBackup = ctxt.CurrentContext.ContextDependentOptions;
                ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;

                if (call.PostfixForeExpression is TokenExpression)
                {
                    baseExpression = ExpressionTypeEvaluation.GetResolvedConstructorOverloads((TokenExpression)call.PostfixForeExpression, ctxt);
                }
                else
                {
                    var fore = call.PostfixForeExpression;
                    if (fore is TemplateInstanceExpression)
                    {
                        ImplicitlyExecute = false;
                        tix = call.PostfixForeExpression as TemplateInstanceExpression;
                    }
                    else if (fore is IdentifierExpression)
                    {
                        ImplicitlyExecute = false;
                    }

                    if (call.PostfixForeExpression != null)
                    {
                        baseValue = call.PostfixForeExpression.Accept(this) as ISymbolValue;
                    }

                    if (baseValue is InternalOverloadValue)
                    {
                        baseExpression = ((InternalOverloadValue)baseValue).Overloads;
                    }
                    else if (baseValue != null)
                    {
                        baseExpression = new[] { baseValue.RepresentedType }
                    }
                    ;
                    else
                    {
                        baseExpression = null;
                    }
                }

                ctxt.CurrentContext.ContextDependentOptions = optBackup;
            }
        }
예제 #31
0
        public override void Visit(TemplateInstanceExpression x)
        {
            byte type;
            if (DoPrimaryIdCheck(x.TemplateIdHash, out type))
                AddResult(x, type);

            base.Visit (x);
        }
예제 #32
0
 public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable <AbstractType> rawOverloadList,
                                                             TemplateInstanceExpression templateInstanceExpr,
                                                             ResolverContextStack ctxt)
 {
     return(DeduceParamsAndFilterOverloads(rawOverloadList, PreResolveTemplateArgs(templateInstanceExpr, ctxt), false, ctxt));
 }
예제 #33
0
 public AbstractType Visit(TemplateInstanceExpression tix)
 {
     return(TryPretendMethodExecution(AmbiguousType.Get(GetOverloads(tix, ctxt), tix)));
 }
예제 #34
0
        ISemantic E(PostfixExpression_MethodCall call, bool returnBaseTypeOnly = true)
        {
            // Deduce template parameters later on
            AbstractType[]             baseExpression = null;
            ISymbolValue               baseValue      = null;
            TemplateInstanceExpression tix            = null;
            bool isUFCSFunction = false;

            GetRawCallOverloads(call, out baseExpression, out baseValue, out tix, out isUFCSFunction);

            var methodOverloads = new List <AbstractType>();

            #region Search possible methods, opCalls or delegates that could be called
            bool requireStaticItems = true;             //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
            IEnumerable <AbstractType> scanResults = DResolver.StripAliasSymbols(baseExpression);
            var nextResults = new List <AbstractType>();

            while (scanResults != null)
            {
                foreach (var b in scanResults)
                {
                    if (b is MemberSymbol)
                    {
                        var mr = (MemberSymbol)b;

                        if (mr.Definition is DMethod)
                        {
                            methodOverloads.Add(mr);
                            continue;
                        }
                        else if (mr.Definition is DVariable)
                        {
                            // If we've got a variable here, get its base type/value reference
                            if (eval)
                            {
                                var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

                                if (dgVal != null)
                                {
                                    nextResults.Add(dgVal.Definition);
                                    continue;
                                }
                                else
                                {
                                    throw new EvaluationException(call, "Variable must be a delegate, not anything else", mr);
                                }
                            }
                            else
                            {
                                var bt = DResolver.StripAliasSymbol(mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt));

                                // Must be of type delegate
                                if (bt is DelegateType)
                                {
                                    //TODO: Ensure that there's no further overload - inform the user elsewise

                                    if (returnBaseTypeOnly)
                                    {
                                        return(bt);
                                    }
                                    else
                                    {
                                        return(new MemberSymbol(mr.Definition, bt, mr.DeclarationOrExpressionBase));
                                    }
                                }
                                else
                                {
                                    /*
                                     * If mr.Node is not a method, so e.g. if it's a variable
                                     * pointing to a delegate
                                     *
                                     * class Foo
                                     * {
                                     *	string opCall() {  return "asdf";  }
                                     * }
                                     *
                                     * Foo f=new Foo();
                                     * f(); -- calls opCall, opCall is not static
                                     */
                                    nextResults.Add(bt);
                                    requireStaticItems = false;
                                }
                                //TODO: Can other types work as function/are callable?
                            }
                        }
                    }
                    else if (b is DelegateType)
                    {
                        var dg = (DelegateType)b;

                        /*
                         * int a = delegate(x) { return x*2; } (12); // a is 24 after execution
                         * auto dg=delegate(x) {return x*3;};
                         * int b = dg(4);
                         */

                        if (dg.IsFunctionLiteral)
                        {
                            methodOverloads.Add(dg);
                        }
                        else
                        {
                            // If it's just wanted to pass back the delegate's return type, skip the remaining parts of this method.
                            if (eval)
                            {
                                throw new EvaluationException(call, "TODO", dg);
                            }
                            //TODO
                            //if(returnBaseTypeOnly)
                            //TODO: Check for multiple definitions. Also, make a parameter-argument check to inform the user about wrong arguments.
                            return(dg);
                        }
                    }
                    else if (b is ClassType)
                    {
                        /*
                         * auto a = MyStruct(); -- opCall-Overloads can be used
                         */
                        var classDef = ((ClassType)b).Definition;

                        if (classDef == null)
                        {
                            continue;
                        }

                        foreach (var i in classDef)
                        {
                            if (i.Name == "opCall" && i is DMethod && (!requireStaticItems || (i as DNode).IsStatic))
                            {
                                methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);
                            }
                        }
                    }

                    /*
                     * Every struct can contain a default ctor:
                     *
                     * struct S { int a; bool b; }
                     *
                     * auto s = S(1,true); -- ok
                     * auto s2= new S(2,false); -- error, no constructor found!
                     */
                    else if (b is StructType && methodOverloads.Count == 0)
                    {
                        //TODO: Deduce parameters
                        return(b);
                    }

                    /*
                     * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
                     * child inside a template + that is named as the template.
                     */
                    else if (b is TemplateType &&
                             ImplicitTemplateProperties.ContainsEquallyNamedChildrenOnly(((TemplateType)b).Definition))
                    {
                        methodOverloads.Add(b);
                    }
                }

                scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
                nextResults.Clear();
            }
            #endregion

            if (methodOverloads.Count == 0)
            {
                return(null);
            }

            // Get all arguments' types
            var callArguments = new List <ISemantic>();

            // If it's sure that we got a ufcs call here, add the base expression's type as first argument type
            if (isUFCSFunction)
            {
                callArguments.Add(eval ? (ISemantic)baseValue : ((MemberSymbol)baseExpression[0]).Base);
            }

            if (call.Arguments != null)
            {
                foreach (var arg in call.Arguments)
                {
                    callArguments.Add(E(arg));
                }
            }

            #region Deduce template parameters and filter out unmatching overloads
            // First add optionally given template params
            // http://dlang.org/template.html#function-templates
            var tplParamDeductionArguments = tix == null ?
                                             new List <ISemantic>() :
                                             TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt);

            // Then add the arguments[' member types]
            foreach (var arg in callArguments)
            {
                if (arg is VariableValue)
                {
                    tplParamDeductionArguments.Add(ValueProvider[((VariableValue)arg).Variable]);
                }
                else if (arg is AbstractType)
                {
                    tplParamDeductionArguments.Add(DResolver.StripMemberSymbols((AbstractType)arg));
                }
                else
                {
                    tplParamDeductionArguments.Add(arg);
                }
            }

            var templateParamFilteredOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(
                methodOverloads,
                tplParamDeductionArguments.Count > 0 ? tplParamDeductionArguments.ToArray() : null,
                true, ctxt);
            #endregion

            #region Filter by parameter-argument comparison
            var argTypeFilteredOverloads = new List <AbstractType>();

            if (templateParamFilteredOverloads != null)
            {
                foreach (var ov in templateParamFilteredOverloads)
                {
                    if (ov is MemberSymbol)
                    {
                        var  ms  = (MemberSymbol)ov;
                        var  dm  = ms.Definition as DMethod;
                        bool add = false;

                        if (dm != null)
                        {
                            ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms);

                            add = false;

                            if (callArguments.Count == 0 && dm.Parameters.Count == 0)
                            {
                                add = true;
                            }
                            else
                            {
                                for (int i = 0; i < dm.Parameters.Count; i++)
                                {
                                    var paramType = TypeDeclarationResolver.ResolveSingle(dm.Parameters[i].Type, ctxt);

                                    // TODO: Expression tuples & variable argument lengths
                                    if (i >= callArguments.Count ||
                                        !ResultComparer.IsImplicitlyConvertible(callArguments[i], paramType, ctxt))
                                    {
                                        continue;
                                    }

                                    add = true;
                                }
                            }

                            if (add)
                            {
                                var bt = ms.Base ?? TypeDeclarationResolver.GetMethodReturnType(dm, ctxt);

                                if (returnBaseTypeOnly)
                                {
                                    argTypeFilteredOverloads.Add(bt);
                                }
                                else
                                {
                                    argTypeFilteredOverloads.Add(ms.Base == null ? new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes) : ms);
                                }
                            }

                            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ms);
                        }
                    }
                    else if (ov is DelegateType)
                    {
                        var dg = (DelegateType)ov;
                        var bt = TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

                        //TODO: Param-Arg check
                        if (returnBaseTypeOnly)
                        {
                            argTypeFilteredOverloads.Add(bt);
                        }
                        else
                        {
                            argTypeFilteredOverloads.Add(new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters));
                        }
                    }
                }
            }
            #endregion

            if (eval)
            {
                // Convert ISemantic[] to ISymbolValue[]
                var args = new List <ISymbolValue>(callArguments.Count);

                foreach (var a in callArguments)
                {
                    args.Add(a as ISymbolValue);
                }

                // Execute/Evaluate the variable contents etc.
                return(TryDoCTFEOrGetValueRefs(argTypeFilteredOverloads.ToArray(), call.PostfixForeExpression, true, args.ToArray()));
            }
            else
            {
                // Check if one overload remains and return that one.
                ctxt.CheckForSingleResult(argTypeFilteredOverloads.ToArray(), call);
                return(argTypeFilteredOverloads != null && argTypeFilteredOverloads.Count != 0 ?
                       argTypeFilteredOverloads[0] : null);
            }
        }
        DNode[] ResolveTemplateInstanceId(TemplateInstanceExpression tix)
        {
            /*
             * Again a very unclear/buggy situation:
             * When having a cascaded tix as parameter, it uses the left-most part (i.e. the inner most) of the typedeclaration construct.
             *
             * class C(A!X.SubClass, X) {} can be instantiated via C!(A!int), but not via C!(A!int.SubClass) - totally confusing
             * (dmd v2.060)
             */
            if (tix.InnerDeclaration != null)
            {
                if (tix.InnerMost is TemplateInstanceExpression)
                    tix = (TemplateInstanceExpression)tix.InnerMost;
                else
                    return new DNode[0];
            }

            var optBackup = ctxt.CurrentContext.ContextDependentOptions;
            ctxt.CurrentContext.ContextDependentOptions = ResolutionOptions.DontResolveBaseClasses | ResolutionOptions.DontResolveBaseTypes;

            var initialResults = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdHash, ctxt, tix);

            var l = new List<DNode>();
            foreach (var res in initialResults)
                if (res is DSymbol)
                    l.Add((res as DSymbol).Definition);

            ctxt.CurrentContext.ContextDependentOptions = optBackup;

            return l.ToArray();
        }
예제 #36
0
        public override void Visit(TemplateInstanceExpression tix)
        {
            var resolvedSymbol = TryPopPFAStack ();
            if (tix.TemplateIdHash == searchHash) {
                if(resolvedSymbol == null)
                    resolvedSymbol = ExpressionTypeEvaluation.EvaluateType(tix, ctxt, false) as DSymbol;

                if (resolvedSymbol != null && resolvedSymbol.Definition == symbol) {
                    l.Add (tix);
                    return;
                }
            }
            base.Visit (tix);
        }
예제 #37
0
        public TemplateInstanceExpression TemplateInstance(IBlockNode Scope)
        {
            var loc = la.Location;

            var mod = INVALID;

            if (DTokens.StorageClass [laKind]) {
                mod = laKind;
                Step ();
            }

            if (!Expect (Identifier))
                return null;

            ITypeDeclaration td = new IdentifierDeclaration (t.Value) {
                Location = t.Location,
                EndLocation = t.EndLocation
            };

            td = new TemplateInstanceExpression(mod != DTokens.INVALID ? new MemberFunctionAttributeDecl(mod) { InnerType = td } : td) {
                Location = loc
            };
            LastParsedObject = td;

            var args = new List<IExpression>();

            if (!Expect(Not))
                return td as TemplateInstanceExpression;

            if (laKind == (OpenParenthesis))
            {
                Step();

                if (laKind != CloseParenthesis)
                {
                    bool init = true;
                    while (laKind == Comma || init)
                    {
                        if (!init) Step();
                        init = false;

                        if (laKind == CloseParenthesis)
                            break;

                        if (IsEOF)
                        {
                            args.Add(new TokenExpression(DTokens.INVALID) { Location= la.Location, EndLocation=la.EndLocation });
                            break;
                        }

                        Lexer.PushLookAheadBackup();

                        bool wp = AllowWeakTypeParsing;
                        AllowWeakTypeParsing = true;

                        var typeArg = Type();

                        AllowWeakTypeParsing = wp;

                        if (typeArg != null && (laKind == CloseParenthesis || laKind==Comma)){
                            Lexer.PopLookAheadBackup();
                            args.Add(new TypeDeclarationExpression(typeArg));
                        }else
                        {
                            Lexer.RestoreLookAheadBackup();
                            args.Add(AssignExpression(Scope));
                        }
                    }
                }
                Expect(CloseParenthesis);
            }
            else
            {
                Step();

                /*
                 * TemplateSingleArgument:
                 *		Identifier
                 *		BasicTypeX
                 *		CharacterLiteral
                 *		StringLiteral
                 *		IntegerLiteral
                 *		FloatLiteral
                 *		true
                 *		false
                 *		null
                 *		__FILE__
                 *		__LINE__
                 */

                IExpression arg= null;

                if (t.Kind == Literal)
                    arg = new IdentifierExpression(t.LiteralFormat == LiteralFormat.StringLiteral ||
                                                   t.LiteralFormat == LiteralFormat.VerbatimStringLiteral ?
                                                   t.Value :
                                                   t.LiteralValue,
                                                   t.LiteralFormat,
                                                   t.Subformat)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };
                else if (t.Kind == Identifier)
                    arg = new IdentifierExpression(t.Value)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };
                else if (BasicTypes[t.Kind])
                    arg = new TypeDeclarationExpression(new DTokenDeclaration(t.Kind)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    });
                else if (
                    t.Kind == True ||
                    t.Kind == False ||
                    t.Kind == Null ||
                    t.Kind == __FILE__ ||
                    t.Kind == __LINE__)
                    arg = new TokenExpression(t.Kind)
                    {
                        Location = t.Location,
                        EndLocation = t.EndLocation
                    };
                else if (IsEOF)
                {
                    TrackerVariables.ExpectingIdentifier = false;
                    td.EndLocation = CodeLocation.Empty;
                    return td as TemplateInstanceExpression;
                }

                args.Add(arg);
            }
            (td as TemplateInstanceExpression).Arguments = args.ToArray();
            td.EndLocation = t.EndLocation;
            return td as TemplateInstanceExpression;
        }
예제 #38
0
        public static List<ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolutionContext ctxt, out bool hasNonFinalArgument)
        {
            hasNonFinalArgument = false;
            // 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.ResolveSingle(tde.Declaration, ctxt);

                        // Might be a simple symbol without any applied template arguments that is then passed to an template alias parameter
                        if (res == null && tde.Declaration is IdentifierDeclaration)
                            res = TypeDeclarationResolver.ResolveSingle(tde.Declaration as IdentifierDeclaration, ctxt, null, false);

                        var amb = res as AmbiguousType;
                        if (amb != null)
                        {
                            // Error
                            res = amb.Overloads[0];
                        }

                        var mr = res 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 ?? (ISemantic)mr);
                        }
                        else{
                            if(!hasNonFinalArgument)
                                hasNonFinalArgument = IsNonFinalArgument(res);
                            templateArguments.Add(res);
                        }
                    }
                    else
                    {
                        ISemantic v = Evaluation.EvaluateValue(arg, ctxt, true);
                        if (v is VariableValue)
                        {
                            var vv = v as VariableValue;
                            if (vv.Variable.IsConst && vv.Variable.Initializer != null)
                                v = Evaluation.EvaluateValue(vv, new StandardValueProvider(ctxt));
                        }
                        if(!hasNonFinalArgument)
                            hasNonFinalArgument = IsNonFinalArgument(v);
                        v = DResolver.StripValueTypeWrappers(v);
                        templateArguments.Add(v);
                    }
                }

            return templateArguments;
        }
예제 #39
0
 public AbstractType[] GetOverloads(TemplateInstanceExpression tix, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true)
 {
     return(GetOverloads(tix, ctxt, resultBases, deduceParameters));
 }
예제 #40
0
 public override void Visit(TemplateInstanceExpression x)
 {
     CallExpressionStack.Push(x);
     base.Visit(x);
     CallExpressionStack.Pop();
 }
예제 #41
0
 public override void Visit(TemplateInstanceExpression x)
 {
     CallExpressionStack.Push (x);
     base.Visit (x);
     CallExpressionStack.Pop ();
 }
예제 #42
0
        public static List <ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolutionContext ctxt, out bool hasNonFinalArgument)
        {
            hasNonFinalArgument = false;
            // 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);

                        // Might be a simple symbol without any applied template arguments that is then passed to an template alias parameter
                        if (res == null && tde.Declaration is IdentifierDeclaration)
                        {
                            res = TypeDeclarationResolver.Resolve(tde.Declaration as IdentifierDeclaration, ctxt, null, false);
                        }

                        if (ctxt.CheckForSingleResult(res, tde.Declaration) || (res != null && res.Length > 0))
                        {
                            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 ?? (ISemantic)mr);
                            }
                            else
                            {
                                if (!hasNonFinalArgument)
                                {
                                    hasNonFinalArgument = IsNonFinalArgument(res[0]);
                                }
                                templateArguments.Add(res[0]);
                            }
                        }
                    }
                    else
                    {
                        ISemantic v = Evaluation.EvaluateValue(arg, ctxt, true);
                        if (v is VariableValue)
                        {
                            var vv = v as VariableValue;
                            if (vv.Variable.IsConst && vv.Variable.Initializer != null)
                            {
                                v = Evaluation.EvaluateValue(vv, new StandardValueProvider(ctxt));
                            }
                        }
                        if (!hasNonFinalArgument)
                        {
                            hasNonFinalArgument = IsNonFinalArgument(v);
                        }
                        v = DResolver.StripValueTypeWrappers(v);
                        templateArguments.Add(v);
                    }
                }
            }

            return(templateArguments);
        }
        public static AbstractType EvalMethodCall(AbstractType[] baseExpression, ISymbolValue baseValue, TemplateInstanceExpression tix,
                                                  ResolutionContext ctxt,
                                                  PostfixExpression_MethodCall call, out List <ISemantic> callArguments, out ISymbolValue delegateValue,
                                                  bool returnBaseTypeOnly, AbstractSymbolValueProvider ValueProvider = null)
        {
            //TODO: Refactor this crap!

            delegateValue = null;
            callArguments = null;

            var methodOverloads = new List <AbstractType>();

            #region Search possible methods, opCalls or delegates that could be called
            bool requireStaticItems = true;             //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
            IEnumerable <AbstractType> scanResults = baseExpression;
            var nextResults = new List <AbstractType>();

            while (scanResults != null)
            {
                foreach (var b in scanResults)
                {
                    if (b is AmbiguousType)
                    {
                        nextResults.AddRange((b as AmbiguousType).Overloads);
                    }
                    else if (b is TemplateParameterSymbol)
                    {
                        nextResults.Add((b as TemplateParameterSymbol).Base);
                    }
                    else if (b is MemberSymbol)
                    {
                        var mr = (MemberSymbol)b;

                        if (mr.Definition is DMethod)
                        {
                            methodOverloads.Add(mr);
                            continue;
                        }
                        else if (mr.Definition is DVariable)
                        {
                            // If we've got a variable here, get its base type/value reference
                            if (ValueProvider != null)
                            {
                                var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

                                if (dgVal != null)
                                {
                                    nextResults.Add(dgVal.Definition);
                                    continue;
                                }
                                else
                                {
                                    ValueProvider.LogError(call, "Variable must be a delegate, not anything else");
                                    return(null);
                                }
                            }
                            else
                            {
                                var bt = mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt);

                                // Must be of type delegate
                                if (bt is DelegateType)
                                {
                                    var ret = HandleCallDelegateType(ValueProvider, bt as DelegateType, methodOverloads, returnBaseTypeOnly);
                                    if (ret is ISymbolValue)
                                    {
                                        delegateValue = ret as ISymbolValue;
                                        return(null);
                                    }
                                    else if (ret is AbstractType)
                                    {
                                        return(ret as AbstractType);
                                    }
                                }
                                else
                                {
                                    /*
                                     * If mr.Node is not a method, so e.g. if it's a variable
                                     * pointing to a delegate
                                     *
                                     * class Foo
                                     * {
                                     *	string opCall() {  return "asdf";  }
                                     * }
                                     *
                                     * Foo f=new Foo();
                                     * f(); -- calls opCall, opCall is not static
                                     */
                                    nextResults.Add(bt);
                                    requireStaticItems = false;
                                }
                                //TODO: Can other types work as function/are callable?
                            }
                        }
                    }
                    else if (b is DelegateType)
                    {
                        var ret = HandleCallDelegateType(ValueProvider, b as DelegateType, methodOverloads, returnBaseTypeOnly);
                        if (ret is ISymbolValue)
                        {
                            delegateValue = ret as ISymbolValue;
                            return(null);
                        }
                        else if (ret is AbstractType)
                        {
                            return(ret as AbstractType);
                        }
                    }
                    else if (b is ClassType || b is StructType)
                    {
                        var tit = (TemplateIntermediateType)b;

                        /*
                         * auto a = MyStruct(); -- opCall-Overloads can be used
                         */
                        var classDef = tit.Definition;

                        if (classDef == null)
                        {
                            continue;
                        }

                        foreach (var i in ExpressionTypeEvaluation.GetOpCalls(tit, requireStaticItems))
                        {
                            methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);
                        }

                        /*
                         * Every struct can contain a default ctor:
                         *
                         * struct S { int a; bool b; }
                         *
                         * auto s = S(1,true); -- ok
                         * auto s2= new S(2,false); -- error, no constructor found!
                         */
                        if (b is StructType && methodOverloads.Count == 0)
                        {
                            //TODO: Deduce parameters
                            return(b);
                        }
                    }

                    /*
                     * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
                     * child inside a template + that is named as the template.
                     */
                    else if (b is TemplateType)
                    {
                        methodOverloads.Add(b);
                    }
                    else if (b is PrimitiveType)                     // dmd 2.066: Uniform Construction Syntax. creal(3) is of type creal.
                    {
                        methodOverloads.Add(b);
                    }
                }

                scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
                nextResults.Clear();
            }
            #endregion

            if (methodOverloads.Count == 0)
            {
                return(null);
            }

            // Get all arguments' types
            callArguments = new List <ISemantic>();

            if (call.Arguments != null)
            {
                if (ValueProvider != null)
                {
                    foreach (var arg in call.Arguments)
                    {
                        callArguments.Add(arg != null ? Evaluation.EvaluateValue(arg, ValueProvider) : null);
                    }
                }
                else
                {
                    foreach (var arg in call.Arguments)
                    {
                        callArguments.Add(arg != null ? ExpressionTypeEvaluation.EvaluateType(arg, ctxt) : null);
                    }
                }
            }

            #region If explicit template type args were given, try to associate them with each overload
            if (tix != null)
            {
                var args             = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt);
                var deducedOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(methodOverloads, args, true, ctxt);
                methodOverloads.Clear();
                if (deducedOverloads != null)
                {
                    methodOverloads.AddRange(deducedOverloads);
                }
            }
            #endregion

            #region Filter by parameter-argument comparison
            var          argTypeFilteredOverloads   = new List <AbstractType>();
            bool         hasHandledUfcsResultBefore = false;
            AbstractType untemplatedMethodResult    = null;

            foreach (var ov in methodOverloads)
            {
                if (ov is MemberSymbol)
                {
                    HandleDMethodOverload(ctxt, ValueProvider != null, baseValue, callArguments, returnBaseTypeOnly, argTypeFilteredOverloads, ref hasHandledUfcsResultBefore,
                                          ov as MemberSymbol, ref untemplatedMethodResult);
                }
                else if (ov is DelegateType)
                {
                    var dg = ov as DelegateType;
                    var bt = dg.Base ?? TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

                    //TODO: Param-Arg check

                    if (returnBaseTypeOnly)
                    {
                        argTypeFilteredOverloads.Add(bt);
                    }
                    else
                    {
                        if (dg.Base == null)
                        {
                            if (dg.IsFunctionLiteral)
                            {
                                dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters);
                            }
                            else
                            {
                                dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as DelegateDeclaration, dg.Parameters);
                            }
                        }
                        argTypeFilteredOverloads.Add(new DelegateCallSymbol(dg, call));
                    }
                }
                else if (ov is PrimitiveType)                 // dmd 2.066: Uniform Construction Syntax. creal(3) is of type creal.
                {
                    if (ValueProvider != null)
                    {
                        if (callArguments == null || callArguments.Count != 1)
                        {
                            ValueProvider.LogError(call, "Uniform construction syntax expects exactly one argument");
                        }
                        else
                        {
                            var pv = callArguments[0] as PrimitiveValue;
                            if (pv == null)
                            {
                                ValueProvider.LogError(call, "Uniform construction syntax expects one built-in scalar value as first argument");
                            }
                            else
                            {
                                delegateValue = new PrimitiveValue(pv.Value, ov as PrimitiveType, pv.ImaginaryPart);
                            }
                        }
                    }

                    argTypeFilteredOverloads.Add(ov);
                }
            }

            // Prefer untemplated methods over templated ones
            if (untemplatedMethodResult != null)
            {
                return(untemplatedMethodResult);
            }
            #endregion

            return(AmbiguousType.Get(argTypeFilteredOverloads, tix));
        }
예제 #44
0
        public TemplateInstanceExpression TemplateInstance(IBlockNode Scope)
        {
            var loc = la.Location;

            var mod = INVALID;

            if (DTokens.IsStorageClass(laKind)) {
                mod = laKind;
                Step ();
            }

            if (!Expect (Identifier))
                return null;

            ITypeDeclaration td = new IdentifierDeclaration (t.Value) {
                Location = t.Location,
                EndLocation = t.EndLocation
            };

            td = new TemplateInstanceExpression(mod != DTokens.INVALID ? new MemberFunctionAttributeDecl(mod) { InnerType = td } : td) {
                Location = loc
            };

            var args = new List<IExpression>();

            if (!Expect(Not))
                return td as TemplateInstanceExpression;

            if (laKind == (OpenParenthesis))
            {
                Step();

                if (laKind != CloseParenthesis)
                {
                    bool init = true;
                    while (laKind == Comma || init)
                    {
                        if (!init) Step();
                        init = false;

                        if (laKind == CloseParenthesis)
                            break;

                        Lexer.PushLookAheadBackup();

                        bool wp = AllowWeakTypeParsing;
                        AllowWeakTypeParsing = true;

                        var typeArg = Type();

                        AllowWeakTypeParsing = wp;

                        if (typeArg != null && (laKind == CloseParenthesis || laKind==Comma)){
                            Lexer.PopLookAheadBackup();
                            args.Add(new TypeDeclarationExpression(typeArg));
                        }else
                        {
                            Lexer.RestoreLookAheadBackup();
                            args.Add(AssignExpression(Scope));
                        }
                    }
                }
                Expect(CloseParenthesis);
            }
            else
            {
                /*
                 * TemplateSingleArgument:
                 *		Identifier
                 *		BasicTypeX
                 *		CharacterLiteral
                 *		StringLiteral
                 *		IntegerLiteral
                 *		FloatLiteral
                 *		true
                 *		false
                 *		null
                 *		this
                *		__FILE__
                *		__MODULE__
                *		__LINE__
                *		__FUNCTION__
                *		__PRETTY_FUNCTION__
                 */

                switch (laKind)
                {
                    case Literal:
                    case True:
                    case False:
                    case Null:
                    case This:
                    case __FILE__:
                    case __MODULE__:
                    case __LINE__:
                    case __FUNCTION__:
                    case __PRETTY_FUNCTION__:
                        args.Add(PrimaryExpression(Scope));
                        break;
                    case Identifier:
                        Step();
                        args.Add(new IdentifierExpression(t.Value) {
                            Location = t.Location,
                            EndLocation = t.EndLocation
                        });
                        break;
                    default:
                        if (IsBasicType(laKind))
                        {
                            Step ();
                            args.Add (new TypeDeclarationExpression (new DTokenDeclaration (t.Kind) {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            }));
                            break;
                        }
                        else if (IsEOF)
                            goto case Literal;
                        SynErr(laKind, "Illegal token found on template instance expression argument");
                        Step();
                        break;
                }

                if (laKind == Not && Peek(1).Kind != Is && Peek(1).Kind != In)
                {
                    SynErr(laKind, "multiple ! arguments are not allowed");
                    Step();
                }
            }
            (td as TemplateInstanceExpression).Arguments = args.ToArray();
            td.EndLocation = t.EndLocation;
            return td as TemplateInstanceExpression;
        }
예제 #45
0
		public override void Visit (TemplateInstanceExpression x)
		{
			if (DoPrimaryIdCheck(x.TemplateIdHash))
				AddResult(x);

			base.Visit (x);
		}
		public void Visit(TemplateInstanceExpression tix)
		{
			res.IsTemplateInstanceArguments = true;

			res.MethodIdentifier = tix;
			ctxt.ContextIndependentOptions = ResolutionOptions.NoTemplateParameterDeduction;
			res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, null, false);

			if (tix.Arguments != null)
				res.CurrentlyTypedArgumentIndex = tix.Arguments.Length;
			else
				res.CurrentlyTypedArgumentIndex = 0;
		}
        bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r)
        {
            /*
             * TODO: Scan down r for having at least one templateinstanceexpression as declaration base.
             * If a tix was found, check if the definition of the respective result base level
             * and the un-aliased identifier of the 'tix' parameter match.
             * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes),
             * it is only important that the definition is inside this bundle.
             * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t!
             *
             * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME
             */
            var paramTix_TemplateMatchPossibilities = ResolveTemplateInstanceId(tix);
            TemplateIntermediateType tixBasedArgumentType = null;
            var r_ = r as DSymbol;
            while (r_ != null)
            {
                if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression)
                {
                    var tit = r_ as TemplateIntermediateType;
                    if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition))
                    {
                        tixBasedArgumentType = tit;
                        break;
                    }
                }

                r_ = r_.Base as DSymbol;
            }

            /*
             * This part is very tricky:
             * I still dunno what is allowed over here--
             *
             * class Foo(T:Bar!E[],E) {}
             * ...
             * Foo!(Bar!string[]) f; -- E will be 'string' then
             *
             * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar
             *		obviously is not a template instance expression - it's a normal identifier only.
             */
            if (tixBasedArgumentType != null)
            {
                var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator();

                foreach (var p in tix.Arguments)
                {
                    if (!argEnum_given.MoveNext() || argEnum_given.Current == null)
                        return false;

                    // Convert p to type declaration
                    var param_Expected = ConvertToTypeDeclarationRoughly(p);

                    if (param_Expected == null)
                        return false;

                    var result_Given = ExpressionTypeEvaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt);

                    if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given))
                        return false;
                }

                // Too many params passed..
                if (argEnum_given.MoveNext())
                    return false;

                return true;
            }

            return false;
        }
        void GetRawCallOverloads(PostfixExpression_MethodCall call, 
			out AbstractType[] baseExpression, 
			out ISymbolValue baseValue, 
			out TemplateInstanceExpression tix)
        {
            baseExpression = null;
            baseValue = null;
            tix = null;

            if (call.PostfixForeExpression is PostfixExpression_Access)
            {
                var pac = (PostfixExpression_Access)call.PostfixForeExpression;
                tix = pac.AccessExpression as TemplateInstanceExpression;

                var vs = E(pac, null, false, false);

                if (vs != null && vs.Length != 0)
                {
                    if (vs[0] is ISymbolValue)
                    {
                        baseValue = (ISymbolValue)vs[0];
                        baseExpression = new[] { baseValue.RepresentedType };
                    }
                    else if (vs[0] is InternalOverloadValue)
                        baseExpression = ((InternalOverloadValue)vs[0]).Overloads;
                    else
                        baseExpression = TypeDeclarationResolver.Convert(vs);
                }
            }
            else
            {
                // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one
                var optBackup = ctxt.CurrentContext.ContextDependentOptions;
                ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;

                if (call.PostfixForeExpression is TokenExpression)
                    baseExpression = GetResolvedConstructorOverloads((TokenExpression)call.PostfixForeExpression, ctxt);
                else if (eval)
                {
                    if (call.PostfixForeExpression is TemplateInstanceExpression)
                        baseValue = E(tix = call.PostfixForeExpression as TemplateInstanceExpression, false) as ISymbolValue;
                    else if (call.PostfixForeExpression is IdentifierExpression)
                        baseValue = E((IdentifierExpression)call.PostfixForeExpression, false) as ISymbolValue;
                    else
                        baseValue = E(call.PostfixForeExpression) as ISymbolValue;

                    if (baseValue is InternalOverloadValue)
                        baseExpression = ((InternalOverloadValue)baseValue).Overloads;
                    else if (baseValue != null)
                        baseExpression = new[] { baseValue.RepresentedType };
                    else baseExpression = null;
                }
                else
                {
                    if (call.PostfixForeExpression is TemplateInstanceExpression)
                        baseExpression = GetOverloads(tix = (TemplateInstanceExpression)call.PostfixForeExpression, null, false);
                    else if (call.PostfixForeExpression is IdentifierExpression)
                        baseExpression = GetOverloads(call.PostfixForeExpression as IdentifierExpression, deduceParameters:false);
                    else
                        baseExpression = new[] { AbstractType.Get(E(call.PostfixForeExpression)) };
                }

                ctxt.CurrentContext.ContextDependentOptions = optBackup;
            }
        }
        static void HandleTemplateInstance(TemplateInstanceExpression tix,
			ArgumentsResolutionResult res,
			IEditorData Editor,
			ResolutionContext ctxt,
			IBlockNode curBlock,
			IEnumerable<AbstractType> resultBases = null)
        {
            res.IsTemplateInstanceArguments = true;

            res.MethodIdentifier = tix;
            res.ResolvedTypesOrMethods = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, resultBases, false);

            if (tix.Arguments != null)
                res.CurrentlyTypedArgumentIndex = tix.Arguments.Length;
            else
                res.CurrentlyTypedArgumentIndex = 0;
        }
예제 #50
0
        void GetRawCallOverloads(PostfixExpression_MethodCall call,
                                 out AbstractType[] baseExpression,
                                 out ISymbolValue baseValue,
                                 out TemplateInstanceExpression tix)
        {
            baseExpression = null;
            baseValue      = null;
            tix            = null;

            if (call.PostfixForeExpression is PostfixExpression_Access)
            {
                var pac = (PostfixExpression_Access)call.PostfixForeExpression;
                tix = pac.AccessExpression as TemplateInstanceExpression;

                var vs = E(pac, null, false, false);

                if (vs != null && vs.Length != 0)
                {
                    if (vs[0] is ISymbolValue)
                    {
                        baseValue      = (ISymbolValue)vs[0];
                        baseExpression = new[] { baseValue.RepresentedType };
                    }
                    else if (vs[0] is InternalOverloadValue)
                    {
                        baseExpression = ((InternalOverloadValue)vs[0]).Overloads;
                    }
                    else
                    {
                        baseExpression = TypeDeclarationResolver.Convert(vs);
                    }
                }
            }
            else
            {
                // Explicitly don't resolve the methods' return types - it'll be done after filtering to e.g. resolve template types to the deduced one
                var optBackup = ctxt.CurrentContext.ContextDependentOptions;
                ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;

                if (call.PostfixForeExpression is TokenExpression)
                {
                    baseExpression = GetResolvedConstructorOverloads((TokenExpression)call.PostfixForeExpression, ctxt);
                }
                else if (eval)
                {
                    if (call.PostfixForeExpression is TemplateInstanceExpression)
                    {
                        baseValue = E(tix = call.PostfixForeExpression as TemplateInstanceExpression, false) as ISymbolValue;
                    }
                    else if (call.PostfixForeExpression is IdentifierExpression)
                    {
                        baseValue = E((IdentifierExpression)call.PostfixForeExpression, false) as ISymbolValue;
                    }
                    else
                    {
                        baseValue = E(call.PostfixForeExpression) as ISymbolValue;
                    }

                    if (baseValue is InternalOverloadValue)
                    {
                        baseExpression = ((InternalOverloadValue)baseValue).Overloads;
                    }
                    else if (baseValue != null)
                    {
                        baseExpression = new[] { baseValue.RepresentedType }
                    }
                    ;
                    else
                    {
                        baseExpression = null;
                    }
                }
                else
                {
                    if (call.PostfixForeExpression is TemplateInstanceExpression)
                    {
                        baseExpression = GetOverloads(tix = (TemplateInstanceExpression)call.PostfixForeExpression, null, false);
                    }
                    else if (call.PostfixForeExpression is IdentifierExpression)
                    {
                        baseExpression = GetOverloads((IdentifierExpression)call.PostfixForeExpression, false);
                    }
                    else
                    {
                        baseExpression = new[] { AbstractType.Get(E(call.PostfixForeExpression)) }
                    };
                }

                ctxt.CurrentContext.ContextDependentOptions = optBackup;
            }
        }
		public virtual void Visit(TemplateInstanceExpression x)
		{
			if (x.Identifier != null)
				x.Identifier.Accept(this);

			if (x.Arguments != null)
				foreach (var arg in x.Arguments)
					arg.Accept(this);
		}
예제 #52
0
 public AbstractType[] GetOverloads(TemplateInstanceExpression tix, IEnumerable<AbstractType> resultBases = null, bool deduceParameters = true)
 {
     return GetOverloads(tix, ctxt, resultBases, deduceParameters);
 }
예제 #53
0
        ITypeDeclaration QualifiedName()
        {
            ITypeDeclaration td = null;
            int n;

            while(PeekIsDecNumber)
            {
                // Read number of either the first LName or TemplateInstanceName
                n = (int)Number();
                sb.Clear();
                if((char)r.Peek() == '_')
                {
                    r.Read();
                    sb.Append('_');
                    if((char)r.Peek() == '_')
                    {
                        r.Read();
                        sb.Append('_');
                        if((char)r.Peek() == 'T')
                        {
                            r.Read();
                            // We've got to handle a Template instance:
                            // Number __T LName TemplateArgs Z
                            var tpi = new TemplateInstanceExpression(new IdentifierDeclaration(LName()));

                            tpi.InnerDeclaration = td;
                            td = tpi;

                            var xx = new List<IExpression>();
                            while(r.Peek() != -1)
                            {
                                var arg = TemplateArg();
                                if(arg == null)
                                    break;
                                xx.Add(arg);
                            }
                            tpi.Arguments = xx.ToArray();
                            continue;
                        }
                    }
                }

                // Just an LName
                if(n > sb.Length)
                    sb.Append(LName(n-sb.Length));

                var ttd = new IdentifierDeclaration(sb.ToString());
                ttd.InnerDeclaration = td;
                td = ttd;
            }

            return td;
        }
예제 #54
0
        public static AbstractType[] EvalAndFilterOverloads(IEnumerable<AbstractType> rawOverloadList,
			TemplateInstanceExpression templateInstanceExpr,
			ResolverContextStack ctxt)
        {
            return EvalAndFilterOverloads(rawOverloadList, PreResolveTemplateArgs(templateInstanceExpr, ctxt), false, ctxt);
        }