From 35a4995584e4ea5ceb23463b18b1eb97e4cc4c73 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:27:20 +0000 Subject: [PATCH 01/18] bringing #nowarn args warnings back --- src/Compiler/Driver/CompilerConfig.fs | 36 ++++++++--------- src/Compiler/Driver/CompilerConfig.fsi | 2 +- src/Compiler/Driver/ParseAndCheckInputs.fs | 6 +-- .../CompilerDirectives/NonStringArgs.fs | 39 ++++++++++++++----- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index cd883c6f7c7..bbd9a1dee46 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -91,25 +91,25 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let GetWarningNumber (m, warningNumber: string, prefixSupported) = - try - let warningNumber = - if warningNumber.StartsWithOrdinal "FS" then - if prefixSupported then - warningNumber.Substring 2 - else - raise (new ArgumentException()) - else - warningNumber +let GetWarningNumber (m, warningNumberString: string, (langVersion: LanguageVersion)) = + let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes + let prefixSupported = langVersion.SupportsFeature(argFeature) - if Char.IsDigit(warningNumber[0]) then - Some(int32 warningNumber) - else - None - with _ -> - warning (Error(FSComp.SR.buildInvalidWarningNumber warningNumber, m)) + let warn err = + warning err None + if (warningNumberString.StartsWithOrdinal "FS") then + match prefixSupported, System.Int32.TryParse(warningNumberString.Substring 2) with + | true, (true, i) -> Some i + | true, (false, _) + | false, (false, _) -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) + | false, (true, _) -> warn (languageFeatureError langVersion argFeature m) + else + match System.Int32.TryParse warningNumberString with + | true, i -> Some i + | false, _ -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) + let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try // remove any quotation marks from the path first @@ -931,7 +931,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOff(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonQuotes)) with + match GetWarningNumber(m, s, tcConfigB.langVersion) with | None -> () | Some n -> // nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus @@ -946,7 +946,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOn(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonQuotes)) with + match GetWarningNumber(m, s, tcConfigB.langVersion) with | None -> () | Some n -> // warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 98c52f900e0..72e2c1e14db 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -922,7 +922,7 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string -val GetWarningNumber: m: range * warningNumber: string * prefixSupported: bool -> int option +val GetWarningNumber: m: range * warningNumberString: string * langVersion: LanguageVersion -> int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index a6804bfe746..3dc1dcd1c29 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -228,9 +228,9 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = match supportsNonStringArguments, s with | _, ParsedHashDirectiveArgument.SourceIdentifier _ -> None | true, ParsedHashDirectiveArgument.LongIdent _ -> None - | true, ParsedHashDirectiveArgument.Int32(n, _) -> GetWarningNumber(m, string n, true) - | true, ParsedHashDirectiveArgument.Ident(s, _) -> GetWarningNumber(m, s.idText, true) - | _, ParsedHashDirectiveArgument.String(s, _, _) -> GetWarningNumber(m, s, true) + | true, ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion) + | true, ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion) + | _, ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, s, langVersion) | _ -> None match warningNumber with diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 080811bd7c2..30e7ab854a9 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -24,15 +24,21 @@ module NonStringArgs = |> asExe |> compile |> shouldFail - |> withDiagnostics[ + |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 203, Line 6, Col 1, Line 6, Col 13, "Invalid warning number 'FS'") + (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'") + (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'") + (Warning 203, Line 8, Col 9, Line 8, Col 15, "Invalid warning number 'ACME'") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 9, Line 4, Col 15, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 9, Line 5, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") else - (Warning 203, Line 3, Col 1, Line 3, Col 11, "Invalid warning number 'FS'") - (Warning 203, Line 6, Col 1, Line 6, Col 13, "Invalid warning number 'FS'") + (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); + (Warning 203, Line 4, Col 9, Line 4, Col 15, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 5, Col 9, Line 5, Col 13, "Invalid warning number 'ACME'"); + (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'"); + (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 8, Col 9, Line 8, Col 15, "Invalid warning number 'ACME'") ] @@ -55,14 +61,21 @@ module NonStringArgs = |> asExe |> compile |> shouldFail - |> withDiagnostics[ + |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 203, Line 2, Col 1, Line 9, Col 11, "Invalid warning number 'FS'") + (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'") + (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'") + (Warning 203, Line 9, Col 5, Line 9, Col 11, "Invalid warning number 'ACME'") (Error 3350, Line 4, Col 5, Line 4, Col 7, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 5, Line 5, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 6, Col 5, Line 6, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") else - (Warning 203, Line 2, Col 1, Line 9, Col 11, "Invalid warning number 'FS'") + (Warning 203, Line 4, Col 5, Line 4, Col 7, "Invalid warning number 'FS'"); + (Warning 203, Line 5, Col 5, Line 5, Col 11, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 6, Col 5, Line 6, Col 9, "Invalid warning number 'ACME'"); + (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'"); + (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 9, Col 5, Line 9, Col 11, "Invalid warning number 'ACME'") ] @@ -81,12 +94,19 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 203, Line 3, Col 1, Line 3, Col 44, "Invalid warning number 'FS'") + (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'") + (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'") + (Warning 203, Line 3, Col 38, Line 3, Col 44, "Invalid warning number 'ACME'") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 12, Line 3, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 19, Line 3, Col 23, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") else - (Warning 203, Line 3, Col 1, Line 3, Col 44, "Invalid warning number 'FS'") + (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); + (Warning 203, Line 3, Col 12, Line 3, Col 18, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 3, Col 19, Line 3, Col 23, "Invalid warning number 'ACME'"); + (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'"); + (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 3, Col 38, Line 3, Col 44, "Invalid warning number 'ACME'") ] @@ -126,6 +146,7 @@ module DoBinding = |> shouldFail |> withDiagnostics [ (Warning 1104, Line 5, Col 15, Line 5, Col 31, "Identifiers containing '@' are reserved for use in F# code generation") + (Warning 3350, Line 2, Col 26, Line 2, Col 34, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 2, Col 9, Line 2, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 2, Col 12, Line 2, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") ] From ba5e277ab56f24d2a985521040d9b65867e7ff09 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:20:45 +0000 Subject: [PATCH 02/18] warnings for invalid #nowarn arguments --- src/Compiler/Driver/CompilerConfig.fs | 8 ++++---- src/Compiler/Driver/CompilerConfig.fsi | 2 +- src/Compiler/Driver/ParseAndCheckInputs.fs | 6 +++--- .../CompilerOptions/fsc/warn/warn.fs | 5 +++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index bbd9a1dee46..9d56408ae5d 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -91,9 +91,9 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let GetWarningNumber (m, warningNumberString: string, (langVersion: LanguageVersion)) = +let GetWarningNumber (m, warningNumberString: string, (langVersion: LanguageVersion), isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes - let prefixSupported = langVersion.SupportsFeature(argFeature) + let prefixSupported = langVersion.SupportsFeature(argFeature) || isCompilerOption let warn err = warning err @@ -931,7 +931,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOff(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion) with + match GetWarningNumber(m, s, tcConfigB.langVersion, true) with | None -> () | Some n -> // nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus @@ -946,7 +946,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOn(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion) with + match GetWarningNumber(m, s, tcConfigB.langVersion, true) with | None -> () | Some n -> // warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 72e2c1e14db..31b4c0cfa40 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -922,7 +922,7 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string -val GetWarningNumber: m: range * warningNumberString: string * langVersion: LanguageVersion -> int option +val GetWarningNumber: m: range * warningNumberString: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 3dc1dcd1c29..b36a708b1f9 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -228,9 +228,9 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = match supportsNonStringArguments, s with | _, ParsedHashDirectiveArgument.SourceIdentifier _ -> None | true, ParsedHashDirectiveArgument.LongIdent _ -> None - | true, ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion) - | true, ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion) - | _, ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, s, langVersion) + | true, ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion, false) + | true, ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion, false) + | _, ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, s, langVersion, false) | _ -> None match warningNumber with diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs index 9dd6dea0e91..4d2a5bf193c 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs @@ -145,8 +145,9 @@ module TestCompilerWarningLevel = compilation |> asExe |> withOptions ["--nowarn:NU0000;FS40;NU0001;FS21"] - |> compileAndRun - |> shouldSucceed + |> compile + |> shouldFail + |> withWarningCodes [203; 203] |> ignore [] From 9d521fa901cb2646d46c2dc0e488de5b836ea756 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:07:52 +0000 Subject: [PATCH 03/18] fix v8 case --- src/Compiler/Driver/CompilerConfig.fs | 7 ++++--- .../CompilerDirectives/NonStringArgs.fs | 3 --- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 9d56408ae5d..fa67683c4e7 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -106,9 +106,10 @@ let GetWarningNumber (m, warningNumberString: string, (langVersion: LanguageVers | false, (false, _) -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) | false, (true, _) -> warn (languageFeatureError langVersion argFeature m) else - match System.Int32.TryParse warningNumberString with - | true, i -> Some i - | false, _ -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) + match prefixSupported, System.Int32.TryParse warningNumberString with + | _, (true, i) -> Some i + | true, (false, _) -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) + | false, (false, _) -> None let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 30e7ab854a9..ebf1859b102 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -28,7 +28,6 @@ module NonStringArgs = if languageVersion = "8.0" then (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'") (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'") - (Warning 203, Line 8, Col 9, Line 8, Col 15, "Invalid warning number 'ACME'") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 9, Line 4, Col 15, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 9, Line 5, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") @@ -65,7 +64,6 @@ module NonStringArgs = if languageVersion = "8.0" then (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'") (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'") - (Warning 203, Line 9, Col 5, Line 9, Col 11, "Invalid warning number 'ACME'") (Error 3350, Line 4, Col 5, Line 4, Col 7, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 5, Line 5, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 6, Col 5, Line 6, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") @@ -96,7 +94,6 @@ module NonStringArgs = if languageVersion = "8.0" then (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'") (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'") - (Warning 203, Line 3, Col 38, Line 3, Col 44, "Invalid warning number 'ACME'") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 12, Line 3, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 19, Line 3, Col 23, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") From a85a29c41d31db754fe8444fe4f57fd70c98f5e5 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:12:57 +0000 Subject: [PATCH 04/18] formatting --- src/Compiler/Driver/CompilerConfig.fsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 31b4c0cfa40..b347016a0d6 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -922,7 +922,8 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string -val GetWarningNumber: m: range * warningNumberString: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option +val GetWarningNumber: + m: range * warningNumberString: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string From fba907a0ff5e9f542bc2e98f7f3830f66736dba6 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:20:56 +0000 Subject: [PATCH 05/18] release notes --- docs/release-notes/.FSharp.Compiler.Service/9.0.200.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index fe3cde0444a..7268a88b284 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -19,5 +19,6 @@ * Better ranges for CE `return, yield, return! and yield!` error reporting. ([PR #17792](https://github.com/dotnet/fsharp/pull/17792)) * Better ranges for CE `match!`. ([PR #17789](https://github.com/dotnet/fsharp/pull/17789)) * Better ranges for CE `use` error reporting. ([PR #17811](https://github.com/dotnet/fsharp/pull/17811)) +* Better ranges for #nowarn error reporting; bring back warnings for --langVerison:80; add warnings under feature flag ([PR #17871(https://github.com/dotnet/fsharp/pull/17871)]) ### Breaking Changes From d555e8870b814f2c5708874d62f8bd3e9d17d83d Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 13:21:53 +0000 Subject: [PATCH 06/18] further v8 fixes --- src/Compiler/Driver/CompilerConfig.fs | 36 +++++++++++-------- src/Compiler/Driver/CompilerConfig.fsi | 2 +- src/Compiler/Driver/ParseAndCheckInputs.fs | 2 +- .../CompilerDirectives/NonStringArgs.fs | 32 ++++++++--------- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index fa67683c4e7..cbcf059f706 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -27,6 +27,7 @@ open FSharp.Compiler.Text.Range open FSharp.Compiler.Xml open FSharp.Compiler.TypedTree open FSharp.Compiler.BuildGraph +open System.Text.RegularExpressions #if !NO_TYPEPROVIDERS open FSharp.Core.CompilerServices @@ -91,25 +92,32 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let GetWarningNumber (m, warningNumberString: string, (langVersion: LanguageVersion), isCompilerOption: bool) = +let private optionRegex = Regex("""^()[A-Z]?(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private codeRegex = Regex("""^(\"?)(?:(?:FS)?(\d+))\1$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private codeRegex8 = Regex("""^"()(\d+)"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private codeRegex8fs = Regex("""^"FS.*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private codeRegex8ignore = Regex("""^"\d*\D+\d*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private codeRegex8nonQuote = Regex("""^[^"].+$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) + +let GetWarningNumber (m, numStr: string, (langVersion: LanguageVersion), isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes let prefixSupported = langVersion.SupportsFeature(argFeature) || isCompilerOption - let warn err = - warning err + let getNum (regex: Regex) = + let mtch = regex.Match numStr + if not mtch.Success || mtch.Groups.Count <> 3 || mtch.Groups[2].Captures.Count <> 1 then + warning(Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) + None + else Some (int mtch.Groups[2].Captures[0].Value) + + if isCompilerOption then getNum optionRegex + elif prefixSupported then getNum codeRegex + elif codeRegex8nonQuote.Match(numStr).Success || codeRegex8fs.Match(numStr).Success then + warning(languageFeatureError langVersion argFeature m) None + elif codeRegex8ignore.Match(numStr).Success then None + else getNum codeRegex8 - if (warningNumberString.StartsWithOrdinal "FS") then - match prefixSupported, System.Int32.TryParse(warningNumberString.Substring 2) with - | true, (true, i) -> Some i - | true, (false, _) - | false, (false, _) -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) - | false, (true, _) -> warn (languageFeatureError langVersion argFeature m) - else - match prefixSupported, System.Int32.TryParse warningNumberString with - | _, (true, i) -> Some i - | true, (false, _) -> warn (Error(FSComp.SR.buildInvalidWarningNumber warningNumberString, m)) - | false, (false, _) -> None let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index b347016a0d6..8eeb916ee21 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -923,7 +923,7 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string val GetWarningNumber: - m: range * warningNumberString: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option + m: range * numStr: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index b36a708b1f9..a3d2b15716a 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -230,7 +230,7 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = | true, ParsedHashDirectiveArgument.LongIdent _ -> None | true, ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion, false) | true, ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion, false) - | _, ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, s, langVersion, false) + | _, ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, $"\"{s}\"", langVersion, false) | _ -> None match warningNumber with diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index ebf1859b102..7d751b3b81a 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -26,8 +26,8 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'") - (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'") + (Warning 3350, Line 6, Col 9, Line 6, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 3350, Line 7, Col 9, Line 7, Col 17, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 9, Line 4, Col 15, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 9, Line 5, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") @@ -35,9 +35,9 @@ module NonStringArgs = (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 4, Col 9, Line 4, Col 15, "Invalid warning number 'FSBLAH'"); (Warning 203, Line 5, Col 9, Line 5, Col 13, "Invalid warning number 'ACME'"); - (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'"); - (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'"); - (Warning 203, Line 8, Col 9, Line 8, Col 15, "Invalid warning number 'ACME'") + (Warning 203, Line 6, Col 9, Line 6, Col 13, """Invalid warning number '"FS"'"""); + (Warning 203, Line 7, Col 9, Line 7, Col 17, """Invalid warning number '"FSBLAH"'"""); + (Warning 203, Line 8, Col 9, Line 8, Col 15, """Invalid warning number '"ACME"'""") ] @@ -62,8 +62,8 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'") - (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'") + (Warning 3350, Line 7, Col 5, Line 7, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 3350, Line 8, Col 5, Line 8, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 5, Line 4, Col 7, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 5, Line 5, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 6, Col 5, Line 6, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") @@ -71,9 +71,9 @@ module NonStringArgs = (Warning 203, Line 4, Col 5, Line 4, Col 7, "Invalid warning number 'FS'"); (Warning 203, Line 5, Col 5, Line 5, Col 11, "Invalid warning number 'FSBLAH'"); (Warning 203, Line 6, Col 5, Line 6, Col 9, "Invalid warning number 'ACME'"); - (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'"); - (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'"); - (Warning 203, Line 9, Col 5, Line 9, Col 11, "Invalid warning number 'ACME'") + (Warning 203, Line 7, Col 5, Line 7, Col 9, """Invalid warning number '"FS"'"""); + (Warning 203, Line 8, Col 5, Line 8, Col 13, """Invalid warning number '"FSBLAH"'"""); + (Warning 203, Line 9, Col 5, Line 9, Col 11, """Invalid warning number '"ACME"'""") ] @@ -92,8 +92,8 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'") - (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'") + (Warning 3350, Line 3, Col 24, Line 3, Col 28, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 3350, Line 3, Col 29, Line 3, Col 37, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 12, Line 3, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 19, Line 3, Col 23, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") @@ -101,9 +101,9 @@ module NonStringArgs = (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 3, Col 12, Line 3, Col 18, "Invalid warning number 'FSBLAH'"); (Warning 203, Line 3, Col 19, Line 3, Col 23, "Invalid warning number 'ACME'"); - (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'"); - (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'"); - (Warning 203, Line 3, Col 38, Line 3, Col 44, "Invalid warning number 'ACME'") + (Warning 203, Line 3, Col 24, Line 3, Col 28, """Invalid warning number '"FS"'"""); + (Warning 203, Line 3, Col 29, Line 3, Col 37, """Invalid warning number '"FSBLAH"'"""); + (Warning 203, Line 3, Col 38, Line 3, Col 44, """Invalid warning number '"ACME"'""") ] @@ -266,7 +266,7 @@ printfn "Hello, World" |> asExe |> compile |> shouldFail - |> withDiagnostics[ + |> withDiagnostics [ (Error 76, Line 2, Col 9, Line 2, Col 11, "This directive may only be used in F# script files (extensions .fsx or .fsscript). Either remove the directive, move this code to a script file or delimit the directive with '#if INTERACTIVE'/'#endif'.") (Error 76, Line 3, Col 9, Line 3, Col 14, "This directive may only be used in F# script files (extensions .fsx or .fsscript). Either remove the directive, move this code to a script file or delimit the directive with '#if INTERACTIVE'/'#endif'.") (Error 76, Line 4, Col 9, Line 4, Col 17, "This directive may only be used in F# script files (extensions .fsx or .fsscript). Either remove the directive, move this code to a script file or delimit the directive with '#if INTERACTIVE'/'#endif'.") From d10b2b48eff50c23d40da997f1fb7231a706e25c Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 14:05:14 +0000 Subject: [PATCH 07/18] fix duplicate prefix removal and add test for it --- src/Compiler/Driver/CompilerOptions.fs | 4 ++-- .../CompilerDirectives/NonStringArgs.fs | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index 96c40724ef4..ee57936c7ee 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -832,7 +832,7 @@ let errorsAndWarningsFlags (tcConfigB: TcConfigBuilder) = CompilerOption( "nowarn", tagWarnList, - OptionStringList(fun n -> tcConfigB.TurnWarningOff(rangeCmdArgs, trimFS n)), + OptionStringList(fun n -> tcConfigB.TurnWarningOff(rangeCmdArgs, n)), None, Some(FSComp.SR.optsNowarn ()) ) @@ -840,7 +840,7 @@ let errorsAndWarningsFlags (tcConfigB: TcConfigBuilder) = CompilerOption( "warnon", tagWarnList, - OptionStringList(fun n -> tcConfigB.TurnWarningOn(rangeCmdArgs, trimFS n)), + OptionStringList(fun n -> tcConfigB.TurnWarningOn(rangeCmdArgs, n)), None, Some(FSComp.SR.optsWarnOn ()) ) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 7d751b3b81a..2dabda4c8d9 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -152,6 +152,26 @@ module DoBinding = |> shouldSucceed + [] + [] + [] + let ``#nowarn - errors - compiler options`` (languageVersion) = + + FSharp """ +() + """ + |> withLangVersion languageVersion + |> withOptions ["--nowarn:988"; "--nowarn:FS"; "--nowarn:FSBLAH"; "--nowarn:NU0001"] + |> asExe + |> compile + |> shouldFail + |> withDiagnostics [ + (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FS'"); + (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'NU0001'") + ] + + [] [] [] From 526b930dad39d8097b70f9bceea23c21dc171f30 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:51:55 +0000 Subject: [PATCH 08/18] another stupid error fixed and test added --- src/Compiler/Driver/CompilerConfig.fs | 2 +- .../CompilerDirectives/NonStringArgs.fs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index cbcf059f706..3fb7b5ee415 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -92,7 +92,7 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let private optionRegex = Regex("""^()[A-Z]?(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private optionRegex = Regex("""^()[A-Z]*(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex = Regex("""^(\"?)(?:(?:FS)?(\d+))\1$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex8 = Regex("""^"()(\d+)"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex8fs = Regex("""^"FS.*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 2dabda4c8d9..ad011b7ca4c 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -161,14 +161,13 @@ module DoBinding = () """ |> withLangVersion languageVersion - |> withOptions ["--nowarn:988"; "--nowarn:FS"; "--nowarn:FSBLAH"; "--nowarn:NU0001"] + |> withOptions ["--nowarn:988"; "--nowarn:FS25"; "--nowarn:FS"; "--nowarn:FSBLAH"; "--nowarn:NU0001"] |> asExe |> compile |> shouldFail |> withDiagnostics [ (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FS'"); (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FSBLAH'"); - (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'NU0001'") ] From 6ae40f7bd6cd3193357a8f0a2d3e95acda16d4f9 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 11 Oct 2024 21:03:51 +0000 Subject: [PATCH 09/18] more fixes, tests --- src/Compiler/Driver/CompilerConfig.fs | 20 +++++++++++-------- .../CompilerDirectives/NonStringArgs.fs | 10 ++++++---- .../CompilerOptions/fsc/warn/warn.fs | 7 +++---- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 3fb7b5ee415..0e84a077db0 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -92,31 +92,35 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let private optionRegex = Regex("""^()[A-Z]*(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private optionRegex = Regex("""^(FS)?(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private optionRegexIgnore = Regex("""^([A-Z]*)(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex = Regex("""^(\"?)(?:(?:FS)?(\d+))\1$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex8 = Regex("""^"()(\d+)"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private codeRegex8fs = Regex("""^"FS.*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private codeRegex8prefix = Regex("""^"FS.*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex8ignore = Regex("""^"\d*\D+\d*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let private codeRegex8nonQuote = Regex("""^[^"].+$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) let GetWarningNumber (m, numStr: string, (langVersion: LanguageVersion), isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes let prefixSupported = langVersion.SupportsFeature(argFeature) || isCompilerOption + let warnInvalid() = warning(Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) - let getNum (regex: Regex) = + let getNum (regex: Regex) failAction = let mtch = regex.Match numStr if not mtch.Success || mtch.Groups.Count <> 3 || mtch.Groups[2].Captures.Count <> 1 then - warning(Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) + failAction() None else Some (int mtch.Groups[2].Captures[0].Value) - if isCompilerOption then getNum optionRegex - elif prefixSupported then getNum codeRegex - elif codeRegex8nonQuote.Match(numStr).Success || codeRegex8fs.Match(numStr).Success then + if isCompilerOption then + getNum optionRegex (fun () -> + if not <| optionRegexIgnore.Match(numStr).Success then warnInvalid()) + elif prefixSupported then getNum codeRegex warnInvalid + elif codeRegex8nonQuote.Match(numStr).Success || codeRegex8prefix.Match(numStr).Success then warning(languageFeatureError langVersion argFeature m) None elif codeRegex8ignore.Match(numStr).Success then None - else getNum codeRegex8 + else getNum codeRegex8 warnInvalid let ComputeMakePathAbsolute implicitIncludeDir (path: string) = diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index ad011b7ca4c..9d7418ad17e 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -158,16 +158,18 @@ module DoBinding = let ``#nowarn - errors - compiler options`` (languageVersion) = FSharp """ -() +match None with None -> () // creates FS0025 +"" // creates FS0020 """ |> withLangVersion languageVersion - |> withOptions ["--nowarn:988"; "--nowarn:FS25"; "--nowarn:FS"; "--nowarn:FSBLAH"; "--nowarn:NU0001"] + |> withOptions ["--nowarn:NU0988"; "--nowarn:FS25"; "--nowarn:20"; "--nowarn:FS"; "--nowarn:FSBLAH"] |> asExe |> compile |> shouldFail |> withDiagnostics [ - (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FS'"); - (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FS'") + (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FSBLAH'") + (Warning 988, Line 3, Col 3, Line 3, Col 3, "Main module of program is empty: nothing will happen when it is run") ] diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs index 4d2a5bf193c..8ed00f86741 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs @@ -142,12 +142,11 @@ module TestCompilerWarningLevel = [] let ``warn40_fs --nowarn:NU0000;FS40;NU0001`` compilation = - compilation + compilation |> asExe |> withOptions ["--nowarn:NU0000;FS40;NU0001;FS21"] - |> compile - |> shouldFail - |> withWarningCodes [203; 203] + |> compileAndRun + |> shouldSucceed |> ignore [] From 87a95f1e4d2b1481774bc7b19172a95101204db6 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Sat, 12 Oct 2024 05:29:59 +0000 Subject: [PATCH 10/18] formatting --- src/Compiler/Driver/CompilerConfig.fs | 49 ++++++++++++++++---------- src/Compiler/Driver/CompilerConfig.fsi | 3 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 0e84a077db0..1930416ac13 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -92,36 +92,47 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let private optionRegex = Regex("""^(FS)?(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private optionRegexIgnore = Regex("""^([A-Z]*)(\d+)$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private codeRegex = Regex("""^(\"?)(?:(?:FS)?(\d+))\1$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private codeRegex8 = Regex("""^"()(\d+)"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private codeRegex8prefix = Regex("""^"FS.*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private codeRegex8ignore = Regex("""^"\d*\D+\d*"$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) -let private codeRegex8nonQuote = Regex("""^[^"].+$""", RegexOptions.Compiled ||| RegexOptions.CultureInvariant) +let private regexCompiled = RegexOptions.Compiled ||| RegexOptions.CultureInvariant +let private optionRegex = Regex("""^(FS)?(\d+)$""", regexCompiled) +let private optionRegexIgnore = Regex("""^([A-Z]*)(\d+)$""", regexCompiled) +let private codeRegex = Regex("""^(\"?)(?:(?:FS)?(\d+))\1$""", regexCompiled) +let private codeRegex8 = Regex("""^"()(\d+)"$""", regexCompiled) +let private codeRegex8prefix = Regex("""^"FS.*"$""", regexCompiled) +let private codeRegex8ignore = Regex("""^"\d*\D+\d*"$""", regexCompiled) +let private codeRegex8nonQuote = Regex("""^[^"].+$""", regexCompiled) let GetWarningNumber (m, numStr: string, (langVersion: LanguageVersion), isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes let prefixSupported = langVersion.SupportsFeature(argFeature) || isCompilerOption - let warnInvalid() = warning(Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) + + let warnInvalid () = + warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) let getNum (regex: Regex) failAction = let mtch = regex.Match numStr + if not mtch.Success || mtch.Groups.Count <> 3 || mtch.Groups[2].Captures.Count <> 1 then - failAction() + failAction () None - else Some (int mtch.Groups[2].Captures[0].Value) - + else + Some(int mtch.Groups[2].Captures[0].Value) + if isCompilerOption then - getNum optionRegex (fun () -> - if not <| optionRegexIgnore.Match(numStr).Success then warnInvalid()) - elif prefixSupported then getNum codeRegex warnInvalid - elif codeRegex8nonQuote.Match(numStr).Success || codeRegex8prefix.Match(numStr).Success then - warning(languageFeatureError langVersion argFeature m) + getNum optionRegex (fun () -> + if not <| optionRegexIgnore.Match(numStr).Success then + warnInvalid ()) + elif prefixSupported then + getNum codeRegex warnInvalid + elif + codeRegex8nonQuote.Match(numStr).Success + || codeRegex8prefix.Match(numStr).Success + then + warning (languageFeatureError langVersion argFeature m) None - elif codeRegex8ignore.Match(numStr).Success then None - else getNum codeRegex8 warnInvalid - + elif codeRegex8ignore.Match(numStr).Success then + None + else + getNum codeRegex8 warnInvalid let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 8eeb916ee21..a7a8a4df0ce 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -922,8 +922,7 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string -val GetWarningNumber: - m: range * numStr: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option +val GetWarningNumber: m: range * numStr: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string From 79ff74c6cfdc030f6ef974713ec2870983247e17 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Sat, 12 Oct 2024 15:55:26 +0000 Subject: [PATCH 11/18] simplification and fixes. --- src/Compiler/Driver/CompilerConfig.fs | 35 +++++++++---------- src/Compiler/Driver/ParseAndCheckInputs.fs | 21 +++++------ src/Compiler/Interactive/fsi.fs | 4 ++- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 10 ++++++ src/Compiler/SyntaxTree/SyntaxTreeOps.fsi | 2 ++ .../CompilerDirectives/NonStringArgs.fs | 14 ++++---- .../CompilerOptions/fsc/warn/warn.fs | 2 +- 7 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 1930416ac13..2915e04414c 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -95,44 +95,43 @@ let ResolveFileUsingPaths (paths, m, fileName) = let private regexCompiled = RegexOptions.Compiled ||| RegexOptions.CultureInvariant let private optionRegex = Regex("""^(FS)?(\d+)$""", regexCompiled) let private optionRegexIgnore = Regex("""^([A-Z]*)(\d+)$""", regexCompiled) -let private codeRegex = Regex("""^(\"?)(?:(?:FS)?(\d+))\1$""", regexCompiled) -let private codeRegex8 = Regex("""^"()(\d+)"$""", regexCompiled) +let private codeRegex = Regex("""^("?)(?:(?:FS)?(\d+))\1$""", regexCompiled) +let private codeRegex8 = Regex("""^(")(\d+)"$""", regexCompiled) +let private codeRegex8nonQuote = Regex("""^[^"].+$""", regexCompiled) let private codeRegex8prefix = Regex("""^"FS.*"$""", regexCompiled) let private codeRegex8ignore = Regex("""^"\d*\D+\d*"$""", regexCompiled) -let private codeRegex8nonQuote = Regex("""^[^"].+$""", regexCompiled) let GetWarningNumber (m, numStr: string, (langVersion: LanguageVersion), isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes - let prefixSupported = langVersion.SupportsFeature(argFeature) || isCompilerOption + let prefixSupported = langVersion.SupportsFeature(argFeature) let warnInvalid () = warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) - let getNum (regex: Regex) failAction = + let getNumber (regex: Regex) failAction = let mtch = regex.Match numStr - if not mtch.Success || mtch.Groups.Count <> 3 || mtch.Groups[2].Captures.Count <> 1 then + if mtch.Success then + Some(int mtch.Groups[2].Captures[0].Value) + else failAction () None - else - Some(int mtch.Groups[2].Captures[0].Value) + + let matches (regex: Regex) = regex.Match(numStr).Success if isCompilerOption then - getNum optionRegex (fun () -> - if not <| optionRegexIgnore.Match(numStr).Success then + getNumber optionRegex (fun () -> + if not (matches optionRegexIgnore) then warnInvalid ()) elif prefixSupported then - getNum codeRegex warnInvalid - elif - codeRegex8nonQuote.Match(numStr).Success - || codeRegex8prefix.Match(numStr).Success - then - warning (languageFeatureError langVersion argFeature m) + getNumber codeRegex warnInvalid + elif matches codeRegex8nonQuote || matches codeRegex8prefix then + errorR (languageFeatureError langVersion argFeature m) None - elif codeRegex8ignore.Match(numStr).Success then + elif matches codeRegex8ignore then None else - getNum codeRegex8 warnInvalid + getNumber codeRegex8 warnInvalid let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index a3d2b15716a..21b1cb9a7f2 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -217,20 +217,15 @@ let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, fileName, intf) SynModuleOrNamespaceSig(lid, isRecursive, kind, decls, xmlDoc, attributes, None, range, trivia) let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = - let supportsNonStringArguments = - langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonQuotes) - [ match hd with - | ParsedHashDirective("nowarn", numbers, m) -> - for s in numbers do + | ParsedHashDirective("nowarn", args, m) -> + for s in args do let warningNumber = - match supportsNonStringArguments, s with - | _, ParsedHashDirectiveArgument.SourceIdentifier _ -> None - | true, ParsedHashDirectiveArgument.LongIdent _ -> None - | true, ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion, false) - | true, ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion, false) - | _, ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, $"\"{s}\"", langVersion, false) + match s with + | ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion, false) + | ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion, false) + | ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, $"\"{s}\"", langVersion, false) | _ -> None match warningNumber with @@ -912,7 +907,9 @@ let ProcessMetaCommandsFromInput state | ParsedHashDirective("nowarn", hashArguments, m) -> - let arguments = parsedHashDirectiveArguments hashArguments tcConfig.langVersion + let arguments = + parsedHashDirectiveArgumentsNoCheck hashArguments tcConfig.langVersion + List.fold (fun state d -> nowarnF state (m, d)) state arguments | ParsedHashDirective(("reference" | "r") as c, [], m) -> diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index 74fcc37340c..785bf97e583 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -3849,7 +3849,9 @@ type FsiInteractionProcessor istate, Completed None | ParsedHashDirective("nowarn", nowarnArguments, m) -> - let numbers = (parsedHashDirectiveArguments nowarnArguments tcConfigB.langVersion) + let numbers = + (parsedHashDirectiveArgumentsNoCheck nowarnArguments tcConfigB.langVersion) + List.iter (fun (d: string) -> tcConfigB.TurnWarningOff(m, d)) numbers istate, Completed None diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 8dc46313341..1c844512a29 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -1005,6 +1005,16 @@ let parsedHashDirectiveArguments (input: ParsedHashDirectiveArgument list) (lang | false -> None) input +let parsedHashDirectiveArgumentsNoCheck (input: ParsedHashDirectiveArgument list) (langVersion: LanguageVersion) = + List.choose + (function + | ParsedHashDirectiveArgument.String(s, _, _) -> Some s + | ParsedHashDirectiveArgument.SourceIdentifier(_, v, _) -> Some v + | ParsedHashDirectiveArgument.Int32(n, m) -> Some(string n) + | ParsedHashDirectiveArgument.Ident(ident, m) -> Some(ident.idText) + | ParsedHashDirectiveArgument.LongIdent(ident, m) -> Some(longIdentToString ident)) + input + let parsedHashDirectiveStringArguments (input: ParsedHashDirectiveArgument list) (_langVersion: LanguageVersion) = List.choose (function diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi index 568e745a167..a5d18607e81 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi @@ -322,6 +322,8 @@ val synExprContainsError: inpExpr: SynExpr -> bool val parsedHashDirectiveArguments: ParsedHashDirectiveArgument list -> LanguageVersion -> string list +val parsedHashDirectiveArgumentsNoCheck: ParsedHashDirectiveArgument list -> LanguageVersion -> string list + val parsedHashDirectiveStringArguments: ParsedHashDirectiveArgument list -> LanguageVersion -> string list /// 'e1 && e2' diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 9d7418ad17e..9b466fd36a3 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -26,11 +26,11 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 3350, Line 6, Col 9, Line 6, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 3350, Line 7, Col 9, Line 7, Col 17, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 9, Line 4, Col 15, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 9, Line 5, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 6, Col 9, Line 6, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 7, Col 9, Line 7, Col 17, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") else (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 4, Col 9, Line 4, Col 15, "Invalid warning number 'FSBLAH'"); @@ -62,11 +62,11 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 3350, Line 7, Col 5, Line 7, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 3350, Line 8, Col 5, Line 8, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 5, Line 4, Col 7, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 5, Line 5, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 6, Col 5, Line 6, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 7, Col 5, Line 7, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 8, Col 5, Line 8, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") else (Warning 203, Line 4, Col 5, Line 4, Col 7, "Invalid warning number 'FS'"); (Warning 203, Line 5, Col 5, Line 5, Col 11, "Invalid warning number 'FSBLAH'"); @@ -92,11 +92,11 @@ module NonStringArgs = |> shouldFail |> withDiagnostics [ if languageVersion = "8.0" then - (Warning 3350, Line 3, Col 24, Line 3, Col 28, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 3350, Line 3, Col 29, Line 3, Col 37, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 12, Line 3, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 19, Line 3, Col 23, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 3, Col 24, Line 3, Col 28, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 3, Col 29, Line 3, Col 37, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") else (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 3, Col 12, Line 3, Col 18, "Invalid warning number 'FSBLAH'"); @@ -143,9 +143,9 @@ module DoBinding = |> shouldFail |> withDiagnostics [ (Warning 1104, Line 5, Col 15, Line 5, Col 31, "Identifiers containing '@' are reserved for use in F# code generation") - (Warning 3350, Line 2, Col 26, Line 2, Col 34, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 2, Col 9, Line 2, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 2, Col 12, Line 2, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Error 3350, Line 2, Col 26, Line 2, Col 34, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") ] else compileResult diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs index 8ed00f86741..9dd6dea0e91 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerOptions/fsc/warn/warn.fs @@ -142,7 +142,7 @@ module TestCompilerWarningLevel = [] let ``warn40_fs --nowarn:NU0000;FS40;NU0001`` compilation = - compilation + compilation |> asExe |> withOptions ["--nowarn:NU0000;FS40;NU0001;FS21"] |> compileAndRun From 9f63a5f962b7df2d7468543bc33223b87b31f880 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Sun, 13 Oct 2024 09:35:23 +0000 Subject: [PATCH 12/18] simplification --- src/Compiler/Driver/CompilerConfig.fs | 43 ++++++++----------- .../CompilerDirectives/NonStringArgs.fs | 20 ++++----- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 2915e04414c..5f4d66fbaba 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -92,21 +92,17 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let private regexCompiled = RegexOptions.Compiled ||| RegexOptions.CultureInvariant -let private optionRegex = Regex("""^(FS)?(\d+)$""", regexCompiled) -let private optionRegexIgnore = Regex("""^([A-Z]*)(\d+)$""", regexCompiled) -let private codeRegex = Regex("""^("?)(?:(?:FS)?(\d+))\1$""", regexCompiled) -let private codeRegex8 = Regex("""^(")(\d+)"$""", regexCompiled) -let private codeRegex8nonQuote = Regex("""^[^"].+$""", regexCompiled) -let private codeRegex8prefix = Regex("""^"FS.*"$""", regexCompiled) -let private codeRegex8ignore = Regex("""^"\d*\D+\d*"$""", regexCompiled) - -let GetWarningNumber (m, numStr: string, (langVersion: LanguageVersion), isCompilerOption: bool) = +let private rxOptions = RegexOptions.Compiled ||| RegexOptions.CultureInvariant +let private flagsRx = Regex("""^(FS)?(\d+)$""", rxOptions) +let private flagsIgnoreRx = Regex("""^([A-Z]+)(\d+)$""", rxOptions) +let private codeRx = Regex("""^("?)(?:(?:FS)?(\d+))\1$""", rxOptions) +let private code8Rx = Regex("""^(")(\d+)"$""", rxOptions) +let private code8nonQuotesRx = Regex("""^[^"].+$""", rxOptions) +let private code8prefixRx = Regex("""^"FS.*"$""", rxOptions) + +let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes - let prefixSupported = langVersion.SupportsFeature(argFeature) - - let warnInvalid () = - warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) + let errorInvalid = Error(FSComp.SR.buildInvalidWarningNumber numStr, m) let getNumber (regex: Regex) failAction = let mtch = regex.Match numStr @@ -117,21 +113,20 @@ let GetWarningNumber (m, numStr: string, (langVersion: LanguageVersion), isCompi failAction () None - let matches (regex: Regex) = regex.Match(numStr).Success - if isCompilerOption then - getNumber optionRegex (fun () -> - if not (matches optionRegexIgnore) then - warnInvalid ()) - elif prefixSupported then - getNumber codeRegex warnInvalid - elif matches codeRegex8nonQuote || matches codeRegex8prefix then + getNumber flagsRx (fun () -> + if not (flagsIgnoreRx.Match(numStr).Success) then + warning errorInvalid) + elif langVersion.SupportsFeature(argFeature) then + getNumber codeRx (fun () -> warning errorInvalid) + elif code8nonQuotesRx.Match(numStr).Success then errorR (languageFeatureError langVersion argFeature m) None - elif matches codeRegex8ignore then + elif code8prefixRx.Match(numStr).Success then + warning errorInvalid None else - getNumber codeRegex8 warnInvalid + getNumber code8Rx (fun () -> ()) let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 9b466fd36a3..38f63fab5fb 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -29,8 +29,8 @@ module NonStringArgs = (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 9, Line 4, Col 15, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 9, Line 5, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 6, Col 9, Line 6, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 7, Col 9, Line 7, Col 17, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 203, Line 6, Col 9, Line 6, Col 13, """Invalid warning number '"FS"'"""); + (Warning 203, Line 7, Col 9, Line 7, Col 17, """Invalid warning number '"FSBLAH"'"""); else (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 4, Col 9, Line 4, Col 15, "Invalid warning number 'FSBLAH'"); @@ -65,8 +65,8 @@ module NonStringArgs = (Error 3350, Line 4, Col 5, Line 4, Col 7, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 5, Line 5, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 6, Col 5, Line 6, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 7, Col 5, Line 7, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 8, Col 5, Line 8, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 203, Line 7, Col 5, Line 7, Col 9, """Invalid warning number '"FS"'"""); + (Warning 203, Line 8, Col 5, Line 8, Col 13, """Invalid warning number '"FSBLAH"'"""); else (Warning 203, Line 4, Col 5, Line 4, Col 7, "Invalid warning number 'FS'"); (Warning 203, Line 5, Col 5, Line 5, Col 11, "Invalid warning number 'FSBLAH'"); @@ -95,8 +95,8 @@ module NonStringArgs = (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 12, Line 3, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 19, Line 3, Col 23, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 3, Col 24, Line 3, Col 28, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 3, Col 29, Line 3, Col 37, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 203, Line 3, Col 24, Line 3, Col 28, """Invalid warning number '"FS"'"""); + (Warning 203, Line 3, Col 29, Line 3, Col 37, """Invalid warning number '"FSBLAH"'"""); else (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 3, Col 12, Line 3, Col 18, "Invalid warning number 'FSBLAH'"); @@ -145,7 +145,7 @@ module DoBinding = (Warning 1104, Line 5, Col 15, Line 5, Col 31, "Identifiers containing '@' are reserved for use in F# code generation") (Error 3350, Line 2, Col 9, Line 2, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 2, Col 12, Line 2, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Error 3350, Line 2, Col 26, Line 2, Col 34, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") + (Warning 203, Line 2, Col 26, Line 2, Col 34, """Invalid warning number '"FS3221"'""") ] else compileResult @@ -158,9 +158,9 @@ module DoBinding = let ``#nowarn - errors - compiler options`` (languageVersion) = FSharp """ -match None with None -> () // creates FS0025 -"" // creates FS0020 - """ +match None with None -> () // creates FS0025 - ignored due to flag +"" // creates FS0020 - ignored due to flag + """ // creates FS0988 - not ignored, different flag prefix |> withLangVersion languageVersion |> withOptions ["--nowarn:NU0988"; "--nowarn:FS25"; "--nowarn:20"; "--nowarn:FS"; "--nowarn:FSBLAH"] |> asExe From f4233e067139f982b6f6ed9ef3c17bfcdd574860 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:25:29 +0000 Subject: [PATCH 13/18] removed regex compilation --- src/Compiler/Driver/CompilerConfig.fs | 28 ++++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 5f4d66fbaba..7965838828a 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -92,20 +92,13 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let private rxOptions = RegexOptions.Compiled ||| RegexOptions.CultureInvariant -let private flagsRx = Regex("""^(FS)?(\d+)$""", rxOptions) -let private flagsIgnoreRx = Regex("""^([A-Z]+)(\d+)$""", rxOptions) -let private codeRx = Regex("""^("?)(?:(?:FS)?(\d+))\1$""", rxOptions) -let private code8Rx = Regex("""^(")(\d+)"$""", rxOptions) -let private code8nonQuotesRx = Regex("""^[^"].+$""", rxOptions) -let private code8prefixRx = Regex("""^"FS.*"$""", rxOptions) - let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, isCompilerOption: bool) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes let errorInvalid = Error(FSComp.SR.buildInvalidWarningNumber numStr, m) + let rxOptions = RegexOptions.CultureInvariant - let getNumber (regex: Regex) failAction = - let mtch = regex.Match numStr + let getNumber regexString failAction = + let mtch = Regex(regexString, rxOptions).Match(numStr) if mtch.Success then Some(int mtch.Groups[2].Captures[0].Value) @@ -113,20 +106,23 @@ let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, isCompile failAction () None + let matches regexString = + Regex(regexString, rxOptions).Match(numStr).Success + if isCompilerOption then - getNumber flagsRx (fun () -> - if not (flagsIgnoreRx.Match(numStr).Success) then + getNumber """^(FS)?(\d+)$""" (fun () -> + if not (matches """^([A-Z]+)(\d+)$""") then warning errorInvalid) elif langVersion.SupportsFeature(argFeature) then - getNumber codeRx (fun () -> warning errorInvalid) - elif code8nonQuotesRx.Match(numStr).Success then + getNumber """^("?)(?:(?:FS)?(\d+))\1$""" (fun () -> warning errorInvalid) + elif matches """^[^"].+$""" then errorR (languageFeatureError langVersion argFeature m) None - elif code8prefixRx.Match(numStr).Success then + elif matches """^"FS.*"$""" then warning errorInvalid None else - getNumber code8Rx (fun () -> ()) + getNumber """^(")(\d+)"$""" (fun () -> ()) let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try From 31eebf31dba955f95f0b9c63d33755d0ace025cf Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:31:14 +0000 Subject: [PATCH 14/18] fixes as proposed in review --- src/Compiler/Driver/CompilerConfig.fs | 23 ++++++++++++++-------- src/Compiler/Driver/CompilerConfig.fsi | 8 +++++++- src/Compiler/Driver/ParseAndCheckInputs.fs | 12 ++++++----- src/Compiler/Interactive/fsi.fs | 3 +-- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 14 ++++++------- src/Compiler/SyntaxTree/SyntaxTreeOps.fsi | 2 +- 6 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 574b5e8df2f..4a036f826e3 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -92,11 +92,18 @@ let ResolveFileUsingPaths (paths, m, fileName) = let searchMessage = String.concat "\n " paths raise (FileNameNotResolved(fileName, searchMessage, m)) -let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, isCompilerOption: bool) = +[] +type WarningNumberSource = + | CommandLineOption + | CompilerDirective + +let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, source: WarningNumberSource) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes - let errorInvalid = Error(FSComp.SR.buildInvalidWarningNumber numStr, m) let rxOptions = RegexOptions.CultureInvariant + let warnInvalid () = + warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) + let getNumber regexString failAction = let mtch = Regex(regexString, rxOptions).Match(numStr) @@ -109,17 +116,17 @@ let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, isCompile let matches regexString = Regex(regexString, rxOptions).Match(numStr).Success - if isCompilerOption then + if source = WarningNumberSource.CommandLineOption then getNumber """^(FS)?(\d+)$""" (fun () -> if not (matches """^([A-Z]+)(\d+)$""") then - warning errorInvalid) + warnInvalid ()) elif langVersion.SupportsFeature(argFeature) then - getNumber """^("?)(?:(?:FS)?(\d+))\1$""" (fun () -> warning errorInvalid) + getNumber """^("?)(?:(?:FS)?(\d+))\1$""" warnInvalid elif matches """^[^"].+$""" then errorR (languageFeatureError langVersion argFeature m) None elif matches """^"FS.*"$""" then - warning errorInvalid + warnInvalid () None else getNumber """^(")(\d+)"$""" (fun () -> ()) @@ -948,7 +955,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOff(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion, true) with + match GetWarningNumber(m, s, tcConfigB.langVersion, WarningNumberSource.CommandLineOption) with | None -> () | Some n -> // nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus @@ -963,7 +970,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOn(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion, true) with + match GetWarningNumber(m, s, tcConfigB.langVersion, WarningNumberSource.CommandLineOption) with | None -> () | Some n -> // warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 73f40ecad77..1d5bd3f691f 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -926,7 +926,13 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string -val GetWarningNumber: m: range * numStr: string * langVersion: LanguageVersion * isCompilerOption: bool -> int option +[] +type WarningNumberSource = + | CommandLineOption + | CompilerDirective + +val GetWarningNumber: + m: range * numStr: string * langVersion: LanguageVersion * source: WarningNumberSource -> int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 21b1cb9a7f2..4b36c85e159 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -223,9 +223,12 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = for s in args do let warningNumber = match s with - | ParsedHashDirectiveArgument.Int32(n, m) -> GetWarningNumber(m, string n, langVersion, false) - | ParsedHashDirectiveArgument.Ident(s, m) -> GetWarningNumber(m, s.idText, langVersion, false) - | ParsedHashDirectiveArgument.String(s, _, m) -> GetWarningNumber(m, $"\"{s}\"", langVersion, false) + | ParsedHashDirectiveArgument.Int32(n, m) -> + GetWarningNumber(m, string n, langVersion, WarningNumberSource.CompilerDirective) + | ParsedHashDirectiveArgument.Ident(s, m) -> + GetWarningNumber(m, s.idText, langVersion, WarningNumberSource.CompilerDirective) + | ParsedHashDirectiveArgument.String(s, _, m) -> + GetWarningNumber(m, $"\"{s}\"", langVersion, WarningNumberSource.CompilerDirective) | _ -> None match warningNumber with @@ -907,8 +910,7 @@ let ProcessMetaCommandsFromInput state | ParsedHashDirective("nowarn", hashArguments, m) -> - let arguments = - parsedHashDirectiveArgumentsNoCheck hashArguments tcConfig.langVersion + let arguments = parsedHashDirectiveArgumentsNoCheck hashArguments List.fold (fun state d -> nowarnF state (m, d)) state arguments diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index 18d89a7ac8f..3ce04b3d5fc 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -3844,8 +3844,7 @@ type FsiInteractionProcessor istate, Completed None | ParsedHashDirective("nowarn", nowarnArguments, m) -> - let numbers = - (parsedHashDirectiveArgumentsNoCheck nowarnArguments tcConfigB.langVersion) + let numbers = (parsedHashDirectiveArgumentsNoCheck nowarnArguments) List.iter (fun (d: string) -> tcConfigB.TurnWarningOff(m, d)) numbers istate, Completed None diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 1c844512a29..7b392487adb 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -1005,14 +1005,14 @@ let parsedHashDirectiveArguments (input: ParsedHashDirectiveArgument list) (lang | false -> None) input -let parsedHashDirectiveArgumentsNoCheck (input: ParsedHashDirectiveArgument list) (langVersion: LanguageVersion) = - List.choose +let parsedHashDirectiveArgumentsNoCheck (input: ParsedHashDirectiveArgument list) = + List.map (function - | ParsedHashDirectiveArgument.String(s, _, _) -> Some s - | ParsedHashDirectiveArgument.SourceIdentifier(_, v, _) -> Some v - | ParsedHashDirectiveArgument.Int32(n, m) -> Some(string n) - | ParsedHashDirectiveArgument.Ident(ident, m) -> Some(ident.idText) - | ParsedHashDirectiveArgument.LongIdent(ident, m) -> Some(longIdentToString ident)) + | ParsedHashDirectiveArgument.String(s, _, _) -> s + | ParsedHashDirectiveArgument.SourceIdentifier(_, v, _) -> v + | ParsedHashDirectiveArgument.Int32(n, m) -> string n + | ParsedHashDirectiveArgument.Ident(ident, m) -> ident.idText + | ParsedHashDirectiveArgument.LongIdent(ident, m) -> longIdentToString ident) input let parsedHashDirectiveStringArguments (input: ParsedHashDirectiveArgument list) (_langVersion: LanguageVersion) = diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi index a5d18607e81..3ca2b58be43 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi @@ -322,7 +322,7 @@ val synExprContainsError: inpExpr: SynExpr -> bool val parsedHashDirectiveArguments: ParsedHashDirectiveArgument list -> LanguageVersion -> string list -val parsedHashDirectiveArgumentsNoCheck: ParsedHashDirectiveArgument list -> LanguageVersion -> string list +val parsedHashDirectiveArgumentsNoCheck: ParsedHashDirectiveArgument list -> string list val parsedHashDirectiveStringArguments: ParsedHashDirectiveArgument list -> LanguageVersion -> string list From 0f4a215d48da878ffd90ead1088ffd80598690a5 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 1 Nov 2024 13:51:09 +0000 Subject: [PATCH 15/18] avoiding Regex --- src/Compiler/Driver/CompilerConfig.fs | 39 +++++++++++-------- .../CompilerDirectives/NonStringArgs.fs | 2 - 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 4a036f826e3..2036b8487cd 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -99,37 +99,42 @@ type WarningNumberSource = let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, source: WarningNumberSource) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes - let rxOptions = RegexOptions.CultureInvariant let warnInvalid () = warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) - let getNumber regexString failAction = - let mtch = Regex(regexString, rxOptions).Match(numStr) - - if mtch.Success then - Some(int mtch.Groups[2].Captures[0].Value) - else + let tryParseIntWithFailAction (s: string) (failAction: unit -> unit) = + match Int32.TryParse s with + | true, n -> Some n + | false, _ -> failAction () None - let matches regexString = - Regex(regexString, rxOptions).Match(numStr).Success - if source = WarningNumberSource.CommandLineOption then - getNumber """^(FS)?(\d+)$""" (fun () -> - if not (matches """^([A-Z]+)(\d+)$""") then - warnInvalid ()) + let s = + if numStr.StartsWithOrdinal "FS" then + numStr[2..] + else + numStr + + tryParseIntWithFailAction s id elif langVersion.SupportsFeature(argFeature) then - getNumber """^("?)(?:(?:FS)?(\d+))\1$""" warnInvalid - elif matches """^[^"].+$""" then + let s = + if numStr[0] = '"' && numStr[numStr.Length - 1] = '"' then + numStr[1 .. numStr.Length - 2] + else + numStr + + let s = if s.StartsWithOrdinal "FS" then s[2..] else s + tryParseIntWithFailAction s warnInvalid + elif numStr[0] <> '"' || numStr[numStr.Length - 1] <> '"' then errorR (languageFeatureError langVersion argFeature m) None - elif matches """^"FS.*"$""" then + elif numStr.StartsWith "\"FS" && numStr[numStr.Length - 1] = '"' then warnInvalid () None else - getNumber """^(")(\d+)"$""" (fun () -> ()) + tryParseIntWithFailAction numStr id let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index 38f63fab5fb..ae504e074af 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -167,8 +167,6 @@ match None with None -> () // creates FS0025 - ignored due to flag |> compile |> shouldFail |> withDiagnostics [ - (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FS'") - (Warning 203, Line 0, Col 1, Line 0, Col 1, "Invalid warning number 'FSBLAH'") (Warning 988, Line 3, Col 3, Line 3, Col 3, "Main module of program is empty: nothing will happen when it is run") ] From b3a1288cb1e8b49a63ae7ea7e69847ec2b8bec94 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:58:28 +0000 Subject: [PATCH 16/18] Using WarningDescription type to get warning number --- src/Compiler/Driver/CompilerConfig.fs | 84 +++++++++++-------- src/Compiler/Driver/CompilerConfig.fsi | 10 ++- src/Compiler/Driver/ParseAndCheckInputs.fs | 20 ++--- .../CompilerDirectives/NonStringArgs.fs | 32 +++---- ...StringAsParsedHashDirectiveArgument.fs.bsl | 2 +- 5 files changed, 84 insertions(+), 64 deletions(-) diff --git a/src/Compiler/Driver/CompilerConfig.fs b/src/Compiler/Driver/CompilerConfig.fs index 2036b8487cd..ac39792977a 100644 --- a/src/Compiler/Driver/CompilerConfig.fs +++ b/src/Compiler/Driver/CompilerConfig.fs @@ -22,12 +22,12 @@ open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.Features open FSharp.Compiler.IO open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax open FSharp.Compiler.Text open FSharp.Compiler.Text.Range open FSharp.Compiler.Xml open FSharp.Compiler.TypedTree open FSharp.Compiler.BuildGraph -open System.Text.RegularExpressions #if !NO_TYPEPROVIDERS open FSharp.Core.CompilerServices @@ -97,44 +97,56 @@ type WarningNumberSource = | CommandLineOption | CompilerDirective -let GetWarningNumber (m, numStr: string, langVersion: LanguageVersion, source: WarningNumberSource) = +[] +type WarningDescription = + | Int32 of int + | String of string + | Ident of Ident + +let GetWarningNumber (m, description: WarningDescription, langVersion: LanguageVersion, source: WarningNumberSource) = let argFeature = LanguageFeature.ParsedHashDirectiveArgumentNonQuotes - let warnInvalid () = - warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) + let parse (numStr: string) = + let trimPrefix (s: string) = + if s.StartsWithOrdinal "FS" then s[2..] else s - let tryParseIntWithFailAction (s: string) (failAction: unit -> unit) = - match Int32.TryParse s with - | true, n -> Some n - | false, _ -> - failAction () - None + let tryParseIntWithFailAction (s: string) (failAction: unit -> unit) = + match Int32.TryParse s with + | true, n -> Some n + | false, _ -> + failAction () + None - if source = WarningNumberSource.CommandLineOption then - let s = - if numStr.StartsWithOrdinal "FS" then - numStr[2..] - else - numStr + let warnInvalid () = + warning (Error(FSComp.SR.buildInvalidWarningNumber numStr, m)) - tryParseIntWithFailAction s id - elif langVersion.SupportsFeature(argFeature) then - let s = - if numStr[0] = '"' && numStr[numStr.Length - 1] = '"' then - numStr[1 .. numStr.Length - 2] - else - numStr - - let s = if s.StartsWithOrdinal "FS" then s[2..] else s - tryParseIntWithFailAction s warnInvalid - elif numStr[0] <> '"' || numStr[numStr.Length - 1] <> '"' then - errorR (languageFeatureError langVersion argFeature m) - None - elif numStr.StartsWith "\"FS" && numStr[numStr.Length - 1] = '"' then - warnInvalid () - None - else - tryParseIntWithFailAction numStr id + if source = WarningNumberSource.CommandLineOption then + tryParseIntWithFailAction (trimPrefix numStr) id + elif langVersion.SupportsFeature(argFeature) then + tryParseIntWithFailAction (trimPrefix numStr) warnInvalid + else + tryParseIntWithFailAction numStr id + + match description with + | WarningDescription.Int32 n -> + if tryCheckLanguageFeatureAndRecover langVersion argFeature m then + Some n + else + None + | WarningDescription.String s -> + if + source = WarningNumberSource.CompilerDirective + && not (langVersion.SupportsFeature argFeature) + && s.StartsWithOrdinal "FS" + then + warning (Error(FSComp.SR.buildInvalidWarningNumber s, m)) + + parse s + | WarningDescription.Ident ident -> + if tryCheckLanguageFeatureAndRecover langVersion argFeature m then + parse ident.idText + else + None let ComputeMakePathAbsolute implicitIncludeDir (path: string) = try @@ -960,7 +972,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOff(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion, WarningNumberSource.CommandLineOption) with + match GetWarningNumber(m, WarningDescription.String s, tcConfigB.langVersion, WarningNumberSource.CommandLineOption) with | None -> () | Some n -> // nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus @@ -975,7 +987,7 @@ type TcConfigBuilder = member tcConfigB.TurnWarningOn(m, s: string) = use _ = UseBuildPhase BuildPhase.Parameter - match GetWarningNumber(m, s, tcConfigB.langVersion, WarningNumberSource.CommandLineOption) with + match GetWarningNumber(m, WarningDescription.String s, tcConfigB.langVersion, WarningNumberSource.CommandLineOption) with | None -> () | Some n -> // warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus diff --git a/src/Compiler/Driver/CompilerConfig.fsi b/src/Compiler/Driver/CompilerConfig.fsi index 1d5bd3f691f..8ea6f5afe5d 100644 --- a/src/Compiler/Driver/CompilerConfig.fsi +++ b/src/Compiler/Driver/CompilerConfig.fsi @@ -17,6 +17,7 @@ open FSharp.Compiler.Diagnostics open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.Features open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax open FSharp.Compiler.Text open FSharp.Compiler.BuildGraph @@ -931,8 +932,15 @@ type WarningNumberSource = | CommandLineOption | CompilerDirective +[] +type WarningDescription = + | Int32 of int + | String of string + | Ident of Ident + val GetWarningNumber: - m: range * numStr: string * langVersion: LanguageVersion * source: WarningNumberSource -> int option + m: range * description: WarningDescription * langVersion: LanguageVersion * source: WarningNumberSource -> + int option /// Get the name used for FSharp.Core val GetFSharpCoreLibraryName: unit -> string diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index 4b36c85e159..a9bb78ed187 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -219,21 +219,21 @@ let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, fileName, intf) let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = [ match hd with - | ParsedHashDirective("nowarn", args, m) -> + | ParsedHashDirective("nowarn", args, _) -> for s in args do - let warningNumber = + let rd = match s with - | ParsedHashDirectiveArgument.Int32(n, m) -> - GetWarningNumber(m, string n, langVersion, WarningNumberSource.CompilerDirective) - | ParsedHashDirectiveArgument.Ident(s, m) -> - GetWarningNumber(m, s.idText, langVersion, WarningNumberSource.CompilerDirective) - | ParsedHashDirectiveArgument.String(s, _, m) -> - GetWarningNumber(m, $"\"{s}\"", langVersion, WarningNumberSource.CompilerDirective) + | ParsedHashDirectiveArgument.Int32(n, m) -> Some(m, WarningDescription.Int32 n) + | ParsedHashDirectiveArgument.Ident(ident, m) -> Some(m, WarningDescription.Ident ident) + | ParsedHashDirectiveArgument.String(s, _, m) -> Some(m, WarningDescription.String s) | _ -> None - match warningNumber with + match rd with | None -> () - | Some n -> ScopedPragma.WarningOff(m, n) + | Some(m, description) -> + match GetWarningNumber(m, description, langVersion, WarningNumberSource.CompilerDirective) with + | None -> () + | Some n -> ScopedPragma.WarningOff(m, n) | _ -> () ] diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs index ae504e074af..32f40de89d2 100644 --- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs +++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/NonStringArgs.fs @@ -29,15 +29,15 @@ module NonStringArgs = (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 4, Col 9, Line 4, Col 15, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 9, Line 5, Col 13, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 203, Line 6, Col 9, Line 6, Col 13, """Invalid warning number '"FS"'"""); - (Warning 203, Line 7, Col 9, Line 7, Col 17, """Invalid warning number '"FSBLAH"'"""); + (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'"); + (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'"); else (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 4, Col 9, Line 4, Col 15, "Invalid warning number 'FSBLAH'"); (Warning 203, Line 5, Col 9, Line 5, Col 13, "Invalid warning number 'ACME'"); - (Warning 203, Line 6, Col 9, Line 6, Col 13, """Invalid warning number '"FS"'"""); - (Warning 203, Line 7, Col 9, Line 7, Col 17, """Invalid warning number '"FSBLAH"'"""); - (Warning 203, Line 8, Col 9, Line 8, Col 15, """Invalid warning number '"ACME"'""") + (Warning 203, Line 6, Col 9, Line 6, Col 13, "Invalid warning number 'FS'"); + (Warning 203, Line 7, Col 9, Line 7, Col 17, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 8, Col 9, Line 8, Col 15, "Invalid warning number 'ACME'") ] @@ -65,15 +65,15 @@ module NonStringArgs = (Error 3350, Line 4, Col 5, Line 4, Col 7, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 5, Col 5, Line 5, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 6, Col 5, Line 6, Col 9, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 203, Line 7, Col 5, Line 7, Col 9, """Invalid warning number '"FS"'"""); - (Warning 203, Line 8, Col 5, Line 8, Col 13, """Invalid warning number '"FSBLAH"'"""); + (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'"); + (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'"); else (Warning 203, Line 4, Col 5, Line 4, Col 7, "Invalid warning number 'FS'"); (Warning 203, Line 5, Col 5, Line 5, Col 11, "Invalid warning number 'FSBLAH'"); (Warning 203, Line 6, Col 5, Line 6, Col 9, "Invalid warning number 'ACME'"); - (Warning 203, Line 7, Col 5, Line 7, Col 9, """Invalid warning number '"FS"'"""); - (Warning 203, Line 8, Col 5, Line 8, Col 13, """Invalid warning number '"FSBLAH"'"""); - (Warning 203, Line 9, Col 5, Line 9, Col 11, """Invalid warning number '"ACME"'""") + (Warning 203, Line 7, Col 5, Line 7, Col 9, "Invalid warning number 'FS'"); + (Warning 203, Line 8, Col 5, Line 8, Col 13, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 9, Col 5, Line 9, Col 11, "Invalid warning number 'ACME'") ] @@ -95,15 +95,15 @@ module NonStringArgs = (Error 3350, Line 3, Col 9, Line 3, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 12, Line 3, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 3, Col 19, Line 3, Col 23, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 203, Line 3, Col 24, Line 3, Col 28, """Invalid warning number '"FS"'"""); - (Warning 203, Line 3, Col 29, Line 3, Col 37, """Invalid warning number '"FSBLAH"'"""); + (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'"); + (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'"); else (Warning 203, Line 3, Col 9, Line 3, Col 11, "Invalid warning number 'FS'"); (Warning 203, Line 3, Col 12, Line 3, Col 18, "Invalid warning number 'FSBLAH'"); (Warning 203, Line 3, Col 19, Line 3, Col 23, "Invalid warning number 'ACME'"); - (Warning 203, Line 3, Col 24, Line 3, Col 28, """Invalid warning number '"FS"'"""); - (Warning 203, Line 3, Col 29, Line 3, Col 37, """Invalid warning number '"FSBLAH"'"""); - (Warning 203, Line 3, Col 38, Line 3, Col 44, """Invalid warning number '"ACME"'""") + (Warning 203, Line 3, Col 24, Line 3, Col 28, "Invalid warning number 'FS'"); + (Warning 203, Line 3, Col 29, Line 3, Col 37, "Invalid warning number 'FSBLAH'"); + (Warning 203, Line 3, Col 38, Line 3, Col 44, "Invalid warning number 'ACME'") ] @@ -145,7 +145,7 @@ module DoBinding = (Warning 1104, Line 5, Col 15, Line 5, Col 31, "Identifiers containing '@' are reserved for use in F# code generation") (Error 3350, Line 2, Col 9, Line 2, Col 11, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") (Error 3350, Line 2, Col 12, Line 2, Col 18, "Feature '# directives with non-quoted string arguments' is not available in F# 8.0. Please use language version 9.0 or greater.") - (Warning 203, Line 2, Col 26, Line 2, Col 34, """Invalid warning number '"FS3221"'""") + (Warning 203, Line 2, Col 26, Line 2, Col 34, "Invalid warning number 'FS3221'") ] else compileResult diff --git a/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl b/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl index 391a462d0b8..fd629563d32 100644 --- a/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl +++ b/tests/service/data/SyntaxTree/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs.bsl @@ -2,7 +2,7 @@ ImplFile (ParsedImplFileInput ("/root/ParsedHashDirective/TripleQuoteStringAsParsedHashDirectiveArgument.fs", false, QualifiedNameOfFile TripleQuoteStringAsParsedHashDirectiveArgument, - [WarningOff ((2,0--2,16), 40)], [], + [WarningOff ((2,8--2,16), 40)], [], [SynModuleOrNamespace ([TripleQuoteStringAsParsedHashDirectiveArgument], false, AnonModule, [HashDirective From 52c3bc81a9ddb4ce8e8171388c3aae7e6460bc09 Mon Sep 17 00:00:00 2001 From: Martin <29605222+Martin521@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:05:34 +0100 Subject: [PATCH 17/18] More descriptive variable names Co-authored-by: Petr Pokorny --- src/Compiler/Driver/ParseAndCheckInputs.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index a9bb78ed187..b662d565061 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -220,9 +220,9 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = [ match hd with | ParsedHashDirective("nowarn", args, _) -> - for s in args do - let rd = - match s with + for arg in args do + let rangeAndDescription = + match arg with | ParsedHashDirectiveArgument.Int32(n, m) -> Some(m, WarningDescription.Int32 n) | ParsedHashDirectiveArgument.Ident(ident, m) -> Some(m, WarningDescription.Ident ident) | ParsedHashDirectiveArgument.String(s, _, m) -> Some(m, WarningDescription.String s) From 1225abc2dc00314afaf2a57740b456368d5f8013 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:27:02 +0000 Subject: [PATCH 18/18] More descriptive variable names - now correct --- src/Compiler/Driver/ParseAndCheckInputs.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs index b662d565061..6423e5f9f19 100644 --- a/src/Compiler/Driver/ParseAndCheckInputs.fs +++ b/src/Compiler/Driver/ParseAndCheckInputs.fs @@ -228,7 +228,7 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) = | ParsedHashDirectiveArgument.String(s, _, m) -> Some(m, WarningDescription.String s) | _ -> None - match rd with + match rangeAndDescription with | None -> () | Some(m, description) -> match GetWarningNumber(m, description, langVersion, WarningNumberSource.CompilerDirective) with