diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
index 7dff2879d0469..335f581c6d10f 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
+++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
@@ -1232,7 +1232,7 @@ internal static string ERR_BadCoClassSig {
}
///
- /// Looks up a localized string similar to Invalid option '{0}' for /langversion; must be ISO-1, ISO-2, Default or an integer in range 1 to 7..
+ /// Looks up a localized string similar to Invalid option '{0}' for /langversion; must be ISO-1, ISO-2, Default, Latest or a valid version in range 1 to 7.1..
///
internal static string ERR_BadCompatMode {
get {
@@ -4453,6 +4453,15 @@ internal static string ERR_FeatureNotAvailableInVersion7 {
}
}
+ ///
+ /// Looks up a localized string similar to Feature '{0}' is not available in C# 7.1. Please use language version {1} or greater..
+ ///
+ internal static string ERR_FeatureNotAvailableInVersion7_1 {
+ get {
+ return ResourceManager.GetString("ERR_FeatureNotAvailableInVersion7_1", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to An expression tree may not contain '{0}'.
///
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 0290d2430281c..280e2b2cc9155 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -2690,7 +2690,7 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep
This warning occurs if the assembly attributes AssemblyKeyFileAttribute or AssemblyKeyNameAttribute found in source conflict with the /keyfile or /keycontainer command line option or key file name or key container specified in the Project Properties.
- Invalid option '{0}' for /langversion; must be ISO-1, ISO-2, Default or an integer in range 1 to 7.
+ Invalid option '{0}' for /langversion; must be ISO-1, ISO-2, Default, Latest or a valid version in range 1 to 7.1.
Cannot create delegate with '{0}' because it or a method it overrides has a Conditional attribute
@@ -5032,4 +5032,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Invalid name for a preprocessing symbol; '{0}' is not a valid identifier
+
+ Feature '{0}' is not available in C# 7.1. Please use language version {1} or greater.
+
\ No newline at end of file
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index f7ce50eaad930..29a51eff04724 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1468,5 +1468,6 @@ internal enum ErrorCode
ERR_Merge_conflict_marker_encountered = 8300,
ERR_InvalidPreprocessingSymbol = 8301,
+ ERR_FeatureNotAvailableInVersion7_1 = 8302,
}
}
\ No newline at end of file
diff --git a/src/Compilers/CSharp/Portable/LanguageVersion.cs b/src/Compilers/CSharp/Portable/LanguageVersion.cs
index 6060b10241058..ee433a587f845 100644
--- a/src/Compilers/CSharp/Portable/LanguageVersion.cs
+++ b/src/Compilers/CSharp/Portable/LanguageVersion.cs
@@ -69,6 +69,11 @@ public enum LanguageVersion
///
CSharp7 = 7,
+ ///
+ /// C# language version 7.1
+ ///
+ CSharp7_1 = 701,
+
///
/// The latest version of the language supported.
///
@@ -79,7 +84,20 @@ internal static class LanguageVersionExtensionsInternal
{
internal static bool IsValid(this LanguageVersion value)
{
- return value >= LanguageVersion.CSharp1 && value <= LanguageVersion.CSharp7;
+ switch (value)
+ {
+ case LanguageVersion.CSharp1:
+ case LanguageVersion.CSharp2:
+ case LanguageVersion.CSharp3:
+ case LanguageVersion.CSharp4:
+ case LanguageVersion.CSharp5:
+ case LanguageVersion.CSharp6:
+ case LanguageVersion.CSharp7:
+ case LanguageVersion.CSharp7_1:
+ return true;
+ }
+
+ return false;
}
internal static ErrorCode GetErrorCode(this LanguageVersion version)
@@ -100,6 +118,8 @@ internal static ErrorCode GetErrorCode(this LanguageVersion version)
return ErrorCode.ERR_FeatureNotAvailableInVersion6;
case LanguageVersion.CSharp7:
return ErrorCode.ERR_FeatureNotAvailableInVersion7;
+ case LanguageVersion.CSharp7_1:
+ return ErrorCode.ERR_FeatureNotAvailableInVersion7_1;
default:
throw ExceptionUtilities.UnexpectedValue(version);
}
@@ -142,6 +162,8 @@ public static string ToDisplayString(this LanguageVersion version)
return "6";
case LanguageVersion.CSharp7:
return "7";
+ case LanguageVersion.CSharp7_1:
+ return "7.1";
case LanguageVersion.Default:
return "default";
case LanguageVersion.Latest:
@@ -172,10 +194,6 @@ public static bool TryParse(this string version, out LanguageVersion result)
result = LanguageVersion.CSharp2;
return true;
- case "7":
- result = LanguageVersion.CSharp7;
- return true;
-
case "default":
result = LanguageVersion.Default;
return true;
@@ -184,19 +202,18 @@ public static bool TryParse(this string version, out LanguageVersion result)
result = LanguageVersion.Latest;
return true;
+ case "7.1":
+ result = LanguageVersion.CSharp7_1;
+ return true;
+
default:
- // We are likely to introduce minor version numbers after C# 7, thus breaking the
- // one-to-one correspondence between the integers and the corresponding
- // LanguageVersion enum values. But for compatibility we continue to accept any
- // integral value parsed by int.TryParse for its corresponding LanguageVersion enum
- // value for language version C# 6 and earlier (e.g. leading zeros are allowed)
- int versionNumber;
- if (int.TryParse(version, NumberStyles.None, CultureInfo.InvariantCulture, out versionNumber) &&
- versionNumber <= 6 &&
- ((LanguageVersion)versionNumber).IsValid())
+ if (int.TryParse(version, NumberStyles.None, CultureInfo.InvariantCulture, out int versionNumber) && versionNumber <= 7)
{
result = (LanguageVersion)versionNumber;
- return true;
+ if (result.IsValid())
+ {
+ return true;
+ }
}
result = LanguageVersion.Default;
@@ -212,6 +229,7 @@ public static LanguageVersion MapSpecifiedToEffectiveVersion(this LanguageVersio
switch (version)
{
case LanguageVersion.Latest:
+ return LanguageVersion.CSharp7_1;
case LanguageVersion.Default:
return LanguageVersion.CSharp7;
default:
diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
index 42e6ee0886678..05206cd42bdcd 100644
--- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
+++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
@@ -13,6 +13,7 @@ Microsoft.CodeAnalysis.CSharp.Conversion.IsThrow.get -> bool
Microsoft.CodeAnalysis.CSharp.Conversion.IsTupleConversion.get -> bool
Microsoft.CodeAnalysis.CSharp.Conversion.IsTupleLiteralConversion.get -> bool
Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp7 = 7 -> Microsoft.CodeAnalysis.CSharp.LanguageVersion
+Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp7_1 = 701 -> Microsoft.CodeAnalysis.CSharp.LanguageVersion
Microsoft.CodeAnalysis.CSharp.LanguageVersion.Default = 0 -> Microsoft.CodeAnalysis.CSharp.LanguageVersion
Microsoft.CodeAnalysis.CSharp.LanguageVersion.Latest = 2147483647 -> Microsoft.CodeAnalysis.CSharp.LanguageVersion
Microsoft.CodeAnalysis.CSharp.LanguageVersionFacts
diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
index 7b064856c0a19..6775f3a8d74fa 100644
--- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
+++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
@@ -1191,7 +1191,8 @@ public void ArgumentParsing()
[Fact]
public void LangVersion()
{
- LanguageVersion defaultVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion();
+ LanguageVersion defaultEffectiveVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion();
+ LanguageVersion latestEffectiveVersion = LanguageVersion.Latest.MapSpecifiedToEffectiveVersion();
var parsedArgs = DefaultParse(new[] { "/langversion:1", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify();
@@ -1233,15 +1234,19 @@ public void LangVersion()
parsedArgs.Errors.Verify();
Assert.Equal(LanguageVersion.CSharp7, parsedArgs.ParseOptions.LanguageVersion);
+ parsedArgs = DefaultParse(new[] { "/langversion:7.1", "a.cs" }, _baseDirectory);
+ parsedArgs.Errors.Verify();
+ Assert.Equal(LanguageVersion.CSharp7_1, parsedArgs.ParseOptions.LanguageVersion);
+
parsedArgs = DefaultParse(new[] { "/langversion:default", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify();
Assert.Equal(LanguageVersion.Default, parsedArgs.ParseOptions.SpecifiedLanguageVersion);
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion:latest", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify();
Assert.Equal(LanguageVersion.Latest, parsedArgs.ParseOptions.SpecifiedLanguageVersion);
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(latestEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion:iso-1", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify();
@@ -1251,14 +1256,11 @@ public void LangVersion()
parsedArgs.Errors.Verify();
Assert.Equal(LanguageVersion.CSharp2, parsedArgs.ParseOptions.LanguageVersion);
- parsedArgs = DefaultParse(new[] { "/langversion:default", "a.cs" }, _baseDirectory);
- parsedArgs.Errors.Verify();
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
-
// default value
parsedArgs = DefaultParse(new[] { "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify();
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(LanguageVersion.Default, parsedArgs.ParseOptions.SpecifiedLanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
// override value with iso-1
parsedArgs = DefaultParse(new[] { "/langversion:6", "/langversion:iso-1", "a.cs" }, _baseDirectory);
@@ -1272,13 +1274,13 @@ public void LangVersion()
// override value with default
parsedArgs = DefaultParse(new[] { "/langversion:6", "/langversion:default", "a.cs" }, _baseDirectory);
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs.Errors.Verify();
// override value with default
parsedArgs = DefaultParse(new[] { "/langversion:7", "/langversion:default", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify();
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
// override value with numeric
parsedArgs = DefaultParse(new[] { "/langversion:iso-2", "/langversion:6", "a.cs" }, _baseDirectory);
@@ -1288,40 +1290,40 @@ public void LangVersion()
// errors
parsedArgs = DefaultParse(new[] { "/langversion:iso-3", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("iso-3"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion:iso1", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("iso1"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion:0", "/langversion:7", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(
Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("0"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion:0", "/langversion:8", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(
Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("0"),
Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("8"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion:0", "/langversion:1000", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(
Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("0"),
Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("1000"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(Diagnostic(ErrorCode.ERR_SwitchNeedsString).WithArguments("", "/langversion:"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/LANGversion:", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(Diagnostic(ErrorCode.ERR_SwitchNeedsString).WithArguments("", "/langversion:"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
parsedArgs = DefaultParse(new[] { "/langversion: ", "a.cs" }, _baseDirectory);
parsedArgs.Errors.Verify(Diagnostic(ErrorCode.ERR_SwitchNeedsString).WithArguments("", "/langversion:"));
- Assert.Equal(defaultVersion, parsedArgs.ParseOptions.LanguageVersion);
+ Assert.Equal(defaultEffectiveVersion, parsedArgs.ParseOptions.LanguageVersion);
}
[Fact]
@@ -1332,14 +1334,14 @@ public void LanguageVersionAdded_Canary()
// - update the "UpgradeProject" codefixer
// - update the IDE drop-down for selecting Language Version
// - don't fix the canary test until you update all the tests that include it
- Assert.Equal(LanguageVersion.CSharp7, LanguageVersion.Latest.MapSpecifiedToEffectiveVersion());
+ Assert.Equal(LanguageVersion.CSharp7_1, LanguageVersion.Latest.MapSpecifiedToEffectiveVersion());
Assert.Equal(LanguageVersion.CSharp7, LanguageVersion.Default.MapSpecifiedToEffectiveVersion());
}
[Fact]
public void LanguageVersion_DisplayString()
{
- AssertEx.SetEqual(new[] { "default", "1", "2", "3", "4", "5", "6", "7", "latest" },
+ AssertEx.SetEqual(new[] { "default", "1", "2", "3", "4", "5", "6", "7", "7.1", "latest" },
Enum.GetValues(typeof(LanguageVersion)).Cast().Select(v => v.ToDisplayString()));
// For minor versions, the format should be "x.y", such as "7.1"
}
@@ -1355,7 +1357,7 @@ public void LanguageVersion_MapSpecifiedToEffectiveVersion()
Assert.Equal(LanguageVersion.CSharp6, LanguageVersion.CSharp6.MapSpecifiedToEffectiveVersion());
Assert.Equal(LanguageVersion.CSharp7, LanguageVersion.CSharp7.MapSpecifiedToEffectiveVersion());
Assert.Equal(LanguageVersion.CSharp7, LanguageVersion.Default.MapSpecifiedToEffectiveVersion());
- Assert.Equal(LanguageVersion.CSharp7, LanguageVersion.Latest.MapSpecifiedToEffectiveVersion());
+ Assert.Equal(LanguageVersion.CSharp7_1, LanguageVersion.Latest.MapSpecifiedToEffectiveVersion());
// The canary check is a reminder that this test needs to be updated when a language version is added
LanguageVersionAdded_Canary();
@@ -1373,7 +1375,8 @@ public void LanguageVersion_MapSpecifiedToEffectiveVersion()
InlineData("05", true, LanguageVersion.CSharp5),
InlineData("6", true, LanguageVersion.CSharp6),
InlineData("7", true, LanguageVersion.CSharp7),
- InlineData("07", false, LanguageVersion.Default),
+ InlineData("07", true, LanguageVersion.CSharp7),
+ InlineData("7.1", true, LanguageVersion.CSharp7_1),
InlineData("default", true, LanguageVersion.Default),
InlineData("latest", true, LanguageVersion.Latest),
InlineData(null, true, LanguageVersion.Default),