提交 9bfdb948 编写于 作者: C Charles Stoner

Ensure mscorlib is included when ignoring unreferenced assemblies

上级 cc6fa894
......@@ -157,5 +157,34 @@ internal static Guid GetModuleVersionIdOrThrow(this MetadataReader reader)
contentType: (AssemblyContentType)((int)(flags & AssemblyFlags.ContentTypeMask) >> 9),
noThrow: true);
}
internal static bool DeclaresTheObjectClass(this MetadataReader reader)
{
foreach (TypeDefinitionHandle handle in reader.TypeDefinitions)
{
try
{
var typeDef = reader.GetTypeDefinition(handle);
if (typeDef.BaseType.IsNil &&
(typeDef.Attributes & (TypeAttributes.Public | TypeAttributes.Interface)) == TypeAttributes.Public &&
reader.IsSystemObjectOrThrow(typeDef))
{
return true;
}
}
catch (BadImageFormatException)
{
}
}
return false;
}
/// <exception cref="BadImageFormatException">An exception from metadata reader.</exception>
private static bool IsSystemObjectOrThrow(this MetadataReader reader, TypeDefinition typeDef)
{
return reader.StringComparer.Equals(typeDef.Name, "Object") &&
reader.StringComparer.Equals(typeDef.Namespace, "System");
}
}
}
......@@ -167,13 +167,8 @@ internal bool DeclaresTheObjectClass
{
if (_lazyDeclaresTheObjectClass == ThreeState.Unknown)
{
if (!_modules[0].FindSystemObjectTypeDef().IsNil)
{
_lazyDeclaresTheObjectClass = ThreeState.True;
return true;
}
_lazyDeclaresTheObjectClass = ThreeState.False;
var value = _modules[0].MetadataReader.DeclaresTheObjectClass();
_lazyDeclaresTheObjectClass = value.ToThreeState();
}
return _lazyDeclaresTheObjectClass == ThreeState.True;
......
......@@ -500,37 +500,6 @@ public bool HasGenericParametersOrThrow(TypeDefinitionHandle typeDef)
extends = row.BaseType;
}
internal TypeDefinitionHandle FindSystemObjectTypeDef()
{
MetadataReader reader = MetadataReader;
foreach (TypeDefinitionHandle handle in reader.TypeDefinitions)
{
try
{
var typeDef = reader.GetTypeDefinition(handle);
if (typeDef.BaseType.IsNil &&
(typeDef.Attributes & (TypeAttributes.Public | TypeAttributes.Interface)) == TypeAttributes.Public &&
IsSystemObjectOrThrow(typeDef))
{
return handle;
}
}
catch (BadImageFormatException)
{ }
}
return default(TypeDefinitionHandle);
}
/// <exception cref="BadImageFormatException">An exception from metadata reader.</exception>
private bool IsSystemObjectOrThrow(TypeDefinition typeDef)
{
return MetadataReader.StringComparer.Equals(typeDef.Name, "Object") &&
MetadataReader.StringComparer.Equals(typeDef.Namespace, "System");
}
/// <exception cref="BadImageFormatException">An exception from metadata reader.</exception>
internal bool IsNestedTypeDefOrThrow(TypeDefinitionHandle typeDef)
{
......
......@@ -13,6 +13,7 @@
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities;
using Xunit;
using Resources = Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests.Resources;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
......@@ -463,7 +464,7 @@ .maxstack 1
/// compiled against portable framework assemblies.
/// </summary>
[WorkItem(1150981)]
[Fact(Skip = "1150981")]
[Fact]
public void MissingMscorlib()
{
var sourceA =
......@@ -507,6 +508,10 @@ class C
var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
var moduleB = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB));
// Include an empty assembly to verify that not all assemblies
// with no references are treated as mscorlib.
var referenceC = AssemblyMetadata.CreateFromImage(Resources.Empty).GetReference();
// At runtime System.Runtime.dll contract assembly is replaced
// by mscorlib.dll and System.Runtime.dll facade assemblies.
var moduleBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
......@@ -514,6 +519,7 @@ class C
moduleBuilder.Add(SystemRuntimeFacadeRef.ToModuleInstance(null, null));
moduleBuilder.Add(moduleA);
moduleBuilder.Add(moduleB);
moduleBuilder.Add(referenceC.ToModuleInstance(null, null));
var modules = moduleBuilder.ToImmutableAndFree();
using (var runtime = new RuntimeInstance(modules))
......
......@@ -6,15 +6,15 @@
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.Metadata;
using Xunit;
using Resources = Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests.Resources;
using Roslyn.Test.PdbUtilities;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
......
......@@ -86,6 +86,7 @@ internal static class MetadataUtilities
// Build assembly references from modules in primary module manifests.
var referencesBuilder = ArrayBuilder<MetadataReference>.GetInstance();
var identitiesBuilder = (identityComparer == null) ? null : ArrayBuilder<AssemblyIdentity>.GetInstance();
AssemblyIdentity corLibrary = null;
foreach (var metadata in metadataBuilder)
{
......@@ -95,8 +96,17 @@ internal static class MetadataUtilities
}
if (identitiesBuilder != null)
{
var identity = metadata.MetadataReader.ReadAssemblyIdentityOrThrow();
var reader = metadata.MetadataReader;
var identity = reader.ReadAssemblyIdentityOrThrow();
identitiesBuilder.Add(identity);
// If this assembly has no references, and declares
// System.Object, assume it is the COR library.
if ((corLibrary == null) &&
(reader.AssemblyReferences.Count == 0) &&
reader.DeclaresTheObjectClass())
{
corLibrary = identity;
}
}
var reference = MakeAssemblyMetadata(metadata, modulesByName);
referencesBuilder.Add(reference);
......@@ -112,6 +122,15 @@ internal static class MetadataUtilities
var referencedModules = ArrayBuilder<AssemblyIdentity>.GetInstance();
referencedModules.Add(module.MetadataReader.ReadAssemblyIdentityOrThrow());
referencedModules.AddRange(module.MetadataReader.GetReferencedAssembliesOrThrow());
// Ensure COR library is included, otherwise any compilation will fail.
// (Note, an equivalent assembly may have already been included from
// GetReferencedAssembliesOrThrow above but RemoveUnreferencedModules
// allows duplicates.)
Debug.Assert(corLibrary != null);
if (corLibrary != null)
{
referencedModules.Add(corLibrary);
}
RemoveUnreferencedModules(referencesBuilder, identitiesBuilder, identityComparer, referencedModules);
referencedModules.Free();
}
......
......@@ -77,6 +77,7 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Resources\Empty.dll" />
<None Include="Resources\LibraryA.winmd" />
<None Include="Resources\LibraryB.winmd" />
<None Include="Resources\NoValidTables.metadata" />
......
......@@ -60,6 +60,16 @@ internal class Resources {
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] Empty {
get {
object obj = ResourceManager.GetObject("Empty", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
......
......@@ -119,6 +119,14 @@
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--
copy NUL Empty.txt
resgen.exe Empty.txt
al.exe /embed:Empty.resources /t:lib /out:Empty.dll
-->
<data name="Empty" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Empty.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<!--
echo namespace Windows.Data.Text { public sealed class TextSegment { } } > Windows.Data.cs
csc /t:winmdobj Windows.Data.cs
winmdexp.exe /r:"%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\mscorlib.dll" /r:"%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.dll" /r:"%ProgramFiles(x86)%\Microsoft SDKs\Portable\v14.0\110C4FEFF2BA61C0746933A9ED6E248D\Windows.winmd" /out:Windows.Data.winmd Windows.Data.winmdobj
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册