Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.400.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
### Added

* Generate new `Equals` overload to avoid boxing for structural comparison ([PR #16857](https://github.com/dotnet/fsharp/pull/16857))
* Allow #nowarn to support the FS prefix on error codes to disable warnings ([Issue #17206](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
* Allow ParsedHashDirectives to have argument types other than strings ([Issue #17240](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
* Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231))

### Changed
Expand Down
2 changes: 2 additions & 0 deletions docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154))
* Make `.Is*` discriminated union properties visible. ([Language suggestion #222](https://github.com/fsharp/fslang-suggestions/issues/222), [PR #16341](https://github.com/dotnet/fsharp/pull/16341))
* Allow returning bool instead of unit option for partial active patterns. ([Language suggestion #1041](https://github.com/fsharp/fslang-suggestions/issues/1041), [PR #16473](https://github.com/dotnet/fsharp/pull/16473))
* Allow #nowarn to support the FS prefix on error codes to disable warnings ([Issue #17206](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
* Allow ParsedHashDirectives to have argument types other than strings ([Issue #17240](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))

### Fixed

Expand Down
17 changes: 12 additions & 5 deletions src/Compiler/Driver/CompilerConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,23 @@ let ResolveFileUsingPaths (paths, m, fileName) =
let searchMessage = String.concat "\n " paths
raise (FileNameNotResolved(fileName, searchMessage, m))

let GetWarningNumber (m, warningNumber: string) =
let GetWarningNumber (m, warningNumber: string, prefixSupported) =
try
// Okay so ...
// #pragma strips FS of the #pragma "FS0004" and validates the warning number
// therefore if we have warning id that starts with a numeric digit we convert it to Some (int32)
// anything else is ignored None
let warningNumber =
if warningNumber.StartsWithOrdinal "FS" then
if prefixSupported then
warningNumber.Substring 2
else
raise (new ArgumentException())
else
warningNumber

if Char.IsDigit(warningNumber[0]) then
Some(int32 warningNumber)
elif warningNumber.StartsWithOrdinal "FS" then
raise (ArgumentException())
else
None
with _ ->
Expand Down Expand Up @@ -918,7 +925,7 @@ type TcConfigBuilder =
member tcConfigB.TurnWarningOff(m, s: string) =
use _ = UseBuildPhase BuildPhase.Parameter

match GetWarningNumber(m, s) with
match GetWarningNumber(m, s, tcConfigB.langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonString)) with
| None -> ()
| Some n ->
// nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus
Expand All @@ -933,7 +940,7 @@ type TcConfigBuilder =
member tcConfigB.TurnWarningOn(m, s: string) =
use _ = UseBuildPhase BuildPhase.Parameter

match GetWarningNumber(m, s) with
match GetWarningNumber(m, s, tcConfigB.langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonString)) with
| None -> ()
| Some n ->
// warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Driver/CompilerConfig.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,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 -> int option
val GetWarningNumber: m: range * warningNumber: string * prefixSupported: bool -> int option

/// Get the name used for FSharp.Core
val GetFSharpCoreLibraryName: unit -> string
Expand Down
31 changes: 20 additions & 11 deletions src/Compiler/Driver/ParseAndCheckInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -216,17 +216,26 @@ let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, fileName, intf)

SynModuleOrNamespaceSig(lid, isRecursive, kind, decls, xmlDoc, attributes, None, range, trivia)

let GetScopedPragmasForHashDirective hd =
let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) =
let supportsNonStringArguments =
langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonString)

[
match hd with
| ParsedHashDirective("nowarn", numbers, m) ->
for s in numbers do
match s with
| ParsedHashDirectiveArgument.SourceIdentifier _ -> ()
| ParsedHashDirectiveArgument.String(s, _, _) ->
match GetWarningNumber(m, s) with
| None -> ()
| Some n -> ScopedPragma.WarningOff(m, n)
let warningNumber =
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)
| _ -> None

match warningNumber with
| None -> ()
| Some n -> ScopedPragma.WarningOff(m, n)
| _ -> ()
]

Expand Down Expand Up @@ -272,10 +281,10 @@ let PostParseModuleImpls
for SynModuleOrNamespace(decls = decls) in impls do
for d in decls do
match d with
| SynModuleDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd
| SynModuleDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
| _ -> ()
for hd in hashDirectives do
yield! GetScopedPragmasForHashDirective hd
yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
]

let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf)
Expand Down Expand Up @@ -323,10 +332,10 @@ let PostParseModuleSpecs
for SynModuleOrNamespaceSig(decls = decls) in specs do
for d in decls do
match d with
| SynModuleSigDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd
| SynModuleSigDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
| _ -> ()
for hd in hashDirectives do
yield! GetScopedPragmasForHashDirective hd
yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
]

let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf)
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1752,3 +1752,4 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [<Struct>] di
3868,tcActivePatternArgsCountNotMatchOnlyPat,"This active pattern expects exactly one pattern argument, e.g., '%s pat'."
3868,tcActivePatternArgsCountNotMatchArgs,"This active pattern expects %d expression argument(s), e.g., '%s%s'."
3868,tcActivePatternArgsCountNotMatchArgsAndPat,"This active pattern expects %d expression argument(s) and a pattern argument, e.g., '%s%s pat'."
featureParsedHashDirectiveArgumentNonString,"# directives with non-quoted string arguments"
2 changes: 1 addition & 1 deletion src/Compiler/FSStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@
<value>Override implementations should be given as part of the initial declaration of a type.</value>
</data>
<data name="IntfImplInIntrinsicAugmentation" xml:space="preserve">
<value>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</value>
<value>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using '#nowarn "69"' if you have checked this is not the case.</value>
</data>
<data name="IntfImplInExtrinsicAugmentation" xml:space="preserve">
<value>Interface implementations should be given on the initial declaration of a type.</value>
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type LanguageFeature =
| LowerInterpolatedStringToConcat
| LowerIntegralRangesToFastLoops
| LowerSimpleMappingsInComprehensionsToDirectCallsToMap
| ParsedHashDirectiveArgumentNonString

/// LanguageVersion management
type LanguageVersion(versionText) =
Expand Down Expand Up @@ -205,6 +206,7 @@ type LanguageVersion(versionText) =
LanguageFeature.LowerInterpolatedStringToConcat, previewVersion
LanguageFeature.LowerIntegralRangesToFastLoops, previewVersion
LanguageFeature.LowerSimpleMappingsInComprehensionsToDirectCallsToMap, previewVersion
LanguageFeature.ParsedHashDirectiveArgumentNonString, previewVersion
]

static let defaultLanguageVersion = LanguageVersion("default")
Expand Down Expand Up @@ -353,6 +355,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.LowerIntegralRangesToFastLoops -> FSComp.SR.featureLowerIntegralRangesToFastLoops ()
| LanguageFeature.LowerSimpleMappingsInComprehensionsToDirectCallsToMap ->
FSComp.SR.featureLowerSimpleMappingsInComprehensionsToDirectCallsToMap ()
| LanguageFeature.ParsedHashDirectiveArgumentNonString -> FSComp.SR.featureParsedHashDirectiveArgumentNonString ()

/// Get a version string associated with the given feature.
static member GetFeatureVersionString feature =
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type LanguageFeature =
| LowerInterpolatedStringToConcat
| LowerIntegralRangesToFastLoops
| LowerSimpleMappingsInComprehensionsToDirectCallsToMap
| ParsedHashDirectiveArgumentNonString

/// LanguageVersion management
type LanguageVersion =
Expand Down
8 changes: 7 additions & 1 deletion src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1647,13 +1647,19 @@ type SynModuleOrNamespaceSig =

[<NoEquality; NoComparison; RequireQualifiedAccess>]
type ParsedHashDirectiveArgument =
| Ident of value: Ident * range: range
| Int32 of value: Int32 * range: range
| LongIdent of value: SynLongIdent * range: range
| String of value: string * stringKind: SynStringKind * range: range
| SourceIdentifier of constant: string * value: string * range: range

member this.Range =
match this with
| ParsedHashDirectiveArgument.Ident(range = m)
| ParsedHashDirectiveArgument.Int32(range = m)
| ParsedHashDirectiveArgument.String(range = m)
| ParsedHashDirectiveArgument.SourceIdentifier(range = m) -> m
| ParsedHashDirectiveArgument.SourceIdentifier(range = m)
| ParsedHashDirectiveArgument.LongIdent(range = m) -> m

[<NoEquality; NoComparison>]
type ParsedHashDirective = ParsedHashDirective of ident: string * args: ParsedHashDirectiveArgument list * range: range
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -1826,6 +1826,9 @@ type SynModuleOrNamespaceSig =
/// Represents a parsed hash directive argument
[<NoEquality; NoComparison; RequireQualifiedAccess>]
type ParsedHashDirectiveArgument =
| Ident of value: Ident * range: range
| Int32 of value: Int32 * range: range
| LongIdent of value: SynLongIdent * range: range
| String of value: string * stringKind: SynStringKind * range: range
| SourceIdentifier of constant: string * value: string * range: range

Expand Down
5 changes: 4 additions & 1 deletion src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,10 @@ let (|ParsedHashDirectiveArguments|) (input: ParsedHashDirectiveArgument list) =
List.map
(function
| ParsedHashDirectiveArgument.String(s, _, _) -> s
| ParsedHashDirectiveArgument.SourceIdentifier(_, v, _) -> v)
| ParsedHashDirectiveArgument.Int32(n, _) -> string n
| ParsedHashDirectiveArgument.SourceIdentifier(_, v, _) -> v
| ParsedHashDirectiveArgument.Ident(ident, _) -> ident.idText
| ParsedHashDirectiveArgument.LongIdent(id, _) -> System.String.Join(".", id.LongIdent |> List.map (fun ident -> ident.ToString())))
input

let prependIdentInLongIdentWithTrivia (SynIdent(ident, identTrivia)) mDot lid =
Expand Down
12 changes: 12 additions & 0 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,18 @@ hashDirectiveArg:
| string
{ let s, kind = $1
ParsedHashDirectiveArgument.String(s, kind, lhs parseState) }
| INT32
{ let n, _ = $1
parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.ParsedHashDirectiveArgumentNonString (rhs parseState 1)
ParsedHashDirectiveArgument.Int32(n, lhs parseState) }
| IDENT
{ let m = rhs parseState 1
parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.ParsedHashDirectiveArgumentNonString (rhs parseState 1)
ParsedHashDirectiveArgument.Ident(Ident($1, m), lhs parseState) }
| pathOp
{ let path = $1
parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.ParsedHashDirectiveArgumentNonString (rhs parseState 1)
ParsedHashDirectiveArgument.LongIdent(path, lhs parseState) }
| sourceIdentifier
{ let c, v = $1
ParsedHashDirectiveArgument.SourceIdentifier(c, v, lhs parseState) }
Expand Down
15 changes: 10 additions & 5 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading