| File: LanguageVersion.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp { /// <summary> /// Specifies the language version. /// </summary> public enum LanguageVersion { /// <summary> /// C# language version 1 /// </summary> CSharp1 = 1, /// <summary> /// C# language version 2 /// </summary> CSharp2 = 2, /// <summary> /// C# language version 3 /// <para> /// Features: LINQ. /// </para> /// </summary> CSharp3 = 3, /// <summary> /// C# language version 4 /// <para> /// Features: dynamic. /// </para> /// </summary> CSharp4 = 4, /// <summary> /// C# language version 5 /// <para> /// Features: async, caller info attributes. /// </para> /// </summary> CSharp5 = 5, /// <summary> /// C# language version 6 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Using of a static class</description></item> /// <item><description>Exception filters</description></item> /// <item><description>Await in catch/finally blocks</description></item> /// <item><description>Auto-property initializers</description></item> /// <item><description>Expression-bodied methods and properties</description></item> /// <item><description>Null-propagating operator ?.</description></item> /// <item><description>String interpolation</description></item> /// <item><description>nameof operator</description></item> /// <item><description>Dictionary initializer</description></item> /// </list> /// </summary> CSharp6 = 6, /// <summary> /// C# language version 7.0 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Out variables</description></item> /// <item><description>Pattern-matching</description></item> /// <item><description>Tuples</description></item> /// <item><description>Deconstruction</description></item> /// <item><description>Discards</description></item> /// <item><description>Local functions</description></item> /// <item><description>Digit separators</description></item> /// <item><description>Ref returns and locals</description></item> /// <item><description>Generalized async return types</description></item> /// <item><description>More expression-bodied members</description></item> /// <item><description>Throw expressions</description></item> /// </list> /// </summary> CSharp7 = 7, /// <summary> /// C# language version 7.1 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Async Main</description></item> /// <item><description>Default literal</description></item> /// <item><description>Inferred tuple element names</description></item> /// <item><description>Pattern-matching with generics</description></item> /// </list> /// </summary> CSharp7_1 = 701, /// <summary> /// C# language version 7.2 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Ref readonly</description></item> /// <item><description>Ref and readonly structs</description></item> /// <item><description>Ref extensions</description></item> /// <item><description>Conditional ref operator</description></item> /// <item><description>Private protected</description></item> /// <item><description>Digit separators after base specifier</description></item> /// <item><description>Non-trailing named arguments</description></item> /// </list> /// </summary> CSharp7_2 = 702, /// <summary> /// C# language version 7.3 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Indexing fixed fields does not require pinning</description></item> /// <item><description>ref local variables may be reassigned</description></item> /// <item><description>stackalloc arrays support initializers</description></item> /// <item><description>More types support the fixed statement</description></item> /// <item><description>Enhanced generic constraints</description></item> /// <item><description>Tuples support == and !=</description></item> /// <item><description>Attach attributes to the backing fields for auto-implemented properties</description></item> /// <item><description>Method overload resolution improvements when arguments differ by 'in'</description></item> /// <item><description>Extend expression variables in initializers</description></item> /// <item><description>Improved overload candidates</description></item> /// <item><description>New compiler options (-publicsign and -pathmap)</description></item> /// </list> /// </summary> CSharp7_3 = 703, /// <summary> /// C# language version 8.0 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Readonly members</description></item> /// <item><description>Default interface methods</description></item> /// <item><description>Pattern matching enhancements (switch expressions, property patterns, tuple patterns, and positional patterns)</description></item> /// <item><description>Using declarations</description></item> /// <item><description>Static local functions</description></item> /// <item><description>Disposable ref structs</description></item> /// <item><description>Nullable reference types</description></item> /// <item><description>Asynchronous streams</description></item> /// <item><description>Asynchronous disposable</description></item> /// <item><description>Indices and ranges</description></item> /// <item><description>Null-coalescing assignment</description></item> /// <item><description>Unmanaged constructed types</description></item> /// <item><description>Stackalloc in nested expressions</description></item> /// <item><description>Enhancement of interpolated verbatim strings</description></item> /// </list> /// </summary> CSharp8 = 800, /// <summary> /// C# language version 9.0 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Records</description></item> /// <item><description>Init only setters</description></item> /// <item><description>Top-level statements</description></item> /// <item><description>Pattern matching enhancements</description></item> /// <item><description>Native sized integers</description></item> /// <item><description>Function pointers</description></item> /// <item><description>Suppress emitting localsinit flag</description></item> /// <item><description>Target-typed new expressions</description></item> /// <item><description>Static anonymous functions</description></item> /// <item><description>Target-typed conditional expressions</description></item> /// <item><description>Covariant return types</description></item> /// <item><description>Extension GetEnumerator support for foreach loops</description></item> /// <item><description>Lambda discard parameters</description></item> /// <item><description>Attributes on local functions</description></item> /// <item><description>Module initializers</description></item> /// <item><description>New features for partial methods</description></item> /// </list> /// </summary> CSharp9 = 900, /// <summary> /// C# language version 10.0 /// <para>Features:</para> /// <list type="bullet"> /// <item><description>Record structs</description></item> /// <item><description>Global using directives</description></item> /// <item><description>Lambda improvements</description></item> /// <item><description>Improved definite assignment</description></item> /// <item><description>Constant interpolated strings</description></item> /// <item><description>Mix declarations and variables in deconstruction</description></item> /// <item><description>Extended property patterns</description></item> /// <item><description>Sealed record ToString</description></item> /// <item><description>Source Generator v2 APIs</description></item> /// <item><description>Method-level AsyncMethodBuilder</description></item> /// </list> /// </summary> CSharp10 = 1000, /// <summary> /// C# language version 11.0 /// <br/> /// Features: /// <list type="bullet"> /// <item><description>Raw string literals</description></item> /// <item><description>Static abstract members in interfaces</description></item> /// <item><description>Generic attributes</description></item> /// <item><description>Newlines in interpolations</description></item> /// <item><description>List-patterns</description></item> /// <item><description>Required members</description></item> /// <item><description>Span<char> constant pattern</description></item> /// <item><description>Struct auto-default</description></item> /// <item><description>Nameof(parameter)</description></item> /// <item><description>Checked user-defined operators</description></item> /// <item><description>UTF-8 string literals</description></item> /// <item><description>Unsigned right-shift operator</description></item> /// <item><description>Relaxed shift operator</description></item> /// <item><description>Ref fields</description></item> /// <item><description>File-local types</description></item> /// </list> /// </summary> CSharp11 = 1100, /// <summary> /// C# language version 12.0 /// <br/> /// Features: /// <list type="bullet"> /// <item><description>Primary constructors</description></item> /// <item><description>Using aliases for any types</description></item> /// <item><description>Nameof accessing instance members</description></item> /// <item><description>Inline arrays</description></item> /// <item><description>Collection expressions</description></item> /// <item><description>Ref readonly parameters</description></item> /// <item><description>Lambda optional parameters</description></item> /// </list> /// </summary> CSharp12 = 1200, /// <summary> /// C# language version 13.0 /// <br/> /// Features: /// <list type="bullet"> /// <item><description>Escape character</description></item> /// <item><description>Method group natural type improvements</description></item> /// <item><description>`Lock` object</description></item> /// <item><description>Implicit indexer access in object initializers</description></item> /// <item><description>`params` collections</description></item> /// <item><description>ref/unsafe in iterators/async</description></item> /// <item><description>`allows ref struct` constraint</description></item> /// <item><description>Partial properties</description></item> /// </list> /// </summary> CSharp13 = 1300, /// <summary> /// C# language version 14.0 /// <br/> /// Features: /// <list type="bullet"> /// <item><description>`field` keyword in properties</description></item> /// <item><description>First-class `Span` types</description></item> /// <item><description>Unbound generic types in `nameof`</description></item> /// <item><description>Simple lambda parameters with modifiers</description></item> /// <item><description>Partial events and constructors</description></item> /// <item><description>Extension methods, properties and operators</description></item> /// <item><description>Null-conditional assignment</description></item> /// <item><description>Ignored directives</description></item> /// <item><description>User-defined compound assignment operators</description></item> /// <item><description>Optional and named arguments in `Expression` trees</description></item> /// </list> /// </summary> CSharp14 = 1400, /// <summary> /// The latest major supported version. /// </summary> LatestMajor = int.MaxValue - 2, /// <summary> /// Preview of the next language version. /// </summary> Preview = int.MaxValue - 1, /// <summary> /// The latest supported version of the language. /// </summary> Latest = int.MaxValue, /// <summary> /// The default language version, which is the latest supported version. /// </summary> Default = 0, } internal static class LanguageVersionExtensionsInternal { internal static bool IsValid(this LanguageVersion value) { 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: case LanguageVersion.CSharp7_2: case LanguageVersion.CSharp7_3: case LanguageVersion.CSharp8: case LanguageVersion.CSharp9: case LanguageVersion.CSharp10: case LanguageVersion.CSharp11: case LanguageVersion.CSharp12: case LanguageVersion.CSharp13: case LanguageVersion.CSharp14: case LanguageVersion.Preview: return true; } return false; } internal static ErrorCode GetErrorCode(this LanguageVersion version) { switch (version) { case LanguageVersion.CSharp1: return ErrorCode.ERR_FeatureNotAvailableInVersion1; case LanguageVersion.CSharp2: return ErrorCode.ERR_FeatureNotAvailableInVersion2; case LanguageVersion.CSharp3: return ErrorCode.ERR_FeatureNotAvailableInVersion3; case LanguageVersion.CSharp4: return ErrorCode.ERR_FeatureNotAvailableInVersion4; case LanguageVersion.CSharp5: return ErrorCode.ERR_FeatureNotAvailableInVersion5; case LanguageVersion.CSharp6: return ErrorCode.ERR_FeatureNotAvailableInVersion6; case LanguageVersion.CSharp7: return ErrorCode.ERR_FeatureNotAvailableInVersion7; case LanguageVersion.CSharp7_1: return ErrorCode.ERR_FeatureNotAvailableInVersion7_1; case LanguageVersion.CSharp7_2: return ErrorCode.ERR_FeatureNotAvailableInVersion7_2; case LanguageVersion.CSharp7_3: return ErrorCode.ERR_FeatureNotAvailableInVersion7_3; case LanguageVersion.CSharp8: return ErrorCode.ERR_FeatureNotAvailableInVersion8; case LanguageVersion.CSharp9: return ErrorCode.ERR_FeatureNotAvailableInVersion9; case LanguageVersion.CSharp10: return ErrorCode.ERR_FeatureNotAvailableInVersion10; case LanguageVersion.CSharp11: return ErrorCode.ERR_FeatureNotAvailableInVersion11; case LanguageVersion.CSharp12: return ErrorCode.ERR_FeatureNotAvailableInVersion12; case LanguageVersion.CSharp13: return ErrorCode.ERR_FeatureNotAvailableInVersion13; case LanguageVersion.CSharp14: return ErrorCode.ERR_FeatureNotAvailableInVersion14; default: throw ExceptionUtilities.UnexpectedValue(version); } } } internal class CSharpRequiredLanguageVersion : RequiredLanguageVersion { internal LanguageVersion Version { get; } internal CSharpRequiredLanguageVersion(LanguageVersion version) { Version = version; } public override string ToString() => Version.ToDisplayString(); } public static class LanguageVersionFacts { /// <summary> /// Usages of: /// - TestOptions.RegularNext, /// - LanguageVersionFacts.CSharpNext, /// - Microsoft.CodeAnalysis.CSharp.Shared.Extensions.LanguageVersionExtensions.CSharpNext /// will be replaced with: /// - TestOptions.RegularN, /// - LanguageVersion.CSharpN, /// - LanguageVersion.CSharpN /// when language version N is introduced. /// </summary> internal const LanguageVersion CSharpNext = LanguageVersion.Preview; /// <summary> /// Displays the version number in the format expected on the command-line (/langver flag). /// For instance, "6", "7.0", "7.1", "latest". /// </summary> public static string ToDisplayString(this LanguageVersion version) { switch (version) { case LanguageVersion.CSharp1: return "1"; case LanguageVersion.CSharp2: return "2"; case LanguageVersion.CSharp3: return "3"; case LanguageVersion.CSharp4: return "4"; case LanguageVersion.CSharp5: return "5"; case LanguageVersion.CSharp6: return "6"; case LanguageVersion.CSharp7: return "7.0"; case LanguageVersion.CSharp7_1: return "7.1"; case LanguageVersion.CSharp7_2: return "7.2"; case LanguageVersion.CSharp7_3: return "7.3"; case LanguageVersion.CSharp8: return "8.0"; case LanguageVersion.CSharp9: return "9.0"; case LanguageVersion.CSharp10: return "10.0"; case LanguageVersion.CSharp11: return "11.0"; case LanguageVersion.CSharp12: return "12.0"; case LanguageVersion.CSharp13: return "13.0"; case LanguageVersion.CSharp14: return "14.0"; case LanguageVersion.Default: return "default"; case LanguageVersion.Latest: return "latest"; case LanguageVersion.LatestMajor: return "latestmajor"; case LanguageVersion.Preview: return "preview"; default: throw ExceptionUtilities.UnexpectedValue(version); } } /// <summary> /// Try parse a <see cref="LanguageVersion"/> from a string input, returning default if input was null. /// </summary> public static bool TryParse(string? version, out LanguageVersion result) { if (version == null) { result = LanguageVersion.Default; return true; } switch (CaseInsensitiveComparison.ToLower(version)) { case "default": result = LanguageVersion.Default; return true; case "latest": result = LanguageVersion.Latest; return true; case "latestmajor": result = LanguageVersion.LatestMajor; return true; case "preview": result = LanguageVersion.Preview; return true; case "1": case "1.0": case "iso-1": result = LanguageVersion.CSharp1; return true; case "2": case "2.0": case "iso-2": result = LanguageVersion.CSharp2; return true; case "3": case "3.0": result = LanguageVersion.CSharp3; return true; case "4": case "4.0": result = LanguageVersion.CSharp4; return true; case "5": case "5.0": result = LanguageVersion.CSharp5; return true; case "6": case "6.0": result = LanguageVersion.CSharp6; return true; case "7": case "7.0": result = LanguageVersion.CSharp7; return true; case "7.1": result = LanguageVersion.CSharp7_1; return true; case "7.2": result = LanguageVersion.CSharp7_2; return true; case "7.3": result = LanguageVersion.CSharp7_3; return true; case "8": case "8.0": result = LanguageVersion.CSharp8; return true; case "9": case "9.0": result = LanguageVersion.CSharp9; return true; case "10": case "10.0": result = LanguageVersion.CSharp10; return true; case "11": case "11.0": result = LanguageVersion.CSharp11; return true; case "12": case "12.0": result = LanguageVersion.CSharp12; return true; case "13": case "13.0": result = LanguageVersion.CSharp13; return true; case "14": case "14.0": result = LanguageVersion.CSharp14; return true; default: result = LanguageVersion.Default; return false; } } /// <summary> /// Map a language version (such as Default, Latest, or CSharpN) to a specific version (CSharpM). /// </summary> public static LanguageVersion MapSpecifiedToEffectiveVersion(this LanguageVersion version) { switch (version) { case LanguageVersion.Latest: case LanguageVersion.Default: case LanguageVersion.LatestMajor: return LanguageVersion.CSharp14; default: return version; } } internal static LanguageVersion CurrentVersion => LanguageVersion.CSharp14; /// <summary>Inference of tuple element names was added in C# 7.1</summary> internal static bool DisallowInferredTupleElementNames(this LanguageVersion self) { return self < MessageID.IDS_FeatureInferredTupleNames.RequiredVersion(); } internal static bool AllowNonTrailingNamedArguments(this LanguageVersion self) { return self >= MessageID.IDS_FeatureNonTrailingNamedArguments.RequiredVersion(); } internal static bool AllowAttributesOnBackingFields(this LanguageVersion self) { return self >= MessageID.IDS_FeatureAttributesOnBackingFields.RequiredVersion(); } internal static bool AllowImprovedOverloadCandidates(this LanguageVersion self) { return self >= MessageID.IDS_FeatureImprovedOverloadCandidates.RequiredVersion(); } } }