Skip to content

Commit 03c95ce

Browse files
authored
Improve error recovery of union case definitions (#15468) (#15474)
* Improve error recovery of union case definitions
1 parent 5d0a22d commit 03c95ce

21 files changed

+198
-50
lines changed

src/Compiler/FSComp.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1697,4 +1697,5 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form
16971697
3565,parsExpectingType,"Expecting type"
16981698
featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj inferred) at informational level, off by default"
16991699
3566,tcMultipleRecdTypeChoice,"Multiple type matches were found:\n%s\nThe type '%s' was used. Due to the overlapping field names\n%s\nconsider using type annotations or change the order of open statements."
1700-
3567,parsMissingMemberBody,"Expecting member body"
1700+
3567,parsMissingMemberBody,"Expecting member body"
1701+
3568,parsMissingKeyword,"Missing keyword '%s'"

src/Compiler/SyntaxTree/ParseHelpers.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,3 +1090,12 @@ let appendValToLeadingKeyword mVal leadingKeyword =
10901090
| SynLeadingKeyword.Override mOverride -> SynLeadingKeyword.OverrideVal(mOverride, mVal)
10911091
| SynLeadingKeyword.Default (mDefault) -> SynLeadingKeyword.DefaultVal(mDefault, mVal)
10921092
| _ -> leadingKeyword
1093+
1094+
let mkSynUnionCase attributes (access: SynAccess option) id kind mDecl (xmlDoc, mBar) =
1095+
match access with
1096+
| Some access -> errorR (Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations (), access.Range))
1097+
| _ -> ()
1098+
1099+
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
1100+
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
1101+
SynUnionCase(attributes, id, kind, xmlDoc, None, mDecl, trivia)

src/Compiler/SyntaxTree/ParseHelpers.fsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,12 @@ val checkForMultipleAugmentations: m: range -> a1: 'a list -> a2: 'a list -> 'a
238238
val rangeOfLongIdent: lid: LongIdent -> range
239239

240240
val appendValToLeadingKeyword: mVal: range -> leadingKeyword: SynLeadingKeyword -> SynLeadingKeyword
241+
242+
val mkSynUnionCase:
243+
attributes: SynAttributes ->
244+
access: SynAccess option ->
245+
id: SynIdent ->
246+
kind: SynUnionCaseKind ->
247+
mDecl: range ->
248+
(PreXmlDoc * range) ->
249+
SynUnionCase

src/Compiler/pars.fsy

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,69 +2485,36 @@ attrUnionCaseDecls:
24852485
/* The core of a union case definition */
24862486
attrUnionCaseDecl:
24872487
| opt_attributes opt_access unionCaseName
2488-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2489-
let mDecl = rhs parseState 3
2490-
(fun (xmlDoc, mBar) ->
2491-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2492-
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
2493-
Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) }
2488+
{ mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 3) >> Choice2Of2 }
24942489

24952490
| opt_attributes opt_access recover
2496-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2497-
(fun (xmlDoc, mBar) ->
2498-
let id = SynIdent(mkSynId mBar.EndRange "", None)
2499-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2500-
let mDecl = unionRangeWithXmlDoc xmlDoc mBar
2501-
Choice2Of2 (SynUnionCase ($1, id, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) }
2491+
{ fun (xmlDoc, mBar) -> mkSynUnionCase $1 $2 (SynIdent(mkSynId mBar.EndRange "", None)) (SynUnionCaseKind.Fields []) mBar (xmlDoc, mBar) |> Choice2Of2 }
25022492

25032493
| opt_attributes opt_access unionCaseName OF unionCaseRepr
2504-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2505-
let mDecl = rhs2 parseState 1 5
2506-
(fun (xmlDoc, mBar) ->
2507-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2508-
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
2509-
Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.Fields $5, xmlDoc, None, mDecl, trivia))) }
2494+
{ mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields $5) (rhs2 parseState 1 5) >> Choice2Of2 }
2495+
2496+
| opt_attributes opt_access unionCaseName unionCaseRepr
2497+
{ errorR (Error(FSComp.SR.parsMissingKeyword("of"), rhs2 parseState 3 4))
2498+
mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields $4) (rhs2 parseState 1 4) >> Choice2Of2 }
25102499

25112500
| opt_attributes opt_access OF unionCaseRepr
2512-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2513-
let mOf = rhs parseState 3
2501+
{ let mOf = rhs parseState 3
25142502
let mId = mOf.StartRange
25152503
errorR (Error(FSComp.SR.parsMissingUnionCaseName(), mOf))
2516-
let mDecl = rhs2 parseState 1 4
2517-
(fun (xmlDoc, mBar) ->
2518-
let id = SynIdent(mkSynId mId "", None)
2519-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2520-
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
2521-
Choice2Of2(SynUnionCase($1, id, SynUnionCaseKind.Fields $4, xmlDoc, None, mDecl, trivia))) }
2504+
mkSynUnionCase $1 $2 (SynIdent(mkSynId mId "", None)) (SynUnionCaseKind.Fields $4) (rhs2 parseState 1 4) >> Choice2Of2 }
25222505

25232506
| opt_attributes opt_access OF recover
2524-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2525-
let mOf = rhs parseState 3
2507+
{ let mOf = rhs parseState 3
25262508
let mId = mOf.StartRange
25272509
errorR (Error(FSComp.SR.parsMissingUnionCaseName(), mOf))
2528-
let mDecl = rhs2 parseState 1 3
2529-
(fun (xmlDoc, mBar) ->
2530-
let id = SynIdent(mkSynId mId "", None)
2531-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2532-
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
2533-
Choice2Of2(SynUnionCase($1, id, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) }
2510+
mkSynUnionCase $1 $2 (SynIdent(mkSynId mId "", None)) (SynUnionCaseKind.Fields []) (rhs2 parseState 1 3) >> Choice2Of2 }
25342511

25352512
| opt_attributes opt_access unionCaseName OF recover
2536-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2537-
let mDecl = rhs2 parseState 1 4
2538-
(fun (xmlDoc, mBar) ->
2539-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2540-
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
2541-
Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) }
2513+
{ mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 }
25422514

25432515
| opt_attributes opt_access unionCaseName COLON topType
2544-
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2))
2545-
if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState)
2546-
let mDecl = rhs2 parseState 1 5
2547-
(fun (xmlDoc, mBar) ->
2548-
let trivia: SynUnionCaseTrivia = { BarRange = Some mBar }
2549-
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
2550-
Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.FullType $5, xmlDoc, None, mDecl, trivia))) }
2516+
{ if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState)
2517+
mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 }
25512518

25522519
| opt_attributes opt_access unionCaseName EQUALS atomicExpr
25532520
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(), rhs parseState 2))

src/Compiler/xlf/FSComp.txt.cs.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@
822822
<target state="translated">Neúplný výraz operátoru (například^b) nebo volání kvalifikovaného typu (příklad: ^T.Name)</target>
823823
<note />
824824
</trans-unit>
825+
<trans-unit id="parsMissingKeyword">
826+
<source>Missing keyword '{0}'</source>
827+
<target state="new">Missing keyword '{0}'</target>
828+
<note />
829+
</trans-unit>
825830
<trans-unit id="parsMissingMemberBody">
826831
<source>Expecting member body</source>
827832
<target state="new">Expecting member body</target>

src/Compiler/xlf/FSComp.txt.de.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@
822822
<target state="translated">Unvollständiger Operatorausdruck (Beispiel: a^b) oder qualifizierter Typaufruf (Beispiel: ^T.Name)</target>
823823
<note />
824824
</trans-unit>
825+
<trans-unit id="parsMissingKeyword">
826+
<source>Missing keyword '{0}'</source>
827+
<target state="new">Missing keyword '{0}'</target>
828+
<note />
829+
</trans-unit>
825830
<trans-unit id="parsMissingMemberBody">
826831
<source>Expecting member body</source>
827832
<target state="new">Expecting member body</target>

src/Compiler/xlf/FSComp.txt.es.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@
822822
<target state="translated">Expresión de operador incompleta (ejemplo, a^b) o invocación de tipo calificada (ejemplo: ^T.Name)</target>
823823
<note />
824824
</trans-unit>
825+
<trans-unit id="parsMissingKeyword">
826+
<source>Missing keyword '{0}'</source>
827+
<target state="new">Missing keyword '{0}'</target>
828+
<note />
829+
</trans-unit>
825830
<trans-unit id="parsMissingMemberBody">
826831
<source>Expecting member body</source>
827832
<target state="new">Expecting member body</target>

src/Compiler/xlf/FSComp.txt.fr.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@
822822
<target state="translated">Expression d’opérateur incomplète (exemple a^b) ou appel de type qualifié (exemple : ^T.Name)</target>
823823
<note />
824824
</trans-unit>
825+
<trans-unit id="parsMissingKeyword">
826+
<source>Missing keyword '{0}'</source>
827+
<target state="new">Missing keyword '{0}'</target>
828+
<note />
829+
</trans-unit>
825830
<trans-unit id="parsMissingMemberBody">
826831
<source>Expecting member body</source>
827832
<target state="new">Expecting member body</target>

src/Compiler/xlf/FSComp.txt.it.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@
822822
<target state="translated">Espressione operatore incompleta (ad esempio a^b) o chiamata di tipo qualificato (ad esempio: ^T.Name)</target>
823823
<note />
824824
</trans-unit>
825+
<trans-unit id="parsMissingKeyword">
826+
<source>Missing keyword '{0}'</source>
827+
<target state="new">Missing keyword '{0}'</target>
828+
<note />
829+
</trans-unit>
825830
<trans-unit id="parsMissingMemberBody">
826831
<source>Expecting member body</source>
827832
<target state="new">Expecting member body</target>

src/Compiler/xlf/FSComp.txt.ja.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@
822822
<target state="translated">不完全な演算子式 (例 a^b) または修飾型の呼び出し (例: ^T.Name)</target>
823823
<note />
824824
</trans-unit>
825+
<trans-unit id="parsMissingKeyword">
826+
<source>Missing keyword '{0}'</source>
827+
<target state="new">Missing keyword '{0}'</target>
828+
<note />
829+
</trans-unit>
825830
<trans-unit id="parsMissingMemberBody">
826831
<source>Expecting member body</source>
827832
<target state="new">Expecting member body</target>

0 commit comments

Comments
 (0)