/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_LocalDeclaration.cs
91 строка
4 KB
AlekseyTs
Restore `dynamic` as result type of some operations involving `dynamic` arguments (#72964)
11 апр 2024, 22:12
Не верифицирован
11 апр 2024, 22:12
5a49045
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp { internal sealed partial class LocalRewriter { public override BoundNode? VisitLocalDeclaration(BoundLocalDeclaration node) { return RewriteLocalDeclaration(node, node.Syntax, node.LocalSymbol, VisitExpression(node.InitializerOpt), node.HasErrors); } private BoundStatement? RewriteLocalDeclaration(BoundLocalDeclaration? originalOpt, SyntaxNode syntax, LocalSymbol localSymbol, BoundExpression? rewrittenInitializer, bool hasErrors = false) { // A declaration of a local variable without an initializer has no associated IL. // Simply remove the declaration from the bound tree. The local symbol will // remain in the bound block, so codegen will make a stack frame location for it. if (rewrittenInitializer == null) { return null; } // A declaration of a local constant also does nothing, even though there is // an assignment. The value will be emitted directly where it is used. The // local symbol remains in the bound block, but codegen will skip making a // stack frame location for it. (We still need a symbol for it to stay // around because we'll be generating debug info for it.) if (localSymbol.IsConst) { if (!localSymbol.Type.IsReferenceType && localSymbol.ConstantValue == null) { // This can occur in error scenarios (e.g. bad imported metadata) hasErrors = true; } else { return null; } } // lowered local declaration node is associated with declaration (not whole statement) // this is done to make sure that debugger stepping is same as before var localDeclaration = syntax as LocalDeclarationStatementSyntax; if (localDeclaration != null) { syntax = localDeclaration.Declaration.Variables[0]; } BoundStatement rewrittenLocalDeclaration = new BoundExpressionStatement( syntax, _factory.AssignmentExpression( syntax, new BoundLocal( syntax, localSymbol, null, localSymbol.Type ), rewrittenInitializer, localSymbol.IsRef), hasErrors); return InstrumentLocalDeclarationIfNecessary(originalOpt, localSymbol, rewrittenLocalDeclaration); } private BoundStatement InstrumentLocalDeclarationIfNecessary(BoundLocalDeclaration? originalOpt, LocalSymbol localSymbol, BoundStatement rewrittenLocalDeclaration) { // Add sequence points, if necessary. if (this.Instrument && originalOpt?.WasCompilerGenerated == false && !localSymbol.IsConst && (originalOpt.Syntax.Kind() == SyntaxKind.VariableDeclarator || (originalOpt.Syntax.Kind() == SyntaxKind.LocalDeclarationStatement && ((LocalDeclarationStatementSyntax)originalOpt.Syntax).Declaration.Variables.Count == 1))) { rewrittenLocalDeclaration = Instrumenter.InstrumentUserDefinedLocalInitialization(originalOpt, rewrittenLocalDeclaration); } return rewrittenLocalDeclaration; } public sealed override BoundNode VisitOutVariablePendingInference(OutVariablePendingInference node) { throw ExceptionUtilities.Unreachable(); } } }