提交 e057056b 编写于 作者: C CyrusNajmabadi

Don't use subclassing of the slot allocator as the way to introduce VB/C# specific lambda behavior.

上级 d2d1f848
......@@ -286,7 +286,7 @@
<Compile Include="DocumentationComments\PEDocumentationCommentUtils.cs" />
<Compile Include="DocumentationComments\SourceDocumentationCommentUtils.cs" />
<Compile Include="Emitter\EditAndContinue\CSharpDefinitionMap.cs" />
<Compile Include="Emitter\EditAndContinue\CSharpEncVariableSlotAllocator.cs" />
<Compile Include="Emitter\EditAndContinue\CSharpLambdaSyntaxHelper.cs" />
<Compile Include="Emitter\EditAndContinue\EmitHelpers.cs" />
<Compile Include="Emitter\EditAndContinue\PEDeltaAssemblyBuilder.cs" />
<Compile Include="Emitter\EditAndContinue\CSharpSymbolMatcher.cs" />
......
......@@ -37,23 +37,9 @@ internal sealed partial class CSharpDefinitionMap : DefinitionMap<CSharpSymbolMa
internal override CommonMessageProvider MessageProvider => CSharp.MessageProvider.Instance;
protected override VariableSlotAllocator CreateSlotAllocator(
CSharpSymbolMatcher symbolMap,
Func<SyntaxNode, SyntaxNode> syntaxMap,
IMethodSymbolInternal previousMethod,
DebugId methodId,
ImmutableArray<EncLocalInfo> previousLocals,
IReadOnlyDictionary<int, KeyValuePair<DebugId, int>> lambdaMap,
IReadOnlyDictionary<int, DebugId> closureMap,
string stateMachineTypeNameOpt,
int hoistedLocalSlotCount,
IReadOnlyDictionary<EncHoistedLocalInfo, int> hoistedLocalMap,
int awaiterSlotCount,
IReadOnlyDictionary<ITypeReference, int> awaiterMap)
protected override ILambdaSyntaxHelper GetLambdaSyntaxHelper()
{
return new CSharpEncVariableSlotAllocator(symbolMap, syntaxMap, previousMethod,
methodId, previousLocals, lambdaMap, closureMap, stateMachineTypeNameOpt,
hoistedLocalSlotCount, hoistedLocalMap, awaiterSlotCount, awaiterMap);
return CSharpLambdaSyntaxHelper.Instance;
}
internal bool TryGetAnonymousTypeName(NamedTypeSymbol template, out string name, out int index)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Symbols;
namespace Microsoft.CodeAnalysis.CSharp.Emit
{
internal class CSharpEncVariableSlotAllocator : EncVariableSlotAllocator
internal class CSharpLambdaSyntaxHelper : ILambdaSyntaxHelper
{
public CSharpEncVariableSlotAllocator(
SymbolMatcher symbolMap,
Func<SyntaxNode, SyntaxNode> syntaxMapOpt,
IMethodSymbolInternal previousTopLevelMethod,
DebugId methodId,
ImmutableArray<EncLocalInfo> previousLocals,
IReadOnlyDictionary<int, KeyValuePair<DebugId, int>> lambdaMapOpt,
IReadOnlyDictionary<int, DebugId> closureMapOpt,
string stateMachineTypeNameOpt,
int hoistedLocalSlotCount,
IReadOnlyDictionary<EncHoistedLocalInfo, int>
hoistedLocalSlotsOpt, int awaiterCount, IReadOnlyDictionary<ITypeReference, int> awaiterMapOpt)
: base(symbolMap, syntaxMapOpt, previousTopLevelMethod, methodId,
previousLocals, lambdaMapOpt, closureMapOpt, stateMachineTypeNameOpt,
hoistedLocalSlotCount, hoistedLocalSlotsOpt, awaiterCount, awaiterMapOpt)
public static readonly ILambdaSyntaxHelper Instance = new CSharpLambdaSyntaxHelper();
private CSharpLambdaSyntaxHelper()
{
}
protected override SyntaxNode GetLambda(SyntaxNode lambdaOrLambdaBodySyntax)
public SyntaxNode GetLambda(SyntaxNode lambdaOrLambdaBodySyntax)
{
return LambdaUtilities.GetLambda(lambdaOrLambdaBodySyntax);
}
protected override SyntaxNode TryGetCorrespondingLambdaBody(
public SyntaxNode TryGetCorrespondingLambdaBody(
SyntaxNode previousLambdaSyntax,
SyntaxNode lambdaOrLambdaBodySyntax)
{
......
......@@ -53,6 +53,7 @@
<Compile Include="CodeGen\ItemTokenMap.cs" />
<Compile Include="Emit\DebugDocumentsBuilder.cs" />
<Compile Include="EmbeddedText.cs" />
<Compile Include="Emit\EditAndContinue\ILambdaHelper.cs" />
<Compile Include="InternalUtilities\EncodingExtensions.cs" />
<Compile Include="InternalUtilities\BlobBuildingStream.cs" />
<Compile Include="GlobalSuppressions.cs" />
......
......@@ -303,7 +303,7 @@ internal VariableSlotAllocator TryCreateVariableSlotAllocator(EmitBaseline basel
symbolMap = mapToMetadata;
}
return CreateSlotAllocator(
return new EncVariableSlotAllocator(
symbolMap,
mappedMethod.SyntaxMap,
mappedMethod.PreviousMethod,
......@@ -315,10 +315,11 @@ internal VariableSlotAllocator TryCreateVariableSlotAllocator(EmitBaseline basel
hoistedLocalSlotCount,
hoistedLocalMap,
awaiterSlotCount,
awaiterMap);
awaiterMap,
GetLambdaSyntaxHelper());
}
protected abstract VariableSlotAllocator CreateSlotAllocator(TSymbolMatcher symbolMap, Func<SyntaxNode, SyntaxNode> syntaxMap, IMethodSymbolInternal previousMethod, DebugId methodId, ImmutableArray<EncLocalInfo> previousLocals, IReadOnlyDictionary<int, KeyValuePair<DebugId, int>> lambdaMap, IReadOnlyDictionary<int, DebugId> closureMap, string stateMachineTypeNameOpt, int hoistedLocalSlotCount, IReadOnlyDictionary<EncHoistedLocalInfo, int> hoistedLocalMap, int awaiterSlotCount, IReadOnlyDictionary<ITypeReference, int> awaiterMap);
protected abstract ILambdaSyntaxHelper GetLambdaSyntaxHelper();
private void ReportMissingStateMachineAttribute(DiagnosticBag diagnostics, IMethodSymbolInternal method, string stateMachineAttributeFullName)
{
......
......@@ -11,7 +11,7 @@
namespace Microsoft.CodeAnalysis.Emit
{
internal abstract class EncVariableSlotAllocator : VariableSlotAllocator
internal class EncVariableSlotAllocator : VariableSlotAllocator
{
// symbols:
private readonly SymbolMatcher _symbolMap;
......@@ -36,7 +36,9 @@ internal abstract class EncVariableSlotAllocator : VariableSlotAllocator
private readonly IReadOnlyDictionary<int, KeyValuePair<DebugId, int>> _lambdaMapOpt; // SyntaxOffset -> (Lambda Id, Closure Ordinal)
private readonly IReadOnlyDictionary<int, DebugId> _closureMapOpt; // SyntaxOffset -> Id
protected EncVariableSlotAllocator(
private readonly ILambdaSyntaxHelper _lambdaSyntaxHelper;
public EncVariableSlotAllocator(
SymbolMatcher symbolMap,
Func<SyntaxNode, SyntaxNode> syntaxMapOpt,
IMethodSymbolInternal previousTopLevelMethod,
......@@ -48,7 +50,8 @@ internal abstract class EncVariableSlotAllocator : VariableSlotAllocator
int hoistedLocalSlotCount,
IReadOnlyDictionary<EncHoistedLocalInfo, int> hoistedLocalSlotsOpt,
int awaiterCount,
IReadOnlyDictionary<Cci.ITypeReference, int> awaiterMapOpt)
IReadOnlyDictionary<Cci.ITypeReference, int> awaiterMapOpt,
ILambdaSyntaxHelper lambdaSyntaxHelper)
{
Debug.Assert(symbolMap != null);
Debug.Assert(previousTopLevelMethod != null);
......@@ -66,6 +69,7 @@ internal abstract class EncVariableSlotAllocator : VariableSlotAllocator
_awaiterMapOpt = awaiterMapOpt;
_lambdaMapOpt = lambdaMapOpt;
_closureMapOpt = closureMapOpt;
_lambdaSyntaxHelper = lambdaSyntaxHelper;
// Create a map from local info to slot.
var previousLocalInfoToSlot = new Dictionary<EncLocalInfo, int>();
......@@ -249,7 +253,9 @@ private bool TryGetPreviousLambdaSyntaxOffset(SyntaxNode lambdaOrLambdaBodySynta
{
// Syntax map contains mapping for lambdas, but not their bodies.
// Map the lambda first and then determine the corresponding body.
var currentLambdaSyntax = isLambdaBody ? GetLambda(lambdaOrLambdaBodySyntax) : lambdaOrLambdaBodySyntax;
var currentLambdaSyntax = isLambdaBody
? _lambdaSyntaxHelper.GetLambda(lambdaOrLambdaBodySyntax)
: lambdaOrLambdaBodySyntax;
// no syntax map
// => the source of the current method is the same as the source of the previous method
......@@ -265,7 +271,7 @@ private bool TryGetPreviousLambdaSyntaxOffset(SyntaxNode lambdaOrLambdaBodySynta
SyntaxNode previousSyntax;
if (isLambdaBody)
{
previousSyntax = TryGetCorrespondingLambdaBody(previousLambdaSyntax, lambdaOrLambdaBodySyntax);
previousSyntax = _lambdaSyntaxHelper.TryGetCorrespondingLambdaBody(previousLambdaSyntax, lambdaOrLambdaBodySyntax);
if (previousSyntax == null)
{
previousSyntaxOffset = 0;
......@@ -281,18 +287,6 @@ private bool TryGetPreviousLambdaSyntaxOffset(SyntaxNode lambdaOrLambdaBodySynta
return true;
}
protected abstract SyntaxNode GetLambda(SyntaxNode lambdaOrLambdaBodySyntax);
/// <summary>
/// When invoked on a node that represents an anonymous function or a query clause [1]
/// with a <paramref name="lambdaOrLambdaBodySyntax"/> of another anonymous function or a query clause of the same kind [2],
/// returns the body of the [1] that positionally corresponds to the specified <paramref name="lambdaOrLambdaBodySyntax"/>.
///
/// E.g. join clause declares left expression and right expression -- each of these expressions is a lambda body.
/// JoinClause1.GetCorrespondingLambdaBody(JoinClause2.RightExpression) returns JoinClause1.RightExpression.
/// </summary>
protected abstract SyntaxNode TryGetCorrespondingLambdaBody(SyntaxNode previousLambdaSyntax, SyntaxNode lambdaOrLambdaBodySyntax);
public override bool TryGetPreviousClosure(SyntaxNode scopeSyntax, out DebugId closureId)
{
int syntaxOffset;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Emit
{
internal interface ILambdaSyntaxHelper
{
SyntaxNode GetLambda(SyntaxNode lambdaOrLambdaBodySyntax);
/// <summary>
/// When invoked on a node that represents an anonymous function or a query clause [1]
/// with a <paramref name="lambdaOrLambdaBodySyntax"/> of another anonymous function or a query clause of the same kind [2],
/// returns the body of the [1] that positionally corresponds to the specified <paramref name="lambdaOrLambdaBodySyntax"/>.
///
/// E.g. join clause declares left expression and right expression -- each of these expressions is a lambda body.
/// JoinClause1.GetCorrespondingLambdaBody(JoinClause2.RightExpression) returns JoinClause1.RightExpression.
/// </summary>
SyntaxNode TryGetCorrespondingLambdaBody(SyntaxNode previousLambdaSyntax, SyntaxNode lambdaOrLambdaBodySyntax);
}
}
\ No newline at end of file
......@@ -39,10 +39,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
End Get
End Property
Protected Overrides Function CreateSlotAllocator(symbolMap As VisualBasicSymbolMatcher, syntaxMap As Func(Of SyntaxNode, SyntaxNode), previousMethod As IMethodSymbolInternal, methodId As DebugId, previousLocals As ImmutableArray(Of EncLocalInfo), lambdaMap As IReadOnlyDictionary(Of Integer, KeyValuePair(Of DebugId, Integer)), closureMap As IReadOnlyDictionary(Of Integer, DebugId), stateMachineTypeNameOpt As String, hoistedLocalSlotCount As Integer, hoistedLocalMap As IReadOnlyDictionary(Of EncHoistedLocalInfo, Integer), awaiterSlotCount As Integer, awaiterMap As IReadOnlyDictionary(Of ITypeReference, Integer)) As VariableSlotAllocator
Return New VisualBasicEncVariableSlotAllocator(symbolMap, syntaxMap, previousMethod,
methodId, previousLocals, lambdaMap, closureMap, stateMachineTypeNameOpt,
hoistedLocalSlotCount, hoistedLocalMap, awaiterSlotCount, awaiterMap)
Protected Overrides Function GetLambdaSyntaxHelper() As ILambdaSyntaxHelper
Return VisualBasicLambdaSyntaxHelper.Instance
End Function
Friend Function TryGetAnonymousTypeName(template As NamedTypeSymbol, <Out> ByRef name As String, <Out> ByRef index As Integer) As Boolean
......
......@@ -7,31 +7,19 @@ Imports Microsoft.CodeAnalysis.Emit
Imports Microsoft.CodeAnalysis.Symbols
Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Friend Class VisualBasicEncVariableSlotAllocator
Inherits EncVariableSlotAllocator
Friend Class VisualBasicLambdaSyntaxHelper
Implements ILambdaSyntaxHelper
Public Sub New(symbolMap As SymbolMatcher,
syntaxMapOpt As Func(Of SyntaxNode, SyntaxNode),
previousTopLevelMethod As IMethodSymbolInternal,
methodId As DebugId,
previousLocals As ImmutableArray(Of EncLocalInfo),
lambdaMapOpt As IReadOnlyDictionary(Of Integer, KeyValuePair(Of DebugId, Integer)),
closureMapOpt As IReadOnlyDictionary(Of Integer, DebugId),
stateMachineTypeNameOpt As String,
hoistedLocalSlotCount As Integer,
hoistedLocalSlotsOpt As IReadOnlyDictionary(Of EncHoistedLocalInfo, Integer),
awaiterCount As Integer,
awaiterMapOpt As IReadOnlyDictionary(Of ITypeReference, Integer))
MyBase.New(symbolMap, syntaxMapOpt, previousTopLevelMethod, methodId,
previousLocals, lambdaMapOpt, closureMapOpt, stateMachineTypeNameOpt,
hoistedLocalSlotCount, hoistedLocalSlotsOpt, awaiterCount, awaiterMapOpt)
Public Shared ReadOnly Instance As ILambdaSyntaxHelper = New VisualBasicLambdaSyntaxHelper()
Private Sub New()
End Sub
Protected Overrides Function GetLambda(lambdaOrLambdaBodySyntax As SyntaxNode) As SyntaxNode
Public Function GetLambda(lambdaOrLambdaBodySyntax As SyntaxNode) As SyntaxNode Implements ILambdaSyntaxHelper.GetLambda
Return LambdaUtilities.GetLambda(lambdaOrLambdaBodySyntax)
End Function
Protected Overrides Function TryGetCorrespondingLambdaBody(previousLambdaSyntax As SyntaxNode, lambdaOrLambdaBodySyntax As SyntaxNode) As SyntaxNode
Public Function TryGetCorrespondingLambdaBody(previousLambdaSyntax As SyntaxNode, lambdaOrLambdaBodySyntax As SyntaxNode) As SyntaxNode Implements ILambdaSyntaxHelper.TryGetCorrespondingLambdaBody
Return LambdaUtilities.GetCorrespondingLambdaBody(lambdaOrLambdaBodySyntax, previousLambdaSyntax)
End Function
End Class
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册