public static string EvaluateMixinExpressionContent(AbstractSymbolValueProvider vp,MixinExpression x)
        {
            var ev = new Evaluation(vp);
            ev.resolveConstOnly = true;

            var v = x.AssignExpression != null ? x.AssignExpression.Accept(ev) as ArrayValue : null;

            return v != null && v.IsString ? v.StringValue : null;
        }
Esempio n. 2
0
        public static AbstractType EvaluateType(IExpression x, ResolutionContext ctxt)
        {
            var ev = new Evaluation(ctxt);
            ISemantic t = null;
            if(!Debugger.IsAttached)
                try { t = ev.E(x); }
                catch { }
            else
                t = ev.E(x);

            return AbstractType.Get(t);
        }
Esempio n. 3
0
        public override ISymbolValue this[DVariable n]
        {
            get
            {
                if (n == null)
                {
                    return(new ErrorValue(new EvaluationException("There must be a valid variable node given in order to retrieve its value")));
                }

                if (n.IsConst)
                {
                    if (varsBeingResolved.Contains(n))
                    {
                        return(new ErrorValue(new EvaluationException("Cannot reference itself")));
                    }
                    varsBeingResolved.Add(n);
                    // .. resolve it's pre-compile time value and make the returned value the given argument
                    ISymbolValue val;
                    try{
                        val = Evaluation.EvaluateValue(n.Initializer, this);
                    }
                    finally{
                        varsBeingResolved.Remove(n);
                    }

                    // If it's null, then the initializer is null - which is equal to e.g. 0 or null !;

                    if (val != null)
                    {
                        return(val);
                    }
                }

                return(new ErrorValue(new EvaluationException(n + " must have a constant initializer")));
            }
            set
            {
                throw new NotImplementedException();
            }
        }
Esempio n. 4
0
        public AbstractType Visit(MixinExpression x)
        {
            var s = Evaluation.EvaluateMixinExpressionContent(ctxt, x);

            if (s == null)
            {
                EvalError(new InvalidStringException(x));
                return(null);
            }

            // Parse it as an expression
            var ex = DParser.ParseAssignExpression(s);

            if (ex == null)
            {
                EvalError(new EvaluationException(x, "Invalid expression code given"));
                return(null);
            }
            //TODO: Excessive caching
            // Evaluate the expression's type/value
            return(ex.Accept(this));
        }
Esempio n. 5
0
 public static AbstractType[] TryGetUnfilteredMethodOverloads(IExpression foreExpression, ResolverContextStack ctxt, IExpression supExpression = null)
 {
     if (foreExpression is TemplateInstanceExpression)
     {
         return(Evaluation.GetOverloads((TemplateInstanceExpression)foreExpression, ctxt, null));
     }
     else if (foreExpression is IdentifierExpression)
     {
         return(Evaluation.GetOverloads((IdentifierExpression)foreExpression, ctxt));
     }
     else if (foreExpression is PostfixExpression_Access)
     {
         bool ufcs = false;                 // TODO?
         return(Evaluation.GetAccessedOverloads((PostfixExpression_Access)foreExpression, ctxt, out ufcs, null, false));
     }
     else if (foreExpression is TokenExpression)
     {
         return(GetResolvedConstructorOverloads((TokenExpression)foreExpression, ctxt));
     }
     else
     {
         return new[] { Evaluation.EvaluateType(foreExpression, ctxt) }
     };
 }
        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));
        }
Esempio n. 7
0
        public AbstractType Visit(PostfixExpression_Index x)
        {
            var foreExpression = EvalForeExpression(x);

            // myArray[0]; myArray[0..5];
            // opIndex/opSlice ?
            if (foreExpression is MemberSymbol)
            {
                foreExpression = DResolver.StripMemberSymbols(foreExpression);
            }

            var udt = foreExpression as UserDefinedType;

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

                var overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(OpIndexIdHash, AmbiguousType.TryDissolve(foreExpression), ctxt, x, false);
                if (overloads != null && overloads.Length > 0)
                {
                    var indexArgs = x.Arguments != null ? new AbstractType[x.Arguments.Length] : null;
                    for (int i = 0; i < indexArgs.Length; i++)
                    {
                        if (x.Arguments[i] != null)
                        {
                            indexArgs[i] = x.Arguments[i].Accept(this);
                        }
                    }

                    overloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(overloads, indexArgs, true, ctxt);
                    ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt);
                    return(TryPretendMethodExecution(AmbiguousType.Get(overloads, x), x, indexArgs));
                }
                ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(udt);

                if (foreExpression is TemplateIntermediateType)
                {                //TODO: Proper resolution of alias this declarations
                    var tit = foreExpression as TemplateIntermediateType;
                    var ch  = tit.Definition[DVariable.AliasThisIdentifierHash];
                    if (ch != null)
                    {
                        foreach (DVariable aliasThis in ch)
                        {
                            foreExpression = TypeDeclarationResolver.HandleNodeMatch(aliasThis, ctxt, foreExpression);
                            if (foreExpression != null)
                            {
                                break;                                 // HACK: Just omit other alias this' to have a quick run-through
                            }
                        }
                    }

                    if (foreExpression == null)
                    {
                        return(tit);
                    }
                }
            }

            foreExpression = DResolver.StripMemberSymbols(foreExpression);

            if (foreExpression is AssocArrayType)
            {
                var ar = foreExpression as AssocArrayType;

                /*
                 * myType_Array[0] -- returns TypeResult myType
                 * return the value type of a given array result
                 */
                //TODO: Handle opIndex overloads
                if (ar.ValueType != null)
                {
                    ar.ValueType.NonStaticAccess = true;
                }

                return(new ArrayAccessSymbol(x, ar.ValueType));
            }

            /*
             * int* a = new int[10];
             *
             * a[0] = 12;
             */
            else if (foreExpression is PointerType)
            {
                var b = (foreExpression as PointerType).Base;
                if (b != null)
                {
                    b.NonStaticAccess = true;
                }
                return(b);
            }
            //return new ArrayAccessSymbol(x,((PointerType)foreExpression).Base);

            else if (foreExpression is DTuple)
            {
                var tt = foreExpression as DTuple;

                if (x.Arguments != null && x.Arguments.Length != 0)
                {
                    var idx = Evaluation.EvaluateValue(x.Arguments[0], ctxt) as PrimitiveValue;

                    if (tt.Items == null)
                    {
                        ctxt.LogError(tt.DeclarationOrExpressionBase, "No items in Type tuple");
                    }
                    else if (idx == null || !DTokens.IsBasicType_Integral(idx.BaseTypeToken))
                    {
                        ctxt.LogError(x.Arguments[0], "Index expression must evaluate to integer value");
                    }
                    else if (idx.Value > (decimal)Int32.MaxValue ||
                             (int)idx.Value >= tt.Items.Length || idx.Value < 0m)
                    {
                        ctxt.LogError(x.Arguments[0], "Index number must be a value between 0 and " + tt.Items.Length);
                    }
                    else
                    {
                        return(AbstractType.Get(tt.Items[(int)idx.Value]));
                    }
                }
            }

            ctxt.LogError(x, "No matching base type for indexing operation");
            return(null);
        }
Esempio n. 8
0
 public AbstractType Visit(PostfixExpression_Access ex)
 {
     return(TryPretendMethodExecution(AmbiguousType.Get(Evaluation.EvalPostfixAccessExpression(this, ctxt, ex))));
 }
Esempio n. 9
0
 public static AbstractType[] GetAccessedOverloads(PostfixExpression_Access acc, ResolutionContext ctxt,
                                                   ISemantic resultBase = null, bool DeducePostfixTemplateParams = true)
 {
     return(Evaluation.EvalPostfixAccessExpression <AbstractType>(new ExpressionTypeEvaluation(ctxt), ctxt, acc, resultBase, DeducePostfixTemplateParams));
 }
Esempio n. 10
0
 ArrayType GetStringType(LiteralSubformat fmt = LiteralSubformat.Utf8)
 {
     return(Evaluation.GetStringType(ctxt, fmt));
 }
Esempio n. 11
0
        public AbstractType Visit(TraitsExpression te)
        {
            PostfixExpression_Access pfa;
            AbstractType             t;
            ResolutionOptions        optionsBackup;

            switch (te.Keyword)
            {
            case "":
            case null:
                return(null);

            case "identifier":
                return(GetStringType());

            case "getMember":
                pfa = prepareMemberTraitExpression(te, out t);

                if (pfa == null || t == null)
                {
                    break;
                }

                var vs = Evaluation.EvalPostfixAccessExpression(this, ctxt, pfa, t);
                if (vs == null || vs.Length == 0)
                {
                    return(null);
                }
                return(vs[0]);


            case "getOverloads":
                optionsBackup = ctxt.ContextIndependentOptions;
                ctxt.ContextIndependentOptions = ResolutionOptions.IgnoreAllProtectionAttributes;

                pfa = prepareMemberTraitExpression(te, out t);

                if (pfa != null && t != null)
                {
                    vs = Evaluation.EvalPostfixAccessExpression(this, ctxt, pfa, t);
                }
                else
                {
                    vs = null;
                }

                ctxt.ContextIndependentOptions = optionsBackup;

                return(new DTuple(te, vs));


            case "getProtection":
                return(GetStringType());

            case "getVirtualFunctions":
                break;

            case "getVirtualMethods":
                break;

            case "parent":
                break;

            case "classInstanceSize":
                break;

            case "allMembers":
                break;

            case "derivedMembers":
                break;

            case "compiles":
                return(new PrimitiveType(DTokens.Bool));
            }

            if (te.Keyword.StartsWith("is") || te.Keyword.StartsWith("has"))
            {
                return(new PrimitiveType(DTokens.Bool));
            }

            return(null);
        }
Esempio n. 12
0
 public AbstractType Visit(ImportExpression x)
 {
     return(Evaluation.GetStringType(ctxt));
 }
Esempio n. 13
0
        /// <summary>
        /// Since most expressions should return a single type only, it's not needed to use this function unless you might
        /// want to pay attention on (illegal) multiple overloads.
        /// </summary>
        public static AbstractType[] EvaluateTypes(IExpression x, ResolutionContext ctxt)
        {
            var ev = new Evaluation(ctxt);
            ISemantic t = null;
            if(!Debugger.IsAttached)
                try { t = ev.E(x); }
                catch { }
            else
                t = ev.E(x);

            if (t is InternalOverloadValue)
                return ((InternalOverloadValue)t).Overloads;

            return t == null ? null : new[]{ AbstractType.Get(t) };
        }
Esempio n. 14
0
        public static ISymbolValue EvaluateValue(IExpression x, AbstractSymbolValueProvider vp)
        {
            if (vp == null)
                vp = new StandardValueProvider(null);

            var ev = new Evaluation(vp);

            var v = ev.E(x) as ISymbolValue;

            if(v == null && ev.Errors.Count != 0)
                return new ErrorValue(ev.Errors.ToArray());

            return v;
        }
Esempio n. 15
0
        public AbstractType Visit(PostfixExpression_Index x)
        {
            var foreExpression = EvalForeExpression(x);

            // myArray[0]; myArray[0..5];
            // opIndex/opSlice ?
            if (foreExpression is MemberSymbol)
            {
                foreExpression = DResolver.StripMemberSymbols(foreExpression);
            }

            foreExpression = DResolver.StripMemberSymbols(foreExpression);

            if (foreExpression is AssocArrayType)
            {
                var ar = foreExpression as AssocArrayType;

                /*
                 * myType_Array[0] -- returns TypeResult myType
                 * return the value type of a given array result
                 */
                //TODO: Handle opIndex overloads

                return(new ArrayAccessSymbol(x, ar.ValueType));
            }

            /*
             * int* a = new int[10];
             *
             * a[0] = 12;
             */
            else if (foreExpression is PointerType)
            {
                return((foreExpression as PointerType).Base);
            }
            //return new ArrayAccessSymbol(x,((PointerType)foreExpression).Base);

            else if (foreExpression is DTuple)
            {
                var tt = foreExpression as DTuple;

                if (x.Arguments != null && x.Arguments.Length != 0)
                {
                    var idx = Evaluation.EvaluateValue(x.Arguments[0], ctxt) as PrimitiveValue;

                    if (tt.Items == null)
                    {
                        ctxt.LogError(tt.DeclarationOrExpressionBase, "No items in Type tuple");
                    }
                    else if (idx == null || !DTokens.IsBasicType_Integral(idx.BaseTypeToken))
                    {
                        ctxt.LogError(x.Arguments[0], "Index expression must evaluate to integer value");
                    }
                    else if (idx.Value > (decimal)Int32.MaxValue ||
                             (int)idx.Value >= tt.Items.Length || idx.Value < 0m)
                    {
                        ctxt.LogError(x.Arguments[0], "Index number must be a value between 0 and " + tt.Items.Length);
                    }
                    else
                    {
                        return(AbstractType.Get(tt.Items[(int)idx.Value]));
                    }
                }
            }

            ctxt.LogError(new ResolutionError(x, "Invalid base type for index expression"));
            return(null);
        }