提交 7f112950 编写于 作者: T Tomáš Matoušek

Merge pull request #8040 from tmat/TypeDups

Enable specifying top-level binder options via an internal compilation option
......@@ -21,6 +21,16 @@ internal partial class Binder
internal readonly BinderFlags Flags;
/// <summary>
/// Used to create a root binder.
/// </summary>
internal Binder(CSharpCompilation compilation)
{
Debug.Assert(compilation != null);
this.Flags = compilation.Options.TopLevelBinderFlags;
this.Compilation = compilation;
}
internal Binder(Binder next)
{
Debug.Assert(next != null);
......@@ -29,13 +39,6 @@ internal Binder(Binder next)
this.Compilation = next.Compilation;
}
internal Binder(CSharpCompilation compilation)
{
Debug.Assert(compilation != null);
this.Flags = BinderFlags.None;
this.Compilation = compilation;
}
protected Binder(Binder next, BinderFlags flags)
{
Debug.Assert(next != null);
......
......@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
using System.Diagnostics;
using System.ComponentModel;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -27,6 +28,12 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
/// </summary>
public ImmutableArray<string> Usings { get; private set; }
/// <summary>
/// Flags applied to the top-level binder created for each syntax tree in the compilation
/// as well as for the binder of global imports.
/// </summary>
internal BinderFlags TopLevelBinderFlags { get; private set; }
// Defaults correspond to the compiler's defaults or indicate that the user did not specify when that is significant.
// That's significant when one option depends on another's setting. SubsystemVersion depends on Platform and Target.
public CSharpCompilationOptions(
......@@ -68,7 +75,8 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
assemblyIdentityComparer: assemblyIdentityComparer,
strongNameProvider: strongNameProvider,
metadataImportOptions: MetadataImportOptions.Public,
publicSign: publicSign)
publicSign: publicSign,
topLevelBinderFlags: BinderFlags.None)
{
}
......@@ -101,7 +109,8 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
AssemblyIdentityComparer assemblyIdentityComparer,
StrongNameProvider strongNameProvider,
MetadataImportOptions metadataImportOptions,
bool publicSign)
bool publicSign,
BinderFlags topLevelBinderFlags)
: base(outputKind, reportSuppressedDiagnostics, moduleName, mainTypeName, scriptClassName,
cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign, publicSign, optimizationLevel, checkOverflow,
platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions.ToImmutableDictionaryOrEmpty(),
......@@ -111,6 +120,7 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
{
this.Usings = usings.AsImmutableOrEmpty();
this.AllowUnsafe = allowUnsafe;
this.TopLevelBinderFlags = topLevelBinderFlags;
}
private CSharpCompilationOptions(CSharpCompilationOptions other) : this(
......@@ -141,10 +151,16 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
strongNameProvider: other.StrongNameProvider,
metadataImportOptions: other.MetadataImportOptions,
reportSuppressedDiagnostics: other.ReportSuppressedDiagnostics,
publicSign: other.PublicSign)
publicSign: other.PublicSign,
topLevelBinderFlags: other.TopLevelBinderFlags)
{
}
internal CSharpCompilationOptions WithTopLevelBinderFlags(BinderFlags flags)
{
return (flags == TopLevelBinderFlags) ? this : new CSharpCompilationOptions(this) { TopLevelBinderFlags = flags };
}
internal override ImmutableArray<string> GetImports() => Usings;
public new CSharpCompilationOptions WithOutputKind(OutputKind kind)
......@@ -585,6 +601,7 @@ public bool Equals(CSharpCompilationOptions other)
}
return this.AllowUnsafe == other.AllowUnsafe &&
this.TopLevelBinderFlags == other.TopLevelBinderFlags &&
(this.Usings == null ? other.Usings == null : this.Usings.SequenceEqual(other.Usings, StringComparer.Ordinal));
}
......@@ -597,7 +614,8 @@ public override int GetHashCode()
{
return Hash.Combine(base.GetHashCodeHelper(),
Hash.Combine(this.AllowUnsafe,
Hash.Combine(Hash.CombineValues(this.Usings, StringComparer.Ordinal), 0)));
Hash.Combine(Hash.CombineValues(this.Usings, StringComparer.Ordinal),
Hash.Combine(TopLevelBinderFlags.GetHashCode(), 0))));
}
internal override Diagnostic FilterDiagnostic(Diagnostic diagnostic)
......@@ -606,6 +624,7 @@ internal override Diagnostic FilterDiagnostic(Diagnostic diagnostic)
}
// 1.1 BACKCOMPAT OVERLOAD -- DO NOT TOUCH
[EditorBrowsable(EditorBrowsableState.Never)]
public CSharpCompilationOptions(
OutputKind outputKind,
string moduleName,
......@@ -645,6 +664,7 @@ internal override Diagnostic FilterDiagnostic(Diagnostic diagnostic)
// 1.0 BACKCOMPAT OVERLOAD -- DO NOT TOUCH
[EditorBrowsable(EditorBrowsableState.Never)]
public CSharpCompilationOptions(
OutputKind outputKind,
string moduleName,
......@@ -685,6 +705,7 @@ internal override Diagnostic FilterDiagnostic(Diagnostic diagnostic)
// Bad constructor -- DO NOT USE
// Violates the rules for optional parameter overloads detailed at
// https://github.com/dotnet/roslyn/blob/e8fdb391703dcb5712ff6a5b83d768d784cba4cf/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md
[EditorBrowsable(EditorBrowsableState.Never)]
public CSharpCompilationOptions(
OutputKind outputKind,
bool reportSuppressedDiagnostics,
......@@ -723,7 +744,8 @@ internal override Diagnostic FilterDiagnostic(Diagnostic diagnostic)
assemblyIdentityComparer: assemblyIdentityComparer,
strongNameProvider: strongNameProvider,
metadataImportOptions: MetadataImportOptions.Public,
publicSign: false)
publicSign: false,
topLevelBinderFlags: BinderFlags.None)
{
}
}
......
......@@ -86,6 +86,9 @@ public void Invariants()
TestProperty((old, value) => old.WithMetadataReferenceResolver(value), opt => opt.MetadataReferenceResolver, new TestMetadataReferenceResolver());
TestProperty((old, value) => old.WithAssemblyIdentityComparer(value), opt => opt.AssemblyIdentityComparer, new DesktopAssemblyIdentityComparer(new AssemblyPortabilityPolicy()));
TestProperty((old, value) => old.WithStrongNameProvider(value), opt => opt.StrongNameProvider, new DesktopStrongNameProvider());
TestProperty((old, value) => old.WithTopLevelBinderFlags(value), opt => opt.TopLevelBinderFlags, BinderFlags.IgnoreCorLibraryDuplicatedTypes);
TestProperty((old, value) => old.WithMetadataImportOptions(value), opt => opt.MetadataImportOptions, MetadataImportOptions.Internal);
}
[Fact]
......@@ -319,7 +322,8 @@ public void TestFieldsForEqualsAndGetHashCode()
ReflectionAssert.AssertPublicAndInternalFieldsAndProperties(
typeof(CSharpCompilationOptions),
"AllowUnsafe",
"Usings");
"Usings",
"TopLevelBinderFlags");
}
[Fact]
......@@ -356,12 +360,14 @@ private static CSharpCompilationOptions CreateCSharpCompilationOptions()
StrongNameProvider strongNameProvider = new DesktopStrongNameProvider();
MetadataImportOptions metadataImportOptions = 0;
bool reportSuppressedDiagnostics = false;
var topLevelBinderFlags = BinderFlags.None;
var publicSign = false;
return new CSharpCompilationOptions(OutputKind.ConsoleApplication, reportSuppressedDiagnostics, moduleName, mainTypeName, scriptClassName, usings,
optimizationLevel, checkOverflow, allowUnsafe, cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign,
platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions,
concurrentBuild, deterministic, extendedCustomDebugInformation, debugPlusMode, xmlReferenceResolver, sourceReferenceResolver, metadataReferenceResolver,
assemblyIdentityComparer, strongNameProvider, metadataImportOptions,
publicSign: false);
assemblyIdentityComparer, strongNameProvider, metadataImportOptions, publicSign, topLevelBinderFlags);
}
private sealed class MetadataReferenceResolverWithEquality : MetadataReferenceResolver
......
......@@ -777,6 +777,53 @@ static void Main()
Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "N.C").WithArguments("A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "N.C", "B, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));
}
[WorkItem(320, "https://github.com/dotnet/cli/issues/320")]
[Fact]
public void DuplicateCoreFxPublicTypes()
{
var sysConsoleSrc = @"
[assembly: System.Reflection.AssemblyVersion(""4.0.0.0"")]
namespace System
{
public static class Console
{
public static void Foo() {}
}
}
";
var sysConsoleRef = CreateCompilation(
sysConsoleSrc,
new[] { SystemRuntimePP7Ref },
TestOptions.ReleaseDll.WithCryptoPublicKey(TestResources.TestKeys.PublicKey_b03f5f7f11d50a3a),
assemblyName: "System.Console").EmitToImageReference();
var mainSrc = @"
System.Console.Foo();
Foo();
";
var main1 = CreateCompilation(
new[] { Parse(mainSrc, options: TestOptions.Script) },
new[] { MscorlibRef_v46, sysConsoleRef },
TestOptions.ReleaseDll.WithUsings("System.Console"));
main1.VerifyDiagnostics(
// error CS0433: The type 'Console' exists in both 'System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Diagnostic(ErrorCode.ERR_SameFullNameAggAgg).WithArguments("System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Console", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"),
// (1,9): error CS0433: The type 'Console' exists in both 'System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "System.Console").WithArguments("System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Console", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"),
// (2,9): error CS0103: The name 'Foo' does not exist in the current context
Diagnostic(ErrorCode.ERR_NameNotInContext, "Foo").WithArguments("Foo"));
var main2 = CreateCompilation(
new[] { Parse(mainSrc, options: TestOptions.Script) },
new[] { MscorlibRef_v46, sysConsoleRef, SystemRuntimeFacadeRef },
TestOptions.ReleaseDll.WithUsings("System.Console").WithTopLevelBinderFlags(BinderFlags.IgnoreCorLibraryDuplicatedTypes));
main2.VerifyDiagnostics();
}
[Fact]
public void SimpleGeneric()
{
......
......@@ -641,14 +641,7 @@ private static BoundStatement BindAssignment(Binder binder, ExpressionSyntax syn
@namespace = @namespace.ContainingNamespace;
}
var binder = (new BuckStopsHereBinder(compilation)).WithAdditionalFlags(
BinderFlags.SuppressObsoleteChecks |
BinderFlags.IgnoreAccessibility |
BinderFlags.UnsafeRegion |
BinderFlags.UncheckedRegion |
BinderFlags.AllowManagedAddressOf |
BinderFlags.AllowAwaitInUnsafeContext |
BinderFlags.IgnoreCorLibraryDuplicatedTypes);
Binder binder = new BuckStopsHereBinder(compilation);
var hasImports = !importRecordGroups.IsDefaultOrEmpty;
var numImportStringGroups = hasImports ? importRecordGroups.Length : 0;
var currentStringGroup = numImportStringGroups - 1;
......
......@@ -127,6 +127,14 @@ private static CSharpCompilation ToCompilation(this ImmutableArray<MetadataRefer
platform: Platform.AnyCpu, // Platform should match PEModule.Machine, in this case I386.
optimizationLevel: OptimizationLevel.Release,
assemblyIdentityComparer: IdentityComparer).
WithMetadataImportOptions(MetadataImportOptions.All);
WithMetadataImportOptions(MetadataImportOptions.All).
WithTopLevelBinderFlags(
BinderFlags.SuppressObsoleteChecks |
BinderFlags.IgnoreAccessibility |
BinderFlags.UnsafeRegion |
BinderFlags.UncheckedRegion |
BinderFlags.AllowManagedAddressOf |
BinderFlags.AllowAwaitInUnsafeContext |
BinderFlags.IgnoreCorLibraryDuplicatedTypes);
}
}
......@@ -64,7 +64,7 @@ public override Compilation CreateSubmission(Script script)
sourceReferenceResolver: script.Options.SourceResolver,
metadataReferenceResolver: script.Options.MetadataResolver,
assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default
),
).WithTopLevelBinderFlags(BinderFlags.IgnoreCorLibraryDuplicatedTypes),
previousSubmission,
script.ReturnType,
script.GlobalsType
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册