internal override void WriteTo(CCodeWriterBase c) { var interfaceCastRequired = this.ConversionKind == ConversionKind.Boxing && Type.TypeKind == TypeKind.Interface; if (interfaceCastRequired) { c.TextSpan(this.TypeSource.AllInterfaces.Contains((INamedTypeSymbol)Type) ? "interface_cast" : "dynamic_interface_cast_or_throw"); c.TextSpan("<"); c.WriteType(Type); c.TextSpan(">"); c.TextSpan("("); } var effectiveExpression = this.Operand; if ((this.ConversionKind == ConversionKind.Boxing || this.ConversionKind == ConversionKind.ImplicitReference) && this.Operand.IsStaticOrSupportedVolatileWrapperCall()) { effectiveExpression = new Cast { Type = this.TypeSource, Operand = effectiveExpression, CCast = true, UseEnumUnderlyingType = true, }; } if (this.ConversionKind == ConversionKind.Unboxing && this.Operand.Type.TypeKind == TypeKind.Interface) { effectiveExpression = new Conversion { Type = new NamedTypeImpl { SpecialType = SpecialType.System_Object }, TypeSource = this.TypeSource, Operand = effectiveExpression, ConversionKind = ConversionKind.ImplicitReference }; } var parenthesis = false; if (this.WriteCast(c, out parenthesis)) { if (parenthesis) { c.WriteExpressionInParenthesesIfNeeded(effectiveExpression); } else { c.TextSpan("("); if (this.ConversionKind == ConversionKind.Boxing && Cs2CGenerator.DebugOutput) { c.TextSpan("__FILE__, __LINE__, "); } effectiveExpression.WriteTo(c); c.TextSpan(")"); } } if (interfaceCastRequired) { c.TextSpan(")"); } }
private static Expression PreprocessParameter(Expression expression, IParameterSymbol parameter, IMethodSymbol method, IMethodSymbol methodOwner = null) { if (parameter == null) { return(expression); } var parameterType = parameter.Type; if (parameterType == null) { return(expression); } var effectiveExpression = expression; var typeDestination = parameterType; if (typeDestination.IsReferenceType) { var literal = expression as Literal; if (literal != null && literal.Value.IsNull) { effectiveExpression = new Conversion { Type = typeDestination, Operand = effectiveExpression, MethodOwner = methodOwner }; } } var thisRef = expression as ThisReference; if (typeDestination.IsValueType && thisRef != null && !thisRef.ValueAsReference) { effectiveExpression = new PointerIndirectionOperator { Operand = expression, MethodOwner = methodOwner }; } if (expression.IsStaticOrSupportedVolatileWrapperCall()) { effectiveExpression = new Cast { Type = typeDestination, Operand = effectiveExpression, Reference = parameter.RefKind.HasFlag(RefKind.Ref) || parameter.RefKind.HasFlag(RefKind.Out), CCast = true, UseEnumUnderlyingType = true, MethodOwner = methodOwner }; } if (effectiveExpression.IsReference && (effectiveExpression.Type.TypeKind == TypeKind.Interface) && parameter.Type.SpecialType == SpecialType.System_Object) { effectiveExpression = new Conversion { ConversionKind = ConversionKind.ImplicitReference, IsReference = true, Operand = expression, TypeSource = effectiveExpression.Type, Type = parameter.Type, MethodOwner = methodOwner }; } // to support virtual generics it is required to sync. types if (method != null && method.IsVirtualGenericMethod()) { var namedTypeImpl = GetTypeForVirtualGenericMethod(parameter, method); effectiveExpression = new Cast { Type = namedTypeImpl, Operand = effectiveExpression, Reference = parameter.RefKind.HasFlag(RefKind.Ref) || parameter.RefKind.HasFlag(RefKind.Out), CCast = true, UseEnumUnderlyingType = true, MethodOwner = methodOwner }; } // to support anonymous types /* * if (method != null && method.ContainingType.IsAnonymousType() && parameter.Type.IsValueType) * { * var namedTypeImpl = new TypeImpl { SpecialType = SpecialType.System_Object }; * effectiveExpression = new Conversion * { * Type = namedTypeImpl, * ConversionKind = ConversionKind.Boxing, * Operand = effectiveExpression, * }; * } */ return(effectiveExpression); }
private Expression PrepareMethodReceiver(Expression receiverOpt, IMethodSymbol methodSymbol) { var effectiveReceiverOpt = receiverOpt; if (effectiveReceiverOpt.Kind == Kinds.ThisReference && methodSymbol.MethodKind == MethodKind.Constructor && ((TypeSymbol)(MethodOwner.ContainingType)).ToKeyString() != ((TypeSymbol)methodSymbol.ContainingType).ToKeyString()) { effectiveReceiverOpt = new BaseReference { Type = this.Method.ContainingType, IsReference = true, MethodOwner = MethodOwner }; } if (!effectiveReceiverOpt.IsReference && (effectiveReceiverOpt.Type.IsPrimitiveValueType() || effectiveReceiverOpt.Type.TypeKind == TypeKind.Enum)) { effectiveReceiverOpt = new ObjectCreationExpression { Arguments = { receiverOpt }, Type = effectiveReceiverOpt.Type, MethodOwner = MethodOwner }; } if (!effectiveReceiverOpt.IsReference && effectiveReceiverOpt.Type.IsValueType && !effectiveReceiverOpt.Type.IsPrimitiveValueType() && methodSymbol.IsVirtualMethod() && effectiveReceiverOpt is ArrayAccess) { effectiveReceiverOpt = new Cast { Constrained = true, Operand = receiverOpt, Type = methodSymbol.ContainingType }; } if (effectiveReceiverOpt.IsReference && (effectiveReceiverOpt.Type.TypeKind == TypeKind.Interface) && methodSymbol.ContainingType.SpecialType == SpecialType.System_Object) { effectiveReceiverOpt = new Conversion { ConversionKind = ConversionKind.ImplicitReference, IsReference = true, Operand = receiverOpt, TypeSource = receiverOpt.Type, Type = methodSymbol.ContainingType, MethodOwner = MethodOwner }; } if (effectiveReceiverOpt.Type.TypeKind == TypeKind.TypeParameter && this.Method.ReceiverType != effectiveReceiverOpt.Type) { ////var constrained = ((ITypeParameterSymbol)receiverOpt.Type).ConstraintTypes; ////foreach (var constrainedType in constrained) ////{ //// receiverOpt = new Cast //// { //// Constrained = true, //// Operand = receiverOpt, //// Type = constrainedType //// }; ////} effectiveReceiverOpt = new Cast { Constrained = true, Operand = effectiveReceiverOpt, Type = this.Method.ReceiverType, MethodOwner = MethodOwner }; } if (effectiveReceiverOpt.Type.IsPrimitiveValueTypePointer() && this.Method.ReceiverType != effectiveReceiverOpt.Type) { effectiveReceiverOpt = new Cast { Operand = effectiveReceiverOpt, Type = this.Method.ReceiverType, BoxByRef = true, IsReference = true, MethodOwner = MethodOwner }; } return(effectiveReceiverOpt); }
private static Expression PreprocessParameter(Expression expression, IParameterSymbol parameter) { if (parameter == null) { return(expression); } var parameterType = parameter.Type; if (parameterType == null) { return(expression); } var effectiveExpression = expression; var typeDestination = parameterType; if (typeDestination.IsReferenceType) { var literal = expression as Literal; if (literal != null && literal.Value.IsNull) { effectiveExpression = new Conversion { Type = typeDestination, Operand = effectiveExpression }; } } if (typeDestination.IsValueType && expression is ThisReference) { effectiveExpression = new PointerIndirectionOperator { Operand = expression }; } if (expression.IsStaticWrapperCall()) { effectiveExpression = new Cast { Type = typeDestination, Operand = effectiveExpression, Reference = parameter.RefKind.HasFlag(RefKind.Ref) || parameter.RefKind.HasFlag(RefKind.Out), CCast = true, UseEnumUnderlyingType = true, }; } if (effectiveExpression.IsReference && (effectiveExpression.Type.TypeKind == TypeKind.Interface) && parameter.Type.SpecialType == SpecialType.System_Object) { effectiveExpression = new Conversion { ConversionKind = ConversionKind.ImplicitReference, IsReference = true, Operand = expression, TypeSource = effectiveExpression.Type, Type = parameter.Type }; } return(effectiveExpression); }