Skip to content

Commit d94d393

Browse files
Merge pull request #102 from aspnet/AddProviderOptions
Add provider options
2 parents ae9ffff + aab6fdb commit d94d393

29 files changed

Lines changed: 712 additions & 235 deletions

Clean.cmd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ set logOptions=/v:n /flp:Summary;Verbosity=diag;LogFile=msbuild.log /flp1:warnin
1313
REM set logOptions=/v:diag /flp:Summary;Verbosity=diag;LogFile=msbuild.log /flp1:warningsonly;logfile=msbuild.wrn /flp2:errorsonly;logfile=msbuild.err
1414

1515
%MSBUILDEXE% "%~dp0\RoslynCodeProvider.msbuild" /t:Clean %logOptions% /maxcpucount /nodeReuse:false %cfgOption%%*
16+
rd /q /s Roslyn45
17+
rd /q /s Roslyn46
18+
rd /q /s Roslyn472
19+
rd /q /s RoslynLatest
1620
del /F msbuild.log
1721
del /F msbuild.wrn
1822
del /F msbuild.err

RoslynCodeProviderTest/App.config

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<system.codedom>
4+
<compilers>
5+
<compiler language="c#;cs;csharp" extension=".fakecs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701">
6+
<providerOption name="CompilerVersion" value="v6.0"/>
7+
<providerOption name="CompilerLocation" value="C:\Path\To\Nowhere\csc.exe"/>
8+
<providerOption name="CompilerServerTTL" value="42"/>
9+
<providerOption name="WarnAsError" value="true"/>
10+
<providerOption name="UseAspNetSettings" value="false"/>
11+
<providerOption name="CustomSetting" value="foo"/>
12+
<providerOption name="AnotherCoolSetting" value="bar"/>
13+
</compiler>
14+
<compiler language="vb;vbs;visualbasic;vbscript" extension=".fakevb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+">
15+
<providerOption name="CustomSetting" value="foo2"/>
16+
<providerOption name="AnotherCoolSetting" value="bar2"/>
17+
</compiler>
18+
</compilers>
19+
</system.codedom>
20+
</configuration>

RoslynCodeProviderTest/CSharpProviderTest.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
2-
using Microsoft.VisualStudio.TestTools.UnitTesting;
1+
using System;
32
using System.CodeDom.Compiler;
43
using System.IO;
4+
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
56

67
namespace Microsoft.CodeDom.Providers.DotNetCompilerPlatformTest {
78

@@ -13,10 +14,10 @@ public class CSharpProviderTest {
1314

1415
[ClassInitialize]
1516
public static void ClassInitialize(TestContext testContext) {
16-
string frameworkFolder = Path.GetDirectoryName(typeof(object).Assembly.Location);
17-
string compilerPath = Path.Combine(frameworkFolder, "csc.exe");
18-
var codeDomProviderType = typeof(Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider);
17+
#pragma warning disable CS0618
1918
csharpCodeProvider = new CSharpCodeProvider(compilerSettings: CompilerSettingsHelper.CSC);
19+
#pragma warning restore CS0618
20+
AppContext.SetSwitch("Switch.System.DisableTempFileCollectionDirectoryFeature", true);
2021
}
2122

2223
[TestMethod]
@@ -112,5 +113,22 @@ public void CompileAssemblyFromDom() {
112113
public void CompileAssemblyFromFile() {
113114
commonTests.CompileAssemblyFromFile(csharpCodeProvider);
114115
}
116+
117+
[TestMethod]
118+
public void CompileAssemblyFromFile_ASPNet_Magic()
119+
{
120+
// Complete added frippery is: "/nowarn:1659;1699;1701;612;618"
121+
ProviderOptions opts = new ProviderOptions(CompilerSettingsHelper.CSC) { UseAspNetSettings = true };
122+
commonTests.CompileAssemblyFromFile_CheckArgs(new CSharpCodeProvider(opts), "/nowarn:1659;1699;1701;612;618", true);
123+
}
124+
125+
[TestMethod]
126+
public void CompileAssemblyFromFile_No_ASPNet_Magic()
127+
{
128+
// _codeProvider uses options (aka CompilerSettingsHelper.VB) created via constructor, so it should
129+
// have the ASP.Net frippery disabled.
130+
commonTests.CompileAssemblyFromFile_CheckArgs(csharpCodeProvider, "/nowarn:1659;1699;1701;612;618", false);
131+
}
132+
115133
}
116134
}

RoslynCodeProviderTest/CommonCodeDomProviderTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,19 @@ public void CompileAssemblyFromDom(CodeDomProvider provider) {
500500
}
501501

502502

503-
public void CompileAssemblyFromFile(CodeDomProvider provider) {
503+
public void CompileAssemblyFromFile(CodeDomProvider provider)
504+
{
505+
CompileAssemblyFromFile_CheckArgs(provider, null, false);
506+
}
507+
508+
public void CompileAssemblyFromFile_CheckArgs(CodeDomProvider provider, string argStringToFind, bool expected) {
504509
var sourcePath = Path.Combine(Path.GetTempPath(), "foobarSourcefile.cs");
505510
try {
506511
using (var sourceStream = File.Create(sourcePath)) {
507512
var content = "public class FooClass { public string Execute() { return \"output\";}}";
513+
// If we're checking cmd args, we actually want to fail compilation so we can examine output.
514+
if (argStringToFind != null)
515+
content = "nonsense that doesn't compile.";
508516
var bytes = Encoding.ASCII.GetBytes(content);
509517
sourceStream.Write(bytes, 0, bytes.Length);
510518
}
@@ -516,6 +524,13 @@ public void CompileAssemblyFromFile(CodeDomProvider provider) {
516524
sourcePath
517525
);
518526

527+
if (argStringToFind != null)
528+
{
529+
Assert.AreNotEqual(Success, result.NativeCompilerReturnValue);
530+
Assert.AreEqual<bool>(expected, result.Output[0].Contains(argStringToFind));
531+
return;
532+
}
533+
519534
Assert.AreEqual(Success, result.NativeCompilerReturnValue);
520535
var type = result.CompiledAssembly.GetType("FooClass");
521536
var obj = Activator.CreateInstance(type);

RoslynCodeProviderTest/CompilerSettingsHelper.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@
77
using System.Threading.Tasks;
88

99
namespace Microsoft.CodeDom.Providers.DotNetCompilerPlatformTest {
10+
11+
#pragma warning disable CS0618
12+
internal class TestCompilerSettings : ICompilerSettings {
13+
public string CompilerFullPath { get; set; }
14+
public int CompilerServerTimeToLive { get; set; }
15+
}
16+
1017
internal static class CompilerSettingsHelper {
1118

1219
private const int DefaultCompilerServerTTL = 0; // set TTL to 0 to turn of keepalive switch
1320

14-
private static ICompilerSettings _csc = new CompilerSettings(CompilerFullPath(@"csc.exe"), DefaultCompilerServerTTL);
15-
private static ICompilerSettings _vb = new CompilerSettings(CompilerFullPath(@"vbc.exe"), DefaultCompilerServerTTL);
21+
private static ICompilerSettings _csc = new ProviderOptions(CompilerFullPath(@"csc.exe"), DefaultCompilerServerTTL);
22+
private static ICompilerSettings _vb = new ProviderOptions(CompilerFullPath(@"vbc.exe"), DefaultCompilerServerTTL);
1623

1724
public static ICompilerSettings CSC {
1825
get {
@@ -33,4 +40,5 @@ private static string CompilerFullPath(string relativePath) {
3340
return compilerFullPath;
3441
}
3542
}
43+
#pragma warning restore CS0618
3644
}

RoslynCodeProviderTest/Microsoft.CodeDom.Providers.DotNetCompilerPlatformTest.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<AppDesignerFolder>Properties</AppDesignerFolder>
1010
<RootNamespace>Microsoft.CodeDom.Providers.DotNetCompilerPlatformTest</RootNamespace>
1111
<AssemblyName>Microsoft.CodeDom.Providers.DotNetCompilerPlatformTest</AssemblyName>
12-
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12+
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
1414
<SignAssembly>true</SignAssembly>
1515
<DelaySign>true</DelaySign>
@@ -27,6 +27,7 @@
2727
<OutputPath>$(TestOutputPath)</OutputPath>
2828
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
2929
<RestorePackages>true</RestorePackages>
30+
<TargetFrameworkProfile />
3031
</PropertyGroup>
3132
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
3233
<DebugSymbols>true</DebugSymbols>
@@ -45,6 +46,7 @@
4546
</PropertyGroup>
4647
<ItemGroup>
4748
<Reference Include="System" />
49+
<Reference Include="System.Configuration" />
4850
</ItemGroup>
4951
<Choose>
5052
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
@@ -63,6 +65,7 @@
6365
<Compile Include="CSharpProviderTest.cs" />
6466
<Compile Include="CompilerSettingsHelper.cs" />
6567
<Compile Include="Properties\AssemblyInfo.cs" />
68+
<Compile Include="ProviderOptionsTests.cs" />
6669
<Compile Include="VBCodeProviderTests.cs" />
6770
</ItemGroup>
6871
<ItemGroup>
@@ -71,6 +74,9 @@
7174
<Name>Microsoft.CodeDom.Providers.DotNetCompilerPlatform</Name>
7275
</ProjectReference>
7376
</ItemGroup>
77+
<ItemGroup>
78+
<None Include="App.config" />
79+
</ItemGroup>
7480
<Choose>
7581
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
7682
<ItemGroup>
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using System;
4+
using System.CodeDom.Compiler;
5+
using System.Collections.Generic;
6+
using System.Configuration;
7+
using System.IO;
8+
using System.Linq;
9+
using System.Reflection;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
13+
namespace Microsoft.CodeDom.Providers.DotNetCompilerPlatformTest {
14+
15+
16+
[TestClass]
17+
public class ProviderOptionsTests {
18+
19+
private const int Failed = 1;
20+
private const int Success = 0;
21+
22+
private static bool IsDev = false;
23+
24+
[ClassInitialize]
25+
public static void ClassInitialize(TestContext context) {
26+
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("DEV_ENVIRONMENT")) ||
27+
!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("IN_DEBUG_MODE")) ||
28+
CompilationUtil.IsDebuggerAttached)
29+
IsDev = true;
30+
}
31+
32+
[TestMethod]
33+
public void DefaultSettings()
34+
{
35+
IProviderOptions opts = CompilationUtil.GetProviderOptionsFor(".fakevb");
36+
Assert.IsNotNull(opts);
37+
Assert.AreEqual<string>(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\roslyn"), opts.CompilerFullPath); // Would include csc.exe or vbc.exe if the extension we searched for wasn't fake.
38+
Assert.AreEqual<int>(IsDev ? 15 * 60 : 10, opts.CompilerServerTimeToLive); // 10 in Production. 900 in a "dev" environment.
39+
Assert.IsTrue(opts.UseAspNetSettings); // Default is false... except through the GetProviderOptionsFor factory method we used here.
40+
Assert.IsFalse(opts.WarnAsError);
41+
Assert.IsNull(opts.CompilerVersion);
42+
Assert.AreEqual<int>(2, opts.AllOptions.Count);
43+
Assert.AreEqual<string>("foo2", opts.AllOptions["CustomSetting"]);
44+
Assert.AreEqual<string>("bar2", opts.AllOptions["AnotherCoolSetting"]);
45+
}
46+
47+
[TestMethod]
48+
public void FromShortConstructor()
49+
{
50+
IProviderOptions opts = new ProviderOptions(@"D:\My\Fun\Compiler\Path\compiles.exe", 123);
51+
Assert.IsNotNull(opts);
52+
Assert.AreEqual<string>(@"D:\My\Fun\Compiler\Path\compiles.exe", opts.CompilerFullPath); // Would include csc.exe or vbc.exe if the extension we searched for wasn't fake.
53+
Assert.AreEqual<int>(123, opts.CompilerServerTimeToLive); // 10 in Production. 900 in a "dev" environment.
54+
Assert.IsFalse(opts.UseAspNetSettings); // Default via constructor is false.
55+
Assert.IsFalse(opts.WarnAsError);
56+
Assert.IsNull(opts.CompilerVersion);
57+
Assert.AreEqual<int>(0, opts.AllOptions.Count);
58+
}
59+
60+
[TestMethod]
61+
public void FromICompilerSettings()
62+
{
63+
#pragma warning disable CS0618
64+
IProviderOptions opts = new ProviderOptions((ICompilerSettings)(CompilerSettingsHelper.CSC));
65+
#pragma warning restore CS0618
66+
Assert.IsNotNull(opts);
67+
Assert.AreEqual<string>(CompilerSettingsHelper.CSC.CompilerFullPath, opts.CompilerFullPath); // Would include csc.exe or vbc.exe if the extension we searched for wasn't fake.
68+
Assert.AreEqual<int>(CompilerSettingsHelper.CSC.CompilerServerTimeToLive, opts.CompilerServerTimeToLive); // 10 in Production. 900 in a "dev" environment.
69+
Assert.IsFalse(opts.UseAspNetSettings); // Default via constructor is false.
70+
Assert.IsFalse(opts.WarnAsError);
71+
Assert.IsNull(opts.CompilerVersion);
72+
Assert.AreEqual<int>(0, opts.AllOptions.Count);
73+
}
74+
75+
// <providerOptions> override defaults
76+
[TestMethod]
77+
public void FromProviderOptions()
78+
{
79+
IProviderOptions opts = CompilationUtil.GetProviderOptionsFor(".fakecs");
80+
Assert.IsNotNull(opts);
81+
Assert.AreEqual<string>(@"C:\Path\To\Nowhere\csc.exe", opts.CompilerFullPath);
82+
Assert.AreEqual<int>(42, opts.CompilerServerTimeToLive);
83+
Assert.IsFalse(opts.UseAspNetSettings);
84+
Assert.IsTrue(opts.WarnAsError);
85+
Assert.AreEqual<string>("v6.0", opts.CompilerVersion);
86+
Assert.AreEqual<int>(7, opts.AllOptions.Count);
87+
Assert.AreEqual<string>("foo", opts.AllOptions["CustomSetting"]);
88+
Assert.AreEqual<string>("bar", opts.AllOptions["AnotherCoolSetting"]);
89+
}
90+
91+
// <appSettings> override <providerOptions> for location only
92+
// Actually, we can't do this because A) AppSettings can be added but not cleaned up after this test, and
93+
// B) the setting has probably already been read and cached by the AppSettings utility class, so updating
94+
// the value here wouldn't have any affect anyway.
95+
//[TestMethod]
96+
public void FromAppSettings()
97+
{
98+
ConfigurationManager.AppSettings.Set("aspnet:RoslynCompilerLocation", @"C:\Location\for\all\from\appSettings\compiler.exe");
99+
IProviderOptions opts = CompilationUtil.GetProviderOptionsFor(".fakecs");
100+
ConfigurationManager.AppSettings.Remove("aspnet:RoslynCompilerLocation");
101+
102+
Assert.IsNotNull(opts);
103+
Assert.AreEqual<string>(@"C:\Location\for\all\from\appSettings\compiler.exe", opts.CompilerFullPath);
104+
Assert.AreEqual<int>(42, opts.CompilerServerTimeToLive);
105+
Assert.IsFalse(opts.UseAspNetSettings);
106+
Assert.IsTrue(opts.WarnAsError);
107+
Assert.AreEqual<string>("v6.0", opts.CompilerVersion);
108+
Assert.AreEqual<int>(7, opts.AllOptions.Count);
109+
Assert.AreEqual<string>("foo", opts.AllOptions["CustomSetting"]);
110+
Assert.AreEqual<string>("bar", opts.AllOptions["AnotherCoolSetting"]);
111+
}
112+
113+
// Environment overrides all for location and TTL
114+
[TestMethod]
115+
public void FromEnvironment()
116+
{
117+
// See note on the 'FromAppSettings' test.
118+
//ConfigurationManager.AppSettings.Set("aspnet:RoslynCompilerLocation", @"C:\Location\for\all\from\appSettings\compiler.exe");
119+
Environment.SetEnvironmentVariable("ROSLYN_COMPILER_LOCATION", @"C:\My\Compiler\Location\vbcsc.exe");
120+
Environment.SetEnvironmentVariable("VBCSCOMPILER_TTL", "98");
121+
IProviderOptions opts = CompilationUtil.GetProviderOptionsFor(".fakecs");
122+
Environment.SetEnvironmentVariable("ROSLYN_COMPILER_LOCATION", null);
123+
Environment.SetEnvironmentVariable("VBCSCOMPILER_TTL", null);
124+
//ConfigurationManager.AppSettings.Remove("aspnet:RoslynCompilerLocation");
125+
126+
Assert.IsNotNull(opts);
127+
Assert.AreEqual<string>(@"C:\My\Compiler\Location\vbcsc.exe", opts.CompilerFullPath);
128+
Assert.AreEqual<int>(98, opts.CompilerServerTimeToLive);
129+
Assert.IsFalse(opts.UseAspNetSettings);
130+
Assert.IsTrue(opts.WarnAsError);
131+
Assert.AreEqual<string>("v6.0", opts.CompilerVersion);
132+
Assert.AreEqual<int>(7, opts.AllOptions.Count);
133+
Assert.AreEqual<string>("foo", opts.AllOptions["CustomSetting"]);
134+
Assert.AreEqual<string>("bar", opts.AllOptions["AnotherCoolSetting"]);
135+
}
136+
137+
// TTL must be int
138+
[TestMethod]
139+
public void TTL_MustBeInteger()
140+
{
141+
Environment.SetEnvironmentVariable("VBCSCOMPILER_TTL", "NotANumber");
142+
IProviderOptions opts = CompilationUtil.GetProviderOptionsFor(".fakevb");
143+
Environment.SetEnvironmentVariable("VBCSCOMPILER_TTL", null);
144+
145+
Assert.IsNotNull(opts);
146+
Assert.AreEqual<string>(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\roslyn"), opts.CompilerFullPath); // Would include csc.exe or vbc.exe if the extension we searched for wasn't fake.
147+
Assert.AreEqual<int>(IsDev ? 15 * 60 : 10, opts.CompilerServerTimeToLive); // 10 in Production. 900 in a "dev" environment.
148+
Assert.IsTrue(opts.UseAspNetSettings); // Default is false... except through the GetProviderOptionsFor factory method we used here.
149+
Assert.IsFalse(opts.WarnAsError);
150+
Assert.IsNull(opts.CompilerVersion);
151+
Assert.AreEqual<int>(2, opts.AllOptions.Count);
152+
Assert.AreEqual<string>("foo2", opts.AllOptions["CustomSetting"]);
153+
Assert.AreEqual<string>("bar2", opts.AllOptions["AnotherCoolSetting"]);
154+
}
155+
}
156+
}

RoslynCodeProviderTest/VBCodeProviderTests.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ public class VBCodeProviderTests {
1818
private const int Failed = 1;
1919
private const int Success = 0;
2020

21+
#pragma warning disable CS0618
2122
private CommonCodeDomProviderTests commonTests = new CommonCodeDomProviderTests();
2223
private CodeDomProvider _codeProvider = new VBCodeProvider(CompilerSettingsHelper.VB);
24+
#pragma warning restore CS0618
2325

2426
[ClassInitialize]
2527
public static void ClassInitialize(TestContext context) {
26-
VBCompiler.MySupport = " ";
28+
//VBCompiler.MySupport = " "; // Don't need to do this anymore with UseAspNetSettings feature
2729
VBCompiler.VBImportsString = " ";
2830
}
2931

@@ -42,7 +44,7 @@ End Function
4244
End Class");
4345
}
4446

45-
[TestMethod]
47+
[TestMethod]
4648
public void CompileAssemblyFromSource_WarningAsError() {
4749
commonTests.CompileAssemblyFromSource_WarningAsError(_codeProvider,
4850
// the variable a is declared but not used
@@ -54,6 +56,23 @@ End Function
5456
End Class",
5557
"BC42024");
5658
}
59+
60+
[TestMethod]
61+
public void CompileAssemblyFromFile_ASPNet_Magic()
62+
{
63+
// Complete added frippery is: "/nowarn:41008,40000,40008 /define:_MYTYPE=\\\"Web\\\" /optionInfer+"
64+
// But let's just check for _MYTYPE.
65+
ProviderOptions opts = new ProviderOptions(CompilerSettingsHelper.VB) { UseAspNetSettings = true };
66+
commonTests.CompileAssemblyFromFile_CheckArgs(new VBCodeProvider(opts), "/define:_MYTYPE=\\\"Web\\\"", true);
67+
}
68+
69+
[TestMethod]
70+
public void CompileAssemblyFromFile_No_ASPNet_Magic()
71+
{
72+
// _codeProvider uses options (aka CompilerSettingsHelper.VB) created via constructor, so it should
73+
// have the ASP.Net frippery disabled.
74+
commonTests.CompileAssemblyFromFile_CheckArgs(_codeProvider, "/define:_MYTYPE=\"Web\"", false);
75+
}
5776
}
5877

5978
}

0 commit comments

Comments
 (0)