本文整理汇总了C#中TypeSymbol.IsErrorType方法的典型用法代码示例。如果您正苦于以下问题:C# TypeSymbol.IsErrorType方法的具体用法?C# TypeSymbol.IsErrorType怎么用?C# TypeSymbol.IsErrorType使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TypeSymbol
的用法示例。
在下文中一共展示了TypeSymbol.IsErrorType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: DoSignaturesMatch
private static bool DoSignaturesMatch(
PEModuleSymbol moduleSymbol,
TypeSymbol eventType,
PEMethodSymbol addMethod,
PEMethodSymbol removeMethod)
{
return
(eventType.IsDelegateType() || eventType.IsErrorType()) &&
DoesSignatureMatch(moduleSymbol, eventType, addMethod) &&
DoesSignatureMatch(moduleSymbol, eventType, removeMethod) &&
DoModifiersMatch(addMethod, removeMethod);
}
示例2: BindVariableDeclaration
protected BoundLocalDeclaration BindVariableDeclaration(
SourceLocalSymbol localSymbol,
LocalDeclarationKind kind,
bool isVar,
VariableDeclaratorSyntax declarator,
TypeSyntax typeSyntax,
TypeSymbol declTypeOpt,
AliasSymbol aliasOpt,
DiagnosticBag diagnostics,
CSharpSyntaxNode associatedSyntaxNode = null)
{
Debug.Assert(declarator != null);
Debug.Assert((object)declTypeOpt != null || isVar);
Debug.Assert(typeSyntax != null);
var localDiagnostics = DiagnosticBag.GetInstance();
// if we are not given desired syntax, we use declarator
associatedSyntaxNode = associatedSyntaxNode ?? declarator;
bool hasErrors = false;
BoundExpression initializerOpt;
// Check for variable declaration errors.
hasErrors |= this.ValidateDeclarationNameConflictsInScope(localSymbol, localDiagnostics);
EqualsValueClauseSyntax equalsValueClauseSyntax = declarator.Initializer;
if (isVar)
{
aliasOpt = null;
var binder = new ImplicitlyTypedLocalBinder(this, localSymbol);
initializerOpt = binder.BindInferredVariableInitializer(localDiagnostics, equalsValueClauseSyntax, declarator);
// If we got a good result then swap the inferred type for the "var"
if ((object)initializerOpt?.Type != null)
{
declTypeOpt = initializerOpt.Type;
if (declTypeOpt.SpecialType == SpecialType.System_Void)
{
Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt);
declTypeOpt = CreateErrorType("var");
hasErrors = true;
}
if (!declTypeOpt.IsErrorType())
{
if (declTypeOpt.IsStatic)
{
Error(localDiagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, initializerOpt.Type);
hasErrors = true;
}
}
}
else
{
declTypeOpt = CreateErrorType("var");
hasErrors = true;
}
}
else
{
if (ReferenceEquals(equalsValueClauseSyntax, null))
{
initializerOpt = null;
}
else
{
// Basically inlined BindVariableInitializer, but with conversion optional.
initializerOpt = BindPossibleArrayInitializer(equalsValueClauseSyntax.Value, declTypeOpt, localDiagnostics);
if (kind != LocalDeclarationKind.FixedVariable)
{
// If this is for a fixed statement, we'll do our own conversion since there are some special cases.
initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, localDiagnostics);
}
}
}
Debug.Assert((object)declTypeOpt != null);
if (kind == LocalDeclarationKind.FixedVariable)
{
// NOTE: this is an error, but it won't prevent further binding.
if (isVar)
{
if (!hasErrors)
{
Error(localDiagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator);
hasErrors = true;
}
}
if (!declTypeOpt.IsPointerType())
{
if (!hasErrors)
{
Error(localDiagnostics, ErrorCode.ERR_BadFixedInitType, declarator);
hasErrors = true;
}
//.........这里部分代码省略.........
示例3: SetTypeSymbol
internal void SetTypeSymbol(TypeSymbol newType)
{
TypeSymbol originalType = this.type;
// In the event that we race to set the type of a local, we should
// always deduce the same type, or deduce that the type is an error.
Debug.Assert((object)originalType == null ||
originalType.IsErrorType() && newType.IsErrorType() ||
originalType == newType);
if ((object)originalType == null)
{
Interlocked.CompareExchange(ref this.type, newType, null);
}
}
示例4: GenerateAnonymousFunctionConversionError
internal void GenerateAnonymousFunctionConversionError(DiagnosticBag diagnostics, CSharpSyntaxNode syntax,
UnboundLambda anonymousFunction, TypeSymbol targetType)
{
Debug.Assert((object)targetType != null);
Debug.Assert(anonymousFunction != null);
// Is the target type simply bad?
// If the target type is an error then we've already reported a diagnostic. Don't bother
// reporting the conversion error.
if (targetType.IsErrorType() || syntax.HasErrors)
{
return;
}
// CONSIDER: Instead of computing this again, cache the reason why the conversion failed in
// CONSIDER: the Conversion result, and simply report that.
var reason = Conversions.IsAnonymousFunctionCompatibleWithType(anonymousFunction, targetType);
// It is possible that the conversion from lambda to delegate is just fine, and
// that we ended up here because the target type, though itself is not an error
// type, contains a type argument which is an error type. For example, converting
// (Foo foo)=>{} to Action<Foo> is a perfectly legal conversion even if Foo is undefined!
// In that case we have already reported an error that Foo is undefined, so just bail out.
if (reason == LambdaConversionResult.Success)
{
return;
}
var id = anonymousFunction.MessageID.Localize();
if (reason == LambdaConversionResult.BadTargetType)
{
if (ReportDelegateInvokeUseSiteDiagnostic(diagnostics, targetType, node: syntax))
{
return;
}
// Cannot convert {0} to type '{1}' because it is not a delegate type
Error(diagnostics, ErrorCode.ERR_AnonMethToNonDel, syntax, id, targetType);
return;
}
if (reason == LambdaConversionResult.ExpressionTreeMustHaveDelegateTypeArgument)
{
Debug.Assert(targetType.IsExpressionTree());
Error(diagnostics, ErrorCode.ERR_ExpressionTreeMustHaveDelegate, syntax, ((NamedTypeSymbol)targetType).TypeArgumentsNoUseSiteDiagnostics[0]);
return;
}
if (reason == LambdaConversionResult.ExpressionTreeFromAnonymousMethod)
{
Debug.Assert(targetType.IsExpressionTree());
Error(diagnostics, ErrorCode.ERR_AnonymousMethodToExpressionTree, syntax);
return;
}
// At this point we know that we have either a delegate type or an expression type for the target.
var delegateType = targetType.GetDelegateType();
// The target type is a vaid delegate or expression tree type. Is there something wrong with the
// parameter list?
// First off, is there a parameter list at all?
if (reason == LambdaConversionResult.MissingSignatureWithOutParameter)
{
// COMPATIBILITY: The C# 4 compiler produces two errors for:
//
// delegate void D (out int x);
// ...
// D d = delegate {};
//
// error CS1676: Parameter 1 must be declared with the 'out' keyword
// error CS1688: Cannot convert anonymous method block without a parameter list
// to delegate type 'D' because it has one or more out parameters
//
// This seems redundant, (because there is no "parameter 1" in the source code)
// and unnecessary. I propose that we eliminate the first error.
Error(diagnostics, ErrorCode.ERR_CantConvAnonMethNoParams, syntax, targetType);
return;
}
// There is a parameter list. Does it have the right number of elements?
if (reason == LambdaConversionResult.BadParameterCount)
{
// Delegate '{0}' does not take {1} arguments
Error(diagnostics, ErrorCode.ERR_BadDelArgCount, syntax, targetType, anonymousFunction.ParameterCount);
return;
}
// The parameter list exists and had the right number of parameters. Were any of its types bad?
// If any parameter type of the lambda is an error type then suppress
// further errors. We've already reported errors on the bad type.
//.........这里部分代码省略.........
示例5: GenerateImplicitConversionError
protected static void GenerateImplicitConversionError(DiagnosticBag diagnostics, Compilation compilation, CSharpSyntaxNode syntax,
Conversion conversion, TypeSymbol sourceType, TypeSymbol targetType, ConstantValue sourceConstantValueOpt = null)
{
Debug.Assert(!conversion.IsImplicit || !conversion.IsValid);
// If the either type is an error then an error has already been reported
// for some aspect of the analysis of this expression. (For example, something like
// "garbage g = null; short s = g;" -- we don't want to report that g is not
// convertible to short because we've already reported that g does not have a good type.
if (!sourceType.IsErrorType() && !targetType.IsErrorType())
{
if (conversion.IsExplicit)
{
if (sourceType.SpecialType == SpecialType.System_Double && syntax.Kind() == SyntaxKind.NumericLiteralExpression &&
(targetType.SpecialType == SpecialType.System_Single || targetType.SpecialType == SpecialType.System_Decimal))
{
Error(diagnostics, ErrorCode.ERR_LiteralDoubleCast, syntax, (targetType.SpecialType == SpecialType.System_Single) ? "F" : "M", targetType);
}
else if (conversion.Kind == ConversionKind.ExplicitNumeric && sourceConstantValueOpt != null && sourceConstantValueOpt != ConstantValue.Bad &&
ConversionsBase.HasImplicitConstantExpressionConversion(new BoundLiteral(syntax, ConstantValue.Bad, sourceType), targetType))
{
// CLEVERNESS: By passing ConstantValue.Bad, we tell HasImplicitConstantExpressionConversion to ignore the constant
// value and only consider the types.
// If there would be an implicit constant conversion for a different constant of the same type
// (i.e. one that's not out of range), then it's more helpful to report the range check failure
// than to suggest inserting a cast.
Error(diagnostics, ErrorCode.ERR_ConstOutOfRange, syntax, sourceConstantValueOpt.Value, targetType);
}
else
{
SymbolDistinguisher distinguisher = new SymbolDistinguisher(compilation, sourceType, targetType);
Error(diagnostics, ErrorCode.ERR_NoImplicitConvCast, syntax, distinguisher.First, distinguisher.Second);
}
}
else if (conversion.ResultKind == LookupResultKind.OverloadResolutionFailure)
{
Debug.Assert(conversion.IsUserDefined);
ImmutableArray<MethodSymbol> originalUserDefinedConversions = conversion.OriginalUserDefinedConversions;
if (originalUserDefinedConversions.Length > 1)
{
Error(diagnostics, ErrorCode.ERR_AmbigUDConv, syntax, originalUserDefinedConversions[0], originalUserDefinedConversions[1], sourceType, targetType);
}
else
{
Debug.Assert(originalUserDefinedConversions.Length == 0,
"How can there be exactly one applicable user-defined conversion if the conversion doesn't exist?");
SymbolDistinguisher distinguisher = new SymbolDistinguisher(compilation, sourceType, targetType);
Error(diagnostics, ErrorCode.ERR_NoImplicitConv, syntax, distinguisher.First, distinguisher.Second);
}
}
else
{
SymbolDistinguisher distinguisher = new SymbolDistinguisher(compilation, sourceType, targetType);
Error(diagnostics, ErrorCode.ERR_NoImplicitConv, syntax, distinguisher.First, distinguisher.Second);
}
}
}
示例6: CheckConstraints
// See TypeBind::CheckSingleConstraint.
private static bool CheckConstraints(
Symbol containingSymbol,
ConversionsBase conversions,
TypeMap substitution,
TypeParameterSymbol typeParameter,
TypeSymbol typeArgument,
Compilation currentCompilation,
ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder,
ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
HashSet<TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt)
{
Debug.Assert(substitution != null);
// The type parameters must be original definitions of type parameters from the containing symbol.
Debug.Assert(ReferenceEquals(typeParameter.ContainingSymbol, containingSymbol.OriginalDefinition));
if (typeArgument.IsErrorType())
{
return true;
}
if (typeArgument.IsPointerType() || typeArgument.IsRestrictedType() || typeArgument.SpecialType == SpecialType.System_Void)
{
// "The type '{0}' may not be used as a type argument"
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument)));
return false;
}
if (typeArgument.IsStatic)
{
// "'{0}': static types cannot be used as type arguments"
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_GenericArgIsStaticClass, typeArgument)));
return false;
}
if (typeParameter.HasReferenceTypeConstraint && !typeArgument.IsReferenceType)
{
// "The type '{2}' must be a reference type in order to use it as parameter '{1}' in the generic type or method '{0}'"
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_RefConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
return false;
}
if (typeParameter.HasValueTypeConstraint && !typeArgument.IsNonNullableValueType())
{
// "The type '{2}' must be a non-nullable value type in order to use it as parameter '{1}' in the generic type or method '{0}'"
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_ValConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
return false;
}
// The type parameters for a constructed type/method are the type parameters of
// the ConstructedFrom type/method, so the constraint types are not substituted.
// For instance with "class C<T, U> where T : U", the type parameter for T in "C<object, int>"
// has constraint "U", not "int". We need to substitute the constraints from the
// original definition of the type parameters using the map from the constructed symbol.
var constraintTypes = ArrayBuilder<TypeSymbol>.GetInstance();
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
substitution.SubstituteTypesDistinctWithoutModifiers(typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics), constraintTypes,
ignoreTypeConstraintsDependentOnTypeParametersOpt);
bool hasError = false;
foreach (var constraintType in constraintTypes)
{
if (SatisfiesConstraintType(conversions, typeArgument, constraintType, ref useSiteDiagnostics))
{
continue;
}
ErrorCode errorCode;
if (typeArgument.IsReferenceType)
{
errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType;
}
else if (typeArgument.IsNullableType())
{
errorCode = constraintType.IsInterfaceType() ? ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface : ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum;
}
else if (typeArgument.TypeKind == TypeKind.TypeParameter)
{
errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar;
}
else
{
errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedValType;
}
SymbolDistinguisher distinguisher = new SymbolDistinguisher(currentCompilation, constraintType, typeArgument);
diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(errorCode, containingSymbol.ConstructedFrom(), distinguisher.First, typeParameter, distinguisher.Second)));
hasError = true;
}
if (AppendUseSiteDiagnostics(useSiteDiagnostics, typeParameter, ref useSiteDiagnosticsBuilder))
{
hasError = true;
}
constraintTypes.Free();
// Check the constructor constraint.
if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument))
//.........这里部分代码省略.........
示例7: SatisfiesConstraintType
private static bool SatisfiesConstraintType(
ConversionsBase conversions,
TypeSymbol typeArgument,
TypeSymbol constraintType,
ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if (constraintType.IsErrorType())
{
return false;
}
// Spec 4.4.4 describes the valid conversions from
// type argument A to constraint type C:
// "An identity conversion (6.1.1).
// An implicit reference conversion (6.1.6). ..."
if (conversions.HasIdentityOrImplicitReferenceConversion(typeArgument, constraintType, ref useSiteDiagnostics))
{
return true;
}
// "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..."
// NOTE: we extend this to allow, for example, a conversion from Nullable<T> to object.
if (typeArgument.IsValueType &&
conversions.HasBoxingConversion(typeArgument.IsNullableType() ? ((NamedTypeSymbol)typeArgument).ConstructedFrom : typeArgument, constraintType, ref useSiteDiagnostics))
{
return true;
}
if (typeArgument.TypeKind == TypeKind.TypeParameter)
{
var typeParameter = (TypeParameterSymbol)typeArgument;
// "... An implicit reference, boxing, or type parameter conversion
// from type parameter A to C."
if (conversions.HasImplicitTypeParameterConversion(typeParameter, constraintType, ref useSiteDiagnostics))
{
return true;
}
// TypeBind::SatisfiesBound allows cases where one of the
// type parameter constraints satisfies the constraint.
foreach (var typeArgumentConstraint in typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics))
{
if (SatisfiesConstraintType(conversions, typeArgumentConstraint, constraintType, ref useSiteDiagnostics))
{
return true;
}
}
}
return false;
}
示例8: IsPossiblyByRefTypeParameter
private static bool IsPossiblyByRefTypeParameter(TypeSymbol type)
{
if (type.IsTypeParameter())
{
return true;
}
if (type.IsErrorType())
{
//var byRefReturnType = type as ByRefReturnErrorTypeSymbol;
//return ((object)byRefReturnType != null) && byRefReturnType.ReferencedType.IsTypeParameter();
throw new NotImplementedException();
}
return false;
}
示例9: CheckEffectiveAndDeducedBaseTypes
private static void CheckEffectiveAndDeducedBaseTypes(ConversionsBase conversions, TypeSymbol effectiveBase, TypeSymbol deducedBase)
{
Debug.Assert((object)deducedBase != null);
Debug.Assert((object)effectiveBase != null);
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
Debug.Assert(deducedBase.IsErrorType() ||
effectiveBase.IsErrorType() ||
conversions.HasIdentityOrImplicitReferenceConversion(deducedBase, effectiveBase, ref useSiteDiagnostics) ||
conversions.HasBoxingConversion(deducedBase, effectiveBase, ref useSiteDiagnostics));
}
示例10: ClassifyConversionForCast
/// <summary>
/// Determines what type of conversion, if any, would be used if a given expression was
/// converted to a given type using an explicit cast.
/// </summary>
/// <param name="position">The character position for determining the enclosing declaration
/// scope and accessibility.</param>
/// <param name="expression">The expression to classify. This expression does not need to be
/// present in the syntax tree associated with this object.</param>
/// <param name="destination">The type to attempt conversion to.</param>
/// <returns>Returns a Conversion object that summarizes whether the conversion was
/// possible, and if so, what kind of conversion it was. If no conversion was possible, a
/// Conversion object with a false "Exists" property is returned.</returns>
/// <remarks>To determine the conversion between two types (instead of an expression and a
/// type), use Compilation.ClassifyConversion.</remarks>
internal Conversion ClassifyConversionForCast(int position, ExpressionSyntax expression, TypeSymbol destination)
{
if ((object)destination == null)
{
throw new ArgumentNullException(nameof(destination));
}
position = CheckAndAdjustPosition(position);
var binder = this.GetEnclosingBinder(position);
if (binder != null)
{
var diagnostics = DiagnosticBag.GetInstance();
var bnode = binder.BindExpression(expression, diagnostics);
diagnostics.Free();
if (bnode != null && !destination.IsErrorType())
{
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
return binder.Conversions.ClassifyConversionForCast(bnode, destination, ref useSiteDiagnostics);
}
}
return Conversion.NoConversion;
}
示例11: CheckValidPatternType
private bool CheckValidPatternType(
CSharpSyntaxNode typeSyntax,
BoundExpression operand,
TypeSymbol operandType,
TypeSymbol patternType,
bool patternTypeWasInSource,
bool isVar,
DiagnosticBag diagnostics)
{
Debug.Assert((object)operandType != null);
Debug.Assert((object)patternType != null);
if (operandType.IsErrorType() || patternType.IsErrorType())
{
return false;
}
else if (patternType.IsNullableType() && !isVar && patternTypeWasInSource)
{
// It is an error to use pattern-matching with a nullable type, because you'll never get null. Use the underlying type.
Error(diagnostics, ErrorCode.ERR_PatternNullableType, typeSyntax, patternType, patternType.GetNullableUnderlyingType());
return true;
}
else if (patternType.IsStatic)
{
Error(diagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, patternType);
return true;
}
else if (!isVar)
{
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
Conversion conversion =
operand != null
? this.Conversions.ClassifyConversionFromExpression(operand, patternType, ref useSiteDiagnostics, forCast: true)
: this.Conversions.ClassifyConversionFromType(operandType, patternType, ref useSiteDiagnostics, forCast: true);
diagnostics.Add(typeSyntax, useSiteDiagnostics);
switch (conversion.Kind)
{
case ConversionKind.Boxing:
case ConversionKind.ExplicitNullable:
case ConversionKind.ExplicitReference:
case ConversionKind.Identity:
case ConversionKind.ImplicitReference:
case ConversionKind.Unboxing:
case ConversionKind.NullLiteral:
case ConversionKind.ImplicitNullable:
// these are the conversions allowed by a pattern match
break;
//case ConversionKind.ExplicitNumeric: // we do not perform numeric conversions of the operand
//case ConversionKind.ImplicitConstant:
//case ConversionKind.ImplicitNumeric:
default:
Error(diagnostics, ErrorCode.ERR_PatternWrongType, typeSyntax, operandType, patternType);
return true;
}
}
return false;
}
示例12: IsReallyAType
private static bool IsReallyAType(TypeSymbol type)
{
return (object)type != null &&
!type.IsErrorType() &&
(type.SpecialType != SpecialType.System_Void);
}
示例13: Better
private TypeSymbol Better(TypeSymbol type1, TypeSymbol type2, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
// Anything is better than an error sym.
if (type1.IsErrorType())
{
return type2;
}
if ((object)type2 == null || type2.IsErrorType())
{
return type1;
}
var t1tot2 = _conversions.ClassifyImplicitConversion(type1, type2, ref useSiteDiagnostics).Exists;
var t2tot1 = _conversions.ClassifyImplicitConversion(type2, type1, ref useSiteDiagnostics).Exists;
if (t1tot2 && t2tot1)
{
if (type1.IsDynamic())
{
return type1;
}
if (type2.IsDynamic())
{
return type2;
}
return null;
}
if (t1tot2)
{
return type2;
}
if (t2tot1)
{
return type1;
}
return null;
}
示例14: IsPossiblyByRefTypeParameter
private static bool IsPossiblyByRefTypeParameter(TypeSymbol type)
{
if (type.IsTypeParameter())
{
return true;
}
if (type.IsErrorType())
{
var byRefReturnType = type as ByRefReturnErrorTypeSymbol;
return ((object)byRefReturnType != null) && byRefReturnType.ReferencedType.IsTypeParameter();
}
return false;
}
示例15: BindVariableDeclaration
protected BoundLocalDeclaration BindVariableDeclaration(
LocalDeclarationKind kind,
bool isVar,
VariableDeclaratorSyntax declarator,
TypeSyntax typeSyntax,
TypeSymbol declTypeOpt,
AliasSymbol aliasOpt,
DiagnosticBag diagnostics,
CSharpSyntaxNode associatedSyntaxNode = null)
{
Debug.Assert(declarator != null);
Debug.Assert((object)declTypeOpt != null || isVar);
Debug.Assert(typeSyntax != null);
// if we are not given desired syntax, we use declarator
associatedSyntaxNode = associatedSyntaxNode ?? declarator;
bool hasErrors = false;
BoundExpression initializerOpt;
SourceLocalSymbol localSymbol = this.LookupLocal(declarator.Identifier);
// In error scenarios with misplaced code, it is possible we can't bind the local declaration.
// This occurs through the semantic model. In that case concoct a plausible result.
if ((object)localSymbol == null)
{
localSymbol = SourceLocalSymbol.MakeLocal(
ContainingMemberOrLambda as MethodSymbol, this, typeSyntax,
declarator.Identifier, declarator.Initializer, LocalDeclarationKind.Variable);
}
// Check for variable declaration errors.
hasErrors |= this.EnsureDeclarationInvariantMeaningInScope(localSymbol, diagnostics);
EqualsValueClauseSyntax equalsValueClauseSyntax = declarator.Initializer;
if (isVar)
{
aliasOpt = null;
var binder = new ImplicitlyTypedLocalBinder(this, localSymbol);
initializerOpt = binder.BindInferredVariableInitializer(diagnostics, equalsValueClauseSyntax, declarator);
// If we got a good result then swap the inferred type for the "var"
if (initializerOpt != null && (object)initializerOpt.Type != null)
{
declTypeOpt = initializerOpt.Type;
if (declTypeOpt.SpecialType == SpecialType.System_Void)
{
Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, declarator, declTypeOpt);
declTypeOpt = CreateErrorType("var");
hasErrors = true;
}
if (!declTypeOpt.IsErrorType())
{
if (declTypeOpt.IsStatic)
{
Error(diagnostics, ErrorCode.ERR_VarDeclIsStaticClass, typeSyntax, initializerOpt.Type);
hasErrors = true;
}
}
}
else
{
declTypeOpt = CreateErrorType("var");
hasErrors = true;
}
}
else
{
if (ReferenceEquals(equalsValueClauseSyntax, null))
{
initializerOpt = null;
}
else
{
// Basically inlined BindVariableInitializer, but with conversion optional.
initializerOpt = BindPossibleArrayInitializer(equalsValueClauseSyntax.Value, declTypeOpt, diagnostics);
if (kind != LocalDeclarationKind.Fixed)
{
// If this is for a fixed statement, we'll do our own conversion since there are some special cases.
initializerOpt = GenerateConversionForAssignment(declTypeOpt, initializerOpt, diagnostics);
}
}
}
Debug.Assert((object)declTypeOpt != null);
if (kind == LocalDeclarationKind.Fixed)
{
// NOTE: this is an error, but it won't prevent further binding.
if (isVar)
{
if (!hasErrors)
{
Error(diagnostics, ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed, declarator);
hasErrors = true;
}
//.........这里部分代码省略.........