コード例 #1
0
        public override Expression DoResolve(ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }

            expr = expr.DoResolve(rc);
            if (expr == null)
            {
                return(null);
            }

            var pc = expr.Type as PointerTypeSpec;

            if (pc == null)
            {
                rc.Report.Error(0, loc, "The * or -> operator must be applied to a pointer");
                return(null);
            }

            ResolvedType = pc.ElementType;

            if (ResolvedType.Kind == TypeKind.Void)
            {
                rc.Report.Error(0, loc, "The operation in question is undefined on void pointers");
                return(null);
            }

            eclass = ExprClass.Variable;
            return(this);
        }
コード例 #2
0
        public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }

            ResolveContext oldResolver = rc;

            try
            {
                rc   = rc.WithCheckForOverflow(true);
                Expr = Expr.DoResolve(rc);
            }
            finally
            {
                rc = oldResolver;
            }


            if (Expr == null)
            {
                return(null);
            }

            //TODO:Anonymous
            if (Expr is Constant || Expr is MethodGroupExpression || /*Expr is AnonymousMethodExpression ||*/ Expr is DefaultValueExpression)
            {
                return(Expr);
            }
            eclass       = Expr.eclass;
            ResolvedType = Expr.Type;
            _resolved    = true;
            return(this);
        }
コード例 #3
0
        public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            UnaryOperatorType op = UnaryOperatorType.PostIncrement;

            if (mode == Mode.PreIncrement)
            {
                op = UnaryOperatorType.PreIncrement;
            }
            else if (mode == Mode.PreDecrement)
            {
                op = UnaryOperatorType.Decrement;
            }
            else if (mode == Mode.PostDecrement)
            {
                op = UnaryOperatorType.PostDecrement;
            }

            expr = expr.DoResolve(rc);
            if (expr == null)
            {
                return(null);
            }

            // ++/-- on pointer variables of all types except void*
            if (expr.Type is PointerTypeSpec)
            {
                if (((PointerTypeSpec)expr.Type).ElementType.Kind == TypeKind.Void)
                {
                    rc.Report.Error(0, loc, "The operation in question is undefined on void pointers");
                    return(null);
                }
            }
            if (expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess)
            {
                expr = expr.DoResolveLeftValue(rc, expr);
            }
            else
            {
                rc.Report.Error(0, loc, "The operand of an increment or decrement operator must be a variable, property or indexer");
            }

            operation = new UnaryExpression(op, expr, loc).DoResolve(rc);
            if (operation == null)
            {
                return(null);
            }



            _resolved    = true;
            ResolvedType = operation.Type;
            eclass       = ExprClass.Value;
            return(this);
        }
コード例 #4
0
        public override Expression Resolve(ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }
            else
            {
                Expression    targetRR = expr.DoResolve(rc);
                IList <IType> typeArgs = typeArgumentsrefs.Resolve(rc.CurrentTypeResolveContext);
                if (LookForAttribute)
                {
                    var wa = ResolveMemberAccess(rc, targetRR, name + "Attribute", typeArgs, lookupMode);
                    if (wa == null || wa.IsError)
                    {
                        wa = ResolveMemberAccess(rc, targetRR, name, typeArgs, lookupMode);
                        if (wa == null || wa.IsError)
                        {
                            rc.Report.Error(148, loc, "Type `{0}' does not contain a definition for `{1}' and no extension method `{1}' of type `{0}' could be found.", expr.GetSignatureForError(), GetSignatureForError());
                        }
                    }
                    LookForAttribute = false;
                    return(wa);
                }
                else
                {
                    var wa = ResolveMemberAccess(rc, targetRR, name, typeArgs, lookupMode);
                    if (wa == null || wa.IsError)
                    {
                        rc.Report.Error(148, loc, "Type `{0}' does not contain a definition for `{1}' and no extension method `{1}' of type `{0}' could be found.", expr.GetSignatureForError(), GetSignatureForError());
                    }

                    return(wa);
                }
            }
        }
コード例 #5
0
ファイル: StackAlloc.cs プロジェクト: Arsslensoft/VSharp
        public override Expression DoResolve(ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }

            count = count.DoResolve(rc);
            if (count == null)
            {
                return(null);
            }

            if (!count.Type.IsKnownType(KnownTypeCode.UInt32))
            {
                count = new CastExpression(KnownTypeReference.UInt32.Resolve(rc), count).DoResolve(rc);
                if (count == null)
                {
                    return(null);
                }
            }

            Constant c = count as Constant;

            if (c != null && c.IsNegative)
            {
                rc.Report.Error(0, loc, "Cannot use a negative size with stackalloc");
            }


            if (rc.HasAny(ResolveContext.Options.CatchScope | ResolveContext.Options.FinallyScope))
            {
                rc.Report.Error(0, loc, "Cannot use stackalloc in finally or catch");
            }


            otype = texpr.ResolveAsType(rc);
            if (otype == null)
            {
                return(null);
            }

            ResolvedType = new PointerTypeSpec(otype);
            _resolved    = true;
            eclass       = ExprClass.Value;

            return(this);
        }
コード例 #6
0
        public override Expression DoResolve(ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }
            expr = expr.DoResolve(rc);
            if (expr == null)
            {
                return(null);
            }

            ResolvedType = expr.Type;
            _resolved    = true;
            eclass       = expr.eclass;
            return(this);
        }
コード例 #7
0
ファイル: Argument.cs プロジェクト: Arsslensoft/VSharp
        public void Resolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            // Verify that the argument is readable
            if (ArgType != AType.Out)
            {
                Expr = Expr.DoResolve(rc);
            }

            // Verify that the argument is writeable
            if (Expr != null && IsByRef)
            {
                Expr = Expr.DoResolveLeftValue(rc, EmptyExpression.OutAccess);
            }

            if (Expr == null)
            {
                Expr = Expression.ErrorResult;
            }
        }
コード例 #8
0
ファイル: ArrayCreation.cs プロジェクト: Arsslensoft/VSharp
        protected virtual Expression ResolveArrayElement(ResolveContext ec, Expression element)
        {
            element = element.DoResolve(ec);
            if (element == null)
            {
                return(null);
            }

            if (element is CompoundAssign.TargetExpression)
            {
                if (first_emit != null)
                {
                    throw new InternalErrorException("Can only handle one mutator at a time");
                }
                first_emit = element;
                element    = first_emit_temp = new LocalTemporary(element.Type);
            }

            return(new CastExpression(array_element_type, element, loc).DoResolve(ec));
        }
コード例 #9
0
ファイル: ElementAccess.cs プロジェクト: Arsslensoft/VSharp
        //
        // We perform some simple tests, and then to "split" the emit and store
        // code we create an instance of a different class, and return that.
        //
        Expression ResolveAccessExpression(ResolveContext rc, bool conditionalAccessReceiver)
        {
            Expr = Expr.DoResolve(rc);
            if (Expr == null)
            {
                return(null);
            }

            ResolvedType = Expr.Type;

            if (ConditionalAccess && !IsNullPropagatingValid(ResolvedType))
            {
                rc.Report.Error(0, loc, "The `{0}' operator cannot be applied to operand of type `{1}'",
                                "?", ResolvedType.ToString());
                return(null);
            }
            string[]     argumentNames;
            Expression[] arguments = Arguments.GetArguments(out argumentNames);

            return(ResolveIndexer(rc, Expr, arguments, argumentNames));
        }
コード例 #10
0
        public override Expression DoResolve(ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }

            Expr = Expr.DoResolve(rc);
            if (Expr == null)
            {
                return(null);
            }
            ITypeDefinition inputTypeDef = Expr.Type.GetDefinition();

            if (Expr.IsCompileTimeConstant && Expr is Constant && inputTypeDef != null)
            {
                // Special cases for int.MinValue and long.MinValue
                if (inputTypeDef.KnownTypeCode == KnownTypeCode.UInt32 && 2147483648.Equals(Expr.ConstantValue))
                {
                    return(Constant.CreateConstantFromValue(rc, rc.Compilation.FindType(KnownTypeCode.Int32), -2147483648, Expr.Location));
                }
                else if (inputTypeDef.KnownTypeCode == KnownTypeCode.UInt64 && 9223372036854775808.Equals(Expr.ConstantValue))
                {
                    return(Constant.CreateConstantFromValue(rc, rc.Compilation.FindType(KnownTypeCode.Int64), -9223372036854775808, Expr.Location));
                }
            }
            Expression rr = ResolveUnaryOperator(rc, Oper, Expr);

            if (rr.IsError)
            {
                rc.Report.Error(0, loc, "The `{0}' operator cannot be applied to operand of type `{1}'",
                                OperName(Oper), rr.Type.ToString());
                return(null);
            }
            rr.eclass = ExprClass.Value;
            _resolved = true;

            return(rr);
        }
コード例 #11
0
        public override Expression DoResolve(ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }
            left  = left.DoResolve(rc);
            right = right.DoResolve(rc);
            if (left == null || right == null)
            {
                return(null);
            }
            Expression expr = ResolveBinaryOperator(rc, oper, left, right);

            if (expr == null)
            {
                rc.Report.Error(0, loc, "Operator `{0}' cannot be applied to operands of type `{1}' and `{2}'",
                                OperName(oper), left.Type.ToString(), right.Type.ToString());
                return(null);
            }
            expr.eclass = ExprClass.Value;
            return(expr);
        }
コード例 #12
0
ファイル: ProbeExpression.cs プロジェクト: Arsslensoft/VSharp
        protected Expression ResolveCommon(ResolveContext rc)
        {
            expr = expr.DoResolve(rc);
            if (expr == null)
            {
                return(null);
            }

            ResolveProbeType(rc);
            if (probe_type_expr == null)
            {
                return(this);
            }

            if (rc.IsStaticType(probe_type_expr))
            {
                rc.Report.Error(250, loc, "The second operand of `is' or `as' operator cannot be static type `{0}'",
                                probe_type_expr.ToString());
                return(null);
            }

            if (expr.Type is PointerTypeSpec || probe_type_expr is PointerTypeSpec)
            {
                rc.Report.Error(251, loc, "The `{0}' operator cannot be applied to an operand of pointer type",
                                OperatorName);
                return(null);
            }
            //TODO:Method Group type & anonymous method type
            if (/*expr.Type == InternalType.AnonymousMethod ||*/ expr is MethodGroupExpression)
            {
                rc.Report.Error(837, loc, "The `{0}' operator cannot be applied to a lambda expression, anonymous method, or method group",
                                OperatorName);
                return(null);
            }

            return(this);
        }
コード例 #13
0
ファイル: ArrayCreation.cs プロジェクト: Arsslensoft/VSharp
        bool CheckIndices(ResolveContext ec, ArrayInitializer probe, int idx, bool specified_dims, int child_bounds)
        {
            if (initializers != null && bounds == null)
            {
                //
                // We use this to store all the data values in the order in which we
                // will need to store them in the byte blob later
                //
                array_data = new List <Expression>(probe.Count);
                bounds     = new Dictionary <int, int>();
            }

            if (specified_dims)
            {
                Expression a = arguments[idx];
                a = a.DoResolve(ec);
                if (a == null)
                {
                    return(false);
                }

                a = ConvertExpressionToArrayIndex(ec, a);
                if (a == null)
                {
                    return(false);
                }

                arguments[idx] = a;

                if (initializers != null)
                {
                    Constant c = a as Constant;
                    if (c == null && a is CastExpression)
                    {
                        c = ((CastExpression)a).Expr as Constant;
                    }

                    if (c == null)
                    {
                        ec.Report.Error(0, a.Location, "A constant value is expected");
                        return(false);
                    }

                    int value;
                    try
                    {
                        value = System.Convert.ToInt32(c.GetValue());
                    }
                    catch
                    {
                        ec.Report.Error(0, a.Location, "A constant value is expected");
                        return(false);
                    }

                    // TODO: probe.Count does not fit ulong in
                    if (value != probe.Count)
                    {
                        ec.Report.Error(0, loc, "An array initializer of length `{0}' was expected", value.ToString());
                        return(false);
                    }

                    bounds[idx] = value;
                }
            }

            if (initializers == null)
            {
                return(true);
            }

            for (int i = 0; i < probe.Count; ++i)
            {
                var o = probe[i];
                if (o is ArrayInitializer)
                {
                    var sub_probe = o as ArrayInitializer;
                    if (idx + 1 >= dimensions)
                    {
                        ec.Report.Error(0, loc, "Array initializers can only be used in a variable or field initializer. Try using a new expression instead");
                        return(false);
                    }

                    // When we don't have explicitly specified dimensions, record whatever dimension we first encounter at each level
                    if (!bounds.ContainsKey(idx + 1))
                    {
                        bounds[idx + 1] = sub_probe.Count;
                    }

                    if (bounds[idx + 1] != sub_probe.Count)
                    {
                        ec.Report.Error(0, sub_probe.Location, "An array initializer of length `{0}' was expected", bounds[idx + 1].ToString());
                        return(false);
                    }

                    bool ret = CheckIndices(ec, sub_probe, idx + 1, specified_dims, child_bounds - 1);
                    if (!ret)
                    {
                        return(false);
                    }
                }
                else if (child_bounds > 1)
                {
                    ec.Report.Error(0, o.Location, "A nested array initializer was expected");
                }
                else
                {
                    Expression element = ResolveArrayElement(ec, o);
                    if (element == null)
                    {
                        continue;
                    }
                    array_data.Add(element);
                }
            }

            return(true);
        }
コード例 #14
0
        public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            List <string> element_names = null;

            for (int i = 0; i < initializers.Count; ++i)
            {
                Expression         initializer         = initializers[i];
                ElementInitializer element_initializer = initializer as ElementInitializer;

                if (i == 0)
                {
                    if (element_initializer != null)
                    {
                        element_names = new List <string>(initializers.Count);
                        element_names.Add(element_initializer.Name);
                    }
                    //else if (initializer is CompletingExpression)//TODO:Add complete
                    //{
                    //    initializer.Resolve(ec);
                    //    throw new InternalErrorException("This line should never be reached");
                    //}
                    else
                    {
                        var t = rc.CurrentObjectInitializerType;
                        // LAMESPEC: The collection must implement IEnumerable only, no dynamic support
                        if (!t.Implements(KnownTypeReference.IEnumerable.Resolve(rc)))
                        {
                            rc.Report.Error(0, loc, "A field or property `{0}' cannot be initialized with a collection " +
                                            "object initializer because type `{1}' does not implement `{2}' interface",
                                            rc.CurrentObjectInitializer.GetSignatureForError(),
                                            rc.CurrentObjectInitializerType.ToString(),
                                            KnownTypeReference.IEnumerable.ToString());
                            return(null);
                        }
                        is_collection_initialization = true;
                    }
                }
                else
                {
                    if (is_collection_initialization != (element_initializer == null))
                    {
                        rc.Report.Error(0, initializer.Location, "Inconsistent `{0}' member declaration",
                                        is_collection_initialization ? "collection initializer" : "object initializer");
                        continue;
                    }

                    if (!is_collection_initialization)
                    {
                        if (element_names.Contains(element_initializer.Name))
                        {
                            rc.Report.Error(0, element_initializer.Location,
                                            "An object initializer includes more than one member `{0}' initialization",
                                            element_initializer.Name);
                        }
                        else
                        {
                            element_names.Add(element_initializer.Name);
                        }
                    }
                }

                Expression e = initializer.DoResolve(rc);
                if (e == EmptyExpressionStatement.Instance)
                {
                    initializers.RemoveAt(i--);
                }
                else
                {
                    initializers[i] = e;
                }
            }

            ResolvedType = rc.CurrentObjectInitializerType;
            if (is_collection_initialization)
            {
                if (ResolvedType is ElementTypeSpec)
                {
                    rc.Report.Error(0, loc, "Cannot initialize object of type `{0}' with a collection initializer",
                                    ResolvedType.ToString());
                }
            }

            eclass = ExprClass.Variable;
            return(this);
        }
コード例 #15
0
        public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            expr       = expr.DoResolve(rc);
            true_expr  = true_expr.DoResolve(rc);
            false_expr = false_expr.DoResolve(rc);

            if (true_expr == null || false_expr == null || expr == null)
            {
                return(null);
            }

            eclass = ExprClass.Value;


            // V# 4.0 spec §7.14: Conditional operator

            bool  isValid;
            IType resultType;

            if (true_expr.Type.Kind == TypeKind.Dynamic || false_expr.Type.Kind == TypeKind.Dynamic)
            {
                resultType = SpecialTypeSpec.Dynamic;
                isValid    = rc.TryConvert(ref true_expr, resultType) & rc.TryConvert(ref false_expr, resultType);
            }
            else if (rc.HasType(true_expr) && rc.HasType(false_expr))
            {
                Conversion t2f = rc.conversions.ImplicitConversion(true_expr, false_expr.Type);
                Conversion f2t = rc.conversions.ImplicitConversion(false_expr, true_expr.Type);
                // The operator is valid:
                // a) if there's a conversion in one direction but not the other
                // b) if there are conversions in both directions, and the types are equivalent
                if (rc.IsBetterConditionalConversion(t2f, f2t))
                {
                    resultType = false_expr.Type;
                    isValid    = true;
                    true_expr  = rc.Convert(true_expr, resultType, t2f);
                }
                else if (rc.IsBetterConditionalConversion(f2t, t2f))
                {
                    resultType = true_expr.Type;
                    isValid    = true;
                    false_expr = rc.Convert(false_expr, resultType, f2t);
                }
                else
                {
                    resultType = true_expr.Type;
                    isValid    = true_expr.Type.Equals(false_expr.Type);
                    if (!isValid)
                    {
                        _resolved    = true;
                        ResolvedType = resultType;
                        rc.Report.Error(248, true_expr.Location,
                                        "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other",
                                        true_expr.Type.ToString(), false_expr.Type.ToString());
                        return(this);
                    }
                }
            }
            else if (rc.HasType(true_expr))
            {
                resultType = true_expr.Type;
                isValid    = rc.TryConvert(ref false_expr, resultType);
            }
            else if (rc.HasType(false_expr))
            {
                resultType = false_expr.Type;
                isValid    = rc.TryConvert(ref true_expr, resultType);
            }
            else
            {
                return(ErrorResult);
            }
            expr = rc.ResolveCondition(expr);
            if (isValid)
            {
                if (expr.IsCompileTimeConstant && true_expr.IsCompileTimeConstant && false_expr.IsCompileTimeConstant)
                {
                    bool?val = expr.ConstantValue as bool?;
                    if (val == true)
                    {
                        return(true_expr);
                    }
                    else if (val == false)
                    {
                        return(false_expr);
                    }
                }
                _resolved         = true;
                this.ResolvedType = resultType;
                return(this);
            }
            else
            {
                rc.Report.Error(249, true_expr.Location,
                                "Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'",
                                true_expr.Type.ToString(), false_expr.Type.ToString());
            }

            return(this);
        }