using System; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp; internal static class InitializerRewriter { internal static BoundTypeOrInstanceInitializers RewriteConstructor(ImmutableArray boundInitializers, MethodSymbol method) { return new BoundTypeOrInstanceInitializers((SyntaxNode)(object)((method is SourceMemberMethodSymbol sourceMemberMethodSymbol) ? sourceMemberMethodSymbol.SyntaxNode : method.GetNonNullSyntaxNode()), ImmutableArrayExtensions.SelectAsArray(boundInitializers, (Func)RewriteInitializersAsStatements)); } internal static BoundTypeOrInstanceInitializers RewriteScriptInitializer(ImmutableArray boundInitializers, SynthesizedInteractiveInitializerMethod method, out bool hasTrailingExpression) { ArrayBuilder instance = ArrayBuilder.GetInstance(boundInitializers.Length); bool flag = (object)method.ResultType != null; BoundStatement boundStatement = null; BoundExpression boundExpression = null; ImmutableArray.Enumerator enumerator = boundInitializers.GetEnumerator(); while (enumerator.MoveNext()) { BoundInitializer current = enumerator.Current; if (flag && current == boundInitializers.Last() && current.Kind == BoundKind.GlobalStatementInitializer && method.DeclaringCompilation.IsSubmissionSyntaxTree(current.SyntaxTree)) { boundStatement = ((BoundGlobalStatementInitializer)current).Statement; BoundExpression trailingScriptExpression = GetTrailingScriptExpression(boundStatement); if (trailingScriptExpression != null && (object)trailingScriptExpression.Type != null && !trailingScriptExpression.Type.IsVoidType()) { boundExpression = trailingScriptExpression; continue; } } instance.Add(RewriteInitializersAsStatements(current)); } if (flag && boundExpression != null) { instance.Add((BoundStatement)new BoundReturnStatement(boundStatement.Syntax, (RefKind)0, boundExpression, @checked: false)); hasTrailingExpression = true; } else { hasTrailingExpression = false; } return new BoundTypeOrInstanceInitializers((SyntaxNode)(object)method.GetNonNullSyntaxNode(), instance.ToImmutableAndFree()); } internal static BoundExpression GetTrailingScriptExpression(BoundStatement statement) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (statement.Kind == BoundKind.ExpressionStatement) { SyntaxToken semicolonToken = ((ExpressionStatementSyntax)(object)statement.Syntax).SemicolonToken; if (((SyntaxToken)(ref semicolonToken)).IsMissing) { return ((BoundExpressionStatement)statement).Expression; } } return null; } private static BoundStatement RewriteFieldInitializer(BoundFieldEqualsValue fieldInit) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 FieldSymbol field = fieldInit.Field; SyntaxNode syntax = fieldInit.Syntax; syntax = (SyntaxNode)(((object)(syntax as EqualsValueClauseSyntax)?.Value) ?? ((object)syntax)); BoundThisReference receiver = (field.IsStatic ? null : new BoundThisReference(syntax, field.ContainingType)); BoundStatement boundStatement = new BoundExpressionStatement(syntax, new BoundAssignmentOperator(syntax, new BoundFieldAccess(syntax, receiver, field, null), fieldInit.Value, field.Type, (int)field.RefKind > 0) { WasCompilerGenerated = true }) { WasCompilerGenerated = (!fieldInit.Locals.IsEmpty || fieldInit.WasCompilerGenerated) }; if (!fieldInit.Locals.IsEmpty) { boundStatement = new BoundBlock(syntax, fieldInit.Locals, ImmutableArray.Create(boundStatement)) { WasCompilerGenerated = fieldInit.WasCompilerGenerated }; } return boundStatement; } private static BoundStatement RewriteInitializersAsStatements(BoundInitializer initializer) { return initializer.Kind switch { BoundKind.FieldEqualsValue => RewriteFieldInitializer((BoundFieldEqualsValue)initializer), BoundKind.GlobalStatementInitializer => ((BoundGlobalStatementInitializer)initializer).Statement, _ => throw ExceptionUtilities.UnexpectedValue((object)initializer.Kind), }; } }