|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
internal static class CSharpCompilationOptionsExtensions
{
public static void VerifyErrors(this CSharpCompilationOptions options, params DiagnosticDescription[] expected)
{
options.Errors.Verify(expected);
}
}
public class CSharpCompilationOptionsTests : CSharpTestBase
{
/// <summary>
/// Using an instance of <see cref="CSharpCompilationOptions"/>, tests a property in <see cref="CompilationOptions"/> , even it is hidden by <see cref="CSharpCompilationOptions"/>.
/// </summary>
private void TestHiddenProperty<T>(
Func<CompilationOptions, T, CompilationOptions> factory,
Func<CompilationOptions, T> getter,
T validNonDefaultValue)
{
TestPropertyGeneric(new CSharpCompilationOptions(OutputKind.ConsoleApplication), factory, getter, validNonDefaultValue);
}
private static void TestPropertyGeneric<TOptions, T>(TOptions oldOptions, Func<TOptions, T, TOptions> factory,
Func<TOptions, T> getter, T validNonDefaultValue)
where TOptions : CompilationOptions
{
var validDefaultValue = getter(oldOptions);
// we need non-default value to test Equals and GetHashCode
Assert.NotEqual(validNonDefaultValue, validDefaultValue);
// check that the assigned value can be read:
var newOpt1 = factory(oldOptions, validNonDefaultValue);
Assert.Equal(validNonDefaultValue, getter(newOpt1));
Assert.Equal(0, newOpt1.Errors.Length);
// check that creating new options with the same value yields the same options instance:
var newOpt1_alias = factory(newOpt1, validNonDefaultValue);
Assert.Same(newOpt1_alias, newOpt1);
// check that Equals and GetHashCode work
var newOpt2 = factory(oldOptions, validNonDefaultValue);
Assert.False(newOpt1.Equals(oldOptions));
Assert.True(newOpt1.Equals(newOpt2));
Assert.Equal(newOpt1.GetHashCode(), newOpt2.GetHashCode());
// test default(T):
Assert.NotNull(factory(oldOptions, default(T)));
}
[Fact]
public void ShadowInvariants()
{
TestHiddenProperty((old, value) => old.WithOutputKind(value), opt => opt.OutputKind, OutputKind.DynamicallyLinkedLibrary);
TestHiddenProperty((old, value) => old.WithModuleName(value), opt => opt.ModuleName, "goo.dll");
TestHiddenProperty((old, value) => old.WithMainTypeName(value), opt => opt.MainTypeName, "Goo.Bar");
TestHiddenProperty((old, value) => old.WithScriptClassName(value), opt => opt.ScriptClassName, "<Script>");
TestHiddenProperty((old, value) => old.WithOptimizationLevel(value), opt => opt.OptimizationLevel, OptimizationLevel.Release);
TestHiddenProperty((old, value) => old.WithOverflowChecks(value), opt => opt.CheckOverflow, true);
TestHiddenProperty((old, value) => old.WithCryptoKeyContainer(value), opt => opt.CryptoKeyContainer, "goo");
TestHiddenProperty((old, value) => old.WithCryptoKeyFile(value), opt => opt.CryptoKeyFile, "goo");
TestHiddenProperty((old, value) => old.WithCryptoPublicKey(value), opt => opt.CryptoPublicKey, ImmutableArray.Create<byte>(0, 1, 2, 3));
TestHiddenProperty((old, value) => old.WithDelaySign(value), opt => opt.DelaySign, true);
TestHiddenProperty((old, value) => old.WithPlatform(value), opt => opt.Platform, Platform.Itanium);
TestHiddenProperty((old, value) => old.WithGeneralDiagnosticOption(value), opt => opt.GeneralDiagnosticOption, ReportDiagnostic.Suppress);
TestHiddenProperty((old, value) => old.WithSpecificDiagnosticOptions(value), opt => opt.SpecificDiagnosticOptions,
new Dictionary<string, ReportDiagnostic> { { "CS0001", ReportDiagnostic.Error } }.ToImmutableDictionary());
TestHiddenProperty((old, value) => old.WithReportSuppressedDiagnostics(value), opt => opt.ReportSuppressedDiagnostics, true);
TestHiddenProperty((old, value) => old.WithConcurrentBuild(value), opt => opt.ConcurrentBuild, false);
TestHiddenProperty((old, value) => old.WithXmlReferenceResolver(value), opt => opt.XmlReferenceResolver, new XmlFileResolver(null));
TestHiddenProperty((old, value) => old.WithMetadataReferenceResolver(value), opt => opt.MetadataReferenceResolver, new TestMetadataReferenceResolver());
TestHiddenProperty((old, value) => old.WithAssemblyIdentityComparer(value), opt => opt.AssemblyIdentityComparer, new DesktopAssemblyIdentityComparer(new AssemblyPortabilityPolicy()));
TestHiddenProperty((old, value) => old.WithStrongNameProvider(value), opt => opt.StrongNameProvider, new DesktopStrongNameProvider());
}
private void TestProperty<T>(
Func<CSharpCompilationOptions, T, CSharpCompilationOptions> factory,
Func<CSharpCompilationOptions, T> getter,
T validNonDefaultValue)
{
TestPropertyGeneric(new CSharpCompilationOptions(OutputKind.ConsoleApplication), factory, getter, validNonDefaultValue);
}
[Fact]
public void Invariants()
{
TestProperty((old, value) => old.WithOutputKind(value), opt => opt.OutputKind, OutputKind.DynamicallyLinkedLibrary);
TestProperty((old, value) => old.WithModuleName(value), opt => opt.ModuleName, "goo.dll");
TestProperty((old, value) => old.WithMainTypeName(value), opt => opt.MainTypeName, "Goo.Bar");
TestProperty((old, value) => old.WithScriptClassName(value), opt => opt.ScriptClassName, "<Script>");
TestProperty((old, value) => old.WithUsings(value), opt => opt.Usings, ImmutableArray.Create("A", "B"));
TestProperty((old, value) => old.WithOptimizationLevel(value), opt => opt.OptimizationLevel, OptimizationLevel.Release);
TestProperty((old, value) => old.WithOverflowChecks(value), opt => opt.CheckOverflow, true);
TestProperty((old, value) => old.WithAllowUnsafe(value), opt => opt.AllowUnsafe, true);
TestProperty((old, value) => old.WithCryptoKeyContainer(value), opt => opt.CryptoKeyContainer, "goo");
TestProperty((old, value) => old.WithCryptoKeyFile(value), opt => opt.CryptoKeyFile, "goo");
TestProperty((old, value) => old.WithCryptoPublicKey(value), opt => opt.CryptoPublicKey, ImmutableArray.Create<byte>(0, 1, 2, 3));
TestProperty((old, value) => old.WithDelaySign(value), opt => opt.DelaySign, true);
TestProperty((old, value) => old.WithPlatform(value), opt => opt.Platform, Platform.Itanium);
TestProperty((old, value) => old.WithGeneralDiagnosticOption(value), opt => opt.GeneralDiagnosticOption, ReportDiagnostic.Suppress);
TestProperty((old, value) => old.WithWarningLevel(value), opt => opt.WarningLevel, 3);
TestProperty((old, value) => old.WithSpecificDiagnosticOptions(value), opt => opt.SpecificDiagnosticOptions,
new Dictionary<string, ReportDiagnostic> { { "CS0001", ReportDiagnostic.Error } }.ToImmutableDictionary());
TestProperty((old, value) => old.WithReportSuppressedDiagnostics(value), opt => opt.ReportSuppressedDiagnostics, true);
TestProperty((old, value) => old.WithConcurrentBuild(value), opt => opt.ConcurrentBuild, false);
TestProperty((old, value) => old.WithCurrentLocalTime(value), opt => opt.CurrentLocalTime, new DateTime(2005, 1, 1));
TestProperty((old, value) => old.WithDebugPlusMode(value), opt => opt.DebugPlusMode, true);
TestProperty((old, value) => old.WithXmlReferenceResolver(value), opt => opt.XmlReferenceResolver, new XmlFileResolver(null));
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);
TestProperty((old, value) => old.WithReferencesSupersedeLowerVersions(value), opt => opt.ReferencesSupersedeLowerVersions, true);
TestProperty((old, value) => old.WithNullableContextOptions(value), opt => opt.NullableContextOptions, NullableContextOptions.Enable);
}
[Fact]
public void WithXxx()
{
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithScriptClassName(null).VerifyErrors(
// error CS7088: Invalid 'ScriptClassName' value: 'null'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("ScriptClassName", "null"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithScriptClassName("blah\0goo").VerifyErrors(
// error CS7088: Invalid 'ScriptClassName' value: 'blah\0goo'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("ScriptClassName", "blah\0goo"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithScriptClassName("").VerifyErrors(
// error CS7088: Invalid 'ScriptClassName' value: ''.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("ScriptClassName", ""));
Assert.Equal(0, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithMainTypeName(null).Errors.Length);
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithMainTypeName("blah\0goo").VerifyErrors(
// error CS7088: Invalid 'MainTypeName' value: 'blah\0goo'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MainTypeName", "blah\0goo"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithMainTypeName("").VerifyErrors(
// error CS7088: Invalid 'MainTypeName' value: ''.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MainTypeName", ""));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithOutputKind((OutputKind)Int32.MaxValue).VerifyErrors(
// error CS7088: Invalid 'OutputKind' value: 'Int32.MaxValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OutputKind", Int32.MaxValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithOutputKind((OutputKind)Int32.MinValue).VerifyErrors(
// error CS7088: Invalid 'OutputKind' value: 'Int32.MinValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OutputKind", Int32.MinValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithOptimizationLevel((OptimizationLevel)Int32.MaxValue).VerifyErrors(
// error CS7088: Invalid 'OptimizationLevel' value: 'Int32.MaxValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OptimizationLevel", Int32.MaxValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithOptimizationLevel((OptimizationLevel)Int32.MinValue).VerifyErrors(
// error CS7088: Invalid 'OptimizationLevel' value: 'Int32.MinValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OptimizationLevel", Int32.MinValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithPlatform((Platform)Int32.MaxValue).VerifyErrors(
// error CS1672: Invalid option 'Int32.MaxValue' for /platform; must be anycpu, x86, Itanium or x64
Diagnostic(ErrorCode.ERR_BadPlatformType).WithArguments(Int32.MaxValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithPlatform((Platform)Int32.MinValue).VerifyErrors(
// error CS1672: Invalid option 'Int32.MinValue' for /platform; must be anycpu, x86, Itanium or x64
Diagnostic(ErrorCode.ERR_BadPlatformType).WithArguments(Int32.MinValue.ToString()));
var defaultWarnings = new CSharpCompilationOptions(OutputKind.ConsoleApplication);
Assert.Equal(ReportDiagnostic.Default, defaultWarnings.GeneralDiagnosticOption);
Assert.Equal(CodeAnalysis.Diagnostic.DefaultWarningLevel, defaultWarnings.WarningLevel);
Assert.Equal(ReportDiagnostic.Error, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithGeneralDiagnosticOption(ReportDiagnostic.Error).GeneralDiagnosticOption);
Assert.Equal(ReportDiagnostic.Default, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithGeneralDiagnosticOption(ReportDiagnostic.Default).GeneralDiagnosticOption);
}
[Fact]
public void WithUsings()
{
var actual1 = new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings(new[] { "A", "B" }).Usings;
Assert.True(actual1.SequenceEqual(new[] { "A", "B" }));
var actual2 = new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings(Enumerable.Repeat("A", 1)).Usings;
Assert.True(actual2.SequenceEqual(Enumerable.Repeat("A", 1)));
Assert.Equal(0, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings("A", "B").WithUsings(null).Usings.Count());
Assert.Equal(0, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings("A", "B").WithUsings((string[])null).Usings.Count());
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings(new string[] { null }).VerifyErrors(
// error CS7088: Invalid 'Usings' value: 'null'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("Usings", "null"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings(new string[] { "" }).VerifyErrors(
// error CS7088: Invalid 'Usings' value: ''.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("Usings", ""));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithUsings(new string[] { "blah\0goo" }).VerifyErrors(
// error CS7088: Invalid 'Usings' value: 'blah\0goo'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("Usings", "blah\0goo"));
}
[Fact]
public void WithWarnings()
{
var warnings = new Dictionary<string, ReportDiagnostic>
{
{ MessageProvider.Instance.GetIdForErrorCode(1), ReportDiagnostic.Error },
{ MessageProvider.Instance.GetIdForErrorCode(2), ReportDiagnostic.Suppress },
{ MessageProvider.Instance.GetIdForErrorCode(3), ReportDiagnostic.Warn }
};
Assert.Equal(3, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithSpecificDiagnosticOptions(warnings).SpecificDiagnosticOptions.Count);
Assert.Equal(0, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithSpecificDiagnosticOptions(null).SpecificDiagnosticOptions.Count);
Assert.Equal(1, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithWarningLevel(1).WarningLevel);
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithWarningLevel(-1).VerifyErrors(
// error CS7088: Invalid 'WarningLevel' value: '-1'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("WarningLevel", "-1"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithWarningLevel(5).VerifyErrors();
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithWarningLevel(int.MaxValue).VerifyErrors();
}
[Fact]
public void WithModuleName()
{
// ModuleName
Assert.Null(TestOptions.ReleaseDll.WithModuleName(null).ModuleName);
TestOptions.ReleaseDll.WithModuleName("").VerifyErrors(
// error CS7087: Invalid module name: Name cannot be empty.
Diagnostic(ErrorCode.ERR_BadModuleName).WithArguments("Name cannot be empty.").WithLocation(1, 1)
);
TestOptions.ReleaseDll.WithModuleName("a\0a").VerifyErrors(
// error CS7087: Invalid module name: Name contains invalid characters.
Diagnostic(ErrorCode.ERR_BadModuleName).WithArguments("Name contains invalid characters.").WithLocation(1, 1)
);
TestOptions.ReleaseDll.WithModuleName("a\uD800b").VerifyErrors(
// error CS7087: Invalid module name: Name contains invalid characters.
Diagnostic(ErrorCode.ERR_BadModuleName).WithArguments("Name contains invalid characters.").WithLocation(1, 1)
);
TestOptions.ReleaseDll.WithModuleName("a\\b").VerifyErrors(
// error CS7087: Invalid module name: Name contains invalid characters.
Diagnostic(ErrorCode.ERR_BadModuleName).WithArguments("Name contains invalid characters.").WithLocation(1, 1)
);
TestOptions.ReleaseDll.WithModuleName("a/b").VerifyErrors(
// error CS7087: Invalid module name: Name contains invalid characters.
Diagnostic(ErrorCode.ERR_BadModuleName).WithArguments("Name contains invalid characters.").WithLocation(1, 1)
);
TestOptions.ReleaseDll.WithModuleName("a:b").VerifyErrors(
// error CS7087: Invalid module name: Name contains invalid characters.
Diagnostic(ErrorCode.ERR_BadModuleName).WithArguments("Name contains invalid characters.").WithLocation(1, 1)
);
}
[Fact]
public void ConstructorValidation()
{
new CSharpCompilationOptions(OutputKind.ConsoleApplication, usings: new string[] { null }).VerifyErrors(
// error CS7088: Invalid 'Usings' value: 'null'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("Usings", "null"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, usings: new string[] { "" }).VerifyErrors(
// error CS7088: Invalid 'Usings' value: ''.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("Usings", ""));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, usings: new string[] { "blah\0goo" }).VerifyErrors(
// error CS7088: Invalid 'Usings' value: 'blah\0goo'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("Usings", "blah\0goo"));
Assert.Equal("Script", new CSharpCompilationOptions(OutputKind.ConsoleApplication, scriptClassName: null).ScriptClassName);
new CSharpCompilationOptions(OutputKind.ConsoleApplication, scriptClassName: "blah\0goo").VerifyErrors(
// error CS7088: Invalid 'ScriptClassName' value: 'blah\0goo'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("ScriptClassName", "blah\0goo"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, scriptClassName: "").VerifyErrors(
// error CS7088: Invalid 'ScriptClassName' value: ''.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("ScriptClassName", ""));
Assert.Equal(0, new CSharpCompilationOptions(OutputKind.ConsoleApplication, mainTypeName: null).Errors.Length);
new CSharpCompilationOptions(OutputKind.ConsoleApplication, mainTypeName: "blah\0goo").VerifyErrors(
// error CS7088: Invalid 'MainTypeName' value: 'blah\0goo'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MainTypeName", "blah\0goo"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, mainTypeName: "").VerifyErrors(
// error CS7088: Invalid 'MainTypeName' value: ''.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("MainTypeName", ""));
new CSharpCompilationOptions(outputKind: (OutputKind)Int32.MaxValue).VerifyErrors(
// error CS7088: Invalid 'OutputKind' value: 'Int32.MaxValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OutputKind", Int32.MaxValue.ToString()));
new CSharpCompilationOptions(outputKind: (OutputKind)Int32.MinValue).VerifyErrors(
// error CS7088: Invalid 'OutputKind' value: 'Int32.MinValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OutputKind", Int32.MinValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, optimizationLevel: (OptimizationLevel)Int32.MaxValue).VerifyErrors(
// error CS7088: Invalid 'OptimizationLevel' value: 'Int32.MaxValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OptimizationLevel", Int32.MaxValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, optimizationLevel: (OptimizationLevel)Int32.MinValue).VerifyErrors(
// error CS7088: Invalid 'OptimizationLevel' value: 'Int32.MinValue'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("OptimizationLevel", Int32.MinValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, platform: (Platform)Int32.MinValue).VerifyErrors(
// error CS1672: Invalid option 'Int32.MinValue' for /platform; must be anycpu, x86, Itanium or x64
Diagnostic(ErrorCode.ERR_BadPlatformType).WithArguments(Int32.MinValue.ToString()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, warningLevel: -1).VerifyErrors(
// error CS7088: Invalid 'WarningLevel' value: '-1'.
Diagnostic(ErrorCode.ERR_BadCompilationOptionValue).WithArguments("WarningLevel", "-1"));
new CSharpCompilationOptions(OutputKind.ConsoleApplication, warningLevel: 5).VerifyErrors();
new CSharpCompilationOptions(OutputKind.ConsoleApplication, warningLevel: int.MaxValue).VerifyErrors();
new CSharpCompilationOptions(OutputKind.ConsoleApplication, platform: Platform.AnyCpu32BitPreferred).VerifyErrors();
new CSharpCompilationOptions(OutputKind.WindowsRuntimeApplication, platform: Platform.AnyCpu32BitPreferred).VerifyErrors();
new CSharpCompilationOptions(OutputKind.WindowsRuntimeMetadata, platform: Platform.AnyCpu32BitPreferred).VerifyErrors(
Diagnostic(ErrorCode.ERR_BadPrefer32OnLib));
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, platform: Platform.AnyCpu32BitPreferred).VerifyErrors(
Diagnostic(ErrorCode.ERR_BadPrefer32OnLib));
}
/// <summary>
/// If this test fails, please update the <see cref="CompilationOptions.GetHashCode"/>
/// and <see cref="CSharpCompilationOptions.Equals(CSharpCompilationOptions)"/> methods to
/// make sure they are doing the right thing with your new field and then update the baseline
/// here.
/// </summary>
[Fact]
public void TestFieldsForEqualsAndGetHashCode()
{
ReflectionAssert.AssertPublicAndInternalFieldsAndProperties(
typeof(CSharpCompilationOptions),
"Language",
"AllowUnsafe",
"Usings",
"TopLevelBinderFlags",
"NullableContextOptions");
}
[Fact]
public void TestEqualitySemantics()
{
CSharpCompilationOptions first = CreateCSharpCompilationOptions();
CSharpCompilationOptions second = CreateCSharpCompilationOptions();
Assert.Equal(first, second);
Assert.Equal(first.GetHashCode(), second.GetHashCode());
}
private static CSharpCompilationOptions CreateCSharpCompilationOptions()
{
string moduleName = null;
string mainTypeName = null;
string scriptClassName = null;
IEnumerable<string> usings = null;
OptimizationLevel optimizationLevel = OptimizationLevel.Debug;
bool checkOverflow = false;
bool allowUnsafe = false;
string cryptoKeyContainer = null;
string cryptoKeyFile = null;
ImmutableArray<byte> cryptoPublicKey = default(ImmutableArray<byte>);
bool? delaySign = null;
Platform platform = 0;
ReportDiagnostic generalDiagnosticOption = 0;
int warningLevel = 0;
IEnumerable<KeyValuePair<string, ReportDiagnostic>> specificDiagnosticOptions = null;
bool concurrentBuild = false;
bool deterministic = false;
DateTime currentLocalTime = default(DateTime);
bool debugPlusMode = false;
XmlReferenceResolver xmlReferenceResolver = new XmlFileResolver(null);
SourceReferenceResolver sourceReferenceResolver = new SourceFileResolver(ImmutableArray<string>.Empty, null);
SyntaxTreeOptionsProvider syntaxTreeOptionsProvider = null;
MetadataReferenceResolver metadataReferenceResolver = new MetadataReferenceResolverWithEquality();
AssemblyIdentityComparer assemblyIdentityComparer = AssemblyIdentityComparer.Default; // Currently uses reference equality
StrongNameProvider strongNameProvider = new DesktopStrongNameProvider();
MetadataImportOptions metadataImportOptions = 0;
bool referencesSupersedeLowerVersions = false;
bool reportSuppressedDiagnostics = false;
var topLevelBinderFlags = BinderFlags.None;
var publicSign = false;
NullableContextOptions nullableContextOptions = NullableContextOptions.Disable;
return new CSharpCompilationOptions(OutputKind.ConsoleApplication,
reportSuppressedDiagnostics, moduleName, mainTypeName, scriptClassName, usings,
optimizationLevel, checkOverflow, allowUnsafe, cryptoKeyContainer, cryptoKeyFile,
cryptoPublicKey, delaySign, platform, generalDiagnosticOption, warningLevel,
specificDiagnosticOptions, concurrentBuild, deterministic, currentLocalTime,
debugPlusMode, xmlReferenceResolver, sourceReferenceResolver,
syntaxTreeOptionsProvider, metadataReferenceResolver, assemblyIdentityComparer,
strongNameProvider, metadataImportOptions, referencesSupersedeLowerVersions,
publicSign, topLevelBinderFlags, nullableContextOptions);
}
private sealed class MetadataReferenceResolverWithEquality : MetadataReferenceResolver
{
public override bool Equals(object other) => true;
public override int GetHashCode() => 1;
public override ImmutableArray<PortableExecutableReference> ResolveReference(string reference, string baseFilePath, MetadataReferenceProperties properties)
{
throw new NotImplementedException();
}
}
[Fact]
public void WithCryptoPublicKey()
{
var options = new CSharpCompilationOptions(OutputKind.ConsoleApplication);
Assert.Equal(ImmutableArray<byte>.Empty, options.CryptoPublicKey);
Assert.Equal(ImmutableArray<byte>.Empty, options.WithCryptoPublicKey(default(ImmutableArray<byte>)).CryptoPublicKey);
Assert.Same(options, options.WithCryptoPublicKey(default(ImmutableArray<byte>)));
Assert.Same(options, options.WithCryptoPublicKey(ImmutableArray<byte>.Empty));
}
[Fact]
public void TestWithNullable()
{
Assert.Equal(NullableContextOptions.Disable, new CSharpCompilationOptions(OutputKind.ConsoleApplication).NullableContextOptions);
var values = (NullableContextOptions[])System.Enum.GetValues(typeof(NullableContextOptions));
var options = new CSharpCompilationOptions[values.Length];
for (int i = 0; i < values.Length; i++)
{
options[i] = new CSharpCompilationOptions(OutputKind.ConsoleApplication, nullableContextOptions: values[i]);
Assert.Equal(values[i], options[i].NullableContextOptions);
}
for (int i = 0; i < values.Length; i++)
{
var oldOptions = options[i];
for (int j = 0; j < values.Length; j++)
{
var newOptions = oldOptions.WithNullableContextOptions(values[j]);
Assert.Equal(values[j], newOptions.NullableContextOptions);
Assert.Equal(options[j], newOptions);
Assert.Equal(options[j].GetHashCode(), newOptions.GetHashCode());
if (i == j)
{
Assert.Same(oldOptions, newOptions);
}
else
{
Assert.NotSame(oldOptions, newOptions);
Assert.NotEqual(oldOptions, newOptions);
}
}
}
}
}
}
|