本文整理汇总了C#中Microsoft.CodeAnalysis.CSharp.BoundExpression.IsLiteralNull方法的典型用法代码示例。如果您正苦于以下问题:C# BoundExpression.IsLiteralNull方法的具体用法?C# BoundExpression.IsLiteralNull怎么用?C# BoundExpression.IsLiteralNull使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CodeAnalysis.CSharp.BoundExpression
的用法示例。
在下文中一共展示了BoundExpression.IsLiteralNull方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: RewriteNullableNullEquality
private BoundExpression RewriteNullableNullEquality(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
TypeSymbol returnType)
{
// This handles the case where we have a nullable user-defined struct type compared against null, eg:
//
// struct S {} ... S? s = whatever; if (s != null)
//
// If S does not define an overloaded != operator then this is lowered to s.HasValue.
//
// If the type already has a user-defined or built-in operator then comparing to null is
// treated as a lifted equality operator.
Debug.Assert(loweredLeft != null);
Debug.Assert(loweredRight != null);
Debug.Assert((object)returnType != null);
Debug.Assert(returnType.SpecialType == SpecialType.System_Boolean);
Debug.Assert(loweredLeft.IsLiteralNull() != loweredRight.IsLiteralNull());
BoundExpression nullable = loweredRight.IsLiteralNull() ? loweredLeft : loweredRight;
// If the other side is known to always be null then we can simply generate true or false, as appropriate.
if (NullableNeverHasValue(nullable))
{
return MakeLiteral(syntax, ConstantValue.Create(kind == BinaryOperatorKind.NullableNullEqual), returnType);
}
BoundExpression nonNullValue = NullableAlwaysHasValue(nullable);
if (nonNullValue != null)
{
// We have something like "if (new int?(M()) != null)". We can optimize this to
// evaluate M() for its side effects and then result in true or false, as appropriate.
// TODO: If the expression has no side effects then it can be optimized away here as well.
return new BoundSequence(
syntax: syntax,
locals: ImmutableArray<LocalSymbol>.Empty,
sideEffects: ImmutableArray.Create<BoundExpression>(nonNullValue),
value: MakeBooleanConstant(syntax, kind == BinaryOperatorKind.NullableNullNotEqual),
type: returnType);
}
// arr?.Length == null
var conditionalAccess = nullable as BoundLoweredConditionalAccess;
if (conditionalAccess != null &&
(conditionalAccess.WhenNullOpt == null || conditionalAccess.WhenNullOpt.IsDefaultValue()))
{
BoundExpression whenNotNull = RewriteNullableNullEquality(
syntax,
kind,
conditionalAccess.WhenNotNull,
loweredLeft.IsLiteralNull() ? loweredLeft : loweredRight,
returnType);
var whenNull = kind == BinaryOperatorKind.NullableNullEqual ? MakeBooleanConstant(syntax, true) : null;
return conditionalAccess.Update(conditionalAccess.Receiver, conditionalAccess.HasValueMethodOpt, whenNotNull, whenNull, conditionalAccess.Id, whenNotNull.Type);
}
BoundExpression call = MakeNullableHasValue(syntax, nullable);
BoundExpression result = kind == BinaryOperatorKind.NullableNullNotEqual ?
call :
new BoundUnaryOperator(syntax, UnaryOperatorKind.BoolLogicalNegation, call, ConstantValue.NotAvailable, null, LookupResultKind.Viable, returnType);
return result;
}
示例2: RewriteDelegateOperation
private BoundExpression RewriteDelegateOperation(CSharpSyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type, SpecialMember member)
{
MethodSymbol method;
if (operatorKind == BinaryOperatorKind.DelegateEqual || operatorKind == BinaryOperatorKind.DelegateNotEqual)
{
method = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member);
if (loweredRight.IsLiteralNull() ||
loweredLeft.IsLiteralNull() ||
(object)(method = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member)) == null)
{
// use reference equality in the absence of overloaded operators for System.Delegate.
operatorKind = (operatorKind & (~BinaryOperatorKind.Delegate)) | BinaryOperatorKind.Object;
return new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, default(ConstantValue), null, LookupResultKind.Empty, type);
}
}
else
{
method = GetSpecialTypeMethod(syntax, member);
}
Debug.Assert((object)method != null);
BoundExpression call = _inExpressionLambda
? new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, null, method, default(LookupResultKind), method.ReturnType)
: (BoundExpression)BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight);
BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ?
MakeConversionNode(syntax, call, Conversion.ExplicitReference, type, @checked: false) :
call;
return result;
}
示例3: GetAnonymousTypeFieldType
/// <summary>
/// Returns the type to be used as a field type; generates errors in case the type is not
/// supported for anonymous type fields.
/// </summary>
private TypeSymbol GetAnonymousTypeFieldType(BoundExpression expression, CSharpSyntaxNode errorSyntax, DiagnosticBag diagnostics, ref bool hasError)
{
object errorArg = null;
TypeSymbol expressionType = expression.Type;
if (!expression.HasAnyErrors)
{
if (expression.HasExpressionType())
{
if (expressionType.SpecialType == SpecialType.System_Void)
{
errorArg = expressionType;
expressionType = CreateErrorType(SyntaxFacts.GetText(SyntaxKind.VoidKeyword));
}
else if (expressionType.IsUnsafe())
{
errorArg = expressionType;
// CONSIDER: we could use an explicit error type instead of the unsafe type.
}
else if (expressionType.IsRestrictedType())
{
errorArg = expressionType;
}
}
else
{
if (expression.Kind == BoundKind.UnboundLambda)
{
errorArg = ((UnboundLambda)expression).MessageID.Localize();
}
else if (expression.Kind == BoundKind.MethodGroup)
{
errorArg = MessageID.IDS_MethodGroup.Localize();
}
else
{
Debug.Assert(expression.IsLiteralNull(), "How did we successfully bind an expression without a type?");
errorArg = MessageID.IDS_NULL.Localize();
}
}
}
if ((object)expressionType == null)
{
expressionType = CreateErrorType("error");
}
if (errorArg != null)
{
hasError = true;
Error(diagnostics, ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, errorSyntax, errorArg);
// NOTE: ERR_QueryRangeVariableAssignedBadValue is being generated
// by query binding code and never reach this point
}
return expressionType;
}
示例4: ClassifyNullLiteralConversion
private static ConversionKind ClassifyNullLiteralConversion(BoundExpression source, TypeSymbol destination)
{
Debug.Assert((object)source != null);
Debug.Assert((object)destination != null);
if (!source.IsLiteralNull())
{
return ConversionKind.NoConversion;
}
// SPEC: An implicit conversion exists from the null literal to any nullable type.
if (destination.IsNullableType())
{
// The spec defines a "null literal conversion" specifically as a conversion from
// null to nullable type.
return ConversionKind.NullLiteral;
}
// SPEC: An implicit conversion exists from the null literal to any reference type.
// SPEC: An implicit conversion exists from the null literal to type parameter T,
// SPEC: provided T is known to be a reference type. [...] The conversion [is] classified
// SPEC: as implicit reference conversion.
if (destination.IsReferenceType)
{
return ConversionKind.ImplicitReference;
}
// SPEC: The set of implicit conversions is extended to include...
// SPEC: ... from the null literal to any pointer type.
if (destination is PointerTypeSymbol)
{
return ConversionKind.NullToPointer;
}
return ConversionKind.NoConversion;
}
示例5: BindSimpleBinaryOperator
private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, DiagnosticBag diagnostics,
BoundExpression left, BoundExpression right, ref int compoundStringLength)
{
BinaryOperatorKind kind = SyntaxKindToBinaryOperatorKind(node.Kind());
// If either operand is bad, don't try to do binary operator overload resolution; that will just
// make cascading errors.
if (left.HasAnyErrors || right.HasAnyErrors)
{
// NOTE: no user-defined conversion candidates
return new BoundBinaryOperator(node, kind, left, right, ConstantValue.NotAvailable, null, LookupResultKind.Empty, GetBinaryOperatorErrorType(kind, diagnostics, node), true);
}
TypeSymbol leftType = left.Type;
TypeSymbol rightType = right.Type;
if ((object)leftType != null && leftType.IsDynamic() || (object)rightType != null && rightType.IsDynamic())
{
return BindDynamicBinaryOperator(node, kind, left, right, diagnostics);
}
// SPEC OMISSION: The C# 2.0 spec had a line in it that noted that the expressions "null == null"
// SPEC OMISSION: and "null != null" were to be automatically treated as the appropriate constant;
// SPEC OMISSION: overload resolution was to be skipped. That's because a strict reading
// SPEC OMISSION: of the overload resolution spec shows that overload resolution would give an
// SPEC OMISSION: ambiguity error for this case; the expression is ambiguous between the int?,
// SPEC OMISSION: bool? and string versions of equality. This line was accidentally edited
// SPEC OMISSION: out of the C# 3 specification; we should re-insert it.
bool leftNull = left.IsLiteralNull();
bool rightNull = right.IsLiteralNull();
bool isEquality = kind == BinaryOperatorKind.Equal || kind == BinaryOperatorKind.NotEqual;
if (isEquality && leftNull && rightNull)
{
return new BoundLiteral(node, ConstantValue.Create(kind == BinaryOperatorKind.Equal), GetSpecialType(SpecialType.System_Boolean, diagnostics, node));
}
// SPEC: For an operation of one of the forms x == null, null == x, x != null, null != x,
// SPEC: where x is an expression of nullable type, if operator overload resolution
// SPEC: fails to find an applicable operator, the result is instead computed from
// SPEC: the HasValue property of x.
// Note that the spec says "fails to find an applicable operator", not "fails to
// find a unique best applicable operator." For example:
// struct X {
// public static bool operator ==(X? x, double? y) {...}
// public static bool operator ==(X? x, decimal? y) {...}
//
// The comparison "x == null" should produce an ambiguity error rather
// that being bound as !x.HasValue.
//
LookupResultKind resultKind;
ImmutableArray<MethodSymbol> originalUserDefinedOperators;
var best = this.BinaryOperatorOverloadResolution(kind, left, right, node, diagnostics, out resultKind, out originalUserDefinedOperators);
// However, as an implementation detail, we never "fail to find an applicable
// operator" during overload resolution if we have x == null, etc. We always
// find at least the reference conversion object == object; the overload resolution
// code does not reject that. Therefore what we should do is only bind
// "x == null" as a nullable-to-null comparison if overload resolution chooses
// the reference conversion.
BoundExpression resultLeft = left;
BoundExpression resultRight = right;
MethodSymbol resultMethod = null;
ConstantValue resultConstant = null;
BinaryOperatorKind resultOperatorKind;
TypeSymbol resultType;
bool hasErrors;
if (!best.HasValue)
{
resultOperatorKind = kind;
resultType = CreateErrorType();
hasErrors = true;
}
else
{
var signature = best.Signature;
bool isObjectEquality = signature.Kind == BinaryOperatorKind.ObjectEqual || signature.Kind == BinaryOperatorKind.ObjectNotEqual;
bool isNullableEquality = (object)signature.Method == null &&
(signature.Kind.Operator() == BinaryOperatorKind.Equal || signature.Kind.Operator() == BinaryOperatorKind.NotEqual) &&
(leftNull && (object)rightType != null && rightType.IsNullableType() ||
rightNull && (object)leftType != null && leftType.IsNullableType());
if (isNullableEquality)
{
resultOperatorKind = kind | BinaryOperatorKind.NullableNull;
resultType = GetSpecialType(SpecialType.System_Boolean, diagnostics, node);
hasErrors = false;
}
else
{
resultOperatorKind = signature.Kind;
resultType = signature.ReturnType;
//.........这里部分代码省略.........
示例6: VisitBinaryOperator
private BoundExpression VisitBinaryOperator(BinaryOperatorKind opKind, MethodSymbol methodOpt, TypeSymbol type, BoundExpression left, BoundExpression right)
{
bool isChecked, isLifted, requiresLifted;
string opName = GetBinaryOperatorName(opKind, out isChecked, out isLifted, out requiresLifted);
// Fix up the null value for a nullable comparison vs null
if ((object)left.Type == null && left.IsLiteralNull())
{
left = _bound.Default(right.Type);
}
if ((object)right.Type == null && right.IsLiteralNull())
{
right = _bound.Default(left.Type);
}
var loweredLeft = Visit(left);
var loweredRight = Visit(right);
// Enums are handled as per their promoted underlying type
switch (opKind.OperandTypes())
{
case BinaryOperatorKind.Enum:
case BinaryOperatorKind.EnumAndUnderlying:
case BinaryOperatorKind.UnderlyingAndEnum:
{
var enumOperand = (opKind.OperandTypes() == BinaryOperatorKind.UnderlyingAndEnum) ? right : left;
var promotedType = PromotedType(enumOperand.Type.StrippedType().GetEnumUnderlyingType());
if (opKind.IsLifted())
{
promotedType = _nullableType.Construct(promotedType);
}
loweredLeft = PromoteEnumOperand(left, loweredLeft, promotedType, isChecked);
loweredRight = PromoteEnumOperand(right, loweredRight, promotedType, isChecked);
var result = MakeBinary(methodOpt, type, isLifted, requiresLifted, opName, loweredLeft, loweredRight);
return Demote(result, type, isChecked);
}
default:
return MakeBinary(methodOpt, type, isLifted, requiresLifted, opName, loweredLeft, loweredRight);
}
}
示例7: UseOnlyReferenceEquality
private bool UseOnlyReferenceEquality(BoundExpression left, BoundExpression right, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
return
BuiltInOperators.IsValidObjectEquality(Conversions, left.Type, left.IsLiteralNull(), right.Type, right.IsLiteralNull(), ref useSiteDiagnostics) &&
((object)left.Type == null || (!left.Type.IsDelegateType() && left.Type.SpecialType != SpecialType.System_String && left.Type.SpecialType != SpecialType.System_Delegate)) &&
((object)right.Type == null || (!right.Type.IsDelegateType() && right.Type.SpecialType != SpecialType.System_String && right.Type.SpecialType != SpecialType.System_Delegate));
}
示例8: IsLegalDynamicOperand
private static bool IsLegalDynamicOperand(BoundExpression operand)
{
Debug.Assert(operand != null);
TypeSymbol type = operand.Type;
// Literal null is a legal operand to a dynamic operation. The other typeless expressions --
// method groups, lambdas, anonymous methods -- are not.
// If the operand is of a class, interface, delegate, array, struct, enum, nullable
// or type param types, it's legal to use in a dynamic expression. In short, the type
// must be one that is convertible to object.
if ((object)type == null)
{
return operand.IsLiteralNull();
}
// Pointer types and very special types are not convertible to object.
return !type.IsPointerType() && !type.IsRestrictedType() && type.SpecialType != SpecialType.System_Void;
}
示例9: GenerateImplicitConversionError
protected void GenerateImplicitConversionError(DiagnosticBag diagnostics, CSharpSyntaxNode syntax,
Conversion conversion, BoundExpression expression, TypeSymbol targetType)
{
Debug.Assert(expression != null);
Debug.Assert((object)targetType != null);
if (targetType.TypeKind == TypeKind.Error)
{
return;
}
if (expression.Kind == BoundKind.BadExpression)
{
return;
}
if (expression.Kind == BoundKind.UnboundLambda)
{
GenerateAnonymousFunctionConversionError(diagnostics, syntax, (UnboundLambda)expression, targetType);
return;
}
var sourceType = expression.Type;
if ((object)sourceType != null)
{
GenerateImplicitConversionError(diagnostics, this.Compilation, syntax, conversion, sourceType, targetType, expression.ConstantValue);
return;
}
if (expression.IsLiteralNull())
{
if (targetType.TypeKind == TypeKind.TypeParameter)
{
Error(diagnostics, ErrorCode.ERR_TypeVarCantBeNull, syntax, targetType);
return;
}
if (targetType.IsValueType)
{
Error(diagnostics, ErrorCode.ERR_ValueCantBeNull, syntax, targetType);
return;
}
}
if (expression.Kind == BoundKind.MethodGroup)
{
var methodGroup = (BoundMethodGroup)expression;
if (!Conversions.ReportDelegateMethodGroupDiagnostics(this, methodGroup, targetType, diagnostics))
{
var nodeForSquiggle = syntax;
while (nodeForSquiggle.Kind() == SyntaxKind.ParenthesizedExpression)
{
nodeForSquiggle = ((ParenthesizedExpressionSyntax)nodeForSquiggle).Expression;
}
if (nodeForSquiggle.Kind() == SyntaxKind.SimpleMemberAccessExpression || nodeForSquiggle.Kind() == SyntaxKind.PointerMemberAccessExpression)
{
nodeForSquiggle = ((MemberAccessExpressionSyntax)nodeForSquiggle).Name;
}
var location = nodeForSquiggle.Location;
if (ReportDelegateInvokeUseSiteDiagnostic(diagnostics, targetType, location))
{
return;
}
Error(diagnostics,
targetType.IsDelegateType() ? ErrorCode.ERR_MethDelegateMismatch : ErrorCode.ERR_MethGrpToNonDel,
location, methodGroup.Name, targetType);
}
return;
}
Debug.Assert(expression.HasAnyErrors && expression.Kind != BoundKind.UnboundLambda, "Missing a case in implicit conversion error reporting");
}
示例10: GenerateImplicitConversionError
protected void GenerateImplicitConversionError(
DiagnosticBag diagnostics,
CSharpSyntaxNode syntax,
Conversion conversion,
BoundExpression operand,
TypeSymbol targetType)
{
Debug.Assert(operand != null);
Debug.Assert((object)targetType != null);
if (targetType.TypeKind == TypeKind.Error)
{
return;
}
if (operand.Kind == BoundKind.BadExpression)
{
return;
}
if (operand.Kind == BoundKind.UnboundLambda)
{
GenerateAnonymousFunctionConversionError(diagnostics, syntax, (UnboundLambda)operand, targetType);
return;
}
if (operand.Kind == BoundKind.TupleLiteral)
{
var tuple = (BoundTupleLiteral)operand;
var targetElementTypes = default(ImmutableArray<TypeSymbol>);
// If target is a tuple or compatible type with the same number of elements,
// report errors for tuple arguments that failed to convert, which would be more useful.
if (targetType.TryGetElementTypesIfTupleOrCompatible(out targetElementTypes) &&
targetElementTypes.Length == tuple.Arguments.Length)
{
GenerateImplicitConversionErrorsForTupleLiteralArguments(diagnostics, tuple.Arguments, targetElementTypes);
return;
}
// target is not compatible with source and source does not have a type
if ((object)tuple.Type == null)
{
Error(diagnostics, ErrorCode.ERR_ConversionNotTupleCompatible, syntax, tuple.Arguments.Length, targetType);
return;
}
// Otherwise it is just a regular conversion failure from T1 to T2.
}
var sourceType = operand.Type;
if ((object)sourceType != null)
{
GenerateImplicitConversionError(diagnostics, this.Compilation, syntax, conversion, sourceType, targetType, operand.ConstantValue);
return;
}
if (operand.IsLiteralNull())
{
if (targetType.TypeKind == TypeKind.TypeParameter)
{
Error(diagnostics, ErrorCode.ERR_TypeVarCantBeNull, syntax, targetType);
return;
}
if (targetType.IsValueType)
{
Error(diagnostics, ErrorCode.ERR_ValueCantBeNull, syntax, targetType);
return;
}
}
if (operand.Kind == BoundKind.MethodGroup)
{
var methodGroup = (BoundMethodGroup)operand;
if (!Conversions.ReportDelegateMethodGroupDiagnostics(this, methodGroup, targetType, diagnostics))
{
var nodeForSquiggle = syntax;
while (nodeForSquiggle.Kind() == SyntaxKind.ParenthesizedExpression)
{
nodeForSquiggle = ((ParenthesizedExpressionSyntax)nodeForSquiggle).Expression;
}
if (nodeForSquiggle.Kind() == SyntaxKind.SimpleMemberAccessExpression || nodeForSquiggle.Kind() == SyntaxKind.PointerMemberAccessExpression)
{
nodeForSquiggle = ((MemberAccessExpressionSyntax)nodeForSquiggle).Name;
}
var location = nodeForSquiggle.Location;
if (ReportDelegateInvokeUseSiteDiagnostic(diagnostics, targetType, location))
{
return;
}
Error(diagnostics,
targetType.IsDelegateType() ? ErrorCode.ERR_MethDelegateMismatch : ErrorCode.ERR_MethGrpToNonDel,
location, methodGroup.Name, targetType);
}
return;
//.........这里部分代码省略.........
示例11: Convert
public BoundExpression Convert(TypeSymbol type, BoundExpression arg, Conversion conversion, bool isChecked = false)
{
// NOTE: We can see user-defined conversions at this point because there are places in the bound tree where
// the binder stashes Conversion objects for later consumption (e.g. foreach, nullable, increment).
if ((object)conversion.Method != null && conversion.Method.Parameters[0].Type != arg.Type)
{
arg = Convert(conversion.Method.Parameters[0].Type, arg);
}
if (conversion.Kind == ConversionKind.ImplicitReference && arg.IsLiteralNull())
{
return Null(type);
}
return new BoundConversion(Syntax, arg, conversion, isChecked, true, null, type) { WasCompilerGenerated = true };
}
示例12: NullableNeverHasValue
private static bool NullableNeverHasValue(BoundExpression expression)
{
// CONSIDER: A sequence of side effects with an always-null expression as its value
// CONSIDER: can be optimized also. Should we?
if (expression.IsLiteralNull())
{
return true;
}
if (!expression.Type.IsNullableType())
{
return false;
}
// default(int?) never has a value.
if (expression.Kind == BoundKind.DefaultOperator)
{
return true;
}
// new int?() never has a value if there is no argument.
if (expression.Kind == BoundKind.ObjectCreationExpression)
{
if (((BoundObjectCreationExpression)expression).Arguments.Length == 0)
{
return true;
}
}
return false;
}
示例13: IsOperandErrors
private bool IsOperandErrors(CSharpSyntaxNode node, ref BoundExpression operand, DiagnosticBag diagnostics)
{
switch (operand.Kind)
{
case BoundKind.UnboundLambda:
case BoundKind.Lambda:
case BoundKind.MethodGroup: // New in Roslyn - see DevDiv #864740.
// operand for an is or as expression cannot be a lambda expression or method group
if (!operand.HasAnyErrors)
{
Error(diagnostics, ErrorCode.ERR_LambdaInIsAs, node);
operand = BadExpression(node, operand);
}
return true;
default:
if ((object)operand.Type == null && !operand.IsLiteralNull())
{
if (!operand.HasAnyErrors)
{
// Operator 'is' cannot be applied to operand of type '(int, <null>)'
Error(diagnostics, ErrorCode.ERR_BadUnaryOp, node, SyntaxFacts.GetText(SyntaxKind.IsKeyword), operand.Display);
}
return true;
}
break;
}
return operand.HasAnyErrors;
}