From 41dc8df01e2073adc446a5b56b1599ba32f1834f Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 23 Jun 2023 09:42:51 +0200 Subject: [PATCH] Add recovery rules for SynField. --- src/Compiler/SyntaxTree/ParseHelpers.fs | 4 ++ src/Compiler/SyntaxTree/ParseHelpers.fsi | 12 +++++ src/Compiler/pars.fsy | 11 +++-- .../service/data/SyntaxTree/Type/Record 01.fs | 9 ++++ .../data/SyntaxTree/Type/Record 01.fs.bsl | 45 ++++++++++++++++++ .../service/data/SyntaxTree/Type/Record 02.fs | 9 ++++ .../data/SyntaxTree/Type/Record 02.fs.bsl | 46 +++++++++++++++++++ 7 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Type/Record 01.fs create mode 100644 tests/service/data/SyntaxTree/Type/Record 01.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Type/Record 02.fs create mode 100644 tests/service/data/SyntaxTree/Type/Record 02.fs.bsl diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 80929510001..2edb4a33546 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -1099,3 +1099,7 @@ let mkSynUnionCase attributes (access: SynAccess option) id kind mDecl (xmlDoc, let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } let mDecl = unionRangeWithXmlDoc xmlDoc mDecl SynUnionCase(attributes, id, kind, xmlDoc, None, mDecl, trivia) + +let mkSynField parseState idOpt t isMutable vis attributes isStatic mWhole leadingKeyword = + let xmlDoc = grabXmlDocAtRangeStart (parseState, attributes, mWhole) + SynField(attributes, isStatic, idOpt, t, isMutable, xmlDoc, vis, mWhole, { LeadingKeyword = leadingKeyword }) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index 326a806e131..36f3bbaaa0b 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -247,3 +247,15 @@ val mkSynUnionCase: mDecl: range -> (PreXmlDoc * range) -> SynUnionCase + +val mkSynField: + parseState: IParseState -> + idOpt: Ident option -> + t: SynType -> + isMutable: bool -> + vis: SynAccess option -> + attributes: SynAttributeList list -> + isStatic: bool -> + mWhole: range -> + leadingKeyword: SynLeadingKeyword option -> + SynField diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 104e89ee693..987b57507ff 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2633,9 +2633,14 @@ recdFieldDecl: /* Part of a field or val declaration in a record type or object type */ fieldDecl: | opt_mutable opt_access ident COLON typ - { fun attrs stat mWhole leadingKeyword -> - let xmlDoc = grabXmlDocAtRangeStart(parseState, attrs, mWhole) - SynField(attrs, stat, Some $3, $5, $1, xmlDoc, $2, mWhole, { LeadingKeyword = leadingKeyword }) } + { mkSynField parseState (Some $3) $5 $1 $2 } + | opt_mutable opt_access ident COLON recover + { let mColon = rhs parseState 4 + let t = SynType.FromParseError(mColon.EndRange) + mkSynField parseState (Some $3) t $1 $2 } + | opt_mutable opt_access ident recover + { let t = SynType.FromParseError($3.idRange.EndRange) + mkSynField parseState (Some $3) t $1 $2 } /* An exception definition */ exconDefn: diff --git a/tests/service/data/SyntaxTree/Type/Record 01.fs b/tests/service/data/SyntaxTree/Type/Record 01.fs new file mode 100644 index 00000000000..417a2790467 --- /dev/null +++ b/tests/service/data/SyntaxTree/Type/Record 01.fs @@ -0,0 +1,9 @@ +module Foo + +type AU = + { + Invest: int + T + } + +let meh = () diff --git a/tests/service/data/SyntaxTree/Type/Record 01.fs.bsl b/tests/service/data/SyntaxTree/Type/Record 01.fs.bsl new file mode 100644 index 00000000000..91d5f58ca56 --- /dev/null +++ b/tests/service/data/SyntaxTree/Type/Record 01.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Type/Record 01.fs", false, QualifiedNameOfFile Foo, [], [], + [SynModuleOrNamespace + ([Foo], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [AU], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,7)), + Simple + (Record + (None, + [SynField + ([], false, Some Invest, + LongIdent (SynLongIdent ([int], [], [None])), false, + PreXmlDoc ((5,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (5,8--5,19), { LeadingKeyword = None }); + SynField + ([], false, Some T, FromParseError (6,9--6,9), false, + PreXmlDoc ((6,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,8--7,5), { LeadingKeyword = None })], + (4,4--7,5)), (4,4--7,5)), [], None, (3,5--7,5), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,8--3,9) + WithKeyword = None })], (3,0--7,5)); + Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((9,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (meh, None), false, None, (9,4--9,7)), None, + Const (Unit, (9,10--9,12)), (9,4--9,7), Yes (9,0--9,12), + { LeadingKeyword = Let (9,0--9,3) + InlineKeyword = None + EqualsRange = Some (9,8--9,9) })], (9,0--9,12))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--9,12), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(7,4)-(7,5) parse error Unexpected symbol '}' in field declaration. Expected ':' or other token. diff --git a/tests/service/data/SyntaxTree/Type/Record 02.fs b/tests/service/data/SyntaxTree/Type/Record 02.fs new file mode 100644 index 00000000000..d42ab66e1f5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Type/Record 02.fs @@ -0,0 +1,9 @@ +module Foo + +type AU = + { + Invest: int + T : + } + +let meh = () diff --git a/tests/service/data/SyntaxTree/Type/Record 02.fs.bsl b/tests/service/data/SyntaxTree/Type/Record 02.fs.bsl new file mode 100644 index 00000000000..3ebdfe18ae4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Type/Record 02.fs.bsl @@ -0,0 +1,46 @@ +ImplFile + (ParsedImplFileInput + ("/root/Type/Record 02.fs", false, QualifiedNameOfFile Foo, [], [], + [SynModuleOrNamespace + ([Foo], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [AU], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,7)), + Simple + (Record + (None, + [SynField + ([], false, Some Invest, + LongIdent (SynLongIdent ([int], [], [None])), false, + PreXmlDoc ((5,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (5,8--5,19), { LeadingKeyword = None }); + SynField + ([], false, Some T, FromParseError (6,11--6,11), + false, + PreXmlDoc ((6,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,8--7,5), { LeadingKeyword = None })], + (4,4--7,5)), (4,4--7,5)), [], None, (3,5--7,5), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,8--3,9) + WithKeyword = None })], (3,0--7,5)); + Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((9,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (meh, None), false, None, (9,4--9,7)), None, + Const (Unit, (9,10--9,12)), (9,4--9,7), Yes (9,0--9,12), + { LeadingKeyword = Let (9,0--9,3) + InlineKeyword = None + EqualsRange = Some (9,8--9,9) })], (9,0--9,12))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--9,12), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(7,4)-(7,5) parse error Unexpected symbol '}' in field declaration