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);
        }
Exemple #2
0
        public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            if (_resolved)
            {
                return(this);
            }
            if (source == null)
            {
                return(EmptyExpressionStatement.Instance);
            }

            if (!ResolveElement(rc))
            {
                return(null);
            }

            if (source is CollectionOrObjectInitializers)
            {
                rc     = rc.PushObjectInitializer(target);
                source = source.DoResolve(rc);
                rc     = rc.PopObjectInitializer();

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

                eclass       = source.eclass;
                ResolvedType = source.Type;
                _resolved    = true;
                return(this);
            }

            return(base.DoResolve(rc));
        }
Exemple #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);
        }
Exemple #4
0
        public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc)
        {
            if (parameters == null)
            {
                anonymous_type = CreateAnonymousType(rc, EmptyParameters);
                RequestedType  = new TypeExpression(anonymous_type, loc);
                return(base.DoResolve(rc));
            }

            bool error = false;

            arguments = new Arguments(parameters.Count);
            for (int i = 0; i < parameters.Count; ++i)
            {
                Expression e = parameters[i].DoResolve(rc);
                if (e == null)
                {
                    error = true;
                    continue;
                }

                arguments.Add(new Argument(e, e.Location));
            }

            if (error)
            {
                return(null);
            }

            anonymous_type = CreateAnonymousType(rc, parameters);
            if (anonymous_type == null)
            {
                return(null);
            }


            return(base.DoResolve(rc));
        }
Exemple #5
0
 public override VSC.AST.Expression Constantify(VSC.TypeSystem.Resolver.ResolveContext resolver)
 {
     return(DoResolve(resolver) as Constant);
 }
        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);
        }