本文整理汇总了C#中Microsoft.CodeAnalysis.CSharp.BoundExpression.HasDynamicType方法的典型用法代码示例。如果您正苦于以下问题:C# BoundExpression.HasDynamicType方法的具体用法?C# BoundExpression.HasDynamicType怎么用?C# BoundExpression.HasDynamicType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Microsoft.CodeAnalysis.CSharp.BoundExpression
的用法示例。
在下文中一共展示了BoundExpression.HasDynamicType方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: MakeTruthTestForDynamicLogicalOperator
private BoundExpression MakeTruthTestForDynamicLogicalOperator(CSharpSyntaxNode syntax, BoundExpression loweredLeft, TypeSymbol boolean, MethodSymbol leftTruthOperator, bool negative)
{
if (loweredLeft.HasDynamicType())
{
Debug.Assert(leftTruthOperator == null);
return _dynamicFactory.MakeDynamicUnaryOperator(negative ? UnaryOperatorKind.DynamicFalse : UnaryOperatorKind.DynamicTrue, loweredLeft, boolean).ToExpression();
}
// Although the spec doesn't capture it we do the same that Dev11 does:
// Use implicit conversion to Boolean if it is defined on the static type of the left operand.
// If not the type has to implement IsTrue/IsFalse operator - we checked it during binding.
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
var conversion = _compilation.Conversions.ClassifyConversionFromExpression(loweredLeft, boolean, ref useSiteDiagnostics);
_diagnostics.Add(loweredLeft.Syntax, useSiteDiagnostics);
if (conversion.IsImplicit)
{
Debug.Assert(leftTruthOperator == null);
var converted = MakeConversionNode(loweredLeft, boolean, @checked: false);
if (negative)
{
return new BoundUnaryOperator(syntax, UnaryOperatorKind.BoolLogicalNegation, converted, ConstantValue.NotAvailable, MethodSymbol.None, LookupResultKind.Viable, boolean)
{
WasCompilerGenerated = true
};
}
else
{
return converted;
}
}
Debug.Assert(leftTruthOperator != null);
return BoundCall.Synthesized(syntax, null, leftTruthOperator, loweredLeft);
}
示例2: BindConditionalLogicalOperator
private BoundExpression BindConditionalLogicalOperator(BinaryExpressionSyntax node, BoundExpression left, BoundExpression right, DiagnosticBag diagnostics)
{
BinaryOperatorKind kind = SyntaxKindToBinaryOperatorKind(node.Kind());
Debug.Assert(kind == BinaryOperatorKind.LogicalAnd || kind == BinaryOperatorKind.LogicalOr);
// 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 candidate user-defined operators.
return new BoundBinaryOperator(node, kind, left, right, ConstantValue.NotAvailable, methodOpt: null,
resultKind: LookupResultKind.Empty, type: GetBinaryOperatorErrorType(kind, diagnostics, node), hasErrors: true);
}
// Let's take an easy out here. The vast majority of the time the operands will
// both be bool. This is the only situation in which the expression can be a
// constant expression, so do the folding now if we can.
if ((object)left.Type != null && left.Type.SpecialType == SpecialType.System_Boolean &&
(object)right.Type != null && right.Type.SpecialType == SpecialType.System_Boolean)
{
var constantValue = FoldBinaryOperator(node, kind | BinaryOperatorKind.Bool, left, right, SpecialType.System_Boolean, diagnostics);
// NOTE: no candidate user-defined operators.
return new BoundBinaryOperator(node, kind | BinaryOperatorKind.Bool, left, right, constantValue, methodOpt: null,
resultKind: LookupResultKind.Viable, type: left.Type, hasErrors: constantValue != null && constantValue.IsBad);
}
if (left.HasDynamicType() || right.HasDynamicType())
{
return BindDynamicBinaryOperator(node, kind, left, right, diagnostics);
}
LookupResultKind lookupResult;
ImmutableArray<MethodSymbol> originalUserDefinedOperators;
var best = this.BinaryOperatorOverloadResolution(kind, left, right, node, diagnostics, out lookupResult, out originalUserDefinedOperators);
// SPEC: If overload resolution fails to find a single best operator, or if overload
// SPEC: resolution selects one of the predefined integer logical operators, a binding-
// SPEC: time error occurs.
//
// SPEC OMISSION: We should probably clarify that the enum logical operators count as
// SPEC OMISSION: integer logical operators. Basically the rule here should actually be:
// SPEC OMISSION: if overload resolution selects something other than a user-defined
// SPEC OMISSION: operator or the built in not-lifted operator on bool, an error occurs.
//
if (!best.HasValue)
{
ReportBinaryOperatorError(node, diagnostics, node.OperatorToken, left, right, lookupResult);
}
else
{
// There are two non-error possibilities. Either both operands are implicitly convertible to
// bool, or we've got a valid user-defined operator.
BinaryOperatorSignature signature = best.Signature;
bool bothBool = signature.LeftType.SpecialType == SpecialType.System_Boolean &&
signature.RightType.SpecialType == SpecialType.System_Boolean;
MethodSymbol trueOperator = null, falseOperator = null;
if (!bothBool && !signature.Kind.IsUserDefined())
{
ReportBinaryOperatorError(node, diagnostics, node.OperatorToken, left, right, lookupResult);
}
else if (bothBool || IsValidUserDefinedConditionalLogicalOperator(node, signature, diagnostics, out trueOperator, out falseOperator))
{
var resultLeft = CreateConversion(left, best.LeftConversion, signature.LeftType, diagnostics);
var resultRight = CreateConversion(right, best.RightConversion, signature.RightType, diagnostics);
var resultKind = kind | signature.Kind.OperandTypes();
if (signature.Kind.IsLifted())
{
resultKind |= BinaryOperatorKind.Lifted;
}
if (resultKind.IsUserDefined())
{
Debug.Assert(trueOperator != null && falseOperator != null);
return new BoundUserDefinedConditionalLogicalOperator(
node,
resultKind,
resultLeft,
resultRight,
signature.Method,
trueOperator,
falseOperator,
lookupResult,
originalUserDefinedOperators,
signature.ReturnType);
}
else
{
Debug.Assert(bothBool);
return new BoundBinaryOperator(
node,
//.........这里部分代码省略.........
示例3: BindEventAssignment
/// <summary>
/// For "receiver.event += expr", produce "receiver.add_event(expr)".
/// For "receiver.event -= expr", produce "receiver.remove_event(expr)".
/// </summary>
/// <remarks>
/// Performs some validation of the accessor that couldn't be done in CheckEventValueKind, because
/// the specific accessor wasn't known.
/// </remarks>
private BoundExpression BindEventAssignment(AssignmentExpressionSyntax node, BoundEventAccess left, BoundExpression right, BinaryOperatorKind opKind, DiagnosticBag diagnostics)
{
Debug.Assert(opKind == BinaryOperatorKind.Addition || opKind == BinaryOperatorKind.Subtraction);
bool hasErrors = false;
EventSymbol eventSymbol = left.EventSymbol;
BoundExpression receiverOpt = left.ReceiverOpt;
TypeSymbol delegateType = left.Type;
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
Conversion argumentConversion = this.Conversions.ClassifyConversionFromExpression(right, delegateType, ref useSiteDiagnostics);
if (!argumentConversion.IsImplicit || !argumentConversion.IsValid) // NOTE: dev10 appears to allow user-defined conversions here.
{
hasErrors = true;
if (delegateType.IsDelegateType()) // Otherwise, suppress cascading.
{
GenerateImplicitConversionError(diagnostics, node, argumentConversion, right, delegateType);
}
}
BoundExpression argument = CreateConversion(right, argumentConversion, delegateType, diagnostics);
bool isAddition = opKind == BinaryOperatorKind.Addition;
MethodSymbol method = isAddition ? eventSymbol.AddMethod : eventSymbol.RemoveMethod;
TypeSymbol type;
if ((object)method == null)
{
type = this.GetSpecialType(SpecialType.System_Void, diagnostics, node); //we know the return type would have been void
// There will be a diagnostic on the declaration if it is from source.
if (!eventSymbol.OriginalDefinition.IsFromCompilation(this.Compilation))
{
// CONSIDER: better error code? ERR_EventNeedsBothAccessors?
Error(diagnostics, ErrorCode.ERR_MissingPredefinedMember, node, delegateType, SourceEventSymbol.GetAccessorName(eventSymbol.Name, isAddition));
}
}
else if (eventSymbol.IsWindowsRuntimeEvent)
{
// Return type is actually void because this call will be later encapsulated in a call
// to WindowsRuntimeMarshal.AddEventHandler or RemoveEventHandler, which has the return
// type of void.
type = this.GetSpecialType(SpecialType.System_Void, diagnostics, node);
}
else
{
type = method.ReturnType;
if (!this.IsAccessible(method, ref useSiteDiagnostics, this.GetAccessThroughType(receiverOpt)))
{
// CONSIDER: depending on the accessibility (e.g. if it's private), dev10 might just report the whole event bogus.
Error(diagnostics, ErrorCode.ERR_BadAccess, node, method);
hasErrors = true;
}
}
diagnostics.Add(node, useSiteDiagnostics);
return new BoundEventAssignmentOperator(
syntax: node,
@event: eventSymbol,
isAddition: isAddition,
isDynamic: right.HasDynamicType(),
receiverOpt: receiverOpt,
argument: argument,
type: type,
hasErrors: hasErrors);
}
示例4: BindUnaryOperatorCore
private BoundExpression BindUnaryOperatorCore(CSharpSyntaxNode node, string operatorText, BoundExpression operand, DiagnosticBag diagnostics)
{
UnaryOperatorKind kind = SyntaxKindToUnaryOperatorKind(node.Kind());
bool isOperandTypeNull = (object)operand.Type == null;
if (isOperandTypeNull)
{
// Dev10 does not allow unary prefix operators to be applied to the null literal
// (or other typeless expressions).
Error(diagnostics, ErrorCode.ERR_BadUnaryOp, node, operatorText, operand.Display);
}
// If the operand is bad, avoid generating cascading errors.
if (operand.HasAnyErrors || isOperandTypeNull)
{
// Note: no candidate user-defined operators.
return new BoundUnaryOperator(node, kind, operand, ConstantValue.NotAvailable,
methodOpt: null,
resultKind: LookupResultKind.Empty,
type: GetSpecialType(SpecialType.System_Object, diagnostics, node),
hasErrors: true);
}
// If the operand is dynamic then we do not attempt to do overload resolution at compile
// time; we defer that until runtime. If we did overload resolution then the dynamic
// operand would be implicitly convertible to the parameter type of each operator
// signature, and therefore every operator would be an applicable candidate. Instead
// of changing overload resolution to handle dynamic, we just handle it here and let
// overload resolution implement the specification.
if (operand.HasDynamicType())
{
return new BoundUnaryOperator(
syntax: node,
operatorKind: kind.WithType(UnaryOperatorKind.Dynamic).WithOverflowChecksIfApplicable(CheckOverflowAtRuntime),
operand: operand,
constantValueOpt: ConstantValue.NotAvailable,
methodOpt: null,
resultKind: LookupResultKind.Viable,
type: operand.Type);
}
LookupResultKind resultKind;
ImmutableArray<MethodSymbol> originalUserDefinedOperators;
var best = this.UnaryOperatorOverloadResolution(kind, operand, node, diagnostics, out resultKind, out originalUserDefinedOperators);
if (!best.HasValue)
{
ReportUnaryOperatorError(node, diagnostics, operatorText, operand, resultKind);
return new BoundUnaryOperator(
node,
kind,
operand,
ConstantValue.NotAvailable,
null,
resultKind,
originalUserDefinedOperators,
GetSpecialType(SpecialType.System_Object, diagnostics, node),
hasErrors: true);
}
var signature = best.Signature;
var resultOperand = CreateConversion(operand.Syntax, operand, best.Conversion, false, signature.OperandType, diagnostics);
var resultType = signature.ReturnType;
UnaryOperatorKind resultOperatorKind = signature.Kind;
var resultMethod = signature.Method;
var resultConstant = FoldUnaryOperator(node, resultOperatorKind, resultOperand, resultType.SpecialType, diagnostics);
return new BoundUnaryOperator(
node,
resultOperatorKind.WithOverflowChecksIfApplicable(CheckOverflowAtRuntime),
resultOperand,
resultConstant,
resultMethod,
resultKind,
resultType);
}
示例5: GetAwaitableExpressionInfo
/// <summary>
/// Finds and validates the required members of an awaitable expression, as described in spec 7.7.7.1.
/// </summary>
/// <returns>True if the expression is awaitable; false otherwise.</returns>
private bool GetAwaitableExpressionInfo(
BoundExpression expression,
ref MethodSymbol getAwaiter,
ref PropertySymbol isCompleted,
ref MethodSymbol getResult,
CSharpSyntaxNode node,
DiagnosticBag diagnostics)
{
if (!ValidateAwaitedExpression(expression, node, diagnostics))
{
return false;
}
if (expression.HasDynamicType())
{
return true;
}
if (!GetGetAwaiterMethod(expression, node, diagnostics, out getAwaiter))
{
return false;
}
TypeSymbol awaiterType = getAwaiter.ReturnType;
return GetIsCompletedProperty(awaiterType, node, expression.Type, diagnostics, out isCompleted)
&& AwaiterImplementsINotifyCompletion(awaiterType, node, diagnostics)
&& GetGetResultMethod(awaiterType, node, expression.Type, diagnostics, out getResult);
}
示例6: GetEnumeratorInfoAndInferCollectionElementType
private bool GetEnumeratorInfoAndInferCollectionElementType(ref ForEachEnumeratorInfo.Builder builder, ref BoundExpression collectionExpr, DiagnosticBag diagnostics, out TypeSymbol inferredType)
{
UnwrapCollectionExpressionIfNullable(ref collectionExpr, diagnostics);
bool gotInfo = GetEnumeratorInfo(ref builder, collectionExpr, diagnostics);
if (!gotInfo)
{
inferredType = null;
}
else if (collectionExpr.HasDynamicType())
{
// If the enumerator is dynamic, it yields dynamic values
inferredType = DynamicTypeSymbol.Instance;
}
else if (collectionExpr.Type.SpecialType == SpecialType.System_String && builder.CollectionType.SpecialType == SpecialType.System_Collections_IEnumerable)
{
// Reproduce dev11 behavior: we're always going to lower a foreach loop over a string to a for loop
// over the string's Chars indexer. Therefore, we should infer "char", regardless of what the spec
// indicates the element type is. This actually matters in practice because the System.String in
// the portable library doesn't have a pattern GetEnumerator method or implement IEnumerable<char>.
inferredType = GetSpecialType(SpecialType.System_Char, diagnostics, collectionExpr.Syntax);
}
else
{
inferredType = builder.ElementType;
}
return gotInfo;
}