Add support for 'additionalArguments' in compilationOptions
Rather than keep a map that will have to be constantly updated every time a new argument gets added to a compiler, the 'additionalArguments' option will allow users to directly add arguments to the underlying compiler.
This commit is contained in:
parent
44ac20a4ce
commit
6ba581fc17
8 changed files with 125 additions and 18 deletions
|
@ -2,4 +2,5 @@ E2E
|
||||||
StreamForwarderTests
|
StreamForwarderTests
|
||||||
dotnet-publish.Tests
|
dotnet-publish.Tests
|
||||||
dotnet-compile.Tests
|
dotnet-compile.Tests
|
||||||
dotnet-build.Tests
|
dotnet-build.Tests
|
||||||
|
Compiler.Common.Tests
|
||||||
|
|
|
|
@ -36,6 +36,8 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
|
|
||||||
internal static readonly OptionTemplate s_generateXmlDocumentation = new OptionTemplate("generate-xml-documentation");
|
internal static readonly OptionTemplate s_generateXmlDocumentation = new OptionTemplate("generate-xml-documentation");
|
||||||
|
|
||||||
|
internal static readonly OptionTemplate s_additionalArgumentsTemplate = new OptionTemplate("additional-argument");
|
||||||
|
|
||||||
public static CommonCompilerOptions Parse(ArgumentSyntax syntax)
|
public static CommonCompilerOptions Parse(ArgumentSyntax syntax)
|
||||||
{
|
{
|
||||||
IReadOnlyList<string> defines = null;
|
IReadOnlyList<string> defines = null;
|
||||||
|
@ -50,6 +52,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
bool? publicSign = null;
|
bool? publicSign = null;
|
||||||
bool? emitEntryPoint = null;
|
bool? emitEntryPoint = null;
|
||||||
bool? generateXmlDocumentation = null;
|
bool? generateXmlDocumentation = null;
|
||||||
|
IReadOnlyList<string> additionalArguments = null;
|
||||||
|
|
||||||
Func<string, bool?> nullableBoolConverter = v => bool.Parse(v);
|
Func<string, bool?> nullableBoolConverter = v => bool.Parse(v);
|
||||||
|
|
||||||
|
@ -57,6 +60,8 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
|
|
||||||
syntax.DefineOptionList(s_suppressWarningTemplate.LongName, ref suppressWarnings, "Suppresses the specified warning");
|
syntax.DefineOptionList(s_suppressWarningTemplate.LongName, ref suppressWarnings, "Suppresses the specified warning");
|
||||||
|
|
||||||
|
syntax.DefineOptionList(s_additionalArgumentsTemplate.LongName, ref additionalArguments, "Pass the additional argument directly to the compiler");
|
||||||
|
|
||||||
syntax.DefineOption(s_languageVersionTemplate.LongName, ref languageVersion,
|
syntax.DefineOption(s_languageVersionTemplate.LongName, ref languageVersion,
|
||||||
"The version of the language used to compile");
|
"The version of the language used to compile");
|
||||||
|
|
||||||
|
@ -100,7 +105,8 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
DelaySign = delaySign,
|
DelaySign = delaySign,
|
||||||
PublicSign = publicSign,
|
PublicSign = publicSign,
|
||||||
EmitEntryPoint = emitEntryPoint,
|
EmitEntryPoint = emitEntryPoint,
|
||||||
GenerateXmlDocumentation = generateXmlDocumentation
|
GenerateXmlDocumentation = generateXmlDocumentation,
|
||||||
|
AdditionalArguments = additionalArguments
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +124,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
var publicSign = options.PublicSign;
|
var publicSign = options.PublicSign;
|
||||||
var emitEntryPoint = options.EmitEntryPoint;
|
var emitEntryPoint = options.EmitEntryPoint;
|
||||||
var generateXmlDocumentation = options.GenerateXmlDocumentation;
|
var generateXmlDocumentation = options.GenerateXmlDocumentation;
|
||||||
|
var additionalArguments = options.AdditionalArguments;
|
||||||
|
|
||||||
var args = new List<string>();
|
var args = new List<string>();
|
||||||
|
|
||||||
|
@ -131,6 +138,11 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
args.AddRange(suppressWarnings.Select(def => s_suppressWarningTemplate.ToLongArg(def)));
|
args.AddRange(suppressWarnings.Select(def => s_suppressWarningTemplate.ToLongArg(def)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (additionalArguments != null)
|
||||||
|
{
|
||||||
|
args.AddRange(additionalArguments.Select(arg => s_additionalArgumentsTemplate.ToLongArg(arg)));
|
||||||
|
}
|
||||||
|
|
||||||
if (languageVersion != null)
|
if (languageVersion != null)
|
||||||
{
|
{
|
||||||
args.Add(s_languageVersionTemplate.ToLongArg(languageVersion));
|
args.Add(s_languageVersionTemplate.ToLongArg(languageVersion));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
@ -34,6 +35,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public IEnumerable<string> SuppressWarnings { get; set; }
|
public IEnumerable<string> SuppressWarnings { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<string> AdditionalArguments { get; set; }
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
var other = obj as CommonCompilerOptions;
|
var other = obj as CommonCompilerOptions;
|
||||||
|
@ -49,15 +52,29 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
EmitEntryPoint == other.EmitEntryPoint &&
|
EmitEntryPoint == other.EmitEntryPoint &&
|
||||||
GenerateXmlDocumentation == other.GenerateXmlDocumentation &&
|
GenerateXmlDocumentation == other.GenerateXmlDocumentation &&
|
||||||
PreserveCompilationContext == other.PreserveCompilationContext &&
|
PreserveCompilationContext == other.PreserveCompilationContext &&
|
||||||
Enumerable.SequenceEqual(Defines ?? Enumerable.Empty<string>(), other.Defines ?? Enumerable.Empty<string>()) &&
|
EnumerableEquals(Defines, other.Defines) &&
|
||||||
Enumerable.SequenceEqual(SuppressWarnings ?? Enumerable.Empty<string>(), other.SuppressWarnings ?? Enumerable.Empty<string>());
|
EnumerableEquals(SuppressWarnings, other.SuppressWarnings) &&
|
||||||
|
EnumerableEquals(AdditionalArguments, other.AdditionalArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool EnumerableEquals(IEnumerable<string> left, IEnumerable<string> right)
|
||||||
|
=> Enumerable.SequenceEqual(left ?? Array.Empty<string>(), right ?? Array.Empty<string>());
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return base.GetHashCode();
|
return base.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> Combine(IEnumerable<string> @new, IEnumerable<string> old)
|
||||||
|
{
|
||||||
|
if (@new != null)
|
||||||
|
{
|
||||||
|
old = old ?? Array.Empty<string>();
|
||||||
|
return old.Concat(@new).Distinct().ToArray();
|
||||||
|
}
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
public static CommonCompilerOptions Combine(params CommonCompilerOptions[] options)
|
public static CommonCompilerOptions Combine(params CommonCompilerOptions[] options)
|
||||||
{
|
{
|
||||||
var result = new CommonCompilerOptions();
|
var result = new CommonCompilerOptions();
|
||||||
|
@ -69,18 +86,10 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defines and suppressions are always combined
|
// Defines, suppressions, and additional arguments are always combined
|
||||||
if (option.Defines != null)
|
result.Defines = Combine(option.Defines, result.Defines);
|
||||||
{
|
result.SuppressWarnings = Combine(option.SuppressWarnings, result.SuppressWarnings);
|
||||||
var existing = result.Defines ?? Enumerable.Empty<string>();
|
result.AdditionalArguments = Combine(option.AdditionalArguments, result.AdditionalArguments);
|
||||||
result.Defines = existing.Concat(option.Defines).Distinct();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option.SuppressWarnings != null)
|
|
||||||
{
|
|
||||||
var existing = result.SuppressWarnings ?? Enumerable.Empty<string>();
|
|
||||||
result.SuppressWarnings = existing.Concat(option.SuppressWarnings).Distinct();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option.LanguageVersion != null)
|
if (option.LanguageVersion != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -560,6 +560,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
Defines = rawOptions.ValueAsStringArray("define"),
|
Defines = rawOptions.ValueAsStringArray("define"),
|
||||||
SuppressWarnings = rawOptions.ValueAsStringArray("nowarn"),
|
SuppressWarnings = rawOptions.ValueAsStringArray("nowarn"),
|
||||||
|
AdditionalArguments = rawOptions.ValueAsStringArray("additionalArguments"),
|
||||||
LanguageVersion = rawOptions.ValueAsString("languageVersion"),
|
LanguageVersion = rawOptions.ValueAsString("languageVersion"),
|
||||||
AllowUnsafe = rawOptions.ValueAsNullableBoolean("allowUnsafe"),
|
AllowUnsafe = rawOptions.ValueAsNullableBoolean("allowUnsafe"),
|
||||||
Platform = rawOptions.ValueAsString("platform"),
|
Platform = rawOptions.ValueAsString("platform"),
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Csc
|
||||||
syntax.DefineOption("out", ref outputName, "Name of the output assembly");
|
syntax.DefineOption("out", ref outputName, "Name of the output assembly");
|
||||||
|
|
||||||
syntax.DefineOptionList("reference", ref references, "Path to a compiler metadata reference");
|
syntax.DefineOptionList("reference", ref references, "Path to a compiler metadata reference");
|
||||||
|
|
||||||
syntax.DefineOptionList("analyzer", ref analyzers, "Path to an analyzer assembly");
|
syntax.DefineOptionList("analyzer", ref analyzers, "Path to an analyzer assembly");
|
||||||
|
|
||||||
syntax.DefineOptionList("resource", ref resources, "Resources to embed");
|
syntax.DefineOptionList("resource", ref resources, "Resources to embed");
|
||||||
|
@ -147,6 +147,12 @@ namespace Microsoft.DotNet.Tools.Compiler.Csc
|
||||||
commonArgs.AddRange(options.SuppressWarnings.Select(w => $"-nowarn:{w}"));
|
commonArgs.AddRange(options.SuppressWarnings.Select(w => $"-nowarn:{w}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional arguments are added verbatim
|
||||||
|
if (options.AdditionalArguments != null)
|
||||||
|
{
|
||||||
|
commonArgs.AddRange(options.AdditionalArguments);
|
||||||
|
}
|
||||||
|
|
||||||
if (options.LanguageVersion != null)
|
if (options.LanguageVersion != null)
|
||||||
{
|
{
|
||||||
commonArgs.Add($"-langversion:{GetLanguageVersion(options.LanguageVersion)}");
|
commonArgs.Add($"-langversion:{GetLanguageVersion(options.LanguageVersion)}");
|
||||||
|
|
54
test/Compiler.Common.Tests/Tests.cs
Normal file
54
test/Compiler.Common.Tests/Tests.cs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.CommandLine;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
|
{
|
||||||
|
public class Tests : TestBase
|
||||||
|
{
|
||||||
|
private static void EqualAfterDeserialize(IEnumerable<string> args, CommonCompilerOptions original)
|
||||||
|
{
|
||||||
|
CommonCompilerOptions newOptions = null;
|
||||||
|
|
||||||
|
ArgumentSyntax.Parse(args, syntax =>
|
||||||
|
{
|
||||||
|
newOptions = CommonCompilerOptionsExtensions.Parse(syntax);
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal(original, newOptions);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleSerialize()
|
||||||
|
{
|
||||||
|
var options = new CommonCompilerOptions();
|
||||||
|
options.AdditionalArguments = new[] { "-highentropyva+" };
|
||||||
|
|
||||||
|
var args = options.SerializeToArgs();
|
||||||
|
Assert.Equal(new [] { "--additional-argument:-highentropyva+" }, args);
|
||||||
|
|
||||||
|
EqualAfterDeserialize(args, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WithSpaces()
|
||||||
|
{
|
||||||
|
var options = new CommonCompilerOptions();
|
||||||
|
options.AdditionalArguments = new[] { "-highentropyva+", "-addmodule:\"path with spaces\";\"after semicolon\"" };
|
||||||
|
|
||||||
|
var args = options.SerializeToArgs();
|
||||||
|
Assert.Equal(new [] {
|
||||||
|
"--additional-argument:-highentropyva+",
|
||||||
|
"--additional-argument:-addmodule:\"path with spaces\";\"after semicolon\""
|
||||||
|
}, args);
|
||||||
|
|
||||||
|
EqualAfterDeserialize(args, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
test/Compiler.Common.Tests/project.json
Normal file
23
test/Compiler.Common.Tests/project.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.0.0-rc2-23727",
|
||||||
|
"Microsoft.NETCore.TestHost" : "1.0.0-*",
|
||||||
|
|
||||||
|
"xunit": "2.1.0",
|
||||||
|
"xunit.console.netcore": "1.0.2-prerelease-00101",
|
||||||
|
"xunit.netcore.extensions": "1.0.0-prerelease-*",
|
||||||
|
"xunit.runner.utility": "2.1.0",
|
||||||
|
|
||||||
|
"Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" },
|
||||||
|
"Microsoft.DotNet.ProjectModel": { "target": "project" },
|
||||||
|
"Microsoft.DotNet.Compiler.Common": { "target": "project" }
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnxcore50": {
|
||||||
|
"imports": "portable-net45+win8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,8 @@
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
"compilationOptions": {
|
"compilationOptions": {
|
||||||
"nowarn": [ "CS1591" ],
|
"nowarn": [ "CS1591" ],
|
||||||
"xmlDoc": true
|
"xmlDoc": true,
|
||||||
|
"additionalArguments": [ "-highentropyva+" ]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"NETStandard.Library": "1.0.0-rc2-23727"
|
"NETStandard.Library": "1.0.0-rc2-23727"
|
||||||
|
|
Loading…
Reference in a new issue