提交 54d96c66 编写于 作者: C Charles Stoner

Merge pull request #2762 from cston/1170032

EE: Ignore duplicate types from cor library

Ignore types from the cor library that also exist in the other framework assemblies.
This issue arises in the EE when compiling expressions against the runtime assemblies loaded in the debuggee for CoreCLR.
......@@ -82,6 +82,11 @@ internal enum BinderFlags : uint
/// </summary>
AllowAwaitInUnsafeContext = 1 << 25,
/// <summary>
/// Ignore duplicate types from the cor library.
/// </summary>
IgnoreCorLibraryDuplicatedTypes = 1 << 26,
// Groups
AllClearedAtExecutableCodeBoundary = InLockBody | InCatchBlock | InCatchFilter | InFinallyBlock | InTryBlockOfTryCatch | InNestedFinallyBlock,
......
......@@ -386,7 +386,7 @@ private void LookupExtensionMethodsInSingleBinder(ExtensionMethodScope scope, Lo
// Rolsyn reproduces Dev10 compiler behavior which doesn't report an error if one of the
// lookups is single viable and other lookup is ambiguous. If one of the lookup results
// (either with or without "Attribute" suffix) is single viable and is an attribute type we
// use it disregarding the second result which may be ambigous.
// use it disregarding the second result which may be ambiguous.
// Note: if both are single and attribute types, we still report ambiguity.
......@@ -437,7 +437,7 @@ private void LookupExtensionMethodsInSingleBinder(ExtensionMethodScope scope, Lo
if (!result.IsClear)
{
if ((object)symbolWithoutSuffix != null) // was not ambigous, but not viable
if ((object)symbolWithoutSuffix != null) // was not ambiguous, but not viable
{
result.SetFrom(GenerateNonViableAttributeTypeResult(symbolWithoutSuffix, result.Error, diagnose));
}
......
......@@ -563,7 +563,7 @@ private void ReportUseSiteDiagnosticForDynamic(DiagnosticBag diagnostics, Identi
}
// Gets the name lookup options for simple generic or non-generic name.
private static LookupOptions GetSimpleNameLookupOptions(NameSyntax node, bool isVerbatimIdentifer)
private static LookupOptions GetSimpleNameLookupOptions(NameSyntax node, bool isVerbatimIdentifier)
{
if (SyntaxFacts.IsAttributeName(node))
{
......@@ -574,7 +574,7 @@ private static LookupOptions GetSimpleNameLookupOptions(NameSyntax node, bool is
// SPEC: such that its right-most identifier is a verbatim identifier (§2.4.2), then only
// SPEC: an attribute without a suffix is matched, thus enabling such an ambiguity to be resolved.
return isVerbatimIdentifer ? LookupOptions.VerbatimNameAttributeTypeOnly : LookupOptions.AttributeTypeOnly;
return isVerbatimIdentifier ? LookupOptions.VerbatimNameAttributeTypeOnly : LookupOptions.AttributeTypeOnly;
}
else
{
......@@ -682,7 +682,7 @@ private Symbol UnwrapAlias(Symbol symbol, out AliasSymbol alias, DiagnosticBag d
SeparatedSyntaxList<TypeSyntax> typeArguments = node.TypeArgumentList.Arguments;
bool isUnboundTypeExpr = node.IsUnboundGenericName;
LookupOptions options = GetSimpleNameLookupOptions(node, isVerbatimIdentifer: false);
LookupOptions options = GetSimpleNameLookupOptions(node, isVerbatimIdentifier: false);
NamedTypeSymbol unconstructedType = LookupGenericTypeName(
diagnostics, basesBeingResolved, qualifierOpt, node, plainName, node.Arity, options);
......@@ -1288,6 +1288,8 @@ public int Compare(Symbol fst, Symbol snd)
}
else
{
Debug.Assert(!best.IsFromCorLibrary);
// ErrorCode.ERR_SameFullNameAggAgg: The type '{1}' exists in both '{0}' and '{2}'
info = new CSDiagnosticInfo(ErrorCode.ERR_SameFullNameAggAgg, originalSymbols,
new object[] { first.ContainingAssembly, first, second.ContainingAssembly });
......@@ -1301,6 +1303,14 @@ public int Compare(Symbol fst, Symbol snd)
Debug.Assert(best.IsFromCompilation);
reportError = false;
}
else if (this.Flags.Includes(BinderFlags.IgnoreCorLibraryDuplicatedTypes) &&
secondBest.IsFromCorLibrary)
{
// Ignore duplicate types from the cor library if necessary.
// (Specifically the framework assemblies loaded at runtime in
// the EE may contain types also available from mscorlib.dll.)
return first;
}
}
}
else if (first.Kind == SymbolKind.Namespace && second.Kind == SymbolKind.NamedType)
......@@ -1559,22 +1569,21 @@ private static AssemblySymbol GetContainingAssembly(Symbol symbol)
return symbol.ContainingAssembly ?? ((NamespaceSymbol)symbol).ConstituentNamespaces.First().ContainingAssembly;
}
private struct BestSymbolInfo
[Flags]
private enum BestSymbolLocation
{
[Flags]
private enum BestSymbolFlags
{
None = 0x00000000,
IndexMask = 0x0FFFFFFF,
LocationMask = 0x70000000,
// The following flags are mutually exclusive.
FromSourceModule = 0x10000000,
FromAddedModule = 0x20000000,
FromReferencedAssembly = 0x40000000,
}
None,
FromSourceModule,
FromAddedModule,
FromReferencedAssembly,
FromCorLibrary,
}
private readonly BestSymbolFlags _flags;
[DebuggerDisplay("Location = {_location}, Index = {_index}")]
private struct BestSymbolInfo
{
private readonly BestSymbolLocation _location;
private readonly int _index;
/// <summary>
/// Returns -1 if None.
......@@ -1583,12 +1592,7 @@ public int Index
{
get
{
if (IsNone)
{
return -1;
}
return (int)(_flags & BestSymbolFlags.IndexMask);
return IsNone ? -1 : _index;
}
}
......@@ -1596,7 +1600,7 @@ public bool IsFromSourceModule
{
get
{
return (_flags & BestSymbolFlags.FromSourceModule) != 0;
return _location == BestSymbolLocation.FromSourceModule;
}
}
......@@ -1604,7 +1608,7 @@ public bool IsFromAddedModule
{
get
{
return (_flags & BestSymbolFlags.FromAddedModule) != 0;
return _location == BestSymbolLocation.FromAddedModule;
}
}
......@@ -1612,7 +1616,7 @@ public bool IsFromCompilation
{
get
{
return (_flags & (BestSymbolFlags.FromSourceModule | BestSymbolFlags.FromAddedModule)) != 0;
return (_location == BestSymbolLocation.FromSourceModule) || (_location == BestSymbolLocation.FromAddedModule);
}
}
......@@ -1620,39 +1624,23 @@ public bool IsNone
{
get
{
return (_flags & BestSymbolFlags.LocationMask) == 0;
return _location == BestSymbolLocation.None;
}
}
public bool IsFromReferencedAssembly
public bool IsFromCorLibrary
{
get
{
return (_flags & BestSymbolFlags.FromReferencedAssembly) != 0;
return _location == BestSymbolLocation.FromCorLibrary;
}
}
private BestSymbolInfo(BestSymbolFlags flags)
public BestSymbolInfo(BestSymbolLocation location, int index)
{
_flags = flags;
}
public static BestSymbolInfo FromSourceModule(int index)
{
Debug.Assert((index & (int)(~BestSymbolFlags.IndexMask)) == 0);
return new BestSymbolInfo(BestSymbolFlags.FromSourceModule | (BestSymbolFlags)index);
}
public static BestSymbolInfo FromAddedModule(int index)
{
Debug.Assert((index & (int)(~BestSymbolFlags.IndexMask)) == 0);
return new BestSymbolInfo(BestSymbolFlags.FromAddedModule | (BestSymbolFlags)index);
}
public static BestSymbolInfo FromReferencedAssembly(int index)
{
Debug.Assert((index & (int)(~BestSymbolFlags.IndexMask)) == 0);
return new BestSymbolInfo(BestSymbolFlags.FromReferencedAssembly | (BestSymbolFlags)index);
Debug.Assert(location != BestSymbolLocation.None);
_location = location;
_index = index;
}
/// <summary>
......@@ -1661,8 +1649,7 @@ public static BestSymbolInfo FromReferencedAssembly(int index)
/// </summary>
public static bool Sort(ref BestSymbolInfo first, ref BestSymbolInfo second)
{
if (!second.IsNone &&
(first.IsNone || (first._flags & BestSymbolFlags.LocationMask) > (second._flags & BestSymbolFlags.LocationMask)))
if (IsSecondLocationBetter(first._location, second._location))
{
BestSymbolInfo temp = first;
first = second;
......@@ -1672,6 +1659,15 @@ public static bool Sort(ref BestSymbolInfo first, ref BestSymbolInfo second)
return false;
}
/// <summary>
/// Returns true if the second is a better location than the first.
/// </summary>
public static bool IsSecondLocationBetter(BestSymbolLocation firstLocation, BestSymbolLocation secondLocation)
{
Debug.Assert(secondLocation != 0);
return (firstLocation == BestSymbolLocation.None) || (firstLocation > secondLocation);
}
}
/// <summary>
......@@ -1679,70 +1675,67 @@ public static bool Sort(ref BestSymbolInfo first, ref BestSymbolInfo second)
/// </summary>
private BestSymbolInfo GetBestSymbolInfo(ArrayBuilder<Symbol> symbols, out BestSymbolInfo secondBest)
{
var assemblyBeingBuilt = this.Compilation.SourceAssembly;
var moduleBuilt = this.Compilation.SourceModule;
BestSymbolInfo first = default(BestSymbolInfo);
BestSymbolInfo second = default(BestSymbolInfo);
var compilation = this.Compilation;
for (int i = 0; i < symbols.Count; i++)
{
var symbol = symbols[i];
BestSymbolInfo third;
BestSymbolLocation location;
if (symbol.Kind == SymbolKind.Namespace)
{
var ns = ((NamespaceSymbol)symbol).ConstituentNamespaces;
third = default(BestSymbolInfo);
for (int j = 0; j < ns.Length; j++)
location = BestSymbolLocation.None;
foreach (var ns in ((NamespaceSymbol)symbol).ConstituentNamespaces)
{
if (ns[j].ContainingAssembly == assemblyBeingBuilt)
var current = GetLocation(compilation, ns);
if (BestSymbolInfo.IsSecondLocationBetter(location, current))
{
if (ns[j].ContainingModule == moduleBuilt)
location = current;
if (location == BestSymbolLocation.FromSourceModule)
{
third = BestSymbolInfo.FromSourceModule(i);
break;
}
else if (!third.IsFromAddedModule)
{
Debug.Assert(!third.IsFromCompilation);
third = BestSymbolInfo.FromAddedModule(i);
}
}
else if (third.IsNone)
{
third = BestSymbolInfo.FromReferencedAssembly(i);
}
}
}
else if (symbol.ContainingAssembly == assemblyBeingBuilt)
{
if (symbol.ContainingModule == moduleBuilt)
{
third = BestSymbolInfo.FromSourceModule(i);
}
else
{
third = BestSymbolInfo.FromAddedModule(i);
}
}
else
{
third = BestSymbolInfo.FromReferencedAssembly(i);
location = GetLocation(compilation, symbol);
}
var third = new BestSymbolInfo(location, i);
if (BestSymbolInfo.Sort(ref second, ref third))
{
BestSymbolInfo.Sort(ref first, ref second);
}
}
Debug.Assert(!first.IsNone);
Debug.Assert(!second.IsNone);
secondBest = second;
return first;
}
private static BestSymbolLocation GetLocation(CSharpCompilation compilation, Symbol symbol)
{
var containingAssembly = symbol.ContainingAssembly;
if (containingAssembly == compilation.SourceAssembly)
{
return (symbol.ContainingModule == compilation.SourceModule) ?
BestSymbolLocation.FromSourceModule :
BestSymbolLocation.FromAddedModule;
}
else
{
return (containingAssembly == containingAssembly.CorLibrary) ?
BestSymbolLocation.FromCorLibrary :
BestSymbolLocation.FromReferencedAssembly;
}
}
/// <remarks>
/// This is only intended to be called when the type isn't found (i.e. not when it is found but is inaccessible, has the wrong arity, etc).
/// </remarks>
......
......@@ -426,7 +426,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim currentResult As SingleLookupResult = binder.CheckViability(sym, arity, options, Nothing, useSiteDiagnostics)
lookupResult.MergeMembersOfTheSameNamespace(currentResult, sourceModule)
lookupResult.MergeMembersOfTheSameNamespace(currentResult, sourceModule, options)
Next
End Sub
......
......@@ -137,6 +137,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' When performing a lookup in interface do NOT lookup in System.Object
''' </summary>
NoSystemObjectLookupForInterfaces = 1 << 16
''' <summary>
''' Ignore duplicate types from the cor library.
''' </summary>
IgnoreCorLibraryDuplicatedTypes = 1 << 17
End Enum
Friend Module LookupOptionExtensions
......
......@@ -3,10 +3,7 @@
Imports System.Collections.Generic
Imports System.Collections.Immutable
Imports System.Runtime.CompilerServices
Imports System.Threading
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic
......@@ -830,9 +827,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
End Function
Public Sub MergeMembersOfTheSameNamespace(other As SingleLookupResult, sourceModule As ModuleSymbol)
Public Sub MergeMembersOfTheSameNamespace(other As SingleLookupResult, sourceModule As ModuleSymbol, options As LookupOptions)
Dim resolution As Integer = ResolveAmbiguityInTheSameNamespace(other, sourceModule)
Dim resolution As Integer = ResolveAmbiguityInTheSameNamespace(other, sourceModule, options)
If resolution > 0 Then
Return
......@@ -844,39 +841,53 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
MergeAmbiguous(other, s_ambiguousInNSError)
End Sub
Private Shared Function IsSymbolDeclaredInSourceModule(sym As Symbol, [module] As ModuleSymbol) As Boolean
Private Enum SymbolLocation
FromSourceModule
FromReferencedAssembly
FromCorLibrary
End Enum
Private Shared Function GetSymbolLocation(sym As Symbol, sourceModule As ModuleSymbol, options As LookupOptions) As SymbolLocation
' Dev10 pays attention to the fact that the [sym] refers to a namespace
' and the namespace has a declaration in source. This needs some special handling for merged namespaces.
If sym.Kind = SymbolKind.Namespace Then
Return DirectCast(sym, NamespaceSymbol).IsDeclaredInSourceModule([module])
Return If(DirectCast(sym, NamespaceSymbol).IsDeclaredInSourceModule(sourceModule),
SymbolLocation.FromSourceModule,
SymbolLocation.FromReferencedAssembly)
End If
If sym.ContainingModule Is sourceModule Then
Return SymbolLocation.FromSourceModule
End If
Return sym.ContainingModule Is [module]
If (options And LookupOptions.IgnoreCorLibraryDuplicatedTypes) <> 0 Then
' Ignore duplicate types from the cor library if necessary.
' (Specifically the framework assemblies loaded at runtime in
' the EE may contain types also available from mscorlib.dll.)
Dim containingAssembly = sym.ContainingAssembly
If containingAssembly Is containingAssembly.CorLibrary Then
Return SymbolLocation.FromCorLibrary
End If
End If
Return SymbolLocation.FromReferencedAssembly
End Function
''' <summary>
''' Returns: negative value - when current lost, 0 - when neither lost, > 0 - when other lost.
''' </summary>
Private Function ResolveAmbiguityInTheSameNamespace(other As SingleLookupResult, sourceModule As ModuleSymbol) As Integer
Private Function ResolveAmbiguityInTheSameNamespace(other As SingleLookupResult, sourceModule As ModuleSymbol, options As LookupOptions) As Integer
Debug.Assert(Not other.IsAmbiguous)
' Symbols in source take priority over symbols in a referenced assembly.
If other.StopFurtherLookup AndAlso
Me.StopFurtherLookup AndAlso Me.Symbols.Count > 0 Then
Dim currentFromSource = IsSymbolDeclaredInSourceModule(other.Symbol, sourceModule)
Dim contenderFromSource = IsSymbolDeclaredInSourceModule(Me.Symbols(0), sourceModule)
If currentFromSource Then
If Not contenderFromSource Then
' other is better
Return -1
End If
ElseIf contenderFromSource Then
' contender is better
Return 1
Dim currentLocation = GetSymbolLocation(other.Symbol, sourceModule, options)
Dim contenderLocation = GetSymbolLocation(Me.Symbols(0), sourceModule, options)
Dim diff = currentLocation - contenderLocation
If diff <> 0 Then
Return diff
End If
End If
......
......@@ -1014,7 +1014,7 @@ BC32042: Too few type arguments to 'C2.cC3(Of U, V)'.
End Sub
<Fact>
Public Sub InacessibleNonGenericType_01()
Public Sub InaccessibleNonGenericType_01()
Dim compilationDef =
<compilation>
<file name="a.vb">
......
......@@ -638,7 +638,8 @@ private static BoundStatement BindAssignment(Binder binder, ExpressionSyntax syn
BinderFlags.UnsafeRegion |
BinderFlags.UncheckedRegion |
BinderFlags.AllowManagedAddressOf |
BinderFlags.AllowAwaitInUnsafeContext);
BinderFlags.AllowAwaitInUnsafeContext |
BinderFlags.IgnoreCorLibraryDuplicatedTypes);
var hasImports = !importRecordGroups.IsDefaultOrEmpty;
var numImportStringGroups = hasImports ? importRecordGroups.Length : 0;
var currentStringGroup = numImportStringGroups - 1;
......
......@@ -558,6 +558,104 @@ .maxstack 1
}
}
[WorkItem(1170032)]
[Fact]
public void DuplicateTypesInMscorlib()
{
var sourceConsole =
@"namespace System
{
public class Console
{
}
}";
var sourceObjectModel =
@"namespace System.Collections.ObjectModel
{
public class ReadOnlyDictionary<K, V>
{
}
}";
var source =
@"class C
{
static void Main()
{
var t = typeof(System.Console);
var o = (System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null;
}
}";
var systemConsoleComp = CreateCompilationWithMscorlib(sourceConsole, options: TestOptions.DebugDll, assemblyName: "System.Console");
var systemConsoleRef = systemConsoleComp.EmitToImageReference();
var systemObjectModelComp = CreateCompilationWithMscorlib(sourceObjectModel, options: TestOptions.DebugDll, assemblyName: "System.ObjectModel");
var systemObjectModelRef = systemObjectModelComp.EmitToImageReference();
var identityObjectModel = systemObjectModelRef.GetAssemblyIdentity();
// At runtime System.Runtime.dll contract assembly is replaced
// by mscorlib.dll and System.Runtime.dll facade assemblies;
// System.Console.dll and System.ObjectModel.dll are not replaced.
// Test different ordering of modules containing duplicates:
// { System.Console, mscorlib } and { mscorlib, System.ObjectModel }.
var contractReferences = ImmutableArray.Create(systemConsoleRef, SystemRuntimePP7Ref, systemObjectModelRef);
var runtimeReferences = ImmutableArray.Create(systemConsoleRef, MscorlibFacadeRef, SystemRuntimeFacadeRef, systemObjectModelRef);
// Verify the compiler reports duplicate types with facade assemblies.
var compilation = CreateCompilation(
source,
references: runtimeReferences,
options: TestOptions.DebugDll,
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
compilation.VerifyDiagnostics(
// (5,31): error CS0433: The type 'Console' exists in both 'System.Console, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
// var t = typeof(System.Console);
Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "Console").WithArguments("System.Console, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Console", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(5, 31),
// (6,49): error CS0433: The type 'ReadOnlyDictionary<K, V>' exists in both 'System.ObjectModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
// var o = (System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null;
Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "ReadOnlyDictionary<object, object>").WithArguments("System.ObjectModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Collections.ObjectModel.ReadOnlyDictionary<K, V>", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(6, 49));
// EE should not report duplicate type when the original source
// is compiled with contract assemblies and the EE expression
// is compiled with facade assemblies.
compilation = CreateCompilation(
source,
references: contractReferences,
options: TestOptions.DebugDll,
assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
var reference = compilation.EmitToImageReference();
var modules = runtimeReferences.Add(reference).SelectAsArray(r => r.ToModuleInstance(null, null));
using (var runtime = new RuntimeInstance(modules))
{
var context = CreateMethodContext(runtime, "C.Main");
string errorMessage;
// { System.Console, mscorlib }
var testData = new CompilationTestData();
context.CompileExpression("typeof(System.Console)", out errorMessage, testData);
var methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldtoken ""System.Console""
IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
IL_000a: ret
}");
// { mscorlib, System.ObjectModel }
testData = new CompilationTestData();
context.CompileExpression("(System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null", out errorMessage, testData);
methodData = testData.GetMethodData("<>x.<>m0");
methodData.VerifyIL(
@"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldnull
IL_0001: ret
}");
Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityObjectModel.GetDisplayName());
}
}
private static ExpressionCompiler.CreateContextDelegate CreateTypeContextFactory(
Guid moduleVersionId,
int typeToken)
......
......@@ -531,7 +531,7 @@ internal static ModuleMetadata GetModuleMetadata(this MetadataReference referenc
fullImage,
metadataBytes,
symReader,
includeLocalSignatures);
includeLocalSignatures && (fullImage != null));
}
internal static AssemblyIdentity GetAssemblyIdentity(this MetadataReference reference)
......
......@@ -67,7 +67,7 @@
<ItemGroup>
<Compile Include="Binders\EENamedTypeBinder.vb" />
<Compile Include="Binders\ParametersAndLocalsBinder.vb" />
<Compile Include="Binders\SuppressObsoleteDiagnosticsBinder.vb" />
<Compile Include="Binders\SuppressDiagnosticsBinder.vb" />
<Compile Include="CompilationContext.vb" />
<Compile Include="CompilationExtensions.vb" />
<Compile Include="VisualBasicInScopeHoistedLocalsByName.vb" />
......
......@@ -8,7 +8,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
''' and <see cref="T:Windows.Foundation.MetadataDeprecatedAttribute"/>
''' to be suppressed.
''' </summary>
Friend NotInheritable Class SuppressObsoleteDiagnosticsBinder
Friend NotInheritable Class SuppressDiagnosticsBinder
#Enable Warning RS0010
Inherits Binder
......@@ -21,6 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Return True
End Get
End Property
Friend Overrides Function BinderSpecificLookupOptions(options As LookupOptions) As LookupOptions
Return options Or LookupOptions.IgnoreCorLibraryDuplicatedTypes
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -531,7 +531,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
importRecordGroups As ImmutableArray(Of ImmutableArray(Of ImportRecord))) As Binder
Dim binder = BackstopBinder
binder = New SuppressObsoleteDiagnosticsBinder(binder)
binder = New SuppressDiagnosticsBinder(binder)
binder = New IgnoreAccessibilityBinder(binder)
binder = New SourceModuleBinder(binder, DirectCast(compilation.Assembly.Modules(0), SourceModuleSymbol))
......
......@@ -386,6 +386,84 @@ End Class"
End Using
End Sub
<WorkItem(1170032)>
<Fact>
Public Sub DuplicateTypesInMscorlib()
Const sourceConsole =
"Namespace System
Public Class Console
End Class
End Namespace"
Const sourceObjectModel =
"Namespace System.Collections.ObjectModel
Public Class ReadOnlyDictionary(Of K, V)
End Class
End Namespace"
Const source =
"Class C
Shared Sub Main()
Dim t = GetType(System.Console)
Dim o = DirectCast(Nothing, System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object))
End Sub
End Class"
Dim systemConsoleComp = CreateCompilationWithMscorlib({sourceConsole}, options:=TestOptions.DebugDll, assemblyName:="System.Console")
Dim systemConsoleRef = systemConsoleComp.EmitToImageReference()
Dim systemObjectModelComp = CreateCompilationWithMscorlib({sourceObjectModel}, options:=TestOptions.DebugDll, assemblyName:="System.ObjectModel")
Dim systemObjectModelRef = systemObjectModelComp.EmitToImageReference()
Dim identityObjectModel = systemObjectModelRef.GetAssemblyIdentity()
' At runtime System.Runtime.dll contract assembly is replaced
' by mscorlib.dll and System.Runtime.dll facade assemblies;
' System.Console.dll and System.ObjectModel.dll are not replaced.
' Test different ordering of modules containing duplicates:
' { System.Console, mscorlib } and { mscorlib, System.ObjectModel }.
Dim contractReferences = ImmutableArray.Create(systemConsoleRef, SystemRuntimePP7Ref, systemObjectModelRef)
Dim runtimeReferences = ImmutableArray.Create(systemConsoleRef, MscorlibFacadeRef, SystemRuntimeFacadeRef, systemObjectModelRef)
' Verify the compiler reports duplicate types with facade assemblies.
Dim compilation = CreateCompilationWithReferences(MakeSources(source), references:=runtimeReferences, options:=TestOptions.DebugDll)
compilation.VerifyDiagnostics(
Diagnostic(ERRID.ERR_AmbiguousInNamespace2, "System.Console").WithArguments("Console", "System").WithLocation(3, 25),
Diagnostic(ERRID.ERR_AmbiguousInNamespace2, "System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object)").WithArguments("ReadOnlyDictionary", "System.Collections.ObjectModel").WithLocation(4, 37))
' EE should not report duplicate type when the original source
' is compiled with contract assemblies and the EE expression
' is compiled with facade assemblies.
compilation = CreateCompilationWithReferences(MakeSources(source), references:=contractReferences, options:=TestOptions.DebugDll)
Dim reference = compilation.EmitToImageReference()
Dim modules = runtimeReferences.Add(reference).SelectAsArray(Function(r) r.ToModuleInstance(Nothing, Nothing))
Using runtime = CreateRuntimeInstance(modules)
Dim context = CreateMethodContext(runtime, "C.Main")
Dim errorMessage As String = Nothing
' { System.Console, mscorlib }
Dim testData = New CompilationTestData()
context.CompileExpression("GetType(System.Console)", errorMessage, testData)
Dim methodData = testData.GetMethodData("<>x.<>m0")
methodData.VerifyIL(
"{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldtoken ""System.Console""
IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type""
IL_000a: ret
}")
' { mscorlib, System.ObjectModel }
testData = New CompilationTestData()
context.CompileExpression("DirectCast(Nothing, System.Collections.ObjectModel.ReadOnlyDictionary(Of Object, Object))", errorMessage, testData)
methodData = testData.GetMethodData("<>x.<>m0")
methodData.VerifyIL(
"{
// Code size 2 (0x2)
.maxstack 1
IL_0000: ldnull
IL_0001: ret
}")
Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityObjectModel.GetDisplayName())
End Using
End Sub
Private Shared Function CreateTypeContextFactory(
moduleVersionId As Guid,
typeToken As Integer) As ExpressionCompiler.CreateContextDelegate
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册