本文整理汇总了C#中BoundExpression类的典型用法代码示例。如果您正苦于以下问题:C# BoundExpression类的具体用法?C# BoundExpression怎么用?C# BoundExpression使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
BoundExpression类属于命名空间,在下文中一共展示了BoundExpression类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: BindElementAccessCore
private BoundExpression BindElementAccessCore(ElementAccessExpressionSyntax node, BoundExpression expr, IList<BoundExpression> arguments, IList<string> argumentNames)
{
Debug.Assert(node != null);
Debug.Assert(expr != null);
Debug.Assert(arguments != null);
Debug.Assert(argumentNames != null);
// UNDONE: Suppose we have an indexed property P on an instance c. Suppose the
// UNDONE: type of the property is int[]. When binding c.P[123] we must
// UNDONE: treat this as an invocation of the indexed property, not as a
// UNDONE: dereference of the array returned by the property.
//if (expr.isPROP() && expr.asPROP().IsUnboundIndexedProperty() &&
// !IsPropertyBindingInsideBindIndexerContext(node.Expression))
//{
// return BindIndexerAccess(node, expr, arguments, argumentNames);
//}
var exprType = expr.GetExpressionType();
// UNDONE: Ensure that the type of the expression has members defined.
if (exprType is ArrayTypeSymbol)
{
return BindArrayAccess(node, expr, arguments, argumentNames);
}
else if (exprType is PointerTypeSymbol)
{
return BindPointerElementAccess(node, expr, arguments, argumentNames);
}
else
{
return BindIndexerAccess(node, expr, arguments, argumentNames);
}
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:33,代码来源:ElementAccess.cs
示例2: BoundIfStatement
public BoundIfStatement(BoundExpression condition, BoundStatement consequence, BoundStatement alternativeOpt)
: base(BoundNodeKind.IfStatement)
{
Condition = condition;
Consequence = consequence;
AlternativeOpt = alternativeOpt;
}
开发者ID:Samana,项目名称:HlslTools,代码行数:7,代码来源:BoundIfStatement.cs
示例3: IsSafeForReordering
private static bool IsSafeForReordering(BoundExpression expression, RefKind kind)
{
// To be safe for reordering an expression must not cause any observable side effect *or
// observe any side effect*. Accessing a local by value, for example, is possibly not
// safe for reordering because reading a local can give a different result if reordered
// with respect to a write elsewhere.
var current = expression;
while (true)
{
if (current.ConstantValue != null)
{
return true;
}
switch (current.Kind)
{
default:
return false;
case BoundKind.Parameter:
case BoundKind.Local:
// A ref to a local variable or formal parameter is safe to reorder; it
// never has a side effect or consumes one.
return kind != RefKind.None;
case BoundKind.Conversion:
{
BoundConversion conv = (BoundConversion)current;
switch (conv.ConversionKind)
{
case ConversionKind.AnonymousFunction:
case ConversionKind.ImplicitConstant:
case ConversionKind.MethodGroup:
case ConversionKind.NullLiteral:
return true;
case ConversionKind.Boxing:
case ConversionKind.Dynamic:
case ConversionKind.ExplicitEnumeration:
case ConversionKind.ExplicitNullable:
case ConversionKind.ExplicitNumeric:
case ConversionKind.ExplicitReference:
case ConversionKind.Identity:
case ConversionKind.ImplicitEnumeration:
case ConversionKind.ImplicitNullable:
case ConversionKind.ImplicitNumeric:
case ConversionKind.ImplicitReference:
case ConversionKind.Unboxing:
current = conv.Operand;
break;
case ConversionKind.ExplicitUserDefined:
case ConversionKind.ImplicitUserDefined:
return false;
default:
Debug.Fail("Unhandled conversion kind in reordering logic");
return false;
}
break;
}
}
}
}
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:60,代码来源:CallRewriter.cs
示例4: EmitAddress
/// <summary>
/// Emits address as in &
///
/// May introduce a temp which it will return. (otherwise returns null)
/// </summary>
private LocalDefinition EmitAddress(BoundExpression expression, AddressKind addressKind)
{
switch (expression.Kind)
{
case BoundKind.RefValueOperator:
EmitRefValueAddress((BoundRefValueOperator)expression);
break;
case BoundKind.Local:
EmitLocalAddress((BoundLocal)expression);
break;
case BoundKind.Dup:
Debug.Assert(((BoundDup)expression).RefKind != RefKind.None, "taking address of a stack value?");
builder.EmitOpCode(ILOpCode.Dup);
break;
case BoundKind.Parameter:
EmitParameterAddress((BoundParameter)expression);
break;
case BoundKind.FieldAccess:
return EmitFieldAddress((BoundFieldAccess)expression);
case BoundKind.ArrayAccess:
//arrays are covariant, but elements can be written to.
//the flag tells that we do not intend to use the address for writing.
EmitArrayElementAddress((BoundArrayAccess)expression, addressKind);
break;
case BoundKind.ThisReference:
Debug.Assert(expression.Type.IsValueType, "only valuetypes may need a ref to this");
builder.EmitOpCode(ILOpCode.Ldarg_0);
break;
case BoundKind.PreviousSubmissionReference:
// script references are lowered to a this reference and a field access
throw ExceptionUtilities.UnexpectedValue(expression.Kind);
case BoundKind.BaseReference:
Debug.Assert(false, "base is always a reference type, why one may need a reference to it?");
break;
case BoundKind.Sequence:
return EmitSequenceAddress((BoundSequence)expression, addressKind);
case BoundKind.PointerIndirectionOperator:
// The address of a dereferenced address is that address.
BoundExpression operand = ((BoundPointerIndirectionOperator)expression).Operand;
Debug.Assert(operand.Type.IsPointerType());
EmitExpression(operand, used: true);
break;
default:
Debug.Assert(!HasHome(expression));
return EmitAddressOfTempClone(expression);
}
return null;
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:65,代码来源:EmitAddress.cs
示例5: BoundForStatement
public BoundForStatement(BoundMultipleVariableDeclarations declaration, BoundExpression initializer, BoundExpression condition, BoundExpression incrementor, BoundStatement body)
: base(BoundNodeKind.ForStatement)
{
Declarations = declaration;
Initializer = initializer;
Condition = condition;
Incrementor = incrementor;
Body = body;
}
开发者ID:Samana,项目名称:HlslTools,代码行数:9,代码来源:BoundForStatement.cs
示例6: RewriteIfStatement
private static BoundStatement RewriteIfStatement(
SyntaxNode syntax,
BoundExpression rewrittenCondition,
BoundStatement rewrittenConsequence,
BoundStatement rewrittenAlternativeOpt,
bool hasErrors)
{
var afterif = new GeneratedLabelSymbol("afterif");
// if (condition)
// consequence;
//
// becomes
//
// GotoIfFalse condition afterif;
// consequence;
// afterif:
if (rewrittenAlternativeOpt == null)
{
return BoundStatementList.Synthesized(syntax,
new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, afterif),
rewrittenConsequence,
new BoundLabelStatement(syntax, afterif));
}
// if (condition)
// consequence;
// else
// alternative
//
// becomes
//
// GotoIfFalse condition alt;
// consequence
// goto afterif;
// alt:
// alternative;
// afterif:
var alt = new GeneratedLabelSymbol("alternative");
return BoundStatementList.Synthesized(syntax, hasErrors,
new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, alt),
rewrittenConsequence,
new BoundGotoStatement(syntax, afterif),
new BoundLabelStatement(syntax, alt),
rewrittenAlternativeOpt,
new BoundLabelStatement(syntax, afterif));
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:49,代码来源:ControlFlowRewriter.cs
示例7: EmitExpressionCoreWithStackGuard
private void EmitExpressionCoreWithStackGuard(BoundExpression expression, bool used)
{
Debug.Assert(_recursionDepth == 1);
try
{
EmitExpressionCore(expression, used);
Debug.Assert(_recursionDepth == 1);
}
catch (Exception ex) when (StackGuard.IsInsufficientExecutionStackException(ex))
{
_diagnostics.Add(ErrorCode.ERR_InsufficientStack,
BoundTreeVisitor.CancelledByStackGuardException.GetTooLongOrComplexExpressionErrorLocation(expression));
throw new EmitCancelledException();
}
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:16,代码来源:EmitExpression.cs
示例8: GetErrorReportingName
public static string GetErrorReportingName(BoundExpression expression)
{
switch(expression.Kind)
{
case BoundKind.Literal:
if (expression.ConstantValue.IsNull)
return "<null>";
break;
case BoundKind.Lambda:
case BoundKind.UnboundLambda:
return "lambda expression"; // UNDONE: or "anonymous method"
case BoundKind.MethodGroup:
return "method group";
}
return GetErrorReportingName(expression.GetExpressionType());
}
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:16,代码来源:ErrorFormatting.cs
示例9: BindArrayAccess
private BoundExpression BindArrayAccess(ElementAccessExpressionSyntax node, BoundExpression expr, IList<BoundExpression> arguments, IList<string> argumentNames)
{
Debug.Assert(node != null);
Debug.Assert(expr != null);
Debug.Assert(arguments != null);
Debug.Assert(argumentNames != null);
// For an array access, the primary-no-array-creation-expression of the element-access must
// be a value of an array-type. Furthermore, the argument-list of an array access is not
// allowed to contain named arguments.The number of expressions in the argument-list must
// be the same as the rank of the array-type, and each expression must be of type
// int, uint, long, ulong, or must be implicitly convertible to one or more of these types.
if (argumentNames.Any(x => x != null))
{
Error(ErrorCode.ERR_NamedArgumentForArray, node);
}
var arrayType = (ArrayTypeSymbol)expr.GetExpressionType();
// Note that the spec says to determine which of {int, uint, long, ulong} *each*
// index expression is convertible to. That is not what C# 1 through 4
// did; the implementations instead determined which of those four
// types *all* of the index expressions converted to.
int rank = arrayType.Rank;
if (arguments.Count != arrayType.Rank)
{
Error(ErrorCode.ERR_BadIndexCount, node, rank);
return BoundArrayAccess.AsError(node, expr, arguments, arrayType.ElementType);
}
var convertedArguments = arguments.Select(x => ConvertToArrayIndex(x)).ToList();
return new BoundArrayAccess(node, expr, convertedArguments, arrayType.ElementType);
}
开发者ID:EkardNT,项目名称:Roslyn,代码行数:39,代码来源:ElementAccess.cs
示例10: EmitExpression
private void EmitExpression(BoundExpression expression, bool used)
{
if (expression == null)
{
return;
}
var constantValue = expression.ConstantValue;
if (constantValue != null)
{
if (!used)
{
// unused constants have no side-effects.
return;
}
if ((object)expression.Type == null || expression.Type.SpecialType != SpecialType.System_Decimal)
{
EmitConstantExpression(expression.Type, constantValue, used, expression.Syntax);
return;
}
}
_recursionDepth++;
if (_recursionDepth > 1)
{
StackGuard.EnsureSufficientExecutionStack(_recursionDepth);
EmitExpressionCore(expression, used);
}
else
{
EmitExpressionCoreWithStackGuard(expression, used);
}
_recursionDepth--;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:38,代码来源:EmitExpression.cs
示例11: IsThisReceiver
/// <summary>
/// checks if receiver is effectively ldarg.0
/// </summary>
private bool IsThisReceiver(BoundExpression receiver)
{
switch (receiver.Kind)
{
case BoundKind.ThisReference:
return true;
case BoundKind.Sequence:
var seqValue = ((BoundSequence)(receiver)).Value;
return IsThisReceiver(seqValue);
}
return false;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:17,代码来源:EmitExpression.cs
示例12: EmitArgument
private void EmitArgument(BoundExpression argument, RefKind refKind)
{
if (refKind == RefKind.None)
{
EmitExpression(argument, true);
}
else
{
var temp = EmitAddress(argument, AddressKind.Writeable);
Debug.Assert(temp == null, "passing args byref should not clone them into temps");
}
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:12,代码来源:EmitExpression.cs
示例13: StackMergeType
// Implicit casts are not emitted. As a result verifier may operate on a different
// types from the types of operands when performing stack merges in coalesce/ternary.
// Such differences are in general irrelevant since merging rules work the same way
// for base and derived types.
//
// Situation becomes more complicated with delegates, arrays and interfaces since they
// allow implicit casts from types that do not derive from them. In such cases
// we may need to introduce static casts in the code to prod the verifier to the
// right direction
//
// This helper returns actual type of array|interface|delegate expression ignoring implicit
// casts. This would be the effective stack merge type in the verifier.
//
// NOTE: In cases where stack merge type cannot be determined, we just return null.
// We still must assume that it can be an array, delegate or interface though.
private TypeSymbol StackMergeType(BoundExpression expr)
{
// these cases are not interesting. Merge type is the same or derived. No difference.
if (!(expr.Type.IsArray() || expr.Type.IsInterfaceType() || expr.Type.IsDelegateType()))
{
return expr.Type;
}
// Dig through casts. We only need to check for expressions that -
// 1) implicit casts
// 2) transparently return operands, so we need to dig deeper
// 3) stack values
switch (expr.Kind)
{
case BoundKind.Conversion:
var conversion = (BoundConversion)expr;
var conversionKind = conversion.ConversionKind;
if (conversionKind.IsImplicitConversion() &&
conversionKind != ConversionKind.MethodGroup &&
conversionKind != ConversionKind.NullLiteral)
{
return StackMergeType(conversion.Operand);
}
break;
case BoundKind.AssignmentOperator:
var assignment = (BoundAssignmentOperator)expr;
return StackMergeType(assignment.Right);
case BoundKind.Sequence:
var sequence = (BoundSequence)expr;
return StackMergeType(sequence.Value);
case BoundKind.Local:
var local = (BoundLocal)expr;
if (this.IsStackLocal(local.LocalSymbol))
{
// stack value, we cannot be sure what it is
return null;
}
break;
case BoundKind.Dup:
// stack value, we cannot be sure what it is
return null;
}
return expr.Type;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:64,代码来源:EmitExpression.cs
示例14: TargetIsNotOnHeap
// returns True when assignment target is definitely not on the heap
private static bool TargetIsNotOnHeap(BoundExpression left)
{
switch (left.Kind)
{
case BoundKind.Parameter:
return ((BoundParameter)left).ParameterSymbol.RefKind == RefKind.None;
case BoundKind.Local:
// NOTE: stack locals are either homeless or refs, no need to special case them
// they will never be assigned in-place.
return ((BoundLocal)left).LocalSymbol.RefKind == RefKind.None;
}
return false;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:16,代码来源:EmitExpression.cs
示例15: PartialCtorResultCannotEscape
// partial ctor results are not observable when target is not on the heap.
// we also must not be in a try, otherwise if ctor throws
// partially assigned value may be observed in the handler.
private bool PartialCtorResultCannotEscape(BoundExpression left)
{
if (TargetIsNotOnHeap(left))
{
if (_tryNestingLevel != 0)
{
var local = left as BoundLocal;
if (local != null && !_builder.PossiblyDefinedOutsideOfTry(GetLocal(local)))
{
// local defined inside immediate Try - cannot escape
return true;
}
// local defined outside of immediate try or it is a parameter - can escape
return false;
}
// we are not in a try - locals, parameters cannot escape
return true;
}
// left is a reference, partial initializations can escape.
return false;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:27,代码来源:EmitExpression.cs
示例16: GenerateMethodBody
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
{
AnonymousTypeManager manager = ((AnonymousTypeTemplateSymbol)this.ContainingType).Manager;
SyntheticBoundNodeFactory F = this.CreateBoundNodeFactory(compilationState, diagnostics);
// Method body:
//
// {
// return String.Format(
// "{ <name1> = {0}", <name2> = {1}", ... <nameN> = {N-1}",
// this.backingFld_1,
// this.backingFld_2,
// ...
// this.backingFld_N
// }
// Type expression
AnonymousTypeTemplateSymbol anonymousType = (AnonymousTypeTemplateSymbol)this.ContainingType;
// build arguments
int fieldCount = anonymousType.Properties.Length;
BoundExpression retExpression = null;
if (fieldCount > 0)
{
// we do have fields, so have to use String.Format(...)
BoundExpression[] arguments = new BoundExpression[fieldCount];
// process properties
PooledStringBuilder formatString = PooledStringBuilder.GetInstance();
for (int i = 0; i < fieldCount; i++)
{
AnonymousTypePropertySymbol property = anonymousType.Properties[i];
// build format string
formatString.Builder.AppendFormat(i == 0 ? "{{{{ {0} = {{{1}}}" : ", {0} = {{{1}}}", property.Name, i);
// build argument
arguments[i] = F.Convert(manager.System_Object,
new BoundLoweredConditionalAccess(F.Syntax,
F.Field(F.This(), property.BackingField),
null,
F.Call(new BoundConditionalReceiver(
F.Syntax,
id: i,
type: property.BackingField.Type), manager.System_Object__ToString),
null,
id: i,
type: manager.System_String),
ConversionKind.ImplicitReference);
}
formatString.Builder.Append(" }}");
// add format string argument
BoundExpression format = F.Literal(formatString.ToStringAndFree());
// Generate expression for return statement
// retExpression <= System.String.Format(args)
var formatMethod = manager.System_String__Format_IFormatProvider;
retExpression = F.StaticCall(manager.System_String, formatMethod, F.Null(formatMethod.Parameters[0].Type), format, F.Array(manager.System_Object, arguments));
}
else
{
// this is an empty anonymous type, just return "{ }"
retExpression = F.Literal("{ }");
}
F.CloseMethod(F.Block(F.Return(retExpression)));
}
开发者ID:GloryChou,项目名称:roslyn,代码行数:69,代码来源:AnonymousTypeMethodBodySynthesizer.cs
示例17: ConvertToLocalType
internal static BoundExpression ConvertToLocalType(CSharpCompilation compilation, BoundExpression expr, TypeSymbol type, DiagnosticBag diagnostics)
{
if (type.IsPointerType())
{
var syntax = expr.Syntax;
var intPtrType = compilation.GetSpecialType(SpecialType.System_IntPtr);
Binder.ReportUseSiteDiagnostics(intPtrType, diagnostics, syntax);
MethodSymbol conversionMethod;
if (Binder.TryGetSpecialTypeMember(compilation, SpecialMember.System_IntPtr__op_Explicit_ToPointer, syntax, diagnostics, out conversionMethod))
{
var temp = ConvertToLocalTypeHelper(compilation, expr, intPtrType, diagnostics);
expr = BoundCall.Synthesized(
syntax,
receiverOpt: null,
method: conversionMethod,
arg0: temp);
}
else
{
return new BoundBadExpression(
syntax,
LookupResultKind.Empty,
ImmutableArray<Symbol>.Empty,
ImmutableArray.Create<BoundNode>(expr),
type);
}
}
return ConvertToLocalTypeHelper(compilation, expr, type, diagnostics);
}
开发者ID:orthoxerox,项目名称:roslyn,代码行数:30,代码来源:PlaceholderLocalSymbol.cs
示例18: EmitFieldLoadReceiverAddress
// In special case of loading the sequence of field accesses we can perform all the
// necessary field loads using the following IL:
//
// <expr>.a.b...y.z
// |
// V
// Unbox -or- Load.Ref (<expr>)
// Ldflda a
// Ldflda b
// ...
// Ldflda y
// Ldfld z
//
// Returns 'true' if the receiver was actually emitted this way
private bool EmitFieldLoadReceiverAddress(BoundExpression receiver)
{
if (receiver == null || !receiver.Type.IsValueType)
{
return false;
}
else if (receiver.Kind == BoundKind.Conversion)
{
var conversion = (BoundConversion)receiver;
if (conversion.ConversionKind == ConversionKind.Unboxing)
{
EmitExpression(conversion.Operand, true);
_builder.EmitOpCode(ILOpCode.Unbox);
EmitSymbolToken(receiver.Type, receiver.Syntax);
return true;
}
}
else if (receiver.Kind == BoundKind.FieldAccess)
{
var fieldAccess = (BoundFieldAccess)receiver;
var field = fieldAccess.FieldSymbol;
if (!field.IsStatic && EmitFieldLoadReceiverAddress(fieldAccess.ReceiverOpt))
{
Debug.Assert(!field.IsVolatile, "volatile valuetype fields are unexpected");
_builder.EmitOpCode(ILOpCode.Ldflda);
EmitSymbolToken(field, fieldAccess.Syntax);
return true;
}
}
return false;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:48,代码来源:EmitExpression.cs
示例19: EmitExpressionCore
private void EmitExpressionCore(BoundExpression expression, bool used)
{
switch (expression.Kind)
{
case BoundKind.AssignmentOperator:
EmitAssignmentExpression((BoundAssignmentOperator)expression, used ? UseKind.UsedAsValue : UseKind.Unused);
break;
case BoundKind.Call:
EmitCallExpression((BoundCall)expression, used ? UseKind.UsedAsValue : UseKind.Unused);
break;
case BoundKind.ObjectCreationExpression:
EmitObjectCreationExpression((BoundObjectCreationExpression)expression, used);
break;
case BoundKind.DelegateCreationExpression:
EmitDelegateCreationExpression((BoundDelegateCreationExpression)expression, used);
break;
case BoundKind.ArrayCreation:
EmitArrayCreationExpression((BoundArrayCreation)expression, used);
break;
case BoundKind.StackAllocArrayCreation:
EmitStackAllocArrayCreationExpression((BoundStackAllocArrayCreation)expression, used);
break;
case BoundKind.Conversion:
EmitConversionExpression((BoundConversion)expression, used);
break;
case BoundKind.Local:
EmitLocalLoad((BoundLocal)expression, used);
break;
case BoundKind.Dup:
EmitDupExpression((BoundDup)expression, used);
break;
case BoundKind.Parameter:
if (used) // unused parameter has no side-effects
{
EmitParameterLoad((BoundParameter)expression);
}
break;
case BoundKind.FieldAccess:
EmitFieldLoad((BoundFieldAccess)expression, used);
break;
case BoundKind.ArrayAccess:
EmitArrayElementLoad((BoundArrayAccess)expression, used);
break;
case BoundKind.ArrayLength:
EmitArrayLength((BoundArrayLength)expression, used);
break;
case BoundKind.ThisReference:
if (used) // unused this has no side-effects
{
EmitThisReferenceExpression((BoundThisReference)expression);
}
break;
case BoundKind.PreviousSubmissionReference:
// Script references are lowered to a this reference and a field access.
throw ExceptionUtilities.UnexpectedValue(expression.Kind);
case BoundKind.BaseReference:
if (used) // unused base has no side-effects
{
var thisType = _method.ContainingType;
_builder.EmitOpCode(ILOpCode.Ldarg_0);
if (thisType.IsValueType)
{
EmitLoadIndirect(thisType, expression.Syntax);
EmitBox(thisType, expression.Syntax);
}
}
break;
case BoundKind.Sequence:
EmitSequenceExpression((BoundSequence)expression, used);
break;
case BoundKind.SequencePointExpression:
EmitSequencePointExpression((BoundSequencePointExpression)expression, used);
break;
case BoundKind.UnaryOperator:
EmitUnaryOperatorExpression((BoundUnaryOperator)expression, used);
break;
case BoundKind.BinaryOperator:
EmitBinaryOperatorExpression((BoundBinaryOperator)expression, used);
break;
case BoundKind.NullCoalescingOperator:
//.........这里部分代码省略.........
开发者ID:tvsonar,项目名称:roslyn,代码行数:101,代码来源:EmitExpression.cs
示例20: CanUseCallOnRefTypeReceiver
/// <summary>
/// Used to decide if we need to emit call or callvirt.
/// It basically checks if the receiver expression cannot be null, but it is not 100% precise.
/// There are cases where it really can be null, but we do not care.
/// </summary>
private bool CanUseCallOnRefTypeReceiver(BoundExpression receiver)
{
// It seems none of the ways that could produce a receiver typed as a type param
// can guarantee that it is not null.
if (receiver.Type.IsTypeParameter())
{
return false;
}
Debug.Assert(receiver.Type.IsVerifierReference(), "this is not a reference");
Debug.Assert(receiver.Kind != BoundKind.BaseReference, "base should always use call");
var constVal = receiver.ConstantValue;
if (constVal != null)
{
// only when this is a constant Null, we need a callvirt
return !constVal.IsNull;
}
switch (receiver.Kind)
{
case BoundKind.ArrayCreation:
return true;
case BoundKind.ObjectCreationExpression:
//NOTE: there are cases involving ProxyAttribute
//where newobj may produce null
return true;
case BoundKind.Conversion:
var conversion = (BoundConversion)receiver;
switch (conversion.ConversionKind)
{
case ConversionKind.Boxing:
//NOTE: boxing can produce null for Nullable, but any call through that
//will result in null reference exceptions anyways.
return true;
case ConversionKind.MethodGroup:
case ConversionKind.AnonymousFunction:
return true;
case ConversionKind.ExplicitReference:
case ConversionKind.ImplicitReference:
return CanUseCallOnRefTypeReceiver(conversion.Operand);
}
break;
case BoundKind.ThisReference:
//NOTE: these actually can be null if called from a different language
//if that has already happen, we will just propagate the behavior.
return true;
case BoundKind.DelegateCreationExpression:
return true;
case BoundKind.Sequence:
var seqValue = ((BoundSequence)(receiver)).Value;
return CanUseCallOnRefTypeReceiver(seqValue);
case BoundKind.AssignmentOperator:
var rhs = ((BoundAssignmentOperator)receiver).Right;
return CanUseCallOnRefTypeReceiver(rhs);
case BoundKind.TypeOfOperator:
return true;
case BoundKind.FieldAccess:
return ((BoundFieldAccess)receiver).FieldSymbol.IsCapturedFrame;
case BoundKind.ConditionalReceiver:
return true;
//TODO: there could be more cases where we can be sure that receiver is not a null.
}
return false;
}
开发者ID:tvsonar,项目名称:roslyn,代码行数:84,代码来源:EmitExpression.cs
注:本文中的BoundExpression类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论