Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser: recover on unfinished enum case declarations #16401

Merged
merged 3 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
27 changes: 27 additions & 0 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -2721,6 +2721,16 @@ attrUnionCaseDecl:
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
Choice1Of2 (SynEnumCase ($1, $3, fst $5, xmlDoc, mDecl, trivia))) }

| opt_attributes opt_access unionCaseName EQUALS recover
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(), rhs parseState 2))
let mEquals = rhs parseState 4
let expr = arbExpr ("attrUnionCaseDecl", mEquals.EndRange)
let mDecl = rhs2 parseState 1 4
fun (xmlDoc, mBar) ->
let trivia: SynEnumCaseTrivia = { BarRange = Some mBar; EqualsRange = mEquals }
let mDecl = unionRangeWithXmlDoc xmlDoc mDecl
Choice1Of2 (SynEnumCase ($1, $3, expr, xmlDoc, mDecl, trivia)) }

/* The name of a union case */
unionCaseName:
| nameop
Expand Down Expand Up @@ -2750,6 +2760,14 @@ firstUnionCaseDeclOfMany:
let mDecl = (rhs2 parseState 1 3) |> unionRangeWithXmlDoc xmlDoc
Choice1Of2 (SynEnumCase ([], SynIdent($1, None), fst $3, xmlDoc, mDecl, trivia)) }

| ident EQUALS recover opt_OBLOCKSEP
{ let mEquals = rhs parseState 2
let expr = arbExpr ("firstUnionCaseDeclOfMany1", mEquals.EndRange)
let trivia: SynEnumCaseTrivia = { BarRange = None; EqualsRange = mEquals }
let xmlDoc = grabXmlDoc(parseState, [], 1)
let mDecl = (rhs2 parseState 1 2) |> unionRangeWithXmlDoc xmlDoc
Choice1Of2 (SynEnumCase ([], SynIdent($1, None), expr, xmlDoc, mDecl, trivia)) }

| firstUnionCaseDecl opt_OBLOCKSEP
{ $1 }

Expand Down Expand Up @@ -2783,6 +2801,15 @@ firstUnionCaseDecl:
let mDecl = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc
Choice1Of2(SynEnumCase([], SynIdent($1, None), fst $3, xmlDoc, mDecl, trivia)) }

| ident EQUALS recover opt_OBLOCKSEP
{ let mEquals = rhs parseState 2
let expr = arbExpr ("firstUnionCaseDecl", mEquals.EndRange)
let trivia: SynEnumCaseTrivia = { BarRange = None; EqualsRange = mEquals }
let xmlDoc = grabXmlDoc (parseState, [], 1)
let mDecl = rhs2 parseState 1 2 |> unionRangeWithXmlDoc xmlDoc
Choice1Of2(SynEnumCase([], SynIdent($1, None), expr, xmlDoc, mDecl, trivia)) }


unionCaseReprElements:
| unionCaseReprElement STAR unionCaseReprElements
{ $1 :: $3 }
Expand Down
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 01.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

type E =
| A = 1

()
28 changes: 28 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 01.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 01.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
Const (Int32 1, (4,10--4,11)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,6--4,11), { BarRange = Some (4,4--4,5)
EqualsRange = (4,8--4,9) })],
(4,4--4,11)), (4,4--4,11)), [], None, (3,5--4,11),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,11));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 02.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

type E =
A = 1

()
27 changes: 27 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 02.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 02.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None), Const (Int32 1, (4,8--4,9)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,4--4,9), { BarRange = None
EqualsRange = (4,6--4,7) })],
(4,4--4,9)), (4,4--4,9)), [], None, (3,5--4,9),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,9));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 03.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

type E =
| A =

()
31 changes: 31 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 03.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 03.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("attrUnionCaseDecl", (4,9--4,9)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,6--4,9), { BarRange = Some (4,4--4,5)
EqualsRange = (4,8--4,9) })],
(4,4--4,9)), (4,4--4,9)), [], None, (3,5--4,9),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,9));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(6,0)-(6,1) parse error Incomplete structured construct at or before this point in union case
7 changes: 7 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 04.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Module

type E =
| A =
| B = 2

()
37 changes: 37 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 04.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 04.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("attrUnionCaseDecl", (4,9--4,9)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,6--4,9), { BarRange = Some (4,4--4,5)
EqualsRange = (4,8--4,9) });
SynEnumCase
([], SynIdent (B, None),
Const (Int32 2, (5,10--5,11)),
PreXmlDoc ((5,4), FSharp.Compiler.Xml.XmlDocCollector),
(5,6--5,11), { BarRange = Some (5,4--5,5)
EqualsRange = (5,8--5,9) })],
(4,4--5,11)), (4,4--5,11)), [], None, (3,5--5,11),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--5,11));
Expr (Const (Unit, (7,0--7,2)), (7,0--7,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(5,4)-(5,5) parse error Unexpected symbol '|' in union case
6 changes: 6 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 05.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Module

type E =
A =

()
31 changes: 31 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 05.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 05.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("firstUnionCaseDecl", (4,7--4,7)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,4--4,7), { BarRange = None
EqualsRange = (4,6--4,7) })],
(4,4--4,7)), (4,4--4,7)), [], None, (3,5--4,7),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,7));
Expr (Const (Unit, (6,0--6,2)), (6,0--6,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--6,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(6,0)-(6,1) parse error Incomplete structured construct at or before this point in type definition
7 changes: 7 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 06.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Module

type E =
A =
| B = 2

()
37 changes: 37 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 06.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 06.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("firstUnionCaseDeclOfMany1", (4,9--4,9)),
PreXmlDoc ((4,6), FSharp.Compiler.Xml.XmlDocCollector),
(4,6--4,9), { BarRange = None
EqualsRange = (4,8--4,9) });
SynEnumCase
([], SynIdent (B, None),
Const (Int32 2, (5,10--5,11)),
PreXmlDoc ((5,4), FSharp.Compiler.Xml.XmlDocCollector),
(5,6--5,11), { BarRange = Some (5,4--5,5)
EqualsRange = (5,8--5,9) })],
(4,6--5,11)), (4,6--5,11)), [], None, (3,5--5,11),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--5,11));
Expr (Const (Unit, (7,0--7,2)), (7,0--7,2))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--7,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(5,4)-(5,5) parse error Unexpected symbol '|' in type definition
4 changes: 4 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 07 - Eof.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Module

type E =
| A =
30 changes: 30 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 07 - Eof.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 07 - Eof.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("attrUnionCaseDecl", (4,9--4,9)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,6--4,9), { BarRange = Some (4,4--4,5)
EqualsRange = (4,8--4,9) })],
(4,4--4,9)), (4,4--4,9)), [], None, (3,5--4,9),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,9))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--4,9), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(5,0)-(5,0) parse error Incomplete structured construct at or before this point in union case
4 changes: 4 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 08 - Eof.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Module

type E =
A =
30 changes: 30 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 08 - Eof.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 08 - Eof.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("firstUnionCaseDecl", (4,7--4,7)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,4--4,7), { BarRange = None
EqualsRange = (4,6--4,7) })],
(4,4--4,7)), (4,4--4,7)), [], None, (3,5--4,7),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,7))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--4,7), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(5,0)-(5,0) parse error Incomplete structured construct at or before this point in type definition
4 changes: 4 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 09 - Eof.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Module

type E =
| A =
30 changes: 30 additions & 0 deletions tests/service/data/SyntaxTree/Type/Enum 09 - Eof.fs.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ImplFile
(ParsedImplFileInput
("/root/Type/Enum 09 - Eof.fs", false, QualifiedNameOfFile Module, [], [],
[SynModuleOrNamespace
([Module], false, NamedModule,
[Types
([SynTypeDefn
(SynComponentInfo
([], None, [], [E],
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
false, None, (3,5--3,6)),
Simple
(Enum
([SynEnumCase
([], SynIdent (A, None),
ArbitraryAfterError
("attrUnionCaseDecl", (4,9--4,9)),
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
(4,6--4,9), { BarRange = Some (4,4--4,5)
EqualsRange = (4,8--4,9) })],
(4,4--4,9)), (4,4--4,9)), [], None, (3,5--4,9),
{ LeadingKeyword = Type (3,0--3,4)
EqualsRange = Some (3,7--3,8)
WithKeyword = None })], (3,0--4,9))],
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
(1,0--4,9), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
{ ConditionalDirectives = []
CodeComments = [] }, set []))

(4,0)-(4,9) parse error Incomplete structured construct at or before this point in union case
Loading