提交 7852a0ec 编写于 作者: O Omar Tawfik

Addressed PR comments

上级 1a937f3c
...@@ -8999,7 +8999,7 @@ internal class CSharpResources { ...@@ -8999,7 +8999,7 @@ internal class CSharpResources {
} }
/// <summary> /// <summary>
/// Looks up a localized string similar to Type &apos;{0}&apos; is forwarded to multiple assemblies: &apos;{1}&apos; and &apos;{2}&apos;. /// Looks up a localized string similar to Module &apos;{0}&apos; in assembly &apos;{1}&apos; is forwarding the type &apos;{2}&apos; to multiple assemblies: &apos;{3}&apos; and &apos;{4}&apos;..
/// </summary> /// </summary>
internal static string ERR_TypeForwardedToMultipleAssemblies { internal static string ERR_TypeForwardedToMultipleAssemblies {
get { get {
......
...@@ -5009,6 +5009,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ ...@@ -5009,6 +5009,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
<value>Attributes are not allowed on local function parameters or type parameters</value> <value>Attributes are not allowed on local function parameters or type parameters</value>
</data> </data>
<data name="ERR_TypeForwardedToMultipleAssemblies" xml:space="preserve"> <data name="ERR_TypeForwardedToMultipleAssemblies" xml:space="preserve">
<value>Type '{0}' is forwarded to multiple assemblies: '{1}' and '{2}'</value> <value>Module '{0}' in assembly '{1}' is forwarding the type '{2}' to multiple assemblies: '{3}' and '{4}'.</value>
</data> </data>
</root> </root>
\ No newline at end of file
...@@ -370,6 +370,12 @@ internal ErrorTypeSymbol CreateCycleInTypeForwarderErrorTypeSymbol(ref MetadataT ...@@ -370,6 +370,12 @@ internal ErrorTypeSymbol CreateCycleInTypeForwarderErrorTypeSymbol(ref MetadataT
return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Modules[0], ref emittedName, diagnosticInfo); return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Modules[0], ref emittedName, diagnosticInfo);
} }
internal ErrorTypeSymbol CreateMultipleForwardingErrorTypeSymbol(ref MetadataTypeName emittedName, ModuleSymbol forwardingModule, AssemblySymbol destination1, AssemblySymbol destination2)
{
var diagnosticInfo = new CSDiagnosticInfo(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, forwardingModule, this, emittedName.FullName, destination1, destination2);
return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(forwardingModule, ref emittedName, diagnosticInfo);
}
/// <summary> /// <summary>
/// Lookup declaration for predefined CorLib type in this Assembly. /// Lookup declaration for predefined CorLib type in this Assembly.
/// </summary> /// </summary>
......
...@@ -157,13 +157,8 @@ internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetecti ...@@ -157,13 +157,8 @@ internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetecti
{ {
if ((object)secondSymbol != null) if ((object)secondSymbol != null)
{ {
var forwardingErrorInfo = new DiagnosticInfo( // Report the main module as that is the only one checked. clr does not honor type forwarders in non-primary modules.
MessageProvider.Instance, return CreateMultipleForwardingErrorTypeSymbol(ref emittedName, this.PrimaryModule, firstSymbol, secondSymbol);
(int)ErrorCode.ERR_TypeForwardedToMultipleAssemblies,
emittedName.FullName,
firstSymbol.Name,
secondSymbol.Name);
return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(PrimaryModule, ref emittedName, forwardingErrorInfo);
} }
// Don't bother to check the forwarded-to assembly if we've already seen it. // Don't bother to check the forwarded-to assembly if we've already seen it.
......
...@@ -653,9 +653,19 @@ internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emitted ...@@ -653,9 +653,19 @@ internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emitted
string matchedName; string matchedName;
(int firstIndex, int secondIndex) = this.Module.GetAssemblyRefsForForwardedType(fullName.FullName, ignoreCase: false, matchedName: out matchedName); (int firstIndex, int secondIndex) = this.Module.GetAssemblyRefsForForwardedType(fullName.FullName, ignoreCase: false, matchedName: out matchedName);
var firstSymbol = firstIndex < 0 ? null : GetReferencedAssemblySymbol(firstIndex); if (firstIndex < 0)
var secondSymbol = secondIndex < 0 ? null : GetReferencedAssemblySymbol(secondIndex); {
return (null, null);
}
AssemblySymbol firstSymbol = GetReferencedAssemblySymbol(firstIndex);
if (secondIndex < 0)
{
return (firstSymbol, null);
}
AssemblySymbol secondSymbol = GetReferencedAssemblySymbol(secondIndex);
return (firstSymbol, secondSymbol); return (firstSymbol, secondSymbol);
} }
...@@ -663,13 +673,9 @@ internal IEnumerable<NamedTypeSymbol> GetForwardedTypes() ...@@ -663,13 +673,9 @@ internal IEnumerable<NamedTypeSymbol> GetForwardedTypes()
{ {
foreach (KeyValuePair<string, (int FirstIndex, int SecondIndex)> forwarder in Module.GetForwardedTypes()) foreach (KeyValuePair<string, (int FirstIndex, int SecondIndex)> forwarder in Module.GetForwardedTypes())
{ {
if (forwarder.Value.FirstIndex < 0)
{
continue;
}
var name = MetadataTypeName.FromFullName(forwarder.Key); var name = MetadataTypeName.FromFullName(forwarder.Key);
Debug.Assert(forwarder.Value.FirstIndex >= 0, "First index should never be negative");
AssemblySymbol firstSymbol = this.GetReferencedAssemblySymbol(forwarder.Value.FirstIndex); AssemblySymbol firstSymbol = this.GetReferencedAssemblySymbol(forwarder.Value.FirstIndex);
Debug.Assert((object)firstSymbol != null, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()"); Debug.Assert((object)firstSymbol != null, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()");
...@@ -678,8 +684,7 @@ internal IEnumerable<NamedTypeSymbol> GetForwardedTypes() ...@@ -678,8 +684,7 @@ internal IEnumerable<NamedTypeSymbol> GetForwardedTypes()
var secondSymbol = this.GetReferencedAssemblySymbol(forwarder.Value.SecondIndex); var secondSymbol = this.GetReferencedAssemblySymbol(forwarder.Value.SecondIndex);
Debug.Assert((object)secondSymbol != null, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()"); Debug.Assert((object)secondSymbol != null, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()");
var forwardingErrorInfo = new DiagnosticInfo(MessageProvider.Instance, (int)ErrorCode.ERR_TypeForwardedToMultipleAssemblies, forwarder.Key, firstSymbol.Name, secondSymbol.Name); yield return ContainingAssembly.CreateMultipleForwardingErrorTypeSymbol(ref name, this, firstSymbol, secondSymbol);
yield return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this, ref name, forwardingErrorInfo);
} }
else else
{ {
......
...@@ -2589,13 +2589,7 @@ internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetecti ...@@ -2589,13 +2589,7 @@ internal override NamedTypeSymbol TryLookupForwardedMetadataTypeWithCycleDetecti
{ {
if ((object)secondSymbol != null) if ((object)secondSymbol != null)
{ {
var forwardingErrorInfo = new DiagnosticInfo( return CreateMultipleForwardingErrorTypeSymbol(ref emittedName, peModuleSymbol, firstSymbol, secondSymbol);
MessageProvider.Instance,
(int)ErrorCode.ERR_TypeForwardedToMultipleAssemblies,
emittedName.FullName,
firstSymbol.Name,
secondSymbol.Name);
return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(SourceModule, ref emittedName, forwardingErrorInfo);
} }
// Don't bother to check the forwarded-to assembly if we've already seen it. // Don't bother to check the forwarded-to assembly if we've already seen it.
......
...@@ -19508,6 +19508,7 @@ .assembly Forwarder ...@@ -19508,6 +19508,7 @@ .assembly Forwarder
{ {
.ver 1:0:0:0 .ver 1:0:0:0
} }
.module ForwarderModule.dll
.class extern forwarder Destination.TestClass .class extern forwarder Destination.TestClass
{ {
.assembly extern Destination1 .assembly extern Destination1
...@@ -19519,9 +19520,9 @@ .assembly Forwarder ...@@ -19519,9 +19520,9 @@ .assembly Forwarder
var compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader: false); var compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader: false);
compilation.VerifyDiagnostics( compilation.VerifyDiagnostics(
// (8,29): error CS8206: Type 'Destination.TestClass' is forwarded to multiple assemblies: 'Destination1' and 'Destination2' // (8,29): error CS8206: Module 'ForwarderModule.dll' in assembly 'Forwarder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'Destination.TestClass' to multiple assemblies: 'Destination1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' and 'Destination2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
// new Destination.TestClass(); // new Destination.TestClass();
Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, "TestClass").WithArguments("Destination.TestClass", "Destination1", "Destination2").WithLocation(8, 29), Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, "TestClass").WithArguments("ForwarderModule.dll", "Forwarder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Destination.TestClass", "Destination1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Destination2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(8, 29),
// (8,29): error CS0234: The type or namespace name 'TestClass' does not exist in the namespace 'Destination' (are you missing an assembly reference?) // (8,29): error CS0234: The type or namespace name 'TestClass' does not exist in the namespace 'Destination' (are you missing an assembly reference?)
// new Destination.TestClass(); // new Destination.TestClass();
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "TestClass").WithArguments("TestClass", "Destination").WithLocation(8, 29)); Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "TestClass").WithArguments("TestClass", "Destination").WithLocation(8, 29));
...@@ -19542,9 +19543,8 @@ public static void Main() ...@@ -19542,9 +19543,8 @@ public static void Main()
} }
}"; }";
var forwardingIL = @" var forwardingIL = @"
.assembly Forwarder .assembly Forwarder { }
{ .module ForwarderModule.dll
}
.assembly extern Destination1 { } .assembly extern Destination1 { }
.assembly extern Destination2 { } .assembly extern Destination2 { }
.assembly extern Destination3 { } .assembly extern Destination3 { }
...@@ -19573,9 +19573,9 @@ .assembly Forwarder ...@@ -19573,9 +19573,9 @@ .assembly Forwarder
var compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader: false); var compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader: false);
compilation.VerifyDiagnostics( compilation.VerifyDiagnostics(
// (8,29): error CS8206: Type 'Destination.TestClass' is forwarded to multiple assemblies: 'Destination1' and 'Destination2' // (8,29): error CS8206: Module 'ForwarderModule.dll' in assembly 'Forwarder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'Destination.TestClass' to multiple assemblies: 'Destination1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'Destination2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// new Destination.TestClass(); // new Destination.TestClass();
Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, "TestClass").WithArguments("Destination.TestClass", "Destination1", "Destination2").WithLocation(8, 29), Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, "TestClass").WithArguments("ForwarderModule.dll", "Forwarder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Destination.TestClass", "Destination1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Destination2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(8, 29),
// (8,29): error CS0234: The type or namespace name 'TestClass' does not exist in the namespace 'Destination' (are you missing an assembly reference?) // (8,29): error CS0234: The type or namespace name 'TestClass' does not exist in the namespace 'Destination' (are you missing an assembly reference?)
// new Destination.TestClass(); // new Destination.TestClass();
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "TestClass").WithArguments("TestClass", "Destination").WithLocation(8, 29)); Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "TestClass").WithArguments("TestClass", "Destination").WithLocation(8, 29));
...@@ -19631,6 +19631,7 @@ .assembly C ...@@ -19631,6 +19631,7 @@ .assembly C
{ {
.ver 0:0:0:0 .ver 0:0:0:0
} }
.module CModule.dll
.assembly extern D1 { } .assembly extern D1 { }
.assembly extern D2 { } .assembly extern D2 { }
.class extern forwarder C.ClassC .class extern forwarder C.ClassC
...@@ -19645,9 +19646,9 @@ .assembly C ...@@ -19645,9 +19646,9 @@ .assembly C
var referenceC2 = CompileIL(codeC2, appendDefaultHeader: false); var referenceC2 = CompileIL(codeC2, appendDefaultHeader: false);
CreateCompilationWithMscorlib(codeA, references: new MetadataReference[] { referenceB, referenceC2 }, assemblyName: "A").VerifyDiagnostics( CreateCompilationWithMscorlib(codeA, references: new MetadataReference[] { referenceB, referenceC2 }, assemblyName: "A").VerifyDiagnostics(
// (10,13): error CS8206: Type 'C.ClassC' is forwarded to multiple assemblies: 'D1' and 'D2' // (10,13): error CS8206: Module 'CModule.dll' in assembly 'C, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'C.ClassC' to multiple assemblies: 'D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'D2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// ClassB.MethodB(null); // ClassB.MethodB(null);
Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, "ClassB.MethodB").WithArguments("C.ClassC", "D1", "D2").WithLocation(10, 13)); Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies, "ClassB.MethodB").WithArguments("CModule.dll", "C, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "C.ClassC", "D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "D2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));
} }
[Fact, WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")] [Fact, WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")]
...@@ -19718,9 +19719,10 @@ .assembly C ...@@ -19718,9 +19719,10 @@ .assembly C
} }
[Fact, WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")] [Fact, WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")]
public void AddingReferenceToModuleWithMultipleForwardersToDifferentAssembliesShouldErrorOut() public void CompilingModuleWithMultipleForwardersToDifferentAssembliesShouldErrorOut()
{ {
var ilSource = @" var ilSource = @"
.module ForwarderModule.dll
.assembly extern D1 { } .assembly extern D1 { }
.assembly extern D2 { } .assembly extern D2 { }
.class extern forwarder Testspace.TestType .class extern forwarder Testspace.TestType
...@@ -19732,19 +19734,14 @@ public void AddingReferenceToModuleWithMultipleForwardersToDifferentAssembliesSh ...@@ -19732,19 +19734,14 @@ public void AddingReferenceToModuleWithMultipleForwardersToDifferentAssembliesSh
.assembly extern D2 .assembly extern D2
}"; }";
ImmutableArray<byte> ilBytes; var ilModule = GetILModuleReference(ilSource, appendDefaultHeader: false);
ImmutableArray<byte> pdbBytes; CreateCompilationWithMscorlib(string.Empty, references: new MetadataReference[] { ilModule }, assemblyName: "Forwarder").VerifyDiagnostics(
EmitILToArray(ilSource, appendDefaultHeader: false, includePdb: false, assemblyBytes: out ilBytes, pdbBytes: out pdbBytes); // error CS8206: Module 'ForwarderModule.dll' in assembly 'Forwarder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'Testspace.TestType' to multiple assemblies: 'D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'D2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies).WithArguments("ForwarderModule.dll", "Forwarder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "Testspace.TestType", "D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "D2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1));
var ilModule = ModuleMetadata.CreateFromImage(ilBytes).GetReference();
CreateCompilationWithMscorlib(string.Empty, references: new MetadataReference[] { ilModule }).VerifyDiagnostics(
// error CS8206: Type 'Testspace.TestType' is forwarded to multiple assemblies: 'D1' and 'D2'
Diagnostic(ErrorCode.ERR_TypeForwardedToMultipleAssemblies).WithArguments("Testspace.TestType", "D1", "D2").WithLocation(1, 1));
} }
[Fact, WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")] [Fact, WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")]
public void AddingReferenceToModuleWithMultipleForwardersToTheSameAssemblyShouldNotProduceMultipleForwardingErrors() public void CompilingModuleWithMultipleForwardersToTheSameAssemblyShouldNotProduceMultipleForwardingErrors()
{ {
var ilSource = @" var ilSource = @"
.assembly extern D1 { } .assembly extern D1 { }
...@@ -19757,12 +19754,7 @@ public void AddingReferenceToModuleWithMultipleForwardersToTheSameAssemblyShould ...@@ -19757,12 +19754,7 @@ public void AddingReferenceToModuleWithMultipleForwardersToTheSameAssemblyShould
.assembly extern D1 .assembly extern D1
}"; }";
ImmutableArray<byte> ilBytes; var ilModule = GetILModuleReference(ilSource, appendDefaultHeader: false);
ImmutableArray<byte> pdbBytes;
EmitILToArray(ilSource, appendDefaultHeader: false, includePdb: false, assemblyBytes: out ilBytes, pdbBytes: out pdbBytes);
var ilModule = ModuleMetadata.CreateFromImage(ilBytes).GetReference();
CreateCompilationWithMscorlib(string.Empty, references: new MetadataReference[] { ilModule }).VerifyDiagnostics( CreateCompilationWithMscorlib(string.Empty, references: new MetadataReference[] { ilModule }).VerifyDiagnostics(
// error CS0012: The type 'TestType' is defined in an assembly that is not referenced. You must add a reference to assembly 'D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // error CS0012: The type 'TestType' is defined in an assembly that is not referenced. You must add a reference to assembly 'D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("Testspace.TestType", "D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1)); Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("Testspace.TestType", "D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1));
......
...@@ -2901,7 +2901,7 @@ private void EnsureForwardTypeToAssemblyMap() ...@@ -2901,7 +2901,7 @@ private void EnsureForwardTypeToAssemblyMap()
continue; continue;
} }
if (referencedAssemblyIndex >= this.ReferencedAssemblies.Length) if (referencedAssemblyIndex < 0 || referencedAssemblyIndex >= this.ReferencedAssemblies.Length)
{ {
continue; continue;
} }
...@@ -2921,6 +2921,8 @@ private void EnsureForwardTypeToAssemblyMap() ...@@ -2921,6 +2921,8 @@ private void EnsureForwardTypeToAssemblyMap()
if (typesToAssemblyIndexMap.TryGetValue(name, out indices)) if (typesToAssemblyIndexMap.TryGetValue(name, out indices))
{ {
Debug.Assert(indices.FirstIndex >= 0, "Not allowed to store a negative (non-existent) index in typesToAssemblyIndexMap");
// Store it only if it was not a duplicate // Store it only if it was not a duplicate
if (indices.FirstIndex != referencedAssemblyIndex && indices.SecondIndex < 0) if (indices.FirstIndex != referencedAssemblyIndex && indices.SecondIndex < 0)
{ {
......
...@@ -511,9 +511,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -511,9 +511,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Next Next
If forwardedType IsNot Nothing Then If forwardedType IsNot Nothing Then
If Not reportedAnError And forwardedType.IsErrorType Then If Not reportedAnError AndAlso forwardedType.IsErrorType Then
Dim errorInfo = DirectCast(forwardedType, ErrorTypeSymbol).ErrorInfo Dim errorInfo = DirectCast(forwardedType, ErrorTypeSymbol).ErrorInfo
If errorInfo.Code = ERRID.ERR_TypeFwdCycle2 Then If errorInfo.Code = ERRID.ERR_TypeFwdCycle2 Then
Debug.Assert(forwardedType.ContainingAssembly IsNot Nothing, "How did we find a cycle if there is no forwarding?") Debug.Assert(forwardedType.ContainingAssembly IsNot Nothing, "How did we find a cycle if there is no forwarding?")
Binder.ReportDiagnostic(diagBag, typeSyntax, ERRID.ERR_TypeFwdCycle2, fullName, forwardedType.ContainingAssembly) Binder.ReportDiagnostic(diagBag, typeSyntax, ERRID.ERR_TypeFwdCycle2, fullName, forwardedType.ContainingAssembly)
......
...@@ -301,6 +301,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -301,6 +301,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Return New MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(Me.Modules(0), emittedName, diagInfo) Return New MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(Me.Modules(0), emittedName, diagInfo)
End Function End Function
Friend Function CreateMultipleForwardingErrorTypeSymbol(ByRef emittedName As MetadataTypeName, forwardingModule As ModuleSymbol, destination1 As AssemblySymbol, destination2 As AssemblySymbol) As ErrorTypeSymbol
Dim diagnosticInfo = New DiagnosticInfo(MessageProvider.Instance, ERRID.ERR_TypeForwardedToMultipleAssemblies, forwardingModule, Me, emittedName.FullName, destination1, destination2)
Return New MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(forwardingModule, emittedName, diagnosticInfo)
End Function
''' <summary> ''' <summary>
''' Lookup declaration for predefined CorLib type in this Assembly. Only valid if this ''' Lookup declaration for predefined CorLib type in this Assembly. Only valid if this
''' assembly is the Cor Library ''' assembly is the Cor Library
......
...@@ -166,17 +166,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE ...@@ -166,17 +166,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Dim matchedName As String = Nothing Dim matchedName As String = Nothing
Dim forwardedToAssemblies = LookupAssembliesForForwardedMetadataType(emittedName, ignoreCase, matchedName) Dim forwardedToAssemblies = LookupAssembliesForForwardedMetadataType(emittedName, ignoreCase, matchedName)
If DirectCast(forwardedToAssemblies.FirstSymbol, Object) IsNot Nothing If forwardedToAssemblies.FirstSymbol IsNot Nothing Then
If DirectCast(forwardedToAssemblies.SecondSymbol, Object) IsNot Nothing If forwardedToAssemblies.SecondSymbol IsNot Nothing Then
Dim forwardingErrorInfo = New DiagnosticInfo( ' Report the main module as that Is the only one checked. clr does Not honor type forwarders in non-primary modules.
MessageProvider.Instance, Return CreateMultipleForwardingErrorTypeSymbol(emittedName, PrimaryModule, forwardedToAssemblies.FirstSymbol, forwardedToAssemblies.SecondSymbol)
ERRID.ERR_TypeForwardedToMultipleAssemblies,
emittedName.FullName,
forwardedToAssemblies.FirstSymbol.Name,
forwardedToAssemblies.SecondSymbol.Name)
Return new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(PrimaryModule, emittedName, forwardingErrorInfo)
End If End If
' Don't bother to check the forwarded-to assembly if we've already seen it. ' Don't bother to check the forwarded-to assembly if we've already seen it.
If visitedAssemblies IsNot Nothing AndAlso visitedAssemblies.Contains(forwardedToAssemblies.FirstSymbol) Then If visitedAssemblies IsNot Nothing AndAlso visitedAssemblies.Contains(forwardedToAssemblies.FirstSymbol) Then
Return CreateCycleInTypeForwarderErrorTypeSymbol(emittedName) Return CreateCycleInTypeForwarderErrorTypeSymbol(emittedName)
......
...@@ -434,30 +434,34 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE ...@@ -434,30 +434,34 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
''' </remarks> ''' </remarks>
Friend Function GetAssembliesForForwardedType(ByRef fullName As MetadataTypeName, ignoreCase As Boolean, <Out> ByRef matchedName As String) As (FirstSymbol As AssemblySymbol, SecondSymbol As AssemblySymbol) Friend Function GetAssembliesForForwardedType(ByRef fullName As MetadataTypeName, ignoreCase As Boolean, <Out> ByRef matchedName As String) As (FirstSymbol As AssemblySymbol, SecondSymbol As AssemblySymbol)
Dim indices = Me.Module.GetAssemblyRefsForForwardedType(fullName.FullName, ignoreCase, matchedName) Dim indices = Me.Module.GetAssemblyRefsForForwardedType(fullName.FullName, ignoreCase, matchedName)
Dim firstSymbol = If(indices.FirstIndex < 0, Nothing, GetReferencedAssemblySymbol(indices.FirstIndex))
Dim secondSymbol = If(indices.SecondIndex < 0, Nothing, GetReferencedAssemblySymbol(indices.SecondIndex))
return (firstSymbol, secondSymbol) If indices.FirstIndex < 0 Then
Return (Nothing, Nothing)
End If
Dim firstSymbol = GetReferencedAssemblySymbol(indices.FirstIndex)
If indices.SecondIndex < 0 Then
Return (firstSymbol, Nothing)
End If
Dim secondSymbol = GetReferencedAssemblySymbol(indices.SecondIndex)
Return (firstSymbol, secondSymbol)
End Function End Function
Friend Iterator Function GetForwardedTypes() As IEnumerable(Of NamedTypeSymbol) Friend Iterator Function GetForwardedTypes() As IEnumerable(Of NamedTypeSymbol)
For Each forwarder As KeyValuePair(Of String, (FirstIndex As Integer, SecondIndex As Integer)) In Me.Module.GetForwardedTypes() For Each forwarder As KeyValuePair(Of String, (FirstIndex As Integer, SecondIndex As Integer)) In Me.Module.GetForwardedTypes()
If forwarder.Value.FirstIndex < 0 Then
Continue For
End If
Dim name = MetadataTypeName.FromFullName(forwarder.Key) Dim name = MetadataTypeName.FromFullName(forwarder.Key)
Debug.Assert(forwarder.Value.FirstIndex >= 0, "First index should never be negative")
Dim firstSymbol = GetReferencedAssemblySymbol(forwarder.Value.FirstIndex) Dim firstSymbol = GetReferencedAssemblySymbol(forwarder.Value.FirstIndex)
Debug.Assert(DirectCast(firstSymbol, Object) IsNot Nothing, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()") Debug.Assert(firstSymbol IsNot Nothing, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()")
If forwarder.Value.SecondIndex >= 0 Then If forwarder.Value.SecondIndex >= 0 Then
Dim secondSymbol = GetReferencedAssemblySymbol(forwarder.Value.SecondIndex) Dim secondSymbol = GetReferencedAssemblySymbol(forwarder.Value.SecondIndex)
Debug.Assert(DirectCast(secondSymbol, Object) IsNot Nothing, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()") Debug.Assert(secondSymbol IsNot Nothing, "Invalid indexes (out of bound) are discarded during reading metadata in PEModule.EnsureForwardTypeToAssemblyMap()")
Dim forwardingErrorInfo = New DiagnosticInfo(MessageProvider.Instance, ERRID.ERR_TypeForwardedToMultipleAssemblies, forwarder.Key, firstSymbol.Name, secondSymbol.Name) Yield ContainingAssembly.CreateMultipleForwardingErrorTypeSymbol(name, Me, firstSymbol, secondSymbol)
Yield New MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(Me, name, forwardingErrorInfo)
Else Else
Yield firstSymbol.LookupTopLevelMetadataType(name, digThroughForwardedTypes:= true) Yield firstSymbol.LookupTopLevelMetadataType(name, digThroughForwardedTypes:= true)
End If End If
......
...@@ -1695,10 +1695,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -1695,10 +1695,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Dim peModuleSymbol = DirectCast(_modules(i), PEModuleSymbol) Dim peModuleSymbol = DirectCast(_modules(i), PEModuleSymbol)
Dim forwardedToAssemblies = peModuleSymbol.GetAssembliesForForwardedType(emittedName, ignoreCase, matchedName) Dim forwardedToAssemblies = peModuleSymbol.GetAssembliesForForwardedType(emittedName, ignoreCase, matchedName)
If DirectCast(forwardedToAssemblies.FirstSymbol, Object) IsNot Nothing Then If forwardedToAssemblies.FirstSymbol IsNot Nothing Then
If DirectCast(forwardedToAssemblies.SecondSymbol, Object) IsNot Nothing Then If forwardedToAssemblies.SecondSymbol IsNot Nothing Then
Dim forwardingErrorInfo = New DiagnosticInfo(MessageProvider.Instance, ERRID.ERR_TypeForwardedToMultipleAssemblies, emittedName.FullName, forwardedToAssemblies.FirstSymbol.Name, forwardedToAssemblies.SecondSymbol.Name) Return CreateMultipleForwardingErrorTypeSymbol(emittedName, peModuleSymbol, forwardedToAssemblies.FirstSymbol, forwardedToAssemblies.SecondSymbol)
Return New MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(SourceModule, emittedName, forwardingErrorInfo)
End If End If
' Don't bother to check the forwarded-to assembly if we've already seen it. ' Don't bother to check the forwarded-to assembly if we've already seen it.
......
...@@ -10686,7 +10686,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -10686,7 +10686,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Property End Property
'''<summary> '''<summary>
''' Looks up a localized string similar to Type &apos;{0}&apos; is forwarded to multiple assemblies: &apos;{1}&apos; and &apos;{2}&apos;. ''' Looks up a localized string similar to Module &apos;{0}&apos; in assembly &apos;{1}&apos; is forwarding the type &apos;{2}&apos; to multiple assemblies: &apos;{3}&apos; and &apos;{4}&apos;..
'''</summary> '''</summary>
Friend ReadOnly Property ERR_TypeForwardedToMultipleAssemblies() As String Friend ReadOnly Property ERR_TypeForwardedToMultipleAssemblies() As String
Get Get
......
...@@ -5462,6 +5462,6 @@ ...@@ -5462,6 +5462,6 @@
<value>Invalid assembly name: {0}</value> <value>Invalid assembly name: {0}</value>
</data> </data>
<data name="ERR_TypeForwardedToMultipleAssemblies" xml:space="preserve"> <data name="ERR_TypeForwardedToMultipleAssemblies" xml:space="preserve">
<value>Type '{0}' is forwarded to multiple assemblies: '{1}' and '{2}'</value> <value>Module '{0}' in assembly '{1}' is forwarding the type '{2}' to multiple assemblies: '{3}' and '{4}'.</value>
</data> </data>
</root> </root>
\ No newline at end of file
...@@ -23844,6 +23844,7 @@ End Namespace ...@@ -23844,6 +23844,7 @@ End Namespace
{ {
.ver 1:0:0:0 .ver 1:0:0:0
} }
.module ForwarderModule.dll
.class extern forwarder Destination.TestClass .class extern forwarder Destination.TestClass
{ {
.assembly extern Destination1 .assembly extern Destination1
...@@ -23853,12 +23854,12 @@ End Namespace ...@@ -23853,12 +23854,12 @@ End Namespace
.assembly extern Destination2 .assembly extern Destination2
}" }"
Dim compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader:= False) Dim compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader:= False)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[ CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[
BC30002: Type 'Destination.TestClass' is not defined. BC30002: Type 'Destination.TestClass' is not defined.
Dim obj = New Destination.TestClass() Dim obj = New Destination.TestClass()
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
BC37208: Type 'Destination.TestClass' is forwarded to multiple assemblies: 'Destination1' and 'Destination2' BC37208: Module 'ForwarderModule.dll' in assembly 'Forwarder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'Destination.TestClass' to multiple assemblies: 'Destination1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' and 'Destination2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Dim obj = New Destination.TestClass() Dim obj = New Destination.TestClass()
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
]]></errors>) ]]></errors>)
...@@ -23885,6 +23886,7 @@ End Namespace ...@@ -23885,6 +23886,7 @@ End Namespace
.assembly Forwarder .assembly Forwarder
{ {
} }
.module ForwarderModule.dll
.assembly extern Destination1 { } .assembly extern Destination1 { }
.assembly extern Destination2 { } .assembly extern Destination2 { }
.assembly extern Destination3 { } .assembly extern Destination3 { }
...@@ -23912,12 +23914,12 @@ End Namespace ...@@ -23912,12 +23914,12 @@ End Namespace
}" }"
Dim compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader:= False) Dim compilation = CreateCompilationWithCustomILSource(userCode, forwardingIL, appendDefaultHeader:= False)
CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[ CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[
BC30002: Type 'Destination.TestClass' is not defined. BC30002: Type 'Destination.TestClass' is not defined.
Dim obj = New Destination.TestClass() Dim obj = New Destination.TestClass()
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
BC37208: Type 'Destination.TestClass' is forwarded to multiple assemblies: 'Destination1' and 'Destination2' BC37208: Module 'ForwarderModule.dll' in assembly 'Forwarder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'Destination.TestClass' to multiple assemblies: 'Destination1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'Destination2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Dim obj = New Destination.TestClass() Dim obj = New Destination.TestClass()
~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
]]></errors>) ]]></errors>)
...@@ -23984,6 +23986,7 @@ End Namespace" ...@@ -23984,6 +23986,7 @@ End Namespace"
{ {
.ver 0:0:0:0 .ver 0:0:0:0
} }
.module CModule.dll
.assembly extern D1 { } .assembly extern D1 { }
.assembly extern D2 { } .assembly extern D2 { }
.class extern forwarder C.ClassC .class extern forwarder C.ClassC
...@@ -24004,7 +24007,7 @@ End Namespace" ...@@ -24004,7 +24007,7 @@ End Namespace"
assemblyName:= "A") assemblyName:= "A")
CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[ CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[
BC37208: Type 'C.ClassC' is forwarded to multiple assemblies: 'D1' and 'D2' BC37208: Module 'CModule.dll' in assembly 'C, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'C.ClassC' to multiple assemblies: 'D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'D2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
ClassB.MethodB(Nothing) ClassB.MethodB(Nothing)
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
]]></errors>) ]]></errors>)
...@@ -24092,8 +24095,9 @@ BC30652: Reference required to assembly 'D, Version=0.0.0.0, Culture=neutral, Pu ...@@ -24092,8 +24095,9 @@ BC30652: Reference required to assembly 'D, Version=0.0.0.0, Culture=neutral, Pu
<Fact> <Fact>
<WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")> <WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")>
Public Sub AddingReferenceToModuleWithMultipleForwardersToDifferentAssembliesShouldErrorOut() Public Sub CompilingModuleWithMultipleForwardersToDifferentAssembliesShouldErrorOut()
Dim ilSource = " Dim ilSource = "
.module ForwarderModule.dll
.assembly extern D1 { } .assembly extern D1 { }
.assembly extern D2 { } .assembly extern D2 { }
.class extern forwarder Testspace.TestType .class extern forwarder Testspace.TestType
...@@ -24105,22 +24109,21 @@ BC30652: Reference required to assembly 'D, Version=0.0.0.0, Culture=neutral, Pu ...@@ -24105,22 +24109,21 @@ BC30652: Reference required to assembly 'D, Version=0.0.0.0, Culture=neutral, Pu
.assembly extern D2 .assembly extern D2
}" }"
Dim ilBytes As ImmutableArray(Of Byte) = Nothing Dim ilModule = GetILModuleReference(ilSource, appendDefaultHeader:=False)
Dim pdbBytes As ImmutableArray(Of Byte) = Nothing Dim compilation = CreateCompilationWithMscorlib(
EmitILToArray(ilSource, appendDefaultHeader:=False, includePdb:=False, assemblyBytes:=ilBytes, pdbBytes:=pdbBytes) source:=String.Empty,
references:={ilModule},
Dim ilModule = ModuleMetadata.CreateFromImage(ilBytes).GetReference() options:=New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
assemblyName:="Forwarder")
Dim compilation = CreateCompilationWithMscorlib(String.Empty, references:={ilModule}, options:=New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[ CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[
BC37208: Type 'Testspace.TestType' is forwarded to multiple assemblies: 'D1' and 'D2' BC37208: Module 'ForwarderModule.dll' in assembly 'Forwarder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is forwarding the type 'Testspace.TestType' to multiple assemblies: 'D1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'D2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
]]></errors>) ]]></errors>)
End Sub End Sub
<Fact> <Fact>
<WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")> <WorkItem(16484, "https://github.com/dotnet/roslyn/issues/16484")>
Public Sub AddingReferenceToModuleWithMultipleForwardersToTheSameAssemblyShouldNotProduceMultipleForwardingErrors() Public Sub CompilingModuleWithMultipleForwardersToTheSameAssemblyShouldNotProduceMultipleForwardingErrors()
Dim ilSource = " Dim ilSource = "
.assembly extern D1 { } .assembly extern D1 { }
.class extern forwarder Testspace.TestType .class extern forwarder Testspace.TestType
...@@ -24132,12 +24135,7 @@ BC37208: Type 'Testspace.TestType' is forwarded to multiple assemblies: 'D1' and ...@@ -24132,12 +24135,7 @@ BC37208: Type 'Testspace.TestType' is forwarded to multiple assemblies: 'D1' and
.assembly extern D1 .assembly extern D1
}" }"
Dim ilBytes As ImmutableArray(Of Byte) = Nothing Dim ilModule = GetILModuleReference(ilSource, appendDefaultHeader:=False)
Dim pdbBytes As ImmutableArray(Of Byte) = Nothing
EmitILToArray(ilSource, appendDefaultHeader:=False, includePdb:=False, assemblyBytes:=ilBytes, pdbBytes:=pdbBytes)
Dim ilModule = ModuleMetadata.CreateFromImage(ilBytes).GetReference()
Dim compilation = CreateCompilationWithMscorlib(String.Empty, references:={ilModule}, options:=New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) Dim compilation = CreateCompilationWithMscorlib(String.Empty, references:={ilModule}, options:=New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[ CompilationUtils.AssertTheseDiagnostics(compilation, <errors><![CDATA[
......
...@@ -267,6 +267,14 @@ internal static MetadataReference CompileIL(string ilSource, bool appendDefaultH ...@@ -267,6 +267,14 @@ internal static MetadataReference CompileIL(string ilSource, bool appendDefaultH
return AssemblyMetadata.CreateFromImage(assemblyBytes).GetReference(embedInteropTypes: embedInteropTypes); return AssemblyMetadata.CreateFromImage(assemblyBytes).GetReference(embedInteropTypes: embedInteropTypes);
} }
internal static MetadataReference GetILModuleReference(string ilSource, bool appendDefaultHeader = true)
{
ImmutableArray<byte> assemblyBytes;
ImmutableArray<byte> pdbBytes;
EmitILToArray(ilSource, appendDefaultHeader, includePdb: false, assemblyBytes: out assemblyBytes, pdbBytes: out pdbBytes);
return ModuleMetadata.CreateFromImage(assemblyBytes).GetReference();
}
#endregion #endregion
#region Compilation Creation Helpers #region Compilation Creation Helpers
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册