提交 53b25d09 编写于 作者: A Andrew Casey

Add regression tests for #2441

After discussing the matter, @agocke, @tmat and I have concluded that the
implementation in EETypeNameDecoder will never be affected by the bug the
compiler was seeing.  However, we still felt it would be worthwhile to
make the implementations consistent.  There is, however, no test, since
the behavior is unchanged.

I added some using/import tests since they use the compiler implementation
(which has already been fixed).

Fixes #2441
上级 eb2f0d8b
......@@ -20,9 +20,8 @@ internal sealed class EETypeNameDecoder : TypeNameDecoder<PEModuleSymbol, TypeSy
protected override int GetIndexOfReferencedAssembly(AssemblyIdentity identity)
{
var assemblies = this.GetAssemblies();
// Find assembly matching identity.
int index = assemblies.IndexOf((assembly, id) => id.Equals(assembly.Identity), identity);
int index = this.Module.GetReferencedAssemblies().IndexOf(identity);
if (index >= 0)
{
return index;
......@@ -31,6 +30,7 @@ protected override int GetIndexOfReferencedAssembly(AssemblyIdentity identity)
{
// Find placeholder Windows.winmd assembly (created
// in MetadataUtilities.MakeAssemblyReferences).
var assemblies = this.Module.GetReferencedAssemblySymbols();
index = assemblies.IndexOf((assembly, unused) => assembly.Identity.IsWindowsRuntime(), (object)null);
if (index >= 0)
{
......@@ -58,7 +58,7 @@ protected override TypeSymbol LookupNestedTypeDefSymbol(TypeSymbol container, re
protected override TypeSymbol LookupTopLevelTypeDefSymbol(int referencedAssemblyIndex, ref MetadataTypeName emittedName)
{
var assembly = this.GetAssemblies()[referencedAssemblyIndex];
var assembly = this.Module.GetReferencedAssemblySymbols()[referencedAssemblyIndex];
return assembly.LookupTopLevelMetadataType(ref emittedName, digThroughForwardedTypes: true);
}
......@@ -67,14 +67,11 @@ protected override TypeSymbol LookupTopLevelTypeDefSymbol(ref MetadataTypeName e
return this.moduleSymbol.LookupTopLevelMetadataType(ref emittedName, out isNoPiaLocalType);
}
private ImmutableArray<AssemblySymbol> GetAssemblies()
{
return _compilation.Assembly.Modules.Single().GetReferencedAssemblySymbols();
}
private static AssemblyIdentity GetComponentAssemblyIdentity(ModuleSymbol module)
{
return ((PEModuleSymbol)module).Module.ReadAssemblyIdentityOrThrow();
}
private ModuleSymbol Module => _compilation.Assembly.Modules.Single();
}
}
......@@ -8,8 +8,11 @@
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Microsoft.DiaSymReader;
using Roslyn.Test.PdbUtilities;
......@@ -1051,6 +1054,67 @@ class B
includeSymbols: false);
Assert.Null(error);
}
[WorkItem(2441, "https://github.com/dotnet/roslyn/issues/2441")]
[Fact]
public void AssemblyQualifiedNameResolutionWithUnification()
{
var source1 = @"
using SI = System.Int32;
public class C1
{
void M()
{
}
}
";
var source2 = @"
public class C2 : C1
{
}
";
ImmutableArray<MetadataReference> unused;
var comp1 = CreateCompilation(source1, new[] { MscorlibRef_v20}, TestOptions.DebugDll, assemblyName: "A");
byte[] dllBytes1;
byte[] pdbBytes1;
comp1.EmitAndGetReferences(out dllBytes1, out pdbBytes1, out unused);
var ref1 = AssemblyMetadata.CreateFromImage(dllBytes1).GetReference(display: "A");
var comp2 = CreateCompilation(source2, new[] { MscorlibRef_v4_0_30316_17626, ref1 }, TestOptions.DebugDll, assemblyName: "B");
byte[] dllBytes2;
byte[] pdbBytes2;
comp2.EmitAndGetReferences(out dllBytes2, out pdbBytes2, out unused);
var ref2 = AssemblyMetadata.CreateFromImage(dllBytes2).GetReference(display: "B");
var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
modulesBuilder.Add(ref1.ToModuleInstance(dllBytes1, new SymReader(pdbBytes1, dllBytes1)));
modulesBuilder.Add(ref2.ToModuleInstance(dllBytes2, new SymReader(pdbBytes2, dllBytes2)));
modulesBuilder.Add(MscorlibRef_v4_0_30316_17626.ToModuleInstance(fullImage: null, symReader: null));
modulesBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null));
using (var runtime = new RuntimeInstance(modulesBuilder.ToImmutableAndFree()))
{
var context = CreateMethodContext(runtime, "C1.M");
string error;
var testData = new CompilationTestData();
context.CompileExpression("typeof(SI)", out error, testData);
Assert.Null(error);
testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldtoken ""int""
IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
IL_000a: ret
}
");
}
}
}
internal static class ImportChainExtensions
......
......@@ -18,15 +18,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Sub
Protected Overrides Function GetIndexOfReferencedAssembly(identity As AssemblyIdentity) As Integer
Dim assemblies = GetAssemblies()
Dim assemblyIdentities = Me.Module.GetReferencedAssemblies()
' Find assembly matching identity.
Dim index = assemblies.IndexOf(Function(assembly, id) id.Equals(assembly.Identity), identity)
Dim index = assemblyIdentities.IndexOf(identity)
If index >= 0 Then
Return index
End If
If identity.IsWindowsComponent() Then
' Find placeholder Windows.winmd assembly (created
' in MetadataUtilities.MakeAssemblyReferences).
Dim assemblies = Me.Module.GetReferencedAssemblySymbols()
index = assemblies.IndexOf(Function(assembly, unused) assembly.Identity.IsWindowsRuntime(), DirectCast(Nothing, Object))
If index >= 0 Then
' Find module in Windows.winmd matching identity.
......@@ -49,7 +50,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
End Function
Protected Overrides Function LookupTopLevelTypeDefSymbol(referencedAssemblyIndex As Integer, ByRef emittedName As MetadataTypeName) As TypeSymbol
Dim assembly = GetAssemblies()(referencedAssemblyIndex)
Dim assembly = Me.Module.GetReferencedAssemblySymbols()(referencedAssemblyIndex)
Return assembly.LookupTopLevelMetadataType(emittedName, digThroughForwardedTypes:=True)
End Function
......@@ -57,14 +58,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Return moduleSymbol.LookupTopLevelMetadataType(emittedName, isNoPiaLocalType)
End Function
Private Function GetAssemblies() As ImmutableArray(Of AssemblySymbol)
Return _compilation.Assembly.Modules.Single().GetReferencedAssemblySymbols()
End Function
Private Shared Function GetComponentAssemblyIdentity([module] As ModuleSymbol) As AssemblyIdentity
Return DirectCast([module], PEModuleSymbol).Module.ReadAssemblyIdentityOrThrow()
End Function
Private ReadOnly Property [Module] As ModuleSymbol
Get
Return _compilation.Assembly.Modules.Single()
End Get
End Property
End Class
End Namespace
......@@ -7,7 +7,9 @@ Imports System.Reflection.Metadata
Imports System.Reflection.Metadata.Ecma335
Imports System.Reflection.PortableExecutable
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -468,6 +470,61 @@ End Namespace
Assert.Equal("http://xml1", xmlNamespaces("C").XmlNamespace)
End Sub
<WorkItem(2441, "https://github.com/dotnet/roslyn/issues/2441")>
<Fact>
Public Sub AssemblyQualifiedNameResolutionWithUnification()
Const source1 = "
Imports SI = System.Int32
Public Class C1
Sub M()
End Sub
End Class
"
Const source2 = "
Public Class C2 : Inherits C1
End Class
"
Dim comp1 = CreateCompilationWithReferences(VisualBasicSyntaxTree.ParseText(source1), {MscorlibRef_v20}, TestOptions.DebugDll, assemblyName:="A")
Dim dllBytes1 As Byte() = Nothing
Dim pdbBytes1 As Byte() = Nothing
comp1.EmitAndGetReferences(dllBytes1, pdbBytes1, Nothing)
Dim ref1 = AssemblyMetadata.CreateFromImage(dllBytes1).GetReference(display:="A")
Dim comp2 = CreateCompilationWithReferences(VisualBasicSyntaxTree.ParseText(source2), {MscorlibRef_v4_0_30316_17626, ref1}, TestOptions.DebugDll, assemblyName:="B")
Dim dllBytes2 As Byte() = Nothing
Dim pdbBytes2 As Byte() = Nothing
comp2.EmitAndGetReferences(dllBytes2, pdbBytes2, Nothing)
Dim ref2 = AssemblyMetadata.CreateFromImage(dllBytes2).GetReference(display:="B")
Dim modulesBuilder = ArrayBuilder(Of ModuleInstance).GetInstance()
modulesBuilder.Add(ref1.ToModuleInstance(dllBytes1, New SymReader(pdbBytes1, dllBytes1)))
modulesBuilder.Add(ref2.ToModuleInstance(dllBytes2, New SymReader(pdbBytes2, dllBytes2)))
modulesBuilder.Add(MscorlibRef_v4_0_30316_17626.ToModuleInstance(fullImage:=Nothing, symReader:=Nothing))
modulesBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage:=Nothing, symReader:=Nothing))
Using runtime As New RuntimeInstance(modulesBuilder.ToImmutableAndFree())
Dim context = CreateMethodContext(runtime, "C1.M")
Dim errorMessage As String = Nothing
Dim testData As New CompilationTestData()
context.CompileExpression("GetType(SI)", errorMessage, testData)
Assert.Null(errorMessage)
testData.GetMethodData("<>x.<>m0").VerifyIL("
{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldtoken ""Integer""
IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type""
IL_000a: ret
}
")
End Using
End Sub
Private Shared Function GetExpressionStatement(compilation As Compilation) As ExpressionStatementSyntax
Return DirectCast(compilation.SyntaxTrees.Single().GetRoot().DescendantNodes().OfType(Of InvocationExpressionSyntax).Single().Parent, ExpressionStatementSyntax)
End Function
......@@ -511,7 +568,7 @@ End Namespace
aliases = Nothing
xmlNamespaces = Nothing
Const bindingFlags As BindingFlags = bindingFlags.NonPublic Or bindingFlags.Instance
Const bindingFlags As BindingFlags = BindingFlags.NonPublic Or BindingFlags.Instance
Dim typesAndNamespacesField = GetType(ImportedTypesAndNamespacesMembersBinder).GetField("_importedSymbols", bindingFlags)
Assert.NotNull(typesAndNamespacesField)
Dim aliasesField = GetType(ImportAliasesBinder).GetField("_importedAliases", bindingFlags)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册