本文整理汇总了C#中ConversionKind类的典型用法代码示例。如果您正苦于以下问题:C# ConversionKind类的具体用法?C# ConversionKind怎么用?C# ConversionKind使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
ConversionKind类属于命名空间,在下文中一共展示了ConversionKind类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: DistributeLiftedConversionIntoLiftedOperand
private BoundExpression DistributeLiftedConversionIntoLiftedOperand(
CSharpSyntaxNode syntax,
BoundExpression operand,
ConversionKind kind,
bool @checked,
MethodSymbol method,
TypeSymbol type)
{
// Third, an even trickier optimization. Suppose we have a lifted conversion on top of
// a lifted operation. Say, "decimal? d = M() + N()" where M() and N() return nullable ints.
// We can codegen this naively as:
//
// int? m = M();
// int? n = N();
// int? r = m.HasValue && n.HasValue ? new int?(m.Value + n.Value) : new int?();
// decimal? d = r.HasValue ? new decimal?((decimal)r.Value) : new decimal?();
//
// However, we also observe that we could do the conversion on both branches of the conditional:
//
// int? m = M();
// int? n = N();
// decimal? d = m.HasValue && n.HasValue ? (decimal?)(new int?(m.Value + n.Value)) : (decimal?)(new int?());
//
// And we already optimize those, above! So we could reduce this to:
//
// int? m = M();
// int? n = N();
// decimal? d = m.HasValue && n.HasValue ? new decimal?((decimal)(m.Value + n.Value)) : new decimal?());
//
// which avoids entirely the creation of the unnecessary nullable int!
if (operand.Kind == BoundKind.Sequence)
{
BoundSequence seq = (BoundSequence)operand;
if (seq.Value.Kind == BoundKind.ConditionalOperator)
{
BoundConditionalOperator conditional = (BoundConditionalOperator)seq.Value;
Debug.Assert(seq.Type == conditional.Type);
Debug.Assert(conditional.Type == conditional.Consequence.Type);
Debug.Assert(conditional.Type == conditional.Alternative.Type);
if (NullableAlwaysHasValue(conditional.Consequence) != null && NullableNeverHasValue(conditional.Alternative))
{
return new BoundSequence(
seq.Syntax,
seq.Locals,
seq.SideEffects,
RewriteConditionalOperator(
conditional.Syntax,
conditional.Condition,
MakeConversion(null, syntax, conditional.Consequence, kind, method, @checked, false, false, false, ConstantValue.NotAvailable, type),
MakeConversion(null, syntax, conditional.Alternative, kind, method, @checked, false, false, false, ConstantValue.NotAvailable, type),
ConstantValue.NotAvailable,
type),
type);
}
}
}
return null;
}
示例2: GetAsOperatorConstantResult
internal static ConstantValue GetAsOperatorConstantResult(TypeSymbol operandType, TypeSymbol targetType, ConversionKind conversionKind, ConstantValue operandConstantValue)
{
// NOTE: Even though BoundIsOperator and BoundAsOperator will always have no ConstantValue
// NOTE: (they are non-constant expressions according to Section 7.19 of the specification),
// NOTE: we want to perform constant analysis of is/as expressions during binding to generate warnings (always true/false/null)
// NOTE: and during rewriting for optimized codegen.
// Native compiler port:
// // check for case we know is always false
// if (arg->isNull() || !canCast(arg, type2, NOUDC) && type1->IsValType() && type2->isClassType() && (!type1->IsTypeParameterType() || !type2->isPredefType(PT_ENUM)))
// {
// GetErrorContext()->Error(tree, WRN_AlwaysNull, type2);
// return rval;
// }
if (operandConstantValue == ConstantValue.Null ||
(conversionKind == ConversionKind.NoConversion &&
(operandType.IsValueType && targetType.IsClassType() && (!operandType.IsTypeParameter() || targetType.SpecialType != SpecialType.System_Enum))))
{
return ConstantValue.Null;
}
else
{
return null;
}
}
示例3: OptimizeLiftedBuiltInConversion
private BoundExpression OptimizeLiftedBuiltInConversion(
CSharpSyntaxNode syntax,
BoundExpression operand,
ConversionKind kind,
bool @checked,
TypeSymbol type)
{
Debug.Assert(operand != null);
Debug.Assert((object)type != null);
// First, an optimization. If the source is known to always be null then
// we can simply return the alternative.
if (NullableNeverHasValue(operand))
{
return new BoundDefaultOperator(syntax, null, type);
}
// Second, a trickier optimization. If the conversion is "(T?)(new S?(x))" then
// we generate "new T?((T)x)"
BoundExpression nonNullValue = NullableAlwaysHasValue(operand);
if (nonNullValue != null)
{
return new BoundObjectCreationExpression(
syntax,
GetNullableMethod(syntax, type, SpecialMember.System_Nullable_T__ctor),
MakeConversion(
nonNullValue,
type.GetNullableUnderlyingType(),
@checked));
}
// Third, a very tricky optimization.
return DistributeLiftedConversionIntoLiftedOperand(syntax, operand, kind, @checked, null, type);
}
示例4: MakeConversion
/// <summary>
/// Helper method to generate a lowered conversion.
/// </summary>
private BoundExpression MakeConversion(
BoundConversion oldNode,
CSharpSyntaxNode syntax,
BoundExpression rewrittenOperand,
ConversionKind conversionKind,
MethodSymbol symbolOpt,
bool @checked,
bool explicitCastInCode,
bool isExtensionMethod,
bool isArrayIndex,
ConstantValue constantValueOpt,
TypeSymbol rewrittenType)
{
Debug.Assert(oldNode == null || oldNode.Syntax == syntax);
Debug.Assert((object)rewrittenType != null);
@checked = @checked &&
(inExpressionLambda && (explicitCastInCode || DistinctSpecialTypes(rewrittenOperand.Type, rewrittenType)) ||
NeedsChecked(rewrittenOperand.Type, rewrittenType));
switch (conversionKind)
{
case ConversionKind.Identity:
// Spec 6.1.1:
// An identity conversion converts from any type to the same type.
// This conversion exists such that an entity that already has a required type can be said to be convertible to that type.
// Because object and dynamic are considered equivalent there is an identity conversion between object and dynamic,
// and between constructed types that are the same when replacing all occurrences of dynamic with object.
// Why ignoreDynamic: false?
// Lowering phase treats object and dynamic as equivalent types. So we don't need to produce any conversion here,
// but we need to change the Type property on the resulting BoundExpression to match the rewrittenType.
// This is necessary so that subsequent lowering transformations see that the expression is dynamic.
if (inExpressionLambda || !rewrittenOperand.Type.Equals(rewrittenType, ignoreCustomModifiers: false, ignoreDynamic: false))
{
break;
}
// 4.1.6 C# spec: To force a value of a floating point type to the exact precision of its type, an explicit cast can be used.
// If this is not an identity conversion of a float with unknown precision, strip away the identity conversion.
if (!(explicitCastInCode && IsFloatPointExpressionOfUnknownPrecision(rewrittenOperand)))
{
return rewrittenOperand;
}
break;
case ConversionKind.ExplicitUserDefined:
case ConversionKind.ImplicitUserDefined:
return RewriteUserDefinedConversion(
syntax: syntax,
rewrittenOperand: rewrittenOperand,
method: symbolOpt,
rewrittenType: rewrittenType,
conversionKind: conversionKind);
case ConversionKind.IntPtr:
return RewriteIntPtrConversion(oldNode, syntax, rewrittenOperand, conversionKind, symbolOpt, @checked,
explicitCastInCode, isExtensionMethod, isArrayIndex, constantValueOpt, rewrittenType);
case ConversionKind.ImplicitNullable:
case ConversionKind.ExplicitNullable:
return RewriteNullableConversion(
syntax: syntax,
rewrittenOperand: rewrittenOperand,
conversionKind: conversionKind,
@checked: @checked,
explicitCastInCode: explicitCastInCode,
rewrittenType: rewrittenType);
case ConversionKind.Boxing:
if (!inExpressionLambda)
{
// We can perform some optimizations if we have a nullable value type
// as the operand and we know its nullability:
// * (object)new int?() is the same as (object)null
// * (object)new int?(123) is the same as (object)123
if (NullableNeverHasValue(rewrittenOperand))
{
return new BoundDefaultOperator(syntax, rewrittenType);
}
BoundExpression nullableValue = NullableAlwaysHasValue(rewrittenOperand);
if (nullableValue != null)
{
// Recurse, eliminating the unnecessary ctor.
return MakeConversion(oldNode, syntax, nullableValue, conversionKind,
symbolOpt, @checked, explicitCastInCode, isExtensionMethod, isArrayIndex,
constantValueOpt, rewrittenType);
}
}
break;
//.........这里部分代码省略.........
示例5: SynthesizedNonUserDefined
/// <remarks>
/// This method is intended for passes other than the LocalRewriter.
/// Use MakeConversion helper method in the LocalRewriter instead,
/// it generates a synthesized conversion in its lowered form.
/// </remarks>
public static BoundConversion SynthesizedNonUserDefined(CSharpSyntaxNode syntax, BoundExpression operand, ConversionKind kind, TypeSymbol type, ConstantValue constantValueOpt = null)
{
// We need more information than just the conversion kind for creating a synthesized user defined conversion.
Debug.Assert(!kind.IsUserDefinedConversion(), "Use the BoundConversion.Synthesized overload that takes a 'Conversion' parameter for generating synthesized user defined conversions.");
return new BoundConversion(
syntax,
operand,
kind,
resultKind: LookupResultKind.Viable, //not used
isBaseConversion: false,
symbolOpt: null,
@checked: false,
explicitCastInCode: false,
isExtensionMethod: false,
isArrayIndex: false,
constantValueOpt: constantValueOpt,
type: type)
{ WasCompilerGenerated = true };
}
示例6: ConversionTestHelper
/// <summary>
///
/// </summary>
/// <param name="binding"></param>
/// <param name="expr"></param>
/// <param name="ept1">expr -> TypeInParent</param>
/// <param name="ept2">Type(expr) -> TypeInParent</param>
private void ConversionTestHelper(SemanticModel semanticModel, ExpressionSyntax expr, ConversionKind ept1, ConversionKind ept2)
{
var info = semanticModel.GetTypeInfo(expr);
Assert.NotNull(info);
Assert.NotNull(info.ConvertedType);
var conv = semanticModel.GetConversion(expr);
// NOT expect NoConversion
Conversion act1 = semanticModel.ClassifyConversion(expr, (TypeSymbol)info.ConvertedType);
Assert.Equal(ept1, act1.Kind);
ValidateConversion(act1, ept1);
ValidateConversion(act1, conv.Kind);
if (ept2 == ConversionKind.NoConversion)
{
Assert.Null(info.Type);
}
else
{
Assert.NotNull(info.Type);
var act2 = semanticModel.Compilation.ClassifyConversion(info.Type, info.ConvertedType);
Assert.Equal(ept2, act2.Kind);
ValidateConversion(act2, ept2);
}
}
示例7: ClassifyConversionBuiltInNumeric
public void ClassifyConversionBuiltInNumeric()
{
const ConversionKind ID = ConversionKind.Identity;
const ConversionKind IN = ConversionKind.ImplicitNumeric;
const ConversionKind XN = ConversionKind.ExplicitNumeric;
var types = new[] { "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "char", "float", "double", "decimal" };
var conversions = new ConversionKind[,] {
// to sb b s us i ui l ul c f d m
// from
/* sb */ { ID, XN, IN, XN, IN, XN, IN, XN, XN, IN, IN, IN },
/* b */ { XN, ID, IN, IN, IN, IN, IN, IN, XN, IN, IN, IN },
/* s */ { XN, XN, ID, XN, IN, XN, IN, XN, XN, IN, IN, IN },
/* us */ { XN, XN, XN, ID, IN, IN, IN, IN, XN, IN, IN, IN },
/* i */ { XN, XN, XN, XN, ID, XN, IN, XN, XN, IN, IN, IN },
/* ui */ { XN, XN, XN, XN, XN, ID, IN, IN, XN, IN, IN, IN },
/* l */ { XN, XN, XN, XN, XN, XN, ID, XN, XN, IN, IN, IN },
/* ul */ { XN, XN, XN, XN, XN, XN, XN, ID, XN, IN, IN, IN },
/* c */ { XN, XN, XN, IN, IN, IN, IN, IN, ID, IN, IN, IN },
/* f */ { XN, XN, XN, XN, XN, XN, XN, XN, XN, ID, IN, XN },
/* d */ { XN, XN, XN, XN, XN, XN, XN, XN, XN, XN, ID, XN },
/* m */ { XN, XN, XN, XN, XN, XN, XN, XN, XN, XN, XN, ID }
};
for (var from = 0; from < types.Length; from++)
{
for (var to = 0; to < types.Length; to++)
{
TestClassifyConversionBuiltInNumeric(types[from], types[to], conversions[from, to]);
}
}
}
示例8: ValidateConversion
private void ValidateConversion(Conversion conv, ConversionKind kind)
{
Assert.Equal(conv.Kind, kind);
switch (kind)
{
case ConversionKind.NoConversion:
Assert.False(conv.Exists);
Assert.False(conv.IsImplicit);
Assert.False(conv.IsExplicit);
break;
case ConversionKind.Identity:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsIdentity);
break;
case ConversionKind.ImplicitNumeric:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsNumeric);
break;
case ConversionKind.ImplicitEnumeration:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsEnumeration);
break;
case ConversionKind.ImplicitNullable:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsNullable);
break;
case ConversionKind.NullLiteral:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsNullLiteral);
break;
case ConversionKind.ImplicitReference:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsReference);
break;
case ConversionKind.Boxing:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsBoxing);
break;
case ConversionKind.ImplicitDynamic:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsDynamic);
break;
case ConversionKind.ExplicitDynamic:
Assert.True(conv.Exists);
Assert.True(conv.IsExplicit);
Assert.False(conv.IsImplicit);
Assert.True(conv.IsDynamic);
break;
case ConversionKind.ImplicitConstant:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsConstantExpression);
break;
case ConversionKind.ImplicitUserDefined:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsUserDefined);
break;
case ConversionKind.AnonymousFunction:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsAnonymousFunction);
break;
case ConversionKind.MethodGroup:
Assert.True(conv.Exists);
Assert.True(conv.IsImplicit);
Assert.False(conv.IsExplicit);
Assert.True(conv.IsMethodGroup);
break;
case ConversionKind.ExplicitNumeric:
Assert.True(conv.Exists);
Assert.False(conv.IsImplicit);
Assert.True(conv.IsExplicit);
Assert.True(conv.IsNumeric);
break;
case ConversionKind.ExplicitEnumeration:
Assert.True(conv.Exists);
Assert.False(conv.IsImplicit);
Assert.True(conv.IsExplicit);
Assert.True(conv.IsEnumeration);
//.........这里部分代码省略.........
示例9: TestClassifyConversionBuiltInNumeric
private void TestClassifyConversionBuiltInNumeric(string from, string to, ConversionKind ck)
{
const string template = @"
class C
{{
static void Foo({1} v) {{ }}
static void Main() {{ {0} v = default({0}); Foo({2}v); }}
}}
";
var isExplicitConversion = ck == ConversionKind.ExplicitNumeric;
var source = string.Format(template, from, to, isExplicitConversion ? "(" + to + ")" : "");
var tree = Parse(source);
var comp = CreateCompilationWithMscorlib(tree);
comp.VerifyDiagnostics();
var model = comp.GetSemanticModel(tree);
var c = (TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0];
var main = (MethodDeclarationSyntax)c.Members[1];
var call = (InvocationExpressionSyntax)((ExpressionStatementSyntax)main.Body.Statements[1]).Expression;
var arg = call.ArgumentList.Arguments[0].Expression;
if (isExplicitConversion)
{
ConversionTestHelper(model, ((CastExpressionSyntax)arg).Expression, model.GetTypeInfo(arg).ConvertedType, ck);
}
else
{
ConversionTestHelper(model, arg, ck, ck);
}
}
示例10: RewriteUserDefinedConversion
private BoundExpression RewriteUserDefinedConversion(
CSharpSyntaxNode syntax,
BoundExpression rewrittenOperand,
MethodSymbol method,
TypeSymbol rewrittenType,
ConversionKind conversionKind)
{
Debug.Assert((object)method != null && !method.ReturnsVoid && method.ParameterCount == 1);
if (rewrittenOperand.Type != method.ParameterTypes[0])
{
Debug.Assert(rewrittenOperand.Type.IsNullableType());
Debug.Assert(rewrittenOperand.Type.GetNullableUnderlyingType() == method.ParameterTypes[0]);
return RewriteLiftedUserDefinedConversion(syntax, rewrittenOperand, method, rewrittenType, conversionKind);
}
var conv = new Conversion(ConversionKind.ExplicitUserDefined, method, false);
Debug.Assert(conv.IsValid);
BoundExpression result =
inExpressionLambda
? BoundConversion.Synthesized(syntax, rewrittenOperand, MakeConversion(syntax, conv, rewrittenOperand.Type, rewrittenType), false, true, default(ConstantValue), rewrittenType)
: (BoundExpression)BoundCall.Synthesized(syntax, null, method, rewrittenOperand);
Debug.Assert(result.Type == rewrittenType);
return result;
}
示例11: RewriteLiftedUserDefinedConversion
private BoundExpression RewriteLiftedUserDefinedConversion(
CSharpSyntaxNode syntax,
BoundExpression rewrittenOperand,
MethodSymbol method,
TypeSymbol rewrittenType,
ConversionKind conversionKind)
{
if (inExpressionLambda)
{
Conversion conv = MakeConversion(syntax, new Conversion(conversionKind, method, false), rewrittenOperand.Type, rewrittenType);
return BoundConversion.Synthesized(syntax, rewrittenOperand, conv, false, true, default(ConstantValue), rewrittenType);
}
// DELIBERATE SPEC VIOLATION:
// The native compiler allows for a "lifted" conversion even when the return type of the conversion
// not a non-nullable value type. For example, if we have a conversion from struct S to string,
// then a "lifted" conversion from S? to string is considered by the native compiler to exist,
// with the semantics of "s.HasValue ? (string)s.Value : (string)null". The Roslyn compiler
// perpetuates this error for the sake of backwards compatibility.
Debug.Assert((object)rewrittenType != null);
Debug.Assert(rewrittenOperand.Type.IsNullableType());
BoundExpression optimized = OptimizeLiftedUserDefinedConversion(syntax, rewrittenOperand, conversionKind, method, rewrittenType);
if (optimized != null)
{
return optimized;
}
// We have no optimizations we can perform. If the return type of the
// conversion method is a non-nullable value type R then we lower this as:
//
// temp = operand
// temp.HasValue ? new R?(op_Whatever(temp.GetValueOrDefault())) : default(R?)
//
// Otherwise, if the return type of the conversion is a nullable value type, reference type
// or pointer type P, then we lower this as:
//
// temp = operand
// temp.HasValue ? op_Whatever(temp.GetValueOrDefault()) : default(P)
BoundAssignmentOperator tempAssignment;
BoundLocal boundTemp = factory.StoreToTemp(rewrittenOperand, out tempAssignment);
MethodSymbol get_HasValue = GetNullableMethod(syntax, boundTemp.Type, SpecialMember.System_Nullable_T_get_HasValue);
MethodSymbol getValueOrDefault = GetNullableMethod(syntax, boundTemp.Type, SpecialMember.System_Nullable_T_GetValueOrDefault);
// temp.HasValue
BoundExpression condition = BoundCall.Synthesized(syntax, boundTemp, get_HasValue);
// temp.GetValueOrDefault()
BoundCall callGetValueOrDefault = BoundCall.Synthesized(syntax, boundTemp, getValueOrDefault);
// op_Whatever(temp.GetValueOrDefault())
BoundCall userDefinedCall = BoundCall.Synthesized(syntax, null, method, callGetValueOrDefault);
// new R?(op_Whatever(temp.GetValueOrDefault())
BoundExpression consequence = MakeLiftedUserDefinedConversionConsequence(userDefinedCall, rewrittenType);
// default(R?)
BoundExpression alternative = new BoundDefaultOperator(syntax, rewrittenType);
// temp.HasValue ? new R?(op_Whatever(temp.GetValueOrDefault())) : default(R?)
BoundExpression conditionalExpression = RewriteConditionalOperator(
syntax: syntax,
rewrittenCondition: condition,
rewrittenConsequence: consequence,
rewrittenAlternative: alternative,
constantValueOpt: null,
rewrittenType: rewrittenType);
// temp = operand
// temp.HasValue ? new R?(op_Whatever(temp.GetValueOrDefault())) : default(R?)
return new BoundSequence(
syntax: syntax,
locals: ImmutableArray.Create(boundTemp.LocalSymbol),
sideEffects: ImmutableArray.Create<BoundExpression>(tempAssignment),
value: conditionalExpression,
type: rewrittenType);
}
示例12: RewriteNullableConversion
private BoundExpression RewriteNullableConversion(
CSharpSyntaxNode syntax,
BoundExpression rewrittenOperand,
ConversionKind conversionKind,
bool @checked,
bool explicitCastInCode,
TypeSymbol rewrittenType)
{
Debug.Assert((object)rewrittenType != null);
if (inExpressionLambda)
{
return RewriteLiftedConversionInExpressionTree(syntax, rewrittenOperand, conversionKind, @checked, explicitCastInCode, rewrittenType);
}
TypeSymbol rewrittenOperandType = rewrittenOperand.Type;
Debug.Assert(rewrittenType.IsNullableType() || rewrittenOperandType.IsNullableType());
if (rewrittenOperandType.IsNullableType() && rewrittenType.IsNullableType())
{
return RewriteFullyLiftedBuiltInConversion(syntax, rewrittenOperand, conversionKind, @checked, rewrittenType);
}
else if (rewrittenType.IsNullableType())
{
// SPEC: If the nullable conversion is from S to T?, the conversion is
// SPEC: evaluated as the underlying conversion from S to T followed
// SPEC: by a wrapping from T to T?.
BoundExpression rewrittenConversion = MakeConversion(rewrittenOperand, rewrittenType.GetNullableUnderlyingType(), @checked);
MethodSymbol ctor = GetNullableMethod(syntax, rewrittenType, SpecialMember.System_Nullable_T__ctor);
return new BoundObjectCreationExpression(syntax, ctor, rewrittenConversion);
}
else
{
// SPEC: if the nullable conversion is from S? to T, the conversion is
// SPEC: evaluated as an unwrapping from S? to S followed by the underlying
// SPEC: conversion from S to T.
// We can do a simple optimization here if we know that the source is never null:
BoundExpression nonNullValue = NullableAlwaysHasValue(rewrittenOperand);
if (nonNullValue != null)
{
return MakeConversion(nonNullValue, rewrittenType, @checked);
}
// (If the source is known to be null then we need to keep the call to get Value
// in place so that it throws at runtime.)
MethodSymbol get_Value = GetNullableMethod(syntax, rewrittenOperandType, SpecialMember.System_Nullable_T_get_Value);
return MakeConversion(BoundCall.Synthesized(syntax, rewrittenOperand, get_Value), rewrittenType, @checked);
}
}
示例13: RewriteIntPtrConversion
private BoundExpression RewriteIntPtrConversion(
BoundConversion oldNode,
CSharpSyntaxNode syntax,
BoundExpression rewrittenOperand,
ConversionKind conversionKind,
MethodSymbol symbolOpt,
bool @checked,
bool explicitCastInCode,
bool isExtensionMethod,
bool isArrayIndex,
ConstantValue constantValueOpt,
TypeSymbol rewrittenType)
{
Debug.Assert(rewrittenOperand != null);
Debug.Assert((object)rewrittenType != null);
TypeSymbol source = rewrittenOperand.Type;
TypeSymbol target = rewrittenType;
TypeSymbol t0 = target.StrippedType();
TypeSymbol s0 = source.StrippedType();
if (t0 != target && s0 != source)
{
// UNDONE: RewriteLiftedIntPtrConversion
return oldNode != null ?
oldNode.Update(
rewrittenOperand,
conversionKind,
oldNode.ResultKind,
isBaseConversion: oldNode.IsBaseConversion,
symbolOpt: symbolOpt,
@checked: @checked,
explicitCastInCode: explicitCastInCode,
isExtensionMethod: isExtensionMethod,
isArrayIndex: isArrayIndex,
constantValueOpt: constantValueOpt,
type: rewrittenType) :
new BoundConversion(
syntax,
rewrittenOperand,
conversionKind,
LookupResultKind.Viable,
isBaseConversion: false,
symbolOpt: symbolOpt,
@checked: @checked,
explicitCastInCode: explicitCastInCode,
isExtensionMethod: isExtensionMethod,
isArrayIndex: isArrayIndex,
constantValueOpt: constantValueOpt,
type: rewrittenType);
}
SpecialMember member = GetIntPtrConversionMethod(source: rewrittenOperand.Type, target: rewrittenType);
MethodSymbol method = GetSpecialTypeMethod(syntax, member);
Debug.Assert(!method.ReturnsVoid);
Debug.Assert(method.ParameterCount == 1);
rewrittenOperand = MakeConversion(rewrittenOperand, method.ParameterTypes[0], @checked);
var returnType = method.ReturnType;
Debug.Assert((object)returnType != null);
if (inExpressionLambda)
{
return BoundConversion.Synthesized(syntax, rewrittenOperand, new Conversion(conversionKind, method, false), @checked, explicitCastInCode, constantValueOpt, rewrittenType);
}
var rewrittenCall =
inExpressionLambda && oldNode != null
? new BoundConversion(syntax, rewrittenOperand, new Conversion(conversionKind, method, false), @checked, explicitCastInCode, constantValueOpt, returnType)
: MakeCall(
syntax: syntax,
rewrittenReceiver: null,
method: method,
rewrittenArguments: ImmutableArray.Create<BoundExpression>(rewrittenOperand),
type: returnType);
return MakeConversion(rewrittenCall, rewrittenType, @checked);
}
示例14: RewriteLiftedConversionInExpressionTree
private BoundExpression RewriteLiftedConversionInExpressionTree(
CSharpSyntaxNode syntax,
BoundExpression rewrittenOperand,
ConversionKind conversionKind,
bool @checked,
bool explicitCastInCode,
TypeSymbol rewrittenType)
{
Debug.Assert((object)rewrittenType != null);
TypeSymbol rewrittenOperandType = rewrittenOperand.Type;
Debug.Assert(rewrittenType.IsNullableType() || rewrittenOperandType.IsNullableType());
TypeSymbol typeFrom = rewrittenOperandType.StrippedType();
TypeSymbol typeTo = rewrittenType.StrippedType();
if (typeFrom != typeTo && (typeFrom.SpecialType == SpecialType.System_Decimal || typeTo.SpecialType == SpecialType.System_Decimal))
{
// take special care if the underlying conversion is a decimal conversion
TypeSymbol typeFromUnderlying = typeFrom;
TypeSymbol typeToUnderlying = typeTo;
// They can't both be enums, since one of them is decimal.
if (typeFrom.IsEnumType())
{
typeFromUnderlying = typeFrom.GetEnumUnderlyingType();
// NOTE: Dev10 converts enum? to underlying?, rather than directly to underlying.
rewrittenOperandType = rewrittenOperandType.IsNullableType() ? ((NamedTypeSymbol)rewrittenOperandType.OriginalDefinition).Construct(typeFromUnderlying) : typeFromUnderlying;
rewrittenOperand = BoundConversion.SynthesizedNonUserDefined(syntax, rewrittenOperand, ConversionKind.ImplicitEnumeration, rewrittenOperandType);
}
else if (typeTo.IsEnumType())
{
typeToUnderlying = typeTo.GetEnumUnderlyingType();
}
var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(DecimalConversionMethod(typeFromUnderlying, typeToUnderlying));
conversionKind = conversionKind.IsImplicitConversion() ? ConversionKind.ImplicitUserDefined : ConversionKind.ExplicitUserDefined;
var result = new BoundConversion(syntax, rewrittenOperand, new Conversion(conversionKind, method, false), @checked, explicitCastInCode, default(ConstantValue), rewrittenType);
return result;
}
else
{
return new BoundConversion(syntax, rewrittenOperand, new Conversion(conversionKind), @checked, explicitCastInCode, default(ConstantValue), rewrittenType);
}
}
示例15: Convert
public BoundExpression Convert(TypeSymbol type, BoundExpression arg, ConversionKind conversionKind, bool isChecked = false)
{
return new BoundConversion(
Syntax,
arg,
conversionKind,
LookupResultKind.Viable,
isBaseConversion: false,
symbolOpt: null,
@checked: isChecked,
explicitCastInCode: true,
isExtensionMethod: false,
isArrayIndex: false,
constantValueOpt: null,
type: type)
{ WasCompilerGenerated = true };
}