提交 8707ac39 编写于 作者: E Evan Hauck

Merge pull request #3288 from khyperia/FeaturesOptions

Refactor Compilation to pull features from ParseOptions
......@@ -6,6 +6,7 @@
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -60,46 +61,7 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
metadataReferenceResolver: metadataReferenceResolver,
assemblyIdentityComparer: assemblyIdentityComparer,
strongNameProvider: strongNameProvider,
metadataImportOptions: MetadataImportOptions.Public,
features: ImmutableArray<string>.Empty)
{
}
internal CSharpCompilationOptions(
OutputKind outputKind,
ImmutableArray<string> features,
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 = Platform.AnyCpu,
ReportDiagnostic generalDiagnosticOption = ReportDiagnostic.Default,
int warningLevel = 4,
IEnumerable<KeyValuePair<string, ReportDiagnostic>> specificDiagnosticOptions = null,
bool concurrentBuild = true,
XmlReferenceResolver xmlReferenceResolver = null,
SourceReferenceResolver sourceReferenceResolver = null,
MetadataReferenceResolver metadataReferenceResolver = null,
AssemblyIdentityComparer assemblyIdentityComparer = null,
StrongNameProvider strongNameProvider = null)
: this(outputKind, moduleName, mainTypeName, scriptClassName, usings, optimizationLevel, checkOverflow, allowUnsafe,
cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign, platform, generalDiagnosticOption, warningLevel,
specificDiagnosticOptions, concurrentBuild,
extendedCustomDebugInformation: true,
xmlReferenceResolver: xmlReferenceResolver,
sourceReferenceResolver: sourceReferenceResolver,
metadataReferenceResolver: metadataReferenceResolver,
assemblyIdentityComparer: assemblyIdentityComparer,
strongNameProvider: strongNameProvider,
metadataImportOptions: MetadataImportOptions.Public,
features: features)
metadataImportOptions: MetadataImportOptions.Public)
{
}
......@@ -128,12 +90,11 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
MetadataReferenceResolver metadataReferenceResolver,
AssemblyIdentityComparer assemblyIdentityComparer,
StrongNameProvider strongNameProvider,
MetadataImportOptions metadataImportOptions,
ImmutableArray<string> features)
MetadataImportOptions metadataImportOptions)
: base(outputKind, moduleName, mainTypeName, scriptClassName, cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign, optimizationLevel, checkOverflow,
platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions.ToImmutableDictionaryOrEmpty(),
concurrentBuild, extendedCustomDebugInformation, xmlReferenceResolver, sourceReferenceResolver, metadataReferenceResolver, assemblyIdentityComparer,
strongNameProvider, metadataImportOptions, features)
strongNameProvider, metadataImportOptions)
{
this.Usings = usings.AsImmutableOrEmpty();
this.AllowUnsafe = allowUnsafe;
......@@ -163,8 +124,7 @@ public sealed class CSharpCompilationOptions : CompilationOptions, IEquatable<CS
metadataReferenceResolver: other.MetadataReferenceResolver,
assemblyIdentityComparer: other.AssemblyIdentityComparer,
strongNameProvider: other.StrongNameProvider,
metadataImportOptions: other.MetadataImportOptions,
features: other.Features)
metadataImportOptions: other.MetadataImportOptions)
{
}
......@@ -398,16 +358,6 @@ internal CSharpCompilationOptions WithMetadataImportOptions(MetadataImportOption
return new CSharpCompilationOptions(this) { MetadataImportOptions_internal_protected_set = value };
}
internal new CSharpCompilationOptions WithFeatures(ImmutableArray<string> features)
{
if (features == this.Features)
{
return this;
}
return new CSharpCompilationOptions(this) { Features = features };
}
public new CSharpCompilationOptions WithXmlReferenceResolver(XmlReferenceResolver resolver)
{
if (ReferenceEquals(resolver, this.XmlReferenceResolver))
......@@ -500,9 +450,10 @@ protected override CompilationOptions CommonWithStrongNameProvider(StrongNamePro
return WithStrongNameProvider(provider);
}
[Obsolete]
protected override CompilationOptions CommonWithFeatures(ImmutableArray<string> features)
{
return WithFeatures(features);
throw new NotImplementedException();
}
internal override void ValidateOptions(ArrayBuilder<Diagnostic> builder)
......
......@@ -197,7 +197,7 @@ public new CSharpParseOptions WithFeatures(IEnumerable<KeyValuePair<string, stri
throw new ArgumentNullException(nameof(features));
}
return new CSharpParseOptions(this) { _features = features.ToImmutableDictionary() };
return new CSharpParseOptions(this) { _features = features.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase) };
}
public override IReadOnlyDictionary<string, string> Features
......
......@@ -1039,7 +1039,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string bas
preprocessorSymbols: defines.ToImmutableAndFree(),
documentationMode: parseDocumentationComments ? DocumentationMode.Diagnose : DocumentationMode.None,
kind: SourceCodeKind.Regular,
features: features.ToImmutableDictionary(feature => feature, feature => "true")
features: ParseFeatures(features)
);
var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);
......@@ -1061,8 +1061,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string bas
platform: platform,
generalDiagnosticOption: generalDiagnosticOption,
warningLevel: warningLevel,
specificDiagnosticOptions: diagnosticOptions,
features: features.AsImmutable()
specificDiagnosticOptions: diagnosticOptions
);
var emitOptions = new EmitOptions
......
......@@ -4186,7 +4186,7 @@ static int Main()
var outWriter = new StringWriter(CultureInfo.InvariantCulture);
// csc errors_whitespace_008.cs @errors_whitespace_008.cs.rsp
var csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en"});
var csc = new MockCSharpCompiler(rsp, _baseDirectory, new[] { source, "/preferreduilang:en" });
int exitCode = csc.Run(outWriter);
Assert.Equal(0, exitCode);
......@@ -6840,35 +6840,31 @@ public void ParseFeatures()
{
var args = DefaultParse(new[] { "/features:Test", "a.vb" }, _baseDirectory);
args.Errors.Verify();
Assert.Equal("Test", args.CompilationOptions.Features.Single());
Assert.Equal("Test", args.ParseOptions.Features.Single().Key);
args = DefaultParse(new[] { "/features:Test", "a.vb", "/Features:Experiment" }, _baseDirectory);
args.Errors.Verify();
Assert.Equal(2, args.CompilationOptions.Features.Length);
Assert.Equal("Test", args.CompilationOptions.Features[0]);
Assert.Equal("Experiment", args.CompilationOptions.Features[1]);
Assert.Equal(2, args.ParseOptions.Features.Count);
Assert.True(args.ParseOptions.Features.ContainsKey("Test"));
Assert.True(args.ParseOptions.Features.ContainsKey("Experiment"));
args = DefaultParse(new[] { "/features:Test:false,Key:value", "a.vb" }, _baseDirectory);
args = DefaultParse(new[] { "/features:Test=false,Key=value", "a.vb" }, _baseDirectory);
args.Errors.Verify();
Assert.Equal("Test:false,Key:value", args.CompilationOptions.Features.Single());
Assert.Equal("Test:false,Key:value", args.ParseOptions.Features.Single().Key);
Assert.True(args.ParseOptions.Features.SetEquals(new Dictionary<string, string> { { "Test", "false" }, { "Key", "value" } }));
// We don't do any rigorous validation of /features arguments...
// We don't do any rigorous validation of / features arguments...
args = DefaultParse(new[] { "/features", "a.vb" }, _baseDirectory);
args.Errors.Verify();
Assert.Empty(args.CompilationOptions.Features);
Assert.Empty(args.ParseOptions.Features);
args = DefaultParse(new[] { "/features:,", "a.vb" }, _baseDirectory);
args.Errors.Verify();
Assert.Equal(",", args.CompilationOptions.Features.Single());
Assert.Equal("", args.ParseOptions.Features.Single().Key);
args = DefaultParse(new[] { "/features:Test,", "a.vb" }, _baseDirectory);
args.Errors.Verify();
Assert.Equal("Test,", args.CompilationOptions.Features.Single());
Assert.True(args.ParseOptions.Features.SetEquals(new Dictionary<string, string> { { "Test", "true" }, { "", "true" } }));
}
[Fact]
......
......@@ -399,8 +399,10 @@ class C
}
}
";
var standardCompilation = CreateCompilationWithMscorlib(source);
var strictCompilation = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.Regular.WithStrictFeature());
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
standardCompilation.VerifyDiagnostics(
// (8,32): warning CS0642: Possible mistaken empty statement
// lock (default(object)) ;
Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(8, 32),
......@@ -413,8 +415,8 @@ class C
// (12,15): error CS0185: 'TStruct' is not a reference type as required by the lock statement
// lock (default(TStruct)) {} // new CS0185 - constraints to value type (Bug#10756)
Diagnostic(ErrorCode.ERR_LockNeedsReference, "default(TStruct)").WithArguments("TStruct").WithLocation(12, 15)
)
.WithStrictMode().VerifyDiagnostics(
);
strictCompilation.VerifyDiagnostics(
// (8,32): warning CS0642: Possible mistaken empty statement
// lock (default(object)) ;
Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(8, 32),
......
......@@ -1107,7 +1107,7 @@ .maxstack 1
// return ((S?)null) < new S?(N4());
Diagnostic(ErrorCode.WRN_CmpAlwaysFalse, "((S?)null) < new S?(N4())").WithArguments("S?").WithLocation(41, 16)
);
var comp = CompileAndVerify(source, expectedOutput: expectedOutput, options: TestOptions.ReleaseExe.WithStrictMode());
var comp = CompileAndVerify(source, expectedOutput: expectedOutput, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular.WithStrictFeature());
comp.VerifyDiagnostics(
// (21,16): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'short?'
// return new int?(N1()) == new short?();
......
......@@ -20,7 +20,8 @@ private Guid CompiledGuid(string source, string assemblyName, bool debug)
var compilation = CreateCompilation(source,
assemblyName: assemblyName,
references: new[] { MscorlibRef },
options: (debug ? TestOptions.DebugExe : TestOptions.ReleaseExe).WithFeatures(ImmutableArray.Create("deterministic")));
options: (debug ? TestOptions.DebugExe : TestOptions.ReleaseExe),
parseOptions: TestOptions.Regular.WithDeterministicFeature());
Guid result = default(Guid);
base.CompileAndVerify(compilation, emitters: TestEmitters.CCI, validator: (a, eo) =>
......@@ -35,9 +36,9 @@ private Guid CompiledGuid(string source, string assemblyName, bool debug)
private ImmutableArray<byte> EmitDeterministic(string source, Platform platform, bool debug)
{
var options = (debug ? TestOptions.DebugExe : TestOptions.ReleaseExe).WithPlatform(platform);
options = options.WithFeatures((new[] { "dEtErmInIstIc" }).AsImmutable()); // expect case-insensitivity
var compilation = CreateCompilation(source, assemblyName: "DeterminismTest", references: new[] { MscorlibRef }, options: options);
var compilation = CreateCompilation(source, assemblyName: "DeterminismTest", references: new[] { MscorlibRef }, options: options,
parseOptions: TestOptions.Regular.WithFeature("dEtErmInIstIc", "true")); // expect case-insensitivity
// The resolution of the PE header time date stamp is seconds, and we want to make sure that has an opportunity to change
// between calls to Emit.
......@@ -114,11 +115,12 @@ public void CompareAllBytesEmitted_Debug()
[Fact]
public void TestWriteOnlyStream()
{
var tree = CSharpSyntaxTree.ParseText("class Program { static void Main() { } }");
var tree = CSharpSyntaxTree.ParseText("class Program { static void Main() { } }",
TestOptions.Regular.WithDeterministicFeature());
var compilation = CSharpCompilation.Create("Program",
new[] { tree },
new[] { MetadataReference.CreateFromAssembly(typeof(object).Assembly) },
new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithFeatures((new[] { "deterministic" }).AsImmutable()));
new CSharpCompilationOptions(OutputKind.ConsoleApplication));
var output = new WriteOnlyStream();
compilation.Emit(output);
}
......
......@@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
......@@ -199,7 +200,10 @@ public static void Main()
var v2 = v1;
}
}";
CreateCompilationWithMscorlib(source2, options: Test.Utilities.TestOptions.ReleaseDll.WithFeatures(new[] { "strict" }.AsImmutable()), references: new MetadataReference[] { sourceReference }).VerifyDiagnostics(
CreateCompilationWithMscorlib(source2,
options: TestOptions.ReleaseDll,
references: new MetadataReference[] { sourceReference },
parseOptions: TestOptions.Regular.WithStrictFeature()).VerifyDiagnostics(
// (6,18): error CS0165: Use of unassigned local variable 'r1'
// var r2 = r1;
Diagnostic(ErrorCode.ERR_UseDefViolation, "r1").WithArguments("r1").WithLocation(6, 18),
......@@ -342,7 +346,7 @@ public struct Struct
internal C1.S data;
}
";
var comp1 = CreateCompilationWithMscorlib(source, options: Test.Utilities.TestOptions.DebugModule);
var comp1 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugModule);
var moduleReference = comp1.EmitToImageReference();
var source2 =
......@@ -370,7 +374,7 @@ public struct Struct
private string data;
}
";
var comp1 = CreateCompilationWithMscorlib(source, options: Test.Utilities.TestOptions.DebugModule);
var comp1 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugModule);
var moduleReference = comp1.EmitToImageReference();
var source2 =
......
......@@ -765,13 +765,15 @@ public static void Consumer(T monitor3)
}
}
";
var regularCompilation = CreateCompilationWithMscorlib(source);
var strictCompilation = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.Regular.WithStrictFeature());
CreateCompilationWithMscorlib(source).VerifyDiagnostics(
regularCompilation.VerifyDiagnostics(
// (16,15): error CS0185: 'T' is not a reference type as required by the lock statement
// lock (monitor2)
Diagnostic(ErrorCode.ERR_LockNeedsReference, "monitor2").WithArguments("T").WithLocation(16, 15)
)
.WithStrictMode().VerifyDiagnostics(
);
strictCompilation.VerifyDiagnostics(
// (16,15): error CS0185: 'T' is not a reference type as required by the lock statement
// lock (monitor2)
Diagnostic(ErrorCode.ERR_LockNeedsReference, "monitor2").WithArguments("T").WithLocation(16, 15),
......
......@@ -6423,9 +6423,9 @@ public static void Main(string[] args)
M(1 - Color.Red);
}
}";
CreateCompilationWithMscorlib(source1, options: Test.Utilities.TestOptions.ReleaseDll).VerifyDiagnostics(
CreateCompilationWithMscorlib(source1, options: TestOptions.ReleaseDll).VerifyDiagnostics(
);
CreateCompilationWithMscorlib(source1, options: Test.Utilities.TestOptions.ReleaseDll.WithFeatures(new[] { "strict" }.AsImmutable())).VerifyDiagnostics(
CreateCompilationWithMscorlib(source1, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular.WithStrictFeature()).VerifyDiagnostics(
// (7,11): error CS0019: Operator '-' cannot be applied to operands of type 'int' and 'Color'
// M(1 - Color.Red);
Diagnostic(ErrorCode.ERR_BadBinaryOps, "1 - Color.Red").WithArguments("-", "int", "Color").WithLocation(7, 11)
......
......@@ -7605,7 +7605,7 @@ public static void Main(string[] args)
}";
CompileAndVerify(source, expectedOutput: @"pass
pass").VerifyDiagnostics();
CreateCompilationWithMscorlib(source, options: Test.Utilities.TestOptions.ReleaseDll.WithFeatures(new[] { "strict" }.AsImmutable())).VerifyDiagnostics(
CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular.WithStrictFeature()).VerifyDiagnostics(
// (12,36): error CS1657: Cannot pass 'M' as a ref or out argument because it is a 'method group'
// Action a1 = new Action(ref M);
Diagnostic(ErrorCode.ERR_RefReadonlyLocalCause, "M").WithArguments("M", "method group").WithLocation(12, 36),
......
......@@ -6801,7 +6801,7 @@ static Foo()
// Foo<int>.Y = 2;
Diagnostic(ErrorCode.ERR_AssgReadonlyProp, "Foo<int>.Y").WithArguments("Foo<int>.Y").WithLocation(6, 9)
);
CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseDll.WithStrictMode()).VerifyDiagnostics(
CreateCompilationWithMscorlib(text, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular.WithStrictFeature()).VerifyDiagnostics(
// (5,9): error CS0198: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)
// Foo<int>.X = 1;
Diagnostic(ErrorCode.ERR_AssgReadonlyStatic, "Foo<int>.X").WithLocation(5, 9),
......@@ -19389,7 +19389,7 @@ public static void Main()
};
var compatibleExpected = fullExpected.Where(d => !d.Code.Equals((int)ErrorCode.WRN_NubExprIsConstBool2)).ToArray();
this.CompileAndVerify(source: text, expectedOutput: expected).VerifyDiagnostics(compatibleExpected);
this.CompileAndVerify(source: text, expectedOutput: expected, options: TestOptions.ReleaseExe.WithStrictMode()).VerifyDiagnostics(fullExpected);
this.CompileAndVerify(source: text, expectedOutput: expected, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular.WithStrictFeature()).VerifyDiagnostics(fullExpected);
}
[Fact]
......
......@@ -351,12 +351,11 @@ private static CSharpCompilationOptions CreateCSharpCompilationOptions()
AssemblyIdentityComparer assemblyIdentityComparer = AssemblyIdentityComparer.Default; // Currently uses reference equality
StrongNameProvider strongNameProvider = new DesktopStrongNameProvider();
MetadataImportOptions metadataImportOptions = 0;
ImmutableArray<string> features = ImmutableArray<string>.Empty;
return new CSharpCompilationOptions(OutputKind.ConsoleApplication, moduleName, mainTypeName, scriptClassName, usings,
optimizationLevel, checkOverflow, allowUnsafe, cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign,
platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions,
concurrentBuild, extendedCustomDebugInformation, xmlReferenceResolver, sourceReferenceResolver, metadataReferenceResolver,
assemblyIdentityComparer, strongNameProvider, metadataImportOptions, features);
assemblyIdentityComparer, strongNameProvider, metadataImportOptions);
}
[Fact]
......
......@@ -869,7 +869,8 @@ private TestData Compile(string source, int expectedIntervals, params Diagnostic
var compilation = GetCompilationForEmit(
new[] { source },
new MetadataReference[] { },
TestOptions.ReleaseDll
TestOptions.ReleaseDll,
TestOptions.Regular
);
compilation.VerifyDiagnostics(diagnostics);
......@@ -913,7 +914,8 @@ private CSharpCompilation Compile(string source)
return GetCompilationForEmit(
new[] { source },
new MetadataReference[] { },
TestOptions.ReleaseDll
TestOptions.ReleaseDll,
TestOptions.Regular
);
}
......
......@@ -1485,7 +1485,7 @@ public static void Main2()
}
}
";
var compilation = GetCompilationForEmit(new string[] { source1, source2, source3 }, null, TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
var compilation = GetCompilationForEmit(new string[] { source1, source2, source3 }, null, TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal), TestOptions.Regular);
for (int i = 0; i < 10; i++)
{
......
......@@ -12439,10 +12439,10 @@ static void M(object o)
}
}
";
var comp = CreateCompilationWithMscorlib(text);
var regularComp = CreateCompilationWithMscorlib(text);
// these diagnostics correspond to those produced by the native compiler.
comp.VerifyDiagnostics(
regularComp.VerifyDiagnostics(
// (9,11): error CS0039: Cannot convert type 'int' to 'C' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
// M(1 as C);
Diagnostic(ErrorCode.ERR_NoExplicitBuiltinConv, "1 as C").WithArguments("int", "C").WithLocation(9, 11),
......@@ -12461,8 +12461,8 @@ static void M(object o)
);
// in strict mode we also diagnose "is" and "as" operators with a static type.
comp = comp.WithOptions(comp.Options.WithFeatures(new string[] { "strict" }.ToImmutableArray()));
comp.VerifyDiagnostics(
var strictComp = CreateCompilationWithMscorlib(text, parseOptions: TestOptions.Regular.WithStrictFeature());
strictComp.VerifyDiagnostics(
// In the native compiler these three produce no errors.
Diagnostic(ErrorCode.ERR_StaticInAsOrIs, "o as C").WithArguments("C"),
......
......@@ -615,7 +615,7 @@ public void Invoke()
}
";
var comp1 = CreateCompilation(source1, WinRtRefs, TestOptions.ReleaseWinMD, "Lib");
var comp1 = CreateCompilation(source1, WinRtRefs, TestOptions.ReleaseWinMD, TestOptions.Regular, "Lib");
var serializationRef = TestReferences.NetFx.v4_0_30319.System_Runtime_Serialization;
......
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis
{
......@@ -622,7 +623,7 @@ private static string UnquoteAndUnescape(string v)
// unescape escaped \" and \\
for(int i = 0; i < split.Length; i++)
for (int i = 0; i < split.Length; i++)
{
if (split[i].IndexOf('\\') >= 0)
{
......@@ -957,6 +958,31 @@ private IEnumerable<CommandLineSourceFile> ExpandFileNamePattern(string path, st
}
}
internal static ImmutableDictionary<string, string> ParseFeatures(List<string> values)
{
var set = ImmutableDictionary.CreateBuilder<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (var commaFeatures in values)
{
foreach (var feature in commaFeatures.Split(','))
{
int equals = feature.IndexOf('=');
if (equals > 0)
{
string name = feature.Substring(0, equals);
string value = feature.Substring(equals + 1);
set[name] = value;
}
else
{
set[feature] = "true";
}
}
}
return set.ToImmutable();
}
internal abstract void GenerateErrorForNoFilesFoundInRecurse(string path, IList<Diagnostic> errors);
internal ReportDiagnostic GetDiagnosticOptionsFromRulesetFile(Dictionary<string, ReportDiagnostic> diagnosticOptions, IList<Diagnostic> diagnostics, string path, string baseDirectory)
......
......@@ -51,7 +51,7 @@ public abstract partial class Compilation
/// </summary>
private SmallDictionary<int, bool> _lazyMakeMemberMissingMap;
private Dictionary<string, string> _lazyFeatures;
private readonly IReadOnlyDictionary<string, string> _features;
internal Compilation(
string name,
......@@ -79,6 +79,37 @@ public abstract partial class Compilation
{
_lazySubmissionSlotIndex = SubmissionSlotIndexNotApplicable;
}
_features = SyntaxTreeCommonFeatures(syntaxTreeOrdinalMap.Keys);
}
IReadOnlyDictionary<string, string> SyntaxTreeCommonFeatures(IEnumerable<SyntaxTree> trees)
{
IReadOnlyDictionary<string, string> set = null;
foreach (var tree in trees)
{
var treeFeatures = tree.Options.Features;
if (set == null)
{
set = treeFeatures;
}
else
{
if ((object)set != treeFeatures && !set.SetEquals(treeFeatures))
{
throw new ArgumentException("inconsistent syntax tree features", nameof(trees));
}
}
}
if (set == null)
{
// Edge case where there are no syntax trees
set = ImmutableDictionary<string, string>.Empty;
}
return set;
}
internal abstract AnalyzerDriver AnalyzerForLanguage(ImmutableArray<DiagnosticAnalyzer> analyzers, AnalyzerManager analyzerManager, CancellationToken cancellationToken);
......@@ -1834,32 +1865,8 @@ private static EmitResult ToEmitResultAndFree(DiagnosticBag diagnostics, bool su
internal string Feature(string p)
{
if (_lazyFeatures == null)
{
var set = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (Options.Features != null)
{
foreach (var feature in Options.Features)
{
int colon = feature.IndexOf(':');
if (colon > 0)
{
string name = feature.Substring(0, colon);
string value = feature.Substring(colon + 1);
set[name] = value;
}
else
{
set[feature] = "true";
}
}
}
Interlocked.CompareExchange(ref _lazyFeatures, set, null);
}
string v;
return _lazyFeatures.TryGetValue(p, out v) ? v : null;
return _features.TryGetValue(p, out v) ? v : null;
}
#endregion
......
......@@ -187,7 +187,18 @@ public abstract class CompilationOptions
/// <summary>
/// A set of strings designating experimental compiler features that are to be enabled.
/// </summary>
protected internal ImmutableArray<string> Features { get; protected set; }
[Obsolete]
protected internal ImmutableArray<string> Features
{
get
{
throw new NotImplementedException();
}
protected set
{
throw new NotImplementedException();
}
}
private readonly Lazy<ImmutableArray<Diagnostic>> _lazyErrors;
......@@ -214,8 +225,7 @@ public abstract class CompilationOptions
MetadataReferenceResolver metadataReferenceResolver,
AssemblyIdentityComparer assemblyIdentityComparer,
StrongNameProvider strongNameProvider,
MetadataImportOptions metadataImportOptions,
ImmutableArray<string> features)
MetadataImportOptions metadataImportOptions)
{
this.OutputKind = outputKind;
this.ModuleName = moduleName;
......@@ -239,7 +249,6 @@ public abstract class CompilationOptions
this.StrongNameProvider = strongNameProvider;
this.AssemblyIdentityComparer = assemblyIdentityComparer ?? AssemblyIdentityComparer.Default;
this.MetadataImportOptions = metadataImportOptions;
this.Features = features;
_lazyErrors = new Lazy<ImmutableArray<Diagnostic>>(() =>
{
......@@ -359,11 +368,6 @@ public CompilationOptions WithStrongNameProvider(StrongNameProvider provider)
return CommonWithStrongNameProvider(provider);
}
internal CompilationOptions WithFeatures(ImmutableArray<string> features)
{
return CommonWithFeatures(features);
}
protected abstract CompilationOptions CommonWithOutputKind(OutputKind kind);
protected abstract CompilationOptions CommonWithPlatform(Platform platform);
protected abstract CompilationOptions CommonWithOptimizationLevel(OptimizationLevel value);
......@@ -375,6 +379,7 @@ internal CompilationOptions WithFeatures(ImmutableArray<string> features)
protected abstract CompilationOptions CommonWithGeneralDiagnosticOption(ReportDiagnostic generalDiagnosticOption);
protected abstract CompilationOptions CommonWithSpecificDiagnosticOptions(ImmutableDictionary<string, ReportDiagnostic> specificDiagnosticOptions);
protected abstract CompilationOptions CommonWithSpecificDiagnosticOptions(IEnumerable<KeyValuePair<string, ReportDiagnostic>> specificDiagnosticOptions);
[Obsolete]
protected abstract CompilationOptions CommonWithFeatures(ImmutableArray<string> features);
/// <summary>
......@@ -423,8 +428,7 @@ protected bool EqualsHelper(CompilationOptions other)
object.Equals(this.XmlReferenceResolver, other.XmlReferenceResolver) &&
object.Equals(this.SourceReferenceResolver, other.SourceReferenceResolver) &&
object.Equals(this.StrongNameProvider, other.StrongNameProvider) &&
object.Equals(this.AssemblyIdentityComparer, other.AssemblyIdentityComparer) &&
this.Features.SequenceEqual(other.Features, StringComparer.Ordinal);
object.Equals(this.AssemblyIdentityComparer, other.AssemblyIdentityComparer);
return equal;
}
......@@ -453,8 +457,7 @@ protected int GetHashCodeHelper()
Hash.Combine(this.XmlReferenceResolver,
Hash.Combine(this.SourceReferenceResolver,
Hash.Combine(this.StrongNameProvider,
Hash.Combine(this.AssemblyIdentityComparer,
Hash.Combine(Hash.CombineValues(this.Features, StringComparer.Ordinal), 0))))))))))))))))))))));
Hash.Combine(this.AssemblyIdentityComparer, 0)))))))))))))))))))));
}
public static bool operator ==(CompilationOptions left, CompilationOptions right)
......
......@@ -48,7 +48,7 @@ protected override CompilationOptions CompilationOptionsReleaseDll
get { throw new NotImplementedException(); }
}
protected override Compilation GetCompilationForEmit(IEnumerable<string> source, IEnumerable<MetadataReference> additionalRefs, CompilationOptions options)
protected override Compilation GetCompilationForEmit(IEnumerable<string> source, IEnumerable<MetadataReference> additionalRefs, CompilationOptions options, ParseOptions parseOptions)
{
throw new NotImplementedException();
}
......
......@@ -28,9 +28,10 @@ public abstract class CSharpTestBase : CSharpTestBaseBase
protected new CSharpCompilation GetCompilationForEmit(
IEnumerable<string> source,
IEnumerable<MetadataReference> additionalRefs,
CompilationOptions options)
CompilationOptions options,
ParseOptions parseOptions)
{
return (CSharpCompilation)base.GetCompilationForEmit(source, additionalRefs, options);
return (CSharpCompilation)base.GetCompilationForEmit(source, additionalRefs, options, parseOptions);
}
internal new IEnumerable<ModuleSymbol> ReferencesToModuleSymbols(IEnumerable<MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
......@@ -73,6 +74,7 @@ private Action<IModuleSymbol> Translate(Action<ModuleSymbol> action)
SignatureDescription[] expectedSignatures = null,
string expectedOutput = null,
CompilationOptions options = null,
ParseOptions parseOptions = null,
bool collectEmittedAssembly = true,
bool verify = true)
{
......@@ -87,6 +89,7 @@ private Action<IModuleSymbol> Translate(Action<ModuleSymbol> action)
expectedSignatures: expectedSignatures,
expectedOutput: expectedOutput,
options: options,
parseOptions: parseOptions,
collectEmittedAssembly: collectEmittedAssembly,
verify: verify);
}
......@@ -171,6 +174,7 @@ private Action<IModuleSymbol> Translate(Action<ModuleSymbol> action)
SignatureDescription[] expectedSignatures = null,
string expectedOutput = null,
CompilationOptions options = null,
ParseOptions parseOptions = null,
bool collectEmittedAssembly = true,
bool verify = true)
{
......@@ -185,6 +189,7 @@ private Action<IModuleSymbol> Translate(Action<ModuleSymbol> action)
expectedSignatures,
expectedOutput,
options,
parseOptions,
collectEmittedAssembly,
verify);
}
......@@ -277,24 +282,24 @@ public static SyntaxTree Parse(string text, string filename = "", CSharpParseOpt
return SyntaxFactory.ParseSyntaxTree(stringText, options, filename);
}
public static SyntaxTree[] Parse(IEnumerable<string> sources)
public static SyntaxTree[] Parse(IEnumerable<string> sources, CSharpParseOptions options = null)
{
if (sources == null || !sources.Any())
{
return new SyntaxTree[] { };
}
return Parse(sources.ToArray());
return Parse(options, sources.ToArray());
}
public static SyntaxTree[] Parse(params string[] sources)
public static SyntaxTree[] Parse(CSharpParseOptions options = null, params string[] sources)
{
if (sources == null || (sources.Length == 1 && null == sources[0]))
{
return new SyntaxTree[] { };
}
return sources.Select(src => Parse(src)).ToArray();
return sources.Select(src => Parse(src, options: options)).ToArray();
}
public static SyntaxTree ParseWithRoundTripCheck(string text, CSharpParseOptions options = null)
......@@ -389,11 +394,12 @@ public static SyntaxTree ParseWithRoundTripCheck(string text, CSharpParseOptions
public static CSharpCompilation CreateCompilationWithMscorlib45AndCSruntime(
string text,
CSharpCompilationOptions options = null)
CSharpCompilationOptions options = null,
CSharpParseOptions parseOptions = null)
{
var refs = new List<MetadataReference>() { MscorlibRef_v4_0_30316_17626, SystemCoreRef, CSharpRef };
return CreateCompilation(new[] { Parse(text) }, refs, options);
return CreateCompilation(new[] { Parse(text, options: parseOptions) }, refs, options);
}
......@@ -401,9 +407,10 @@ public static SyntaxTree ParseWithRoundTripCheck(string text, CSharpParseOptions
IEnumerable<string> sources,
IEnumerable<MetadataReference> references = null,
CSharpCompilationOptions options = null,
CSharpParseOptions parseOptions = null,
string assemblyName = "")
{
return CreateCompilationWithMscorlib(Parse(sources), references, options, assemblyName);
return CreateCompilationWithMscorlib(Parse(sources, parseOptions), references, options, assemblyName);
}
public static CSharpCompilation CreateCompilationWithMscorlib(
......@@ -466,18 +473,20 @@ public static SyntaxTree ParseWithRoundTripCheck(string text, CSharpParseOptions
string source,
IEnumerable<MetadataReference> references = null,
CSharpCompilationOptions options = null,
CSharpParseOptions parseOptions = null,
string assemblyName = "")
{
return CreateCompilation(new[] { Parse(source) }, references, options, assemblyName);
return CreateCompilation(new[] { Parse(source, options: parseOptions) }, references, options, assemblyName);
}
public static CSharpCompilation CreateCompilation(
IEnumerable<string> sources,
IEnumerable<MetadataReference> references = null,
CSharpCompilationOptions options = null,
CSharpParseOptions parseOptions = null,
string assemblyName = "")
{
return CreateCompilation(Parse(sources), references, options, assemblyName);
return CreateCompilation(Parse(sources, parseOptions), references, options, assemblyName);
}
public static CSharpCompilation CreateCompilation(
......@@ -508,9 +517,10 @@ public static SyntaxTree ParseWithRoundTripCheck(string text, CSharpParseOptions
AssemblyIdentity identity,
string[] sources,
MetadataReference[] references,
CSharpCompilationOptions options = null)
CSharpCompilationOptions options = null,
CSharpParseOptions parseOptions = null)
{
var trees = (sources == null) ? null : sources.Select(s => Parse(s)).ToArray();
var trees = (sources == null) ? null : sources.Select(s => Parse(s, options: parseOptions)).ToArray();
var c = CSharpCompilation.Create(identity.Name, options: options ?? TestOptions.ReleaseDll, references: references, syntaxTrees: trees);
Assert.NotNull(c.Assembly); // force creation of SourceAssemblySymbol
......@@ -551,12 +561,14 @@ public CompilationVerifier CompileWithCustomILSource(string cSharpSource, string
protected override Compilation GetCompilationForEmit(
IEnumerable<string> source,
IEnumerable<MetadataReference> additionalRefs,
CompilationOptions options)
CompilationOptions options,
ParseOptions parseOptions)
{
return CreateCompilationWithMscorlib(
source,
references: additionalRefs,
options: (CSharpCompilationOptions)options,
parseOptions: (CSharpParseOptions)parseOptions,
assemblyName: GetUniqueName());
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities
{
......@@ -35,13 +37,19 @@ public static class TestOptions
public static readonly CSharpCompilationOptions UnsafeDebugDll = DebugDll.WithAllowUnsafe(true);
public static readonly CSharpCompilationOptions UnsafeDebugExe = DebugExe.WithAllowUnsafe(true);
public static CSharpCompilationOptions WithStrictMode(this CSharpCompilationOptions options)
public static CSharpParseOptions WithFeature(this CSharpParseOptions options, string feature, string value)
{
return options.WithFeatures(options.Features.Add("strict"));
return options.WithFeatures(options.Features.Concat(new[] { new KeyValuePair<string, string>(feature, value) }));
}
public static CSharpCompilation WithStrictMode(this CSharpCompilation compilation)
public static CSharpParseOptions WithStrictFeature(this CSharpParseOptions options)
{
return options.WithFeature("strict", "true");
}
public static CSharpParseOptions WithDeterministicFeature(this CSharpParseOptions options)
{
return compilation.WithOptions(compilation.Options.WithFeatures(compilation.Options.Features.Add("strict")));
return options.WithFeature("deterministic", "true");
}
}
}
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports System.Linq
Imports System.Xml.Linq
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.Test.Utilities
......@@ -14,9 +15,10 @@ Public MustInherit Class BasicTestBase
Protected Overloads Function GetCompilationForEmit(
source As IEnumerable(Of String),
additionalRefs() As MetadataReference,
options As VisualBasicCompilationOptions
options As VisualBasicCompilationOptions,
parseOptions As VisualBasicParseOptions
) As VisualBasicCompilation
Return DirectCast(MyBase.GetCompilationForEmit(source, additionalRefs, options), VisualBasicCompilation)
Return DirectCast(MyBase.GetCompilationForEmit(source, additionalRefs, options, parseOptions), VisualBasicCompilation)
End Function
Private Function Translate(action As Action(Of ModuleSymbol)) As Action(Of IModuleSymbol, TestEmitters)
......@@ -483,11 +485,12 @@ Public MustInherit Class BasicTestBaseBase
Protected Overrides Function GetCompilationForEmit(
source As IEnumerable(Of String),
additionalRefs As IEnumerable(Of MetadataReference),
options As CompilationOptions
options As CompilationOptions,
parseOptions As ParseOptions
) As Compilation
Return VisualBasicCompilation.Create(
GetUniqueName(),
syntaxTrees:=source.Select(Function(t) VisualBasicSyntaxTree.ParseText(t)),
syntaxTrees:=source.Select(Function(t) VisualBasicSyntaxTree.ParseText(t, options:=DirectCast(parseOptions, VisualBasicParseOptions))),
references:=If(additionalRefs IsNot Nothing, DefaultReferences.Concat(additionalRefs), DefaultReferences),
options:=DirectCast(options, VisualBasicCompilationOptions))
End Function
......
......@@ -18,8 +18,9 @@ Friend Module CompilationUtils
Public Function CreateCompilationWithMscorlib(sourceTrees As IEnumerable(Of String),
Optional references As IEnumerable(Of MetadataReference) = Nothing,
Optional options As VisualBasicCompilationOptions = Nothing,
Optional assemblyName As String = Nothing) As VisualBasicCompilation
Return VisualBasicCompilation.Create(If(assemblyName, "Test"), sourceTrees.Select(Function(s) VisualBasicSyntaxTree.ParseText(s)), If(references Is Nothing, {MscorlibRef}, {MscorlibRef}.Concat(references)), options)
Optional assemblyName As String = Nothing,
Optional parseOptions As VisualBasicParseOptions = Nothing) As VisualBasicCompilation
Return VisualBasicCompilation.Create(If(assemblyName, "Test"), sourceTrees.Select(Function(s) VisualBasicSyntaxTree.ParseText(s, parseOptions)), If(references Is Nothing, {MscorlibRef}, {MscorlibRef}.Concat(references)), options)
End Function
Public Function CreateCompilationWithMscorlib(sourceTrees As IEnumerable(Of SyntaxTree),
......
......@@ -24,12 +24,17 @@ End Class
Friend Module TestOptionExtensions
<Extension()>
Public Function WithStrictMode(options As VisualBasicCompilationOptions) As VisualBasicCompilationOptions
Return options.WithFeatures(options.Features.Add("strict"))
Public Function WithFeature(options As VisualBasicParseOptions, feature As String, value As String) As VisualBasicParseOptions
Return options.WithFeatures(options.Features.Concat({New KeyValuePair(Of String, String)(feature, value)}))
End Function
<Extension()>
Public Function WithStrictMode(compilation As VisualBasicCompilation) As VisualBasicCompilation
Return compilation.WithOptions(compilation.Options.WithStrictMode())
Public Function WithStrictFeature(options As VisualBasicParseOptions) As VisualBasicParseOptions
Return options.WithFeature("Strict", "true")
End Function
<Extension()>
Public Function WithDeterministicFeature(options As VisualBasicParseOptions) As VisualBasicParseOptions
Return options.WithFeature("Deterministic", "true")
End Function
End Module
......@@ -1138,7 +1138,7 @@ lVbRuntimePlus:
documentationMode:=If(parseDocumentationComments, DocumentationMode.Diagnose, DocumentationMode.None),
kind:=SourceCodeKind.Regular,
preprocessorSymbols:=AddPredefinedPreprocessorSymbols(outputKind, defines.AsImmutableOrEmpty()),
features:=features.ToImmutableDictionary(Function(feature) feature, Function(feature) "true"))
features:=ParseFeatures(features))
Dim scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script)
......@@ -1163,8 +1163,7 @@ lVbRuntimePlus:
generalDiagnosticOption:=generalDiagnosticOption,
specificDiagnosticOptions:=specificDiagnosticOptions,
optimizationLevel:=If(optimize, OptimizationLevel.Release, OptimizationLevel.Debug),
parseOptions:=parseOptions,
features:=features.AsImmutable())
parseOptions:=parseOptions)
Dim emitOptions = New EmitOptions(
metadataOnly:=False,
......
......@@ -122,73 +122,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
metadataReferenceResolver:=metadataReferenceResolver,
assemblyIdentityComparer:=assemblyIdentityComparer,
strongNameProvider:=strongNameProvider,
metadataImportOptions:=MetadataImportOptions.Public,
features:=ImmutableArray(Of String).Empty)
End Sub
Friend Sub New(
outputKind As OutputKind,
features As ImmutableArray(Of String),
Optional moduleName As String = Nothing,
Optional mainTypeName As String = Nothing,
Optional scriptClassName As String = WellKnownMemberNames.DefaultScriptClassName,
Optional globalImports As IEnumerable(Of GlobalImport) = Nothing,
Optional rootNamespace As String = Nothing,
Optional optionStrict As OptionStrict = OptionStrict.Off,
Optional optionInfer As Boolean = True,
Optional optionExplicit As Boolean = True,
Optional optionCompareText As Boolean = False,
Optional parseOptions As VisualBasicParseOptions = Nothing,
Optional embedVbCoreRuntime As Boolean = False,
Optional optimizationLevel As OptimizationLevel = OptimizationLevel.Debug,
Optional checkOverflow As Boolean = True,
Optional cryptoKeyContainer As String = Nothing,
Optional cryptoKeyFile As String = Nothing,
Optional cryptoPublicKey As ImmutableArray(Of Byte) = Nothing,
Optional delaySign As Boolean? = Nothing,
Optional platform As Platform = Platform.AnyCpu,
Optional generalDiagnosticOption As ReportDiagnostic = ReportDiagnostic.Default,
Optional specificDiagnosticOptions As IEnumerable(Of KeyValuePair(Of String, ReportDiagnostic)) = Nothing,
Optional concurrentBuild As Boolean = True,
Optional xmlReferenceResolver As XmlReferenceResolver = Nothing,
Optional sourceReferenceResolver As SourceReferenceResolver = Nothing,
Optional metadataReferenceResolver As MetadataReferenceResolver = Nothing,
Optional assemblyIdentityComparer As AssemblyIdentityComparer = Nothing,
Optional strongNameProvider As StrongNameProvider = Nothing)
MyClass.New(
outputKind,
moduleName,
mainTypeName,
scriptClassName,
globalImports,
rootNamespace,
optionStrict,
optionInfer,
optionExplicit,
optionCompareText,
parseOptions,
embedVbCoreRuntime,
optimizationLevel,
checkOverflow,
cryptoKeyContainer,
cryptoKeyFile,
cryptoPublicKey,
delaySign,
platform,
generalDiagnosticOption,
specificDiagnosticOptions,
concurrentBuild,
suppressEmbeddedDeclarations:=False,
extendedCustomDebugInformation:=True,
xmlReferenceResolver:=xmlReferenceResolver,
sourceReferenceResolver:=sourceReferenceResolver,
metadataReferenceResolver:=metadataReferenceResolver,
assemblyIdentityComparer:=assemblyIdentityComparer,
strongNameProvider:=strongNameProvider,
metadataImportOptions:=MetadataImportOptions.Public,
features:=features)
metadataImportOptions:=MetadataImportOptions.Public)
End Sub
......@@ -222,8 +156,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
metadataReferenceResolver As MetadataReferenceResolver,
assemblyIdentityComparer As AssemblyIdentityComparer,
strongNameProvider As StrongNameProvider,
metadataImportOptions As MetadataImportOptions,
features As ImmutableArray(Of String))
metadataImportOptions As MetadataImportOptions)
MyBase.New(
outputKind:=outputKind,
......@@ -247,8 +180,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
metadataReferenceResolver:=metadataReferenceResolver,
assemblyIdentityComparer:=assemblyIdentityComparer,
strongNameProvider:=strongNameProvider,
metadataImportOptions:=metadataImportOptions,
features:=features)
metadataImportOptions:=metadataImportOptions)
_globalImports = globalImports.AsImmutableOrEmpty()
_rootNamespace = If(rootNamespace, String.Empty)
......@@ -295,8 +227,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
metadataReferenceResolver:=other.MetadataReferenceResolver,
assemblyIdentityComparer:=other.AssemblyIdentityComparer,
strongNameProvider:=other.StrongNameProvider,
metadataImportOptions:=other.MetadataImportOptions,
features:=other.Features)
metadataImportOptions:=other.MetadataImportOptions)
End Sub
''' <summary>
......@@ -689,14 +620,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return New VisualBasicCompilationOptions(Me) With {.Platform = value}
End Function
Friend Shadows Function WithFeatures(features As ImmutableArray(Of String)) As VisualBasicCompilationOptions
If features = Me.Features Then
Return Me
End If
Return New VisualBasicCompilationOptions(Me) With {.Features = features}
End Function
Protected Overrides Function CommonWithGeneralDiagnosticOption(value As ReportDiagnostic) As CompilationOptions
Return Me.WithGeneralDiagnosticOption(value)
End Function
......@@ -709,8 +632,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Me.WithSpecificDiagnosticOptions(specificDiagnosticOptions)
End Function
<Obsolete>
Protected Overrides Function CommonWithFeatures(features As ImmutableArray(Of String)) As CompilationOptions
Return Me.WithFeatures(features)
Throw New NotImplementedException()
End Function
''' <summary>
......
......@@ -285,7 +285,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Throw New ArgumentException(NameOf(features))
End If
Return New VisualBasicParseOptions(Me) With {._features = features.ToImmutableDictionary()}
Return New VisualBasicParseOptions(Me) With {._features = features.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase)}
End Function
Public Overrides ReadOnly Property Features As IReadOnlyDictionary(Of String, String)
......
......@@ -762,7 +762,7 @@ a.vb
<Fact>
Public Sub ManagedResourceOptions()
Dim parsedArgs As VisualBasicCommandLineArguments
Dim resourceDescription As resourceDescription
Dim resourceDescription As ResourceDescription
parsedArgs = DefaultParse({"/resource:a", "a.vb"}, _baseDirectory)
parsedArgs.Errors.Verify()
......@@ -5182,22 +5182,22 @@ End Module
Dim outputFileName As String
Dim target As String
Select Case outputKind
Case outputKind.ConsoleApplication
Case OutputKind.ConsoleApplication
outputFileName = "Test.exe"
target = "exe"
Case outputKind.WindowsApplication
Case OutputKind.WindowsApplication
outputFileName = "Test.exe"
target = "winexe"
Case outputKind.DynamicallyLinkedLibrary
Case OutputKind.DynamicallyLinkedLibrary
outputFileName = "Test.dll"
target = "library"
Case outputKind.NetModule
Case OutputKind.NetModule
outputFileName = "Test.netmodule"
target = "module"
Case outputKind.WindowsRuntimeMetadata
Case OutputKind.WindowsRuntimeMetadata
outputFileName = "Test.winmdobj"
target = "winmdobj"
Case outputKind.WindowsRuntimeApplication
Case OutputKind.WindowsRuntimeApplication
outputFileName = "Test.exe"
target = "appcontainerexe"
Case Else
......@@ -5231,7 +5231,7 @@ End Module
End If
Const resourceType As String = "#24"
Dim resourceId As String = If(outputKind = outputKind.DynamicallyLinkedLibrary, "#2", "#1")
Dim resourceId As String = If(outputKind = OutputKind.DynamicallyLinkedLibrary, "#2", "#1")
Dim manifestSize As UInteger = Nothing
If expectedManifest Is Nothing Then
......@@ -6026,39 +6026,31 @@ C:\*.vb(100) : error BC30451: 'Foo' is not declared. It may be inaccessible due
Public Sub ParseFeatures()
Dim args = DefaultParse({"/features:Test", "a.vb"}, _baseDirectory)
args.Errors.Verify()
Assert.Equal("Test", args.CompilationOptions.Features.Single())
Assert.Equal("Test", args.ParseOptions.Features.Single().Key)
args = DefaultParse({"/features:Test", "a.vb", "/Features:Experiment"}, _baseDirectory)
args.Errors.Verify()
Assert.Equal(2, args.CompilationOptions.Features.Length)
Assert.Equal("Test", args.CompilationOptions.Features(0))
Assert.Equal("Experiment", args.CompilationOptions.Features(1))
Assert.Equal(2, args.ParseOptions.Features.Count)
Assert.True(args.ParseOptions.Features.ContainsKey("Test"))
Assert.True(args.ParseOptions.Features.ContainsKey("Experiment"))
args = DefaultParse({"/features:Test:false,Key:value", "a.vb"}, _baseDirectory)
args = DefaultParse({"/features:Test=false,Key=value", "a.vb"}, _baseDirectory)
args.Errors.Verify()
Assert.Equal("Test:false,Key:value", args.CompilationOptions.Features.Single())
Assert.Equal("Test:false,Key:value", args.ParseOptions.Features.Single().Key)
Assert.True(args.ParseOptions.Features.SetEquals(New Dictionary(Of String, String) From {{"Test", "false"}, {"Key", "value"}}))
' We don't do any rigorous validation of /features arguments...
args = DefaultParse({"/features", "a.vb"}, _baseDirectory)
args.Errors.Verify()
Assert.Empty(args.CompilationOptions.Features)
Assert.Empty(args.ParseOptions.Features)
args = DefaultParse({"/features:,", "a.vb"}, _baseDirectory)
args.Errors.Verify()
Assert.Equal(",", args.CompilationOptions.Features.Single())
Assert.Equal(",", args.ParseOptions.Features.Single().Key)
Assert.Equal("", args.ParseOptions.Features.Single().Key)
args = DefaultParse({"/features:Test,", "a.vb"}, _baseDirectory)
args.Errors.Verify()
Assert.Equal("Test,", args.CompilationOptions.Features.Single())
Assert.Equal("Test,", args.ParseOptions.Features.Single().Key)
Assert.True(args.ParseOptions.Features.SetEquals(New Dictionary(Of String, String) From {{"Test", "true"}, {"", "true"}}))
End Sub
<Fact>
......
......@@ -14,9 +14,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Emit
Private Function GetBytesEmitted(source As String, platform As Platform, debug As Boolean) As ImmutableArray(Of Byte)
Dim options = If(debug, TestOptions.DebugExe, TestOptions.ReleaseExe).WithPlatform(platform)
options = options.WithFeatures({"dEtErmInIstIc"}.AsImmutable()) ' expect case-insensitivity
Dim compilation = CreateCompilationWithMscorlib({source}, assemblyName:="DeterminismTest", options:=options)
Dim compilation = CreateCompilationWithMscorlib({source}, assemblyName:="DeterminismTest", options:=options,
parseOptions:=TestOptions.Regular.WithFeature("dEtErmInIstIc", "true")) ' expect case-insensitivity
' The resolution of the PE header time date stamp is seconds, and we want to make sure
' that has an opportunity to change between calls to Emit.
......
......@@ -1410,8 +1410,7 @@ BC30799: Field 'Clazz.b' has an invalid constant value.
<Fact, WorkItem(1028, "https://github.com/dotnet/roslyn/issues/1028")>
Public Sub WriteOfReadonlySharedMemberOfAnotherInstantiation01()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib(
<compilation>
Dim source = <compilation>
<file name="a.vb">
Class Foo(Of T)
Shared Sub New()
......@@ -1425,15 +1424,19 @@ Class Foo(Of T)
Public Shared ReadOnly Property Y As Integer = 0
End Class
</file>
</compilation>, TestOptions.ReleaseDll)
</compilation>
Dim standardCompilation = CompilationUtils.CreateCompilationWithMscorlib(source, TestOptions.ReleaseDll)
Dim strictCompilation = CompilationUtils.CreateCompilationWithMscorlib(source, TestOptions.ReleaseDll,
parseOptions:=TestOptions.Regular.WithStrictFeature())
CompilationUtils.AssertTheseDiagnostics(compilation, <expected>
CompilationUtils.AssertTheseDiagnostics(standardCompilation, <expected>
BC30526: Property 'Y' is 'ReadOnly'.
Foo(Of Integer).Y = 12
~~~~~~~~~~~~~~~~~~~~~~
</expected>)
CompilationUtils.AssertTheseDiagnostics(compilation.WithStrictMode(), <expected>
CompilationUtils.AssertTheseDiagnostics(strictCompilation, <expected>
BC30064: 'ReadOnly' variable cannot be the target of an assignment.
Foo(Of Integer).X = 12
~~~~~~~~~~~~~~~~~
......@@ -1489,7 +1492,7 @@ String
Private Shared Function GetMember(sources As Xml.Linq.XElement, fieldName As String, Optional typeName As String = "C") As Symbol
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib(sources)
Dim symbol = DirectCast(compilation.SourceModule.GlobalNamespace.GetTypeMembers(typeName).Single.GetMembers(fieldName).Single(), symbol)
Dim symbol = DirectCast(compilation.SourceModule.GlobalNamespace.GetTypeMembers(typeName).Single.GetMembers(fieldName).Single(), Symbol)
Return symbol
End Function
......
......@@ -85,7 +85,8 @@ private static ImmutableArray<Emitter> LoadEmitters()
protected abstract Compilation GetCompilationForEmit(
IEnumerable<string> source,
IEnumerable<MetadataReference> additionalRefs,
CompilationOptions options);
CompilationOptions options,
ParseOptions parseOptions);
protected abstract CompilationOptions CompilationOptionsReleaseDll { get; }
......@@ -128,6 +129,7 @@ private static ImmutableArray<Emitter> Emitters
SignatureDescription[] expectedSignatures = null,
string expectedOutput = null,
CompilationOptions options = null,
ParseOptions parseOptions = null,
bool collectEmittedAssembly = true,
bool verify = true)
{
......@@ -142,6 +144,7 @@ private static ImmutableArray<Emitter> Emitters
expectedSignatures: expectedSignatures,
expectedOutput: expectedOutput,
options: options,
parseOptions: parseOptions,
collectEmittedAssembly: collectEmittedAssembly,
verify: verify);
}
......@@ -157,6 +160,7 @@ private static ImmutableArray<Emitter> Emitters
SignatureDescription[] expectedSignatures = null,
string expectedOutput = null,
CompilationOptions options = null,
ParseOptions parseOptions = null,
bool collectEmittedAssembly = true,
bool verify = true)
{
......@@ -165,7 +169,7 @@ private static ImmutableArray<Emitter> Emitters
options = CompilationOptionsReleaseDll.WithOutputKind((expectedOutput != null) ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary);
}
var compilation = GetCompilationForEmit(sources, additionalRefs, options);
var compilation = GetCompilationForEmit(sources, additionalRefs, options, parseOptions);
return this.CompileAndVerify(
compilation,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册