/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/ObjectIdLocalSymbol.cs
99 строк
4 KB
Cyrus Najmabadi
Merge remote-tracking branch 'upstream/main' into removeUnusedUsings
26 июн 2025, 05:03
26 июн 2025, 05:03
6c5c64f
Код
Авторство
О чём код?
// 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. #nullable disable using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.ExpressionEvaluator; namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator { internal sealed class ObjectIdLocalSymbol : PlaceholderLocalSymbol { private readonly bool _isWritable; internal ObjectIdLocalSymbol(MethodSymbol method, TypeSymbol type, string name, string displayName, bool isWritable) : base(method, name, displayName, type) { _isWritable = isWritable; } internal override bool IsWritableVariable { get { return _isWritable; } } internal override BoundExpression RewriteLocal(CSharpCompilation compilation, SyntaxNode syntax, DiagnosticBag diagnostics) { return RewriteLocalInternal(compilation, syntax, this); } internal static BoundExpression RewriteLocal(CSharpCompilation compilation, SyntaxNode syntax, LocalSymbol local) { return RewriteLocalInternal(compilation, syntax, local); } private static BoundExpression RewriteLocalInternal(CSharpCompilation compilation, SyntaxNode syntax, LocalSymbol local) { return new BoundPseudoVariable( syntax, local, new ObjectIdExpressions(compilation), local.Type); } private sealed class ObjectIdExpressions : PseudoVariableExpressions { private readonly CSharpCompilation _compilation; internal ObjectIdExpressions(CSharpCompilation compilation) { _compilation = compilation; } internal override BoundExpression GetValue(BoundPseudoVariable variable, DiagnosticBag diagnostics) { var method = GetIntrinsicMethod(_compilation, ExpressionCompilerConstants.GetVariableValueMethodName); var local = variable.LocalSymbol; var expr = InvokeGetMethod(method, variable.Syntax, local.Name); return ConvertToLocalType(_compilation, expr, local.Type, diagnostics); } internal override BoundExpression GetAddress(BoundPseudoVariable variable) { var method = GetIntrinsicMethod(_compilation, ExpressionCompilerConstants.GetVariableAddressMethodName); // Currently the MetadataDecoder does not support byref return types // so the return type of GetVariableAddress(Of T)(name As String) // is an error type. Since the method is only used for emit, an // updated placeholder method is used instead. // TODO: refs are available // Debug.Assert(method.ReturnType.TypeKind == TypeKind.Error); // If byref return types are supported in the future, use method as is. method = new PlaceholderMethodSymbol( method.ContainingType, method.Name, m => method.TypeParameters.SelectAsArray(t => (TypeParameterSymbol)new SimpleTypeParameterSymbol(m, t.Ordinal, t.Name)), m => m.TypeParameters[0], // return type is <>T& m => method.Parameters.SelectAsArray(p => SynthesizedParameterSymbol.Create(m, p.TypeWithAnnotations, p.Ordinal, p.RefKind, p.Name, p.EffectiveScope, refCustomModifiers: p.RefCustomModifiers))); var local = variable.LocalSymbol; return InvokeGetMethod(method.Construct(local.Type), variable.Syntax, local.Name); } private static BoundExpression InvokeGetMethod(MethodSymbol method, SyntaxNode syntax, string name) { var argument = new BoundLiteral( syntax, Microsoft.CodeAnalysis.ConstantValue.Create(name), method.Parameters[0].Type); return BoundCall.Synthesized( syntax, receiverOpt: null, initialBindingReceiverIsSubjectToCloning: ThreeState.Unknown, method: method, arguments: ImmutableArray.Create<BoundExpression>(argument)); } } } }