using System; using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp.Symbols; internal sealed class SynthesizedSimpleProgramEntryPointSymbol : SourceMemberMethodSymbol { private readonly SingleTypeDeclaration _declaration; private readonly TypeSymbol _returnType; private readonly ImmutableArray _parameters; private WeakReference? _weakBodyBinder; private WeakReference? _weakIgnoreAccessibilityBodyBinder; public override string Name => "
$"; internal override MethodImplAttributes ImplementationAttributes => MethodImplAttributes.IL; public override ImmutableArray TypeParameters => ImmutableArray.Empty; internal override int ParameterCount => 1; public override ImmutableArray Parameters => _parameters; public override TypeWithAnnotations ReturnTypeWithAnnotations => TypeWithAnnotations.Create(_returnType); public override FlowAnalysisAnnotations ReturnTypeFlowAnalysisAnnotations => FlowAnalysisAnnotations.None; public override ImmutableHashSet ReturnNotNullIfParameterNotNull => ImmutableHashSet.Empty; public override FlowAnalysisAnnotations FlowAnalysisAnnotations => FlowAnalysisAnnotations.None; public override ImmutableArray RefCustomModifiers => ImmutableArray.Empty; public sealed override bool IsImplicitlyDeclared => false; internal sealed override bool GenerateDebugInfo => true; protected override object MethodChecksLockObject => _declaration; internal CompilationUnitSyntax CompilationUnit => (CompilationUnitSyntax)SyntaxNode; public SyntaxNode ReturnTypeSyntax => (SyntaxNode)(object)((IEnumerable)(object)CompilationUnit.Members).First((MemberDeclarationSyntax m) => m.Kind() == SyntaxKind.GlobalStatement); internal SynthesizedSimpleProgramEntryPointSymbol(SourceMemberContainerTypeSymbol containingType, SingleTypeDeclaration declaration, BindingDiagnosticBag diagnostics) : base(containingType, declaration.SyntaxReference, declaration.SyntaxReference.GetLocation(), declaration.IsIterator, MakeModifiersAndFlags(containingType, declaration)) { _declaration = declaration; bool hasAwaitExpressions = declaration.HasAwaitExpressions; bool hasReturnWithExpression = declaration.HasReturnWithExpression; CSharpCompilation declaringCompilation = containingType.DeclaringCompilation; if (hasAwaitExpressions) { if (!hasReturnWithExpression) { _returnType = Binder.GetWellKnownType(declaringCompilation, (WellKnownType)95, diagnostics, NoLocation.Singleton); } else { _returnType = Binder.GetWellKnownType(declaringCompilation, (WellKnownType)96, diagnostics, NoLocation.Singleton).Construct(Binder.GetSpecialType(declaringCompilation, (SpecialType)13, NoLocation.Singleton, diagnostics)); } } else if (!hasReturnWithExpression) { _returnType = Binder.GetSpecialType(declaringCompilation, (SpecialType)6, NoLocation.Singleton, diagnostics); } else { _returnType = Binder.GetSpecialType(declaringCompilation, (SpecialType)13, NoLocation.Singleton, diagnostics); } _parameters = ImmutableArray.Create(SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(ArrayTypeSymbol.CreateCSharpArray(declaringCompilation.Assembly, TypeWithAnnotations.Create(Binder.GetSpecialType(declaringCompilation, (SpecialType)20, NoLocation.Singleton, diagnostics)))), 0, (RefKind)0, "args", (ScopedKind)0)); } private static (DeclarationModifiers, Flags) MakeModifiersAndFlags(SourceMemberContainerTypeSymbol containingType, SingleTypeDeclaration declaration) { bool hasAwaitExpressions = declaration.HasAwaitExpressions; bool hasReturnWithExpression = declaration.HasReturnWithExpression; DeclarationModifiers declarationModifiers = (DeclarationModifiers)(0x104 | (hasAwaitExpressions ? 1048576 : 0)); CSharpCompilation declaringCompilation = containingType.DeclaringCompilation; CompilationUnitSyntax syntax = (CompilationUnitSyntax)(object)declaration.SyntaxReference.GetSyntax(default(CancellationToken)); bool isNullableAnalysisEnabled = IsNullableAnalysisEnabled(declaringCompilation, syntax); Flags item = SourceMemberMethodSymbol.MakeFlags((MethodKind)10, (RefKind)0, declarationModifiers, !hasAwaitExpressions && !hasReturnWithExpression, returnsVoidIsSet: true, isExpressionBodied: false, isExtensionMethod: false, isNullableAnalysisEnabled, isVarArg: false, isExplicitInterfaceImplementation: false); return (declarationModifiers, item); } internal static SynthesizedSimpleProgramEntryPointSymbol? GetSimpleProgramEntryPoint(CSharpCompilation compilation, CompilationUnitSyntax compilationUnit, bool fallbackToMainEntryPoint) { SourceNamedTypeSymbol simpleProgramNamedTypeSymbol = GetSimpleProgramNamedTypeSymbol(compilation); if ((object)simpleProgramNamedTypeSymbol == null) { return null; } ImmutableArray simpleProgramEntryPoints = simpleProgramNamedTypeSymbol.GetSimpleProgramEntryPoints(); ImmutableArray.Enumerator enumerator = simpleProgramEntryPoints.GetEnumerator(); while (enumerator.MoveNext()) { SynthesizedSimpleProgramEntryPointSymbol current = enumerator.Current; if (current.SyntaxTree == compilationUnit.SyntaxTree && current.SyntaxNode == compilationUnit) { return current; } } if (!fallbackToMainEntryPoint) { return null; } return simpleProgramEntryPoints[0]; } internal static SynthesizedSimpleProgramEntryPointSymbol? GetSimpleProgramEntryPoint(CSharpCompilation compilation) { return GetSimpleProgramNamedTypeSymbol(compilation)?.GetSimpleProgramEntryPoints().First(); } private static SourceNamedTypeSymbol? GetSimpleProgramNamedTypeSymbol(CSharpCompilation compilation) { return compilation.SourceModule.GlobalNamespace.GetTypeMembers("Program").OfType().SingleOrDefault((SourceNamedTypeSymbol s) => s.IsSimpleProgram); } internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree) { return localPosition; } protected override void MethodChecks(BindingDiagnosticBag diagnostics) { } public override ImmutableArray> GetTypeParameterConstraintTypes() { return ImmutableArray>.Empty; } public override ImmutableArray GetTypeParameterConstraintKinds() { return ImmutableArray.Empty; } internal override ExecutableCodeBinder TryGetBodyBinder(BinderFactory? binderFactoryOpt = null, bool ignoreAccessibility = false) { return GetBodyBinder(ignoreAccessibility); } private ExecutableCodeBinder CreateBodyBinder(bool ignoreAccessibility) { CSharpCompilation declaringCompilation = DeclaringCompilation; CSharpSyntaxNode syntaxNode = SyntaxNode; Binder next = new BuckStopsHereBinder(declaringCompilation, FileIdentifier.Create(syntaxNode.SyntaxTree)); NamespaceSymbol globalNamespace = declaringCompilation.GlobalNamespace; SourceNamespaceSymbol declaringSymbol = (SourceNamespaceSymbol)declaringCompilation.SourceModule.GlobalNamespace; next = WithExternAndUsingAliasesBinder.Create(declaringSymbol, syntaxNode, WithUsingNamespacesAndTypesBinder.Create(declaringSymbol, syntaxNode, next)); next = new InContainerBinder(globalNamespace, next); next = new InContainerBinder(ContainingType, next); next = new InMethodBinder(this, next); next = next.WithAdditionalFlags(ignoreAccessibility ? BinderFlags.IgnoreAccessibility : BinderFlags.None); return new ExecutableCodeBinder((SyntaxNode)(object)syntaxNode, this, next); } internal ExecutableCodeBinder GetBodyBinder(bool ignoreAccessibility) { ref WeakReference reference = ref ignoreAccessibility ? ref _weakIgnoreAccessibilityBodyBinder : ref _weakBodyBinder; WeakReference weakReference; ExecutableCodeBinder executableCodeBinder; do { weakReference = reference; if (weakReference != null && weakReference.TryGetTarget(out var target)) { return target; } executableCodeBinder = CreateBodyBinder(ignoreAccessibility); } while (Interlocked.CompareExchange(ref reference, new WeakReference(executableCodeBinder), weakReference) != weakReference); return executableCodeBinder; } public override bool IsDefinedInSourceTree(SyntaxTree tree, TextSpan? definedWithinSpan, CancellationToken cancellationToken) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (_declaration.SyntaxReference.SyntaxTree == tree) { if (!definedWithinSpan.HasValue) { return true; } TextSpan valueOrDefault = definedWithinSpan.GetValueOrDefault(); foreach (GlobalStatementSyntax item in ((IEnumerable)(object)((CompilationUnitSyntax)(object)tree.GetRoot(cancellationToken)).Members).OfType()) { cancellationToken.ThrowIfCancellationRequested(); TextSpan span = ((SyntaxNode)item).Span; if (((TextSpan)(ref span)).IntersectsWith(valueOrDefault)) { return true; } } } return false; } private static bool IsNullableAnalysisEnabled(CSharpCompilation compilation, CompilationUnitSyntax syntax) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = syntax.Members.GetEnumerator(); while (enumerator.MoveNext()) { MemberDeclarationSyntax current = enumerator.Current; if (current.Kind() == SyntaxKind.GlobalStatement && compilation.IsNullableAnalysisEnabledIn((SyntaxNode)(object)current)) { return true; } } return false; } }