107 lines
4.9 KiB
C#
107 lines
4.9 KiB
C#
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
|
|
|
internal abstract class VariablePendingInference : BoundExpression
|
|
{
|
|
protected abstract ErrorCode InferenceFailedError { get; }
|
|
|
|
public new TypeSymbol? Type => base.Type;
|
|
|
|
public Symbol VariableSymbol { get; }
|
|
|
|
public BoundExpression? ReceiverOpt { get; }
|
|
|
|
internal BoundExpression SetInferredTypeWithAnnotations(TypeWithAnnotations type, BindingDiagnosticBag? diagnosticsOpt)
|
|
{
|
|
return SetInferredTypeWithAnnotations(type, null, diagnosticsOpt);
|
|
}
|
|
|
|
internal BoundExpression SetInferredTypeWithAnnotations(TypeWithAnnotations type, Binder? binderOpt, BindingDiagnosticBag? diagnosticsOpt)
|
|
{
|
|
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003a: Invalid comparison between Unknown and I4
|
|
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0042: Invalid comparison between Unknown and I4
|
|
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00bc: Invalid comparison between Unknown and I4
|
|
bool flag = !type.HasType;
|
|
if (flag)
|
|
{
|
|
type = TypeWithAnnotations.Create(binderOpt.CreateErrorType("var"));
|
|
}
|
|
SymbolKind kind = VariableSymbol.Kind;
|
|
if ((int)kind != 6)
|
|
{
|
|
if ((int)kind == 8)
|
|
{
|
|
SourceLocalSymbol sourceLocalSymbol = (SourceLocalSymbol)VariableSymbol;
|
|
if (((BindingDiagnosticBag)(diagnosticsOpt?)).DiagnosticBag != null)
|
|
{
|
|
if (flag)
|
|
{
|
|
ReportInferenceFailure(diagnosticsOpt);
|
|
}
|
|
else
|
|
{
|
|
SyntaxNode val = (SyntaxNode)(object)((Syntax.Kind() == SyntaxKind.DeclarationExpression) ? ((DeclarationExpressionSyntax)(object)Syntax).Type : ((TypeSyntax)(object)Syntax));
|
|
Binder.CheckRestrictedTypeInAsyncMethod(sourceLocalSymbol.ContainingSymbol, type.Type, diagnosticsOpt, val);
|
|
if ((int)sourceLocalSymbol.Scope == 2 && !type.Type.IsErrorTypeOrRefLikeType())
|
|
{
|
|
diagnosticsOpt.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly, ((SyntaxNode)((val is TypeSyntax syntax) ? syntax.SkipScoped(out var _).SkipRef() : ((TypeSyntax)(object)val))).Location);
|
|
}
|
|
}
|
|
}
|
|
sourceLocalSymbol.SetTypeWithAnnotations(type);
|
|
return new BoundLocal(Syntax, sourceLocalSymbol, BoundLocalDeclarationKind.WithInferredType, null, isNullableUnknown: false, type.Type, base.HasErrors || flag).WithWasConverted();
|
|
}
|
|
throw ExceptionUtilities.UnexpectedValue((object)VariableSymbol.Kind);
|
|
}
|
|
GlobalExpressionVariable globalExpressionVariable = (GlobalExpressionVariable)VariableSymbol;
|
|
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(withDiagnostics: true, withDependencies: false);
|
|
if (flag)
|
|
{
|
|
ReportInferenceFailure(instance);
|
|
}
|
|
type = globalExpressionVariable.SetTypeWithAnnotations(type, instance);
|
|
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
|
|
return new BoundFieldAccess(Syntax, ReceiverOpt, globalExpressionVariable, null, LookupResultKind.Viable, isDeclaration: true, type.Type, base.HasErrors || flag);
|
|
}
|
|
|
|
internal BoundExpression FailInference(Binder binder, BindingDiagnosticBag? diagnosticsOpt)
|
|
{
|
|
return SetInferredTypeWithAnnotations(default(TypeWithAnnotations), binder, diagnosticsOpt);
|
|
}
|
|
|
|
private void ReportInferenceFailure(BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
|
|
SingleVariableDesignationSyntax singleVariableDesignationSyntax = Syntax.Kind() switch
|
|
{
|
|
SyntaxKind.DeclarationExpression => (SingleVariableDesignationSyntax)((DeclarationExpressionSyntax)(object)Syntax).Designation,
|
|
SyntaxKind.SingleVariableDesignation => (SingleVariableDesignationSyntax)(object)Syntax,
|
|
_ => throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/BoundTree/VariablePendingInference.cs", 131),
|
|
};
|
|
ErrorCode inferenceFailedError = InferenceFailedError;
|
|
SyntaxToken identifier = singleVariableDesignationSyntax.Identifier;
|
|
object[] array = new object[1];
|
|
SyntaxToken identifier2 = singleVariableDesignationSyntax.Identifier;
|
|
array[0] = ((SyntaxToken)(ref identifier2)).ValueText;
|
|
Binder.Error(diagnostics, inferenceFailedError, identifier, array);
|
|
}
|
|
|
|
protected VariablePendingInference(BoundKind kind, SyntaxNode syntax, Symbol variableSymbol, BoundExpression? receiverOpt, bool hasErrors = false)
|
|
: base(kind, syntax, null, hasErrors)
|
|
{
|
|
VariableSymbol = variableSymbol;
|
|
ReceiverOpt = receiverOpt;
|
|
}
|
|
}
|