protected override TypeExpression DoResolveAsTypeStep(ParseContext ec) { var leftExpression = Left.ResolveAsTypeTerminal(ec, false); if (leftExpression == null) { return(null); } var leftType = leftExpression.Type; if ((DimensionSpecifier.Length > 0) && (DimensionSpecifier[0] == '?')) { TypeExpression nullable = new NullableTypeExpression(leftExpression, Span); if (DimensionSpecifier.Length > 1) { nullable = new ComposedCastExpression(nullable, DimensionSpecifier.Substring(1), Span); } return(nullable.ResolveAsTypeTerminal(ec, false)); } if (DimensionSpecifier.Length != 0 && DimensionSpecifier[0] == '[') { if (TypeManager.IsSpecialType(leftType)) { ec.ReportError( 611, string.Format( "Array elements cannot be of type '{0}'.", TypeManager.GetCSharpName(leftType)), Span); return(null); } if (leftType.IsAbstract && leftType.IsSealed) { ec.ReportError( 719, string.Format( "Array elements cannot be of static type `{0}'", TypeManager.GetCSharpName(leftType)), Span); } } if (DimensionSpecifier != "") { Type = TypeManager.GetConstructedType(leftType, DimensionSpecifier); } else { Type = leftType; } if (Type == null) { throw new InternalErrorException("Couldn't create computed type " + leftType + DimensionSpecifier); } ExpressionClass = ExpressionClass.Type; return(this); }
Expression LiftResult(ParseContext ec, Expression res_expr) { TypeExpression lifted_type; // // Avoid double conversion // if (left_unwrap == null || left_null_lifted || !TypeManager.IsEqual(left_unwrap.Type, Left.Type) || (left_unwrap != null && right_null_lifted)) { lifted_type = new NullableTypeExpression(Left.Type, Span); lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false); if (lifted_type == null) { return(null); } if (Left is CastExpression) { ((CastExpression)Left).DestinationType = new TypeExpression(lifted_type.Type); } else { Left = EmptyCastExpression.Create(Left, lifted_type.Type); } } if (right_unwrap == null || right_null_lifted || !TypeManager.IsEqual(right_unwrap.Type, Right.Type) || (right_unwrap != null && left_null_lifted)) { lifted_type = new NullableTypeExpression(Right.Type, Span); lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false); if (lifted_type == null) { return(null); } if (Right is CastExpression) { ((CastExpression)Right).DestinationType = new TypeExpression(lifted_type.Type); } else { Right = EmptyCastExpression.Create(Right, lifted_type.Type); } } if (!Operator.IsComparison()) { lifted_type = new NullableTypeExpression(res_expr.Type, Span); lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false); if (lifted_type == null) { return(null); } wrap_ctor = new NullableInfo(lifted_type.Type).Constructor; ResultType = res_expr.Type = lifted_type.Type; } if (left_null_lifted) { Left = LiftedNullExpression.Create(Right.Type, Left.Span); if (Operator.IsArithmetic() || Operator.IsShift() || Operator.IsBitwise()) { return(LiftedNullExpression.CreateFromExpression(ec, res_expr)); } // // Value types and null comparison // if (right_unwrap == null || Operator.IsRelational()) { return(CreateNullConstant(ec, right_orig).Resolve(ec)); } } if (right_null_lifted) { Right = LiftedNullExpression.Create(Left.Type, Right.Span); if (Operator.IsArithmetic() || Operator.IsShift() || Operator.IsBitwise()) { return(LiftedNullExpression.CreateFromExpression(ec, res_expr)); } // // Value types and null comparison // if (left_unwrap == null || Operator.IsRelational()) { return(CreateNullConstant(ec, left_orig).Resolve(ec)); } } return(res_expr); }