365 lines
16 KiB
C#
365 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using Microsoft.Cci;
|
|
using Microsoft.CodeAnalysis.CSharp.Emit;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
|
|
internal abstract class SynthesizedEntryPointSymbol : MethodSymbol
|
|
{
|
|
internal sealed class AsyncForwardEntryPoint : SynthesizedEntryPointSymbol
|
|
{
|
|
private readonly CSharpSyntaxNode _userMainReturnTypeSyntax;
|
|
|
|
private readonly BoundExpression _getAwaiterGetResultCall;
|
|
|
|
private readonly ImmutableArray<ParameterSymbol> _parameters;
|
|
|
|
internal readonly MethodSymbol UserMain;
|
|
|
|
public override string Name => "<Main>";
|
|
|
|
public override ImmutableArray<ParameterSymbol> Parameters => _parameters;
|
|
|
|
public override TypeWithAnnotations ReturnTypeWithAnnotations => TypeWithAnnotations.Create(_getAwaiterGetResultCall.Type);
|
|
|
|
internal AsyncForwardEntryPoint(CSharpCompilation compilation, NamedTypeSymbol containingType, MethodSymbol userMain)
|
|
: base(containingType)
|
|
{
|
|
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
|
|
UserMain = userMain;
|
|
_userMainReturnTypeSyntax = userMain.ExtractReturnTypeSyntax();
|
|
Binder binder = compilation.GetBinder(_userMainReturnTypeSyntax);
|
|
_parameters = SynthesizedParameterSymbol.DeriveParameters(userMain, this);
|
|
BoundCall expression = new BoundCall(arguments: ImmutableArrayExtensions.SelectAsArray<ParameterSymbol, CSharpSyntaxNode, BoundExpression>(Parameters, (Func<ParameterSymbol, CSharpSyntaxNode, BoundExpression>)((ParameterSymbol p, CSharpSyntaxNode s) => new BoundParameter((SyntaxNode)(object)s, p, p.Type)), _userMainReturnTypeSyntax), syntax: (SyntaxNode)(object)_userMainReturnTypeSyntax, receiverOpt: null, initialBindingReceiverIsSubjectToCloning: (ThreeState)0, method: userMain, argumentNamesOpt: default(ImmutableArray<string>), argumentRefKindsOpt: default(ImmutableArray<RefKind>), isDelegateCall: false, expanded: false, invokedAsExtensionMethod: false, argsToParamsOpt: default(ImmutableArray<int>), defaultArguments: default(BitVector), resultKind: LookupResultKind.Viable, type: userMain.ReturnType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
binder.GetAwaitableExpressionInfo(expression, out _getAwaiterGetResultCall, (SyntaxNode)(object)_userMainReturnTypeSyntax, BindingDiagnosticBag.Discarded);
|
|
}
|
|
|
|
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<SynthesizedAttributeData> attributes)
|
|
{
|
|
base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
|
|
Symbol.AddSynthesizedAttribute(ref attributes, DeclaringCompilation.SynthesizeDebuggerStepThroughAttribute());
|
|
}
|
|
|
|
internal override BoundBlock CreateBody(BindingDiagnosticBag diagnostics)
|
|
{
|
|
CSharpSyntaxNode userMainReturnTypeSyntax = _userMainReturnTypeSyntax;
|
|
if (ReturnsVoid)
|
|
{
|
|
return new BoundBlock((SyntaxNode)(object)userMainReturnTypeSyntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray.Create((BoundStatement)new BoundExpressionStatement((SyntaxNode)(object)userMainReturnTypeSyntax, _getAwaiterGetResultCall)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}, (BoundStatement)new BoundReturnStatement((SyntaxNode)(object)userMainReturnTypeSyntax, (RefKind)0, null, @checked: false)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
return new BoundBlock((SyntaxNode)(object)userMainReturnTypeSyntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray.Create((BoundStatement)new BoundReturnStatement((SyntaxNode)(object)userMainReturnTypeSyntax, (RefKind)0, _getAwaiterGetResultCall, @checked: false)))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
}
|
|
|
|
private sealed class ScriptEntryPoint : SynthesizedEntryPointSymbol
|
|
{
|
|
private readonly TypeWithAnnotations _returnType;
|
|
|
|
public override string Name => "<Main>";
|
|
|
|
public override ImmutableArray<ParameterSymbol> Parameters => ImmutableArray<ParameterSymbol>.Empty;
|
|
|
|
public override TypeWithAnnotations ReturnTypeWithAnnotations => _returnType;
|
|
|
|
internal ScriptEntryPoint(NamedTypeSymbol containingType, TypeWithAnnotations returnType)
|
|
: base(containingType)
|
|
{
|
|
_returnType = returnType;
|
|
}
|
|
|
|
internal override BoundBlock CreateBody(BindingDiagnosticBag diagnostics)
|
|
{
|
|
CSharpSyntaxNode cSharpSyntaxNode = DummySyntax();
|
|
CSharpCompilation declaringCompilation = _containingType.DeclaringCompilation;
|
|
Binder next = WithUsingNamespacesAndTypesBinder.Create(declaringCompilation.GlobalImports, new BuckStopsHereBinder(declaringCompilation, null), withImportChainEntry: true);
|
|
next = new InContainerBinder(declaringCompilation.GlobalNamespace, next);
|
|
SynthesizedInstanceConstructor scriptConstructor = _containingType.GetScriptConstructor();
|
|
SynthesizedInteractiveInitializerMethod scriptInitializer = _containingType.GetScriptInitializer();
|
|
BoundLocal boundLocal = new BoundLocal((SyntaxNode)(object)cSharpSyntaxNode, new SynthesizedLocal(this, TypeWithAnnotations.Create(_containingType), (SynthesizedLocalKind)(-2), null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0), null, _containingType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
BoundCall expression = CreateParameterlessCall(cSharpSyntaxNode, boundLocal, (ThreeState)1, scriptInitializer);
|
|
if (!next.GetAwaitableExpressionInfo(expression, out BoundExpression getAwaiterGetResultCall, (SyntaxNode)(object)cSharpSyntaxNode, diagnostics))
|
|
{
|
|
return new BoundBlock((SyntaxNode)(object)cSharpSyntaxNode, ImmutableArray<LocalSymbol>.Empty, ImmutableArray<BoundStatement>.Empty, hasErrors: true);
|
|
}
|
|
return new BoundBlock((SyntaxNode)(object)cSharpSyntaxNode, ImmutableArray.Create(boundLocal.LocalSymbol), ImmutableArray.Create((BoundStatement)new BoundExpressionStatement((SyntaxNode)(object)cSharpSyntaxNode, new BoundAssignmentOperator((SyntaxNode)(object)cSharpSyntaxNode, boundLocal, new BoundObjectCreationExpression((SyntaxNode)(object)cSharpSyntaxNode, scriptConstructor)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}, _containingType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
})
|
|
{
|
|
WasCompilerGenerated = true
|
|
}, (BoundStatement)new BoundExpressionStatement((SyntaxNode)(object)cSharpSyntaxNode, getAwaiterGetResultCall)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}, (BoundStatement)new BoundReturnStatement((SyntaxNode)(object)cSharpSyntaxNode, (RefKind)0, null, @checked: false)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
}
|
|
|
|
private sealed class SubmissionEntryPoint : SynthesizedEntryPointSymbol
|
|
{
|
|
private readonly ImmutableArray<ParameterSymbol> _parameters;
|
|
|
|
private readonly TypeWithAnnotations _returnType;
|
|
|
|
public override string Name => "<Factory>";
|
|
|
|
public override ImmutableArray<ParameterSymbol> Parameters => _parameters;
|
|
|
|
public override TypeWithAnnotations ReturnTypeWithAnnotations => _returnType;
|
|
|
|
internal SubmissionEntryPoint(NamedTypeSymbol containingType, TypeWithAnnotations returnType, TypeSymbol submissionArrayType)
|
|
: base(containingType)
|
|
{
|
|
_parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(submissionArrayType), 0, (RefKind)0, "submissionArray", (ScopedKind)0));
|
|
_returnType = returnType;
|
|
}
|
|
|
|
internal override BoundBlock CreateBody(BindingDiagnosticBag diagnostics)
|
|
{
|
|
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
|
|
CSharpSyntaxNode syntax = DummySyntax();
|
|
SynthesizedInstanceConstructor scriptConstructor = _containingType.GetScriptConstructor();
|
|
SynthesizedInteractiveInitializerMethod scriptInitializer = _containingType.GetScriptInitializer();
|
|
BoundParameter item = new BoundParameter((SyntaxNode)(object)syntax, _parameters[0])
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
BoundLocal boundLocal = new BoundLocal((SyntaxNode)(object)syntax, new SynthesizedLocal(this, TypeWithAnnotations.Create(_containingType), (SynthesizedLocalKind)(-2), null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0), null, _containingType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
BoundExpressionStatement item2 = new BoundExpressionStatement((SyntaxNode)(object)syntax, new BoundAssignmentOperator((SyntaxNode)(object)syntax, boundLocal, new BoundObjectCreationExpression((SyntaxNode)(object)syntax, scriptConstructor, ImmutableArray.Create((BoundExpression)item), default(ImmutableArray<string>), default(ImmutableArray<RefKind>), expanded: false, default(ImmutableArray<int>), default(BitVector), null, null, _containingType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
}, _containingType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
})
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
BoundCall expressionOpt = CreateParameterlessCall(syntax, boundLocal, (ThreeState)1, scriptInitializer);
|
|
BoundReturnStatement item3 = new BoundReturnStatement((SyntaxNode)(object)syntax, (RefKind)0, expressionOpt, @checked: false)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
return new BoundBlock((SyntaxNode)(object)syntax, ImmutableArray.Create(boundLocal.LocalSymbol), ImmutableArray.Create((BoundStatement)item2, (BoundStatement)item3))
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
}
|
|
|
|
internal const string MainName = "<Main>";
|
|
|
|
internal const string FactoryName = "<Factory>";
|
|
|
|
private readonly NamedTypeSymbol _containingType;
|
|
|
|
internal override bool GenerateDebugInfo => false;
|
|
|
|
public override Symbol ContainingSymbol => _containingType;
|
|
|
|
public abstract override string Name { get; }
|
|
|
|
internal override bool HasSpecialName => true;
|
|
|
|
internal override MethodImplAttributes ImplementationAttributes => MethodImplAttributes.IL;
|
|
|
|
internal override bool RequiresSecurityObject => false;
|
|
|
|
public override bool IsVararg => false;
|
|
|
|
public override ImmutableArray<TypeParameterSymbol> TypeParameters => ImmutableArray<TypeParameterSymbol>.Empty;
|
|
|
|
public override Accessibility DeclaredAccessibility => (Accessibility)1;
|
|
|
|
public override ImmutableArray<Location> Locations => ImmutableArray<Location>.Empty;
|
|
|
|
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences => ImmutableArray<SyntaxReference>.Empty;
|
|
|
|
public override RefKind RefKind => (RefKind)0;
|
|
|
|
public override ImmutableArray<CustomModifier> RefCustomModifiers => ImmutableArray<CustomModifier>.Empty;
|
|
|
|
public override ImmutableArray<TypeWithAnnotations> TypeArgumentsWithAnnotations => ImmutableArray<TypeWithAnnotations>.Empty;
|
|
|
|
public override Symbol AssociatedSymbol => null;
|
|
|
|
public override int Arity => 0;
|
|
|
|
public override bool ReturnsVoid => base.ReturnType.IsVoidType();
|
|
|
|
public sealed override FlowAnalysisAnnotations ReturnTypeFlowAnalysisAnnotations => FlowAnalysisAnnotations.None;
|
|
|
|
public sealed override ImmutableHashSet<string> ReturnNotNullIfParameterNotNull => ImmutableHashSet<string>.Empty;
|
|
|
|
public sealed override FlowAnalysisAnnotations FlowAnalysisAnnotations => FlowAnalysisAnnotations.None;
|
|
|
|
public override MethodKind MethodKind => (MethodKind)10;
|
|
|
|
public override bool IsExtern => false;
|
|
|
|
public override bool IsSealed => false;
|
|
|
|
public override bool IsAbstract => false;
|
|
|
|
public override bool IsOverride => false;
|
|
|
|
public override bool IsVirtual => false;
|
|
|
|
public override bool IsStatic => true;
|
|
|
|
public override bool IsAsync => false;
|
|
|
|
public override bool HidesBaseMethodsByName => false;
|
|
|
|
public override bool IsExtensionMethod => false;
|
|
|
|
internal sealed override ObsoleteAttributeData ObsoleteAttributeData => null;
|
|
|
|
internal override CallingConvention CallingConvention => (CallingConvention)0;
|
|
|
|
internal override bool IsExplicitInterfaceImplementation => false;
|
|
|
|
public override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations => ImmutableArray<MethodSymbol>.Empty;
|
|
|
|
internal sealed override bool IsDeclaredReadOnly => false;
|
|
|
|
internal sealed override bool IsInitOnly => false;
|
|
|
|
internal override bool IsMetadataFinal => false;
|
|
|
|
public override bool IsImplicitlyDeclared => true;
|
|
|
|
public sealed override bool AreLocalsZeroed => ContainingType.AreLocalsZeroed;
|
|
|
|
internal override MarshalPseudoCustomAttributeData ReturnValueMarshallingInformation => null;
|
|
|
|
internal override bool HasDeclarativeSecurity => false;
|
|
|
|
protected sealed override bool HasSetsRequiredMembersImpl
|
|
{
|
|
get
|
|
{
|
|
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs", 311);
|
|
}
|
|
}
|
|
|
|
internal sealed override bool HasUnscopedRefAttribute => false;
|
|
|
|
internal sealed override bool UseUpdatedEscapeRules => ContainingModule.UseUpdatedEscapeRules;
|
|
|
|
internal static SynthesizedEntryPointSymbol Create(SynthesizedInteractiveInitializerMethod initializerMethod, BindingDiagnosticBag diagnostics)
|
|
{
|
|
NamedTypeSymbol containingType = initializerMethod.ContainingType;
|
|
CSharpCompilation declaringCompilation = containingType.DeclaringCompilation;
|
|
if (((Compilation)declaringCompilation).IsSubmission)
|
|
{
|
|
NamedTypeSymbol specialType = Binder.GetSpecialType(declaringCompilation, (SpecialType)1, (SyntaxNode)(object)DummySyntax(), diagnostics);
|
|
ArrayTypeSymbol arrayTypeSymbol = declaringCompilation.CreateArrayTypeSymbol(specialType);
|
|
diagnostics.ReportUseSite(arrayTypeSymbol, NoLocation.Singleton);
|
|
return new SubmissionEntryPoint(containingType, initializerMethod.ReturnTypeWithAnnotations, arrayTypeSymbol);
|
|
}
|
|
NamedTypeSymbol specialType2 = Binder.GetSpecialType(declaringCompilation, (SpecialType)6, (SyntaxNode)(object)DummySyntax(), diagnostics);
|
|
return new ScriptEntryPoint(containingType, TypeWithAnnotations.Create(specialType2));
|
|
}
|
|
|
|
private SynthesizedEntryPointSymbol(NamedTypeSymbol containingType)
|
|
{
|
|
_containingType = containingType;
|
|
}
|
|
|
|
internal abstract BoundBlock CreateBody(BindingDiagnosticBag diagnostics);
|
|
|
|
internal sealed override UnmanagedCallersOnlyAttributeData GetUnmanagedCallersOnlyAttributeData(bool forceComplete)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
internal sealed override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
internal sealed override bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override DllImportData GetDllImportData()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
internal override IEnumerable<SecurityAttribute> GetSecurityInformation()
|
|
{
|
|
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs", 272);
|
|
}
|
|
|
|
internal sealed override ImmutableArray<string> GetAppliedConditionalSymbols()
|
|
{
|
|
return ImmutableArray<string>.Empty;
|
|
}
|
|
|
|
internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
|
|
{
|
|
throw ExceptionUtilities.Unreachable("/_/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs", 282);
|
|
}
|
|
|
|
private static CSharpSyntaxNode DummySyntax()
|
|
{
|
|
return (CSharpSyntaxNode)(object)CSharpSyntaxTree.Dummy.GetRoot(default(CancellationToken));
|
|
}
|
|
|
|
private static BoundCall CreateParameterlessCall(CSharpSyntaxNode syntax, BoundExpression receiver, ThreeState receiverIsSubjectToCloning, MethodSymbol method)
|
|
{
|
|
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
|
|
return new BoundCall((SyntaxNode)(object)syntax, receiver, receiverIsSubjectToCloning, method, ImmutableArray<BoundExpression>.Empty, default(ImmutableArray<string>), default(ImmutableArray<RefKind>), isDelegateCall: false, expanded: false, invokedAsExtensionMethod: false, default(ImmutableArray<int>), default(BitVector), LookupResultKind.Viable, method.ReturnType)
|
|
{
|
|
WasCompilerGenerated = true
|
|
};
|
|
}
|
|
|
|
internal sealed override bool IsNullableAnalysisEnabled()
|
|
{
|
|
return false;
|
|
}
|
|
}
|