Skip to content

Commit

Permalink
Ensure that Language Version support flows to Parser (#6891)
Browse files Browse the repository at this point in the history
* update testing

* Ensure Lange Feature can be used from the parser

* remove comments on tests

* repair tests.fs
  • Loading branch information
KevinRansom authored Jun 3, 2019
1 parent 1464694 commit 522fc42
Show file tree
Hide file tree
Showing 42 changed files with 843 additions and 333 deletions.
6 changes: 6 additions & 0 deletions fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
<Compile Include="$(FSharpSourcesRoot)/fsharp/sr.fs">
<Link>ErrorText/sr.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)/fsharp/LanguageFeatures.fsi">
<Link>Driver\LanguageFeatures.fsi</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)/fsharp/LanguageFeatures.fs">
<Link>Driver\LanguageFeatures.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)/utils/prim-lexing.fsi">
<Link>LexYaccRuntime/prim-lexing.fsi</Link>
</Compile>
Expand Down
91 changes: 9 additions & 82 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ open FSharp.Compiler.AttributeChecking
open FSharp.Compiler.ConstraintSolver
open FSharp.Compiler.DiagnosticMessage
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Features
open FSharp.Compiler.Import
open FSharp.Compiler.Infos
open FSharp.Compiler.Lexhelp
Expand Down Expand Up @@ -1735,7 +1736,7 @@ let CollectDiagnostic (implicitIncludeDir, showFullPaths, flattenErrors, errorSt
let os = System.Text.StringBuilder()
OutputPhasedDiagnostic os err flattenErrors suggestNames
errors.Add( Diagnostic.Short(isError, os.ToString()) )

relatedErrors |> List.iter OutputRelatedError

match err with
Expand Down Expand Up @@ -1834,82 +1835,6 @@ let ComputeMakePathAbsolute implicitIncludeDir (path: string) =
with
:? System.ArgumentException -> path


//------------------------------------------------------------------------------------------------------------------
// Language version command line switch
//------------------------------------------------------------------------------------------------------------------
// Add your features to this List - in code use languageVersion.SupportsFeature(LanguageFeatures.yourFeature)
// a return value of false means your feature is not supported by the user's language selection
// All new language features added from now on must be protected by this.
// Note:
// * The fslang design process will require a decision about feature name and whether it is required.
// * When a feature is assigned a release language, we will scrub the code of feature references and apply
// the Release Language version.

/// LanguageFeature enumeration
[<RequireQualifiedAccess>]
type LanguageFeature =
| LanguageVersion46 = 0
| LanguageVersion47 = 1
| Nullness = 1000
| ScriptingPackageManagement = 1001

/// LanguageVersion management
type LanguageVersion (specifiedVersion) =

// When we increment language versions here preview is higher than current RTM version
static let languageVersion46 = 4.6m
static let languageVersion47 = 4.7m

static let previewVersion = languageVersion47 // Language version when preview specified
static let defaultVersion = languageVersion46 // Language version when default specified
static let latestVersion = defaultVersion // Language version when latest specified
static let latestMajorVersion = languageVersion46 // Language version when latestmajor specified

static let validOptions = [| "preview"; "default"; "latest"; "latestmajor" |]
static let languageVersions = set [| latestVersion |]

static let features = dict [|
// Add new LanguageVersions here ...
LanguageFeature.LanguageVersion47, 4.7m
LanguageFeature.LanguageVersion46, 4.6m
LanguageFeature.Nullness, previewVersion
LanguageFeature.ScriptingPackageManagement, previewVersion
// Add new LanguageFeatures here ...
|]

static let dumpAllowedValues () =
printfn "%s" (FSComp.SR.optsSupportedLangVersions())
for v in validOptions do printfn "%s" v
for v in languageVersions |> Seq.sort do
let label = if v = defaultVersion || v = latestVersion then "(Default)" else ""
printf "%M %s" v label
exit 0
0m

let specified =
match specifiedVersion with
| "?" -> dumpAllowedValues()
| "preview" -> previewVersion
| "default" -> latestVersion
| "latest" -> latestVersion
| "latestmajor" -> latestMajorVersion
| _ ->
let raiseError () = error(Error(FSComp.SR.optsUnrecognizedLanguageVersion specifiedVersion, rangeCmdArgs))
match Decimal.TryParse(specifiedVersion) with
| true, v ->
if languageVersions.Contains(v) then v
else raiseError (); 0m
| _ ->
raiseError ()
0m

/// Check if this feature is supported by the selected langversion
member __.SupportsFeature featureId =
match features.TryGetValue featureId with
| true, v -> v <= specified
| false, _ -> false

//----------------------------------------------------------------------------
// Configuration
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -3556,8 +3481,8 @@ let ParseOneInputFile (tcConfig: TcConfig, lexResourceManager, conditionalCompil
if List.exists (Filename.checkSuffix lower) (FSharpSigFileSuffixes@FSharpImplFileSuffixes) then
if not(FileSystem.SafeExists filename) then
error(Error(FSComp.SR.buildCouldNotFindSourceFile filename, rangeStartup))
// bug 3155: if the file name is indirect, use a full path
let lexbuf = UnicodeLexing.UnicodeFileAsLexbuf(filename, tcConfig.inputCodePage, retryLocked)
let isFeatureSupported featureId = tcConfig.langVersion.SupportsFeature featureId
let lexbuf = UnicodeLexing.UnicodeFileAsLexbuf(isFeatureSupported, filename, tcConfig.inputCodePage, retryLocked)
ParseOneInputLexbuf(tcConfig, lexResourceManager, conditionalCompilationDefines, lexbuf, filename, isLastCompiland, errorLogger)
else error(Error(FSComp.SR.buildInvalidSourceFileExtension(SanitizeFileName filename tcConfig.implicitIncludeDir), rangeStartup))
with e -> (* errorR(Failure("parse failed")); *) errorRecovery e rangeStartup; None
Expand Down Expand Up @@ -5080,11 +5005,13 @@ module private ScriptPreprocessClosure =
| CodeContext.CompilationAndEvaluation -> ["INTERACTIVE"]
| CodeContext.Compilation -> ["COMPILED"]
| CodeContext.Editing -> "EDITING" :: (if IsScript filename then ["INTERACTIVE"] else ["COMPILED"])
let lexbuf = UnicodeLexing.SourceTextAsLexbuf(sourceText)


let isFeatureSupported featureId = tcConfig.langVersion.SupportsFeature featureId
let lexbuf = UnicodeLexing.SourceTextAsLexbuf(isFeatureSupported, sourceText)

let isLastCompiland = (IsScript filename), tcConfig.target.IsExe // The root compiland is last in the list of compilands.
ParseOneInputLexbuf (tcConfig, lexResourceManager, defines, lexbuf, filename, isLastCompiland, errorLogger)

/// Create a TcConfig for load closure starting from a single .fsx file
let CreateScriptTextTcConfig
(legacyReferenceResolver, defaultFSharpBinariesDir,
Expand Down
14 changes: 1 addition & 13 deletions src/fsharp/CompileOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ open FSharp.Compiler.TypeChecker
open FSharp.Compiler.Range
open FSharp.Compiler.Ast
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Features
open FSharp.Compiler.Tast
open FSharp.Compiler.TcGlobals
open FSharp.Compiler.Text
Expand Down Expand Up @@ -217,19 +218,6 @@ type ICompilationThread =
/// Enqueue work to be done on a compilation thread.
abstract EnqueueWork: (CompilationThreadToken -> unit) -> unit

/// LanguageFeature enumeration
[<RequireQualifiedAccess>]
type LanguageFeature =
| LanguageVersion46 = 0
| LanguageVersion47 = 1
| Nullness = 1000
| ScriptingPackageManagement = 1001

/// LanguageVersion management
type LanguageVersion =
new: string -> LanguageVersion
member SupportsFeature: LanguageFeature-> bool

[<RequireQualifiedAccess>]
type CompilerTarget =
| WinExe
Expand Down
19 changes: 17 additions & 2 deletions src/fsharp/CompileOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ open FSharp.Compiler.TcGlobals
open FSharp.Compiler.Tast
open FSharp.Compiler.Tastops
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Features
open FSharp.Compiler.Lib
open FSharp.Compiler.Range
open FSharp.Compiler.IlxGen
Expand Down Expand Up @@ -813,13 +814,27 @@ let codeGenerationFlags isFsi (tcConfigB: TcConfigBuilder) =
//----------------------

let defineSymbol tcConfigB s = tcConfigB.conditionalCompilationDefines <- s :: tcConfigB.conditionalCompilationDefines

let mlCompatibilityFlag (tcConfigB: TcConfigBuilder) =
CompilerOption
("mlcompatibility", tagNone,
OptionUnit (fun () -> tcConfigB.mlCompatibility<-true; tcConfigB.TurnWarningOff(rangeCmdArgs, "62")), None,
Some (FSComp.SR.optsMlcompatibility()))

/// LanguageVersion management
let setLanguageVersion (specifiedVersion) =

let languageVersion = new LanguageVersion(specifiedVersion)
let dumpAllowedValues () =
printfn "%s" (FSComp.SR.optsSupportedLangVersions())
for v in languageVersion.ValidOptions do printfn "%s" v
for v in languageVersion.ValidVersions do printfn "%s" v
exit 0

if specifiedVersion = "?" then dumpAllowedValues ()
if not (languageVersion.ContainsVersion specifiedVersion) then error(Error(FSComp.SR.optsUnrecognizedLanguageVersion specifiedVersion, rangeCmdArgs))
languageVersion

let languageFlags tcConfigB =
[
// -langversion:? Display the allowed values for language version
Expand All @@ -828,7 +843,7 @@ let languageFlags tcConfigB =
// 'latest' (latest version, including minor versions),
// 'preview' (features for preview)
// or specific versions like '4.7'
CompilerOption("langversion", tagLangVersionValues, OptionString (fun switch -> tcConfigB.langVersion <- LanguageVersion(switch)), None, Some (FSComp.SR.optsLangVersion()))
CompilerOption("langversion", tagLangVersionValues, OptionString (fun switch -> tcConfigB.langVersion <- setLanguageVersion(switch)), None, Some (FSComp.SR.optsLangVersion()))

CompilerOption("checked", tagNone, OptionSwitch (fun switch -> tcConfigB.checkOverflow <- (switch = OptionSwitch.On)), None, Some (FSComp.SR.optsChecked()))
CompilerOption("define", tagString, OptionString (defineSymbol tcConfigB), None, Some (FSComp.SR.optsDefine()))
Expand Down
1 change: 1 addition & 0 deletions src/fsharp/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ parsAttributesMustComeBeforeVal,"Attributes should be placed before 'val'"
568,parsAllEnumFieldsRequireValues,"All enum fields must be given values"
569,parsInlineAssemblyCannotHaveVisibilityDeclarations,"Accessibility modifiers are not permitted on inline assembly code types"
571,parsUnexpectedIdentifier,"Unexpected identifier: '%s'"
10,parsUnexpectedSymbolDot,"Unexpected symbol '.' in member definition. Expected 'with', '=' or other token."
572,parsUnionCasesCannotHaveVisibilityDeclarations,"Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation."
573,parsEnumFieldsCannotHaveVisibilityDeclarations,"Accessibility modifiers are not permitted on enumeration fields"
parsConsiderUsingSeparateRecordType,"Consider using a separate record type instead"
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/FSharp.Build/Fsc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ type public Fsc () as this =
for item in embeddedFiles do
builder.AppendSwitchIfNotNull("--embed:", item.ItemSpec)
builder.AppendSwitchIfNotNull("--sourcelink:", sourceLink)
builder.AppendSwitchIfNotNull("--langVersion:", langVersion)
builder.AppendSwitchIfNotNull("--langversion:", langVersion)
// NoFramework
if noFramework then
builder.AppendSwitch("--noframework")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@
<Compile Include="..\sr.fs">
<Link>ErrorText\sr.fs</Link>
</Compile>
<Compile Include="..\LanguageFeatures.fsi">
<Link>Driver\LanguageFeatures.fsi</Link>
</Compile>
<Compile Include="..\LanguageFeatures.fs">
<Link>Driver\LanguageFeatures.fs</Link>
</Compile>
<Compile Include="..\..\utils\prim-lexing.fsi">
<Link>LexYaccRuntime\prim-lexing.fsi</Link>
</Compile>
Expand Down
90 changes: 90 additions & 0 deletions src/fsharp/LanguageFeatures.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

/// Coordinating compiler operations - configuration, loading initial context, reporting errors etc.
module internal FSharp.Compiler.Features

open System

//------------------------------------------------------------------------------------------------------------------
// Language version command line switch
//------------------------------------------------------------------------------------------------------------------
// Add your features to this List - in code use languageVersion.SupportsFeature(LanguageFeatures.yourFeature)
// a return value of false means your feature is not supported by the user's language selection
// All new language features added from now on must be protected by this.
// Note:
// * The fslang design process will require a decision about feature name and whether it is required.
// * When a feature is assigned a release language, we will scrub the code of feature references and apply
// the Release Language version.

/// LanguageFeature enumeration
[<RequireQualifiedAccess>]
type LanguageFeature =
| LanguageVersion46 = 0
| LanguageVersion47 = 1
| SingleUnderscorePattern = 2
| Nullness = 1000
| ScriptingPackageManagement = 1001

/// LanguageVersion management
type LanguageVersion (specifiedVersion) =

// When we increment language versions here preview is higher than current RTM version
static let languageVersion46 = 4.6m
static let languageVersion47 = 4.7m

static let previewVersion = languageVersion47 // Language version when preview specified
static let defaultVersion = languageVersion46 // Language version when default specified
static let latestVersion = defaultVersion // Language version when latest specified
static let latestMajorVersion = languageVersion46 // Language version when latestmajor specified

static let validOptions = [| "preview"; "default"; "latest"; "latestmajor" |]
static let languageVersions = set [| latestVersion |]

static let features = dict [|
// Add new LanguageVersions here ...
LanguageFeature.LanguageVersion47, 4.7m
LanguageFeature.LanguageVersion46, 4.6m
LanguageFeature.Nullness, previewVersion
LanguageFeature.ScriptingPackageManagement, previewVersion
LanguageFeature.SingleUnderscorePattern, previewVersion

// Add new LanguageFeatures here ...
|]

let specified =
match specifiedVersion with
| "?" -> 0m
| "preview" -> previewVersion
| "default" -> latestVersion
| "latest" -> latestVersion
| "latestmajor" -> latestMajorVersion
| _ ->
match Decimal.TryParse(specifiedVersion) with
| true, v -> v
| _ -> 0m

/// Check if this feature is supported by the selected langversion
member __.SupportsFeature featureId =
match features.TryGetValue featureId with
| true, v -> v <= specified
| false, _ -> false

/// Does the languageVersion support this version string
member __.ContainsVersion version =
match version with
| "?" | "preview" | "default" | "latest" | "latestmajor" -> true
| _ ->
match Decimal.TryParse(specifiedVersion) with
| true, v -> languageVersions.Contains v
| _ -> false

/// Get a list of valid strings for help text
member __.ValidOptions = validOptions

/// Get a list of valid versions for help text
member __.ValidVersions = [|
for v in languageVersions |> Seq.sort do
let label = if v = defaultVersion || v = latestVersion then "(Default)" else ""
yield sprintf "%M %s" v label
|]

31 changes: 31 additions & 0 deletions src/fsharp/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

/// Coordinating compiler operations - configuration, loading initial context, reporting errors etc.
module internal FSharp.Compiler.Features

/// LanguageFeature enumeration
[<RequireQualifiedAccess>]
type LanguageFeature =
| LanguageVersion46 = 0
| LanguageVersion47 = 1
| SingleUnderscorePattern = 2
| Nullness = 1000
| ScriptingPackageManagement = 1001

/// LanguageVersion management
type LanguageVersion =

/// Create a LanguageVersion management object
new: string -> LanguageVersion

/// Get the list of valid versions
member ContainsVersion: string -> bool

/// Does the specified LanguageVersion support the specified feature
member SupportsFeature: LanguageFeature -> bool

/// Get the list of valid versions
member ValidVersions: string array

/// Get the list of valid options
member ValidOptions: string array
Loading

0 comments on commit 522fc42

Please sign in to comment.