提交 1e3b92a1 编写于 作者: N Neal Gafter 提交者: GitHub

Merge pull request #12574 from gafter/typeswitch-rename-feature

Rename feature flag used for exercising V7 switch binder with V6 switches
......@@ -34,9 +34,9 @@ internal static SwitchBinder Create(Binder next, SwitchStatementSyntax switchSyn
// In C# 6 and earlier, we use the old binder. In C# 7 and later, we use the new binder which
// is capable of binding both the old and new syntax. However, the new binder does not yet
// lead to a translation that fully supports edit-and-continue, so it delegates to the C# 6
// binder when it can. The "typeswitch" feature flag forces the use of the C# 7 switch binder
// binder when it can. The "testV7SwitchBinder" feature flag forces the use of the C# 7 switch binder
// for all operations; we use it to enhance test coverage.
(parseOptions?.IsFeatureEnabled(MessageID.IDS_FeaturePatternMatching) != false || parseOptions?.Features.ContainsKey("typeswitch") != false)
(parseOptions?.IsFeatureEnabled(MessageID.IDS_FeaturePatternMatching) != false || parseOptions?.Features.ContainsKey("testV7SwitchBinder") != false)
? new PatternSwitchBinder(next, switchSyntax)
: new SwitchBinder(next, switchSyntax);
}
......@@ -461,12 +461,13 @@ private BoundExpression BindSwitchExpression(ExpressionSyntax node, DiagnosticBa
if (!switchExpression.HasAnyErrors)
{
if (PatternsEnabled)
if ((object)switchExpression.Type == null || switchExpression.Type.SpecialType == SpecialType.System_Void)
{
diagnostics.Add(ErrorCode.ERR_PatternValueExpected, node.Location, switchExpression.Display);
}
else
{
Debug.Assert(!PatternsEnabled);
diagnostics.Add(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, node.Location);
}
}
......
......@@ -14,8 +14,6 @@ namespace Microsoft.CodeAnalysis.CSharp
// a totally compatible implementation of switch that also accepts pattern-matching constructs.
internal partial class PatternSwitchBinder : SwitchBinder
{
private bool? _isPatternSwitch;
internal PatternSwitchBinder(Binder next, SwitchStatementSyntax switchSyntax) : base(next, switchSyntax)
{
}
......@@ -27,25 +25,19 @@ internal PatternSwitchBinder(Binder next, SwitchStatementSyntax switchSyntax) :
/// However, until we have edit-and-continue working, we continue using the old binder
/// when we can.
/// </summary>
private bool IsPatternSwitch
private bool UseV7SwitchBinder
{
get
{
if (_isPatternSwitch == null)
{
var parseOptions = SwitchSyntax?.SyntaxTree?.Options as CSharpParseOptions;
_isPatternSwitch =
(parseOptions?.IsFeatureEnabled(MessageID.IDS_FeaturePatternMatching) != false &&
(parseOptions?.Features.ContainsKey("typeswitch") == true ||
IsPatternSwitchSyntax(SwitchSyntax) ||
!SwitchGoverningType.IsValidV6SwitchGoverningType()));
}
return _isPatternSwitch.GetValueOrDefault();
return
parseOptions?.Features.ContainsKey("testV7SwitchBinder") == true ||
HasPatternSwitchSyntax(SwitchSyntax) ||
!SwitchGoverningType.IsValidV6SwitchGoverningType();
}
}
private static bool IsPatternSwitchSyntax(SwitchStatementSyntax switchSyntax)
private static bool HasPatternSwitchSyntax(SwitchStatementSyntax switchSyntax)
{
foreach (var section in switchSyntax.Sections)
{
......@@ -61,7 +53,7 @@ private static bool IsPatternSwitchSyntax(SwitchStatementSyntax switchSyntax)
internal override BoundStatement BindSwitchExpressionAndSections(SwitchStatementSyntax node, Binder originalBinder, DiagnosticBag diagnostics)
{
// If it is a valid C# 6 switch statement, we use the old binder to bind it.
if (!IsPatternSwitch) return base.BindSwitchExpressionAndSections(node, originalBinder, diagnostics);
if (!UseV7SwitchBinder) return base.BindSwitchExpressionAndSections(node, originalBinder, diagnostics);
Debug.Assert(SwitchSyntax.Equals(node));
......
......@@ -12323,7 +12323,7 @@ void Match(object o)
}
" + trivial2uple;
var comp = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.RegularWithPatterns);
var comp = CreateCompilationWithMscorlib(source);
comp.VerifyDiagnostics(
// (7,19): error CS1525: Invalid expression term 'int'
// case (int, int) tuple: return;
......@@ -12358,7 +12358,7 @@ void Match(object o)
}
" + trivial2uple;
var comp = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.RegularWithPatterns);
var comp = CreateCompilationWithMscorlib(source);
comp.VerifyDiagnostics(
// (7,18): error CS0150: A constant value is expected
// case (1, 1): return;
......@@ -12381,7 +12381,7 @@ void Match(object o)
}
" + trivial2uple;
var comp = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.RegularWithPatterns);
var comp = CreateCompilationWithMscorlib(source);
comp.VerifyDiagnostics(
// (7,25): error CS1003: Syntax error, ':' expected
// case (1, 1) t: return;
......
......@@ -8,8 +8,6 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class PatternSwitchTests : CSharpTestBase
{
private static readonly CSharpParseOptions s_patternParseOptions = TestOptions.RegularWithPatterns;
[Fact]
public void EqualConstant()
{
......@@ -29,7 +27,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
Assert.True(compilation.GetDiagnostics().HasAnyErrors());
compilation.VerifyDiagnostics(
// (11,13): error CS0152: The switch statement contains multiple cases with the label value '1'
......@@ -61,7 +59,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
Assert.True(compilation.GetDiagnostics().HasAnyErrors());
compilation.VerifyDiagnostics(
// (9,18): error CS8120: The switch case has already been handled by a previous case.
......@@ -92,7 +90,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (11,13): error CS8120: The switch case has already been handled by a previous case.
// case 1: // error: handled previously
......@@ -124,7 +122,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
Assert.True(compilation.GetDiagnostics().HasAnyErrors());
compilation.VerifyDiagnostics(
// (10,13): error CS8120: The switch case has already been handled by a previous case.
......@@ -154,7 +152,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
Assert.True(compilation.GetDiagnostics().HasAnyErrors());
compilation.VerifyDiagnostics(
// (10,18): error CS0029: Cannot implicitly convert type 'string' to 'bool'
......@@ -185,7 +183,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
Assert.True(compilation.GetDiagnostics().HasAnyErrors());
compilation.VerifyDiagnostics(
// (11,18): error CS8120: The switch case has already been handled by a previous case.
......@@ -217,7 +215,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (12,18): error CS8120: The switch case has already been handled by a previous case.
// case IEnumerable<string> i: // error: subsumed by previous case
......@@ -247,7 +245,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugExe);
Assert.True(compilation.GetDiagnostics().HasAnyErrors());
compilation.VerifyDiagnostics(
// (11,18): error CS8120: The switch case has already been handled by a previous case.
......@@ -278,7 +276,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (11,18): error CS8120: The switch case has already been handled by a previous case.
// case var x: // error: subsumed
......@@ -308,7 +306,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (11,18): error CS8120: The switch case has already been handled by a previous case.
// case var x: // error: subsumed by previous cases
......@@ -338,7 +336,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
);
}
......@@ -359,7 +357,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (8,18): error CS8121: An expression of type string cannot be handled by a pattern of type int.
// case int i: // error: type mismatch.
......@@ -410,7 +408,7 @@ public static void M(bool? b)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput =
@"True
......@@ -437,7 +435,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (10,18): error CS0037: Cannot convert null to 'bool' because it is a non-nullable value type
// case null: // error: impossible given the type
......@@ -463,7 +461,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (10,18): error CS0029: Cannot implicitly convert type 'int' to 'bool'
// case 3: // error: impossible given the type
......@@ -489,7 +487,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (10,18): error CS0031: Constant value '1000' cannot be converted to a 'byte'
// case 1000: // error: impossible given the type
......@@ -514,7 +512,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (9,13): error CS8120: The switch case has already been handled by a previous case.
// case 11: // error: subsumed
......@@ -545,7 +543,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (10,18): error CS8120: The switch case has already been handled by a previous case.
// case bool b: // error: subsumed
......@@ -571,7 +569,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (8,17): warning CS0162: Unreachable code detected
// break; // unreachable
......@@ -594,7 +592,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (8,17): warning CS0162: Unreachable code detected
// break; // unreachable
......@@ -617,7 +615,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (8,17): warning CS0162: Unreachable code detected
// break; // unreachable
......@@ -640,7 +638,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
);
}
......@@ -660,7 +658,7 @@ public static void Main(string[] args)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
);
}
......@@ -683,12 +681,12 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
);
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/12316")]
[Fact]
public void CascadedUnreachableDiagnostic()
{
var source =
......@@ -703,7 +701,7 @@ public static void Main()
case false:
break;
case ""foo"": // wrong type
break; // warning: unreachable (cascaded diagnostic)
break;
}
}
}";
......@@ -712,7 +710,15 @@ public static void Main()
// case "foo": // wrong type
Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""foo""").WithArguments("string", "bool").WithLocation(11, 18)
);
CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions).VerifyDiagnostics(
CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular6WithV7SwitchBinder).VerifyDiagnostics(
// (11,18): error CS0029: Cannot implicitly convert type 'string' to 'bool'
// case "foo": // wrong type
Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""foo""").WithArguments("string", "bool").WithLocation(11, 18),
// (12,17): warning CS0162: Unreachable code detected
// break;
Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(12, 17)
);
CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe).VerifyDiagnostics(
// (10,18): error CS0029: Cannot implicitly convert type 'string' to 'bool'
// case "foo": // wrong type
Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""foo""").WithArguments("string", "bool").WithLocation(11, 18)
......@@ -765,7 +771,7 @@ public static void Main()
// case Color x when false:
Diagnostic(ErrorCode.ERR_SwitchFallOut, "case Color x when false:").WithArguments("case Color x when false:").WithLocation(18, 13)
);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (11,17): warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
// goto case 1; // warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
......@@ -811,7 +817,7 @@ public static void Main()
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (17,17): warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
// goto case 1;
......@@ -858,7 +864,7 @@ public static void M(object o)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput =
@"1
......@@ -949,7 +955,7 @@ public static void M(object o)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput =
@"0.0d !
......@@ -1079,7 +1085,7 @@ public static void M(decimal d)
}
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (13,13): error CS0152: The switch statement contains multiple cases with the label value '1.01'
// case 1.01: // duplicate
......@@ -1147,7 +1153,7 @@ public static double MakeNaN(int x)
return BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(double.NaN) ^ x);
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: s_patternParseOptions);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics();
var expectedOutput =
@"zero
......
......@@ -580,7 +580,7 @@ static void Main(string[] args)
select n1;
}
}";
CreateCompilationWithMscorlibAndSystemCore(csSource, parseOptions: TestOptions.Regular).VerifyDiagnostics(
CreateCompilationWithMscorlibAndSystemCore(csSource).VerifyDiagnostics(
// (6,29): error CS0103: The name 'nums' does not exist in the current context
Diagnostic(ErrorCode.ERR_NameNotInContext, "nums").WithArguments("nums")
);
......@@ -600,7 +600,7 @@ static void Main(string[] args)
var query = from int i in new int[]{ 1 } join null on true equals true select i; //CS1031
}
}";
CreateCompilationWithMscorlibAndSystemCore(csSource, parseOptions: TestOptions.Regular).VerifyDiagnostics(
CreateCompilationWithMscorlibAndSystemCore(csSource).VerifyDiagnostics(
// (8,55): error CS1031: Type expected
// var query = from int i in new int[]{ 1 } join null on true equals true select i; //CS1031
Diagnostic(ErrorCode.ERR_TypeExpected, "null"),
......
......@@ -22271,7 +22271,7 @@ public static void Main()
var p = null ?? null; //CS0019
}
}
", parseOptions: TestOptions.Regular).VerifyDiagnostics(
").VerifyDiagnostics(
// error CS0019: Operator '??' cannot be applied to operands of type '<null>' and '<null>'
Diagnostic(ErrorCode.ERR_BadBinaryOps, "null ?? null").WithArguments("??", "<null>", "<null>"));
}
......@@ -22295,7 +22295,7 @@ public static void Main()
var test = new Top<int>.Outer<string>();
}
}
", parseOptions: TestOptions.Regular).VerifyDiagnostics(
").VerifyDiagnostics(
// (13,33): error CS0122: 'Top<int>.Outer<string>' is inaccessible due to its protection level
// var test = new Top<int>.Outer<string>();
Diagnostic(ErrorCode.ERR_BadAccess, "new Top<int>.Outer<string>()").WithArguments("Top<int>.Outer<string>"));
......@@ -22321,7 +22321,7 @@ public static void Main()
Method1(10, 20); //CS0121
}
}
", parseOptions: TestOptions.Regular).VerifyDiagnostics(
").VerifyDiagnostics(
// (14,9): error CS0121: The call is ambiguous between the following methods or properties: 'Test.Method1(int, long)' and 'Test.Method1(long, int)'
// Method1(10, 20)
Diagnostic(ErrorCode.ERR_AmbigCall, "Method1").WithArguments("Test.Method1(int, long)", "Test.Method1(long, int)"));
......@@ -22350,7 +22350,7 @@ public static void Main()
var i1 = new Class1(10, 20); //CS0121
}
}
", parseOptions: TestOptions.Regular).VerifyDiagnostics(
").VerifyDiagnostics(
// (17,18): error CS0121: The call is ambiguous between the following methods or properties: 'Class1.Class1(int, long)' and 'Class1.Class1(long, int)'
// new Class1(10, 20)
Diagnostic(ErrorCode.ERR_AmbigCall, "Class1").WithArguments("Class1.Class1(int, long)", "Class1.Class1(long, int)"));
......
......@@ -19,8 +19,11 @@ public static class TestOptions
private static readonly SmallDictionary<string, string> s_experimentalFeatures = new SmallDictionary<string, string> { };
public static readonly CSharpParseOptions ExperimentalParseOptions =
new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.None, languageVersion: LanguageVersion.CSharp7).WithFeatures(s_experimentalFeatures);
// enable pattern-switch translation even for switches that use no new syntax.
public static readonly CSharpParseOptions RegularWithPatterns = Regular.WithFeatures(new Dictionary<string, string>() { { "typeswitch", "true" } });
// Enable pattern-switch translation even for switches that use no new syntax. This is used
// to help ensure compatibility of the semantics of the new switch binder with the old switch
// binder, so that we may eliminate the old one in the future.
public static readonly CSharpParseOptions Regular6WithV7SwitchBinder = Regular6.WithFeatures(new Dictionary<string, string>() { { "testV7SwitchBinder", "true" } });
public static readonly CSharpCompilationOptions ReleaseDll = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release).WithExtendedCustomDebugInformation(true);
public static readonly CSharpCompilationOptions ReleaseExe = new CSharpCompilationOptions(OutputKind.ConsoleApplication, optimizationLevel: OptimizationLevel.Release).WithExtendedCustomDebugInformation(true);
......
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>cd77a8cc-2885-47a7-b99c-fbf13353400b</ProjectGuid>
<ProjectGuid>c1930979-c824-496b-a630-70f5369a636f</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册