From f951bcc27bbb1b01952dd4967f89137feb5d3087 Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 22 Jun 2023 13:11:22 +0200 Subject: [PATCH 1/3] Improve error recovery of union case definitions --- src/Compiler/FSComp.txt | 3 +- src/Compiler/SyntaxTree/ParseHelpers.fs | 9 +++ src/Compiler/SyntaxTree/ParseHelpers.fsi | 2 + src/Compiler/pars.fsy | 61 +++++------------- src/Compiler/xlf/FSComp.txt.cs.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 ++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 ++ .../UnionCase/Missing keyword of.fs | 7 +++ .../UnionCase/Missing keyword of.fs.bsl | 62 +++++++++++++++++++ .../UnionCase/Missing name 05.fs.bsl | 2 +- .../UnionCase/Missing name 06.fs.bsl | 2 +- 21 files changed, 163 insertions(+), 50 deletions(-) create mode 100644 tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs create mode 100644 tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 6bcea07ddc1..dc28331da25 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1697,4 +1697,5 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form 3565,parsExpectingType,"Expecting type" featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj inferred) at informational level, off by default" 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." -3567,parsMissingMemberBody,"Expecting member body" \ No newline at end of file +3567,parsMissingMemberBody,"Expecting member body" +3568,parsMissingKeyword,"Missing keyword '%s'" \ No newline at end of file diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 5821534137a..8f6de486335 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -1090,3 +1090,12 @@ let appendValToLeadingKeyword mVal leadingKeyword = | SynLeadingKeyword.Override mOverride -> SynLeadingKeyword.OverrideVal(mOverride, mVal) | SynLeadingKeyword.Default (mDefault) -> SynLeadingKeyword.DefaultVal(mDefault, mVal) | _ -> leadingKeyword + +let mkSynUnionCase attributes (access: SynAccess option) id kind mDecl (xmlDoc, mBar) = + match access with + | Some access -> errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), access.Range)) + | _ -> () + + let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } + let mDecl = unionRangeWithXmlDoc xmlDoc mDecl + SynUnionCase (attributes, id, kind, xmlDoc, None, mDecl, trivia) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index 8d158862f4f..748631836d3 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -238,3 +238,5 @@ val checkForMultipleAugmentations: m: range -> a1: 'a list -> a2: 'a list -> 'a val rangeOfLongIdent: lid: LongIdent -> range val appendValToLeadingKeyword: mVal: range -> leadingKeyword: SynLeadingKeyword -> SynLeadingKeyword + +val mkSynUnionCase: attributes: SynAttributes -> access: SynAccess option -> id: SynIdent -> kind: SynUnionCaseKind -> mDecl: range -> (PreXmlDoc * range) -> SynUnionCase diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index da62e142c25..104e89ee693 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2485,69 +2485,36 @@ attrUnionCaseDecls: /* The core of a union case definition */ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - let mDecl = rhs parseState 3 - (fun (xmlDoc, mBar) -> - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) } + { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 3) >> Choice2Of2 } | opt_attributes opt_access recover - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - (fun (xmlDoc, mBar) -> - let id = SynIdent(mkSynId mBar.EndRange "", None) - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mBar - Choice2Of2 (SynUnionCase ($1, id, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) } + { fun (xmlDoc, mBar) -> mkSynUnionCase $1 $2 (SynIdent(mkSynId mBar.EndRange "", None)) (SynUnionCaseKind.Fields []) mBar (xmlDoc, mBar) |> Choice2Of2 } | opt_attributes opt_access unionCaseName OF unionCaseRepr - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - let mDecl = rhs2 parseState 1 5 - (fun (xmlDoc, mBar) -> - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.Fields $5, xmlDoc, None, mDecl, trivia))) } + { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields $5) (rhs2 parseState 1 5) >> Choice2Of2 } + + | opt_attributes opt_access unionCaseName unionCaseRepr + { errorR (Error(FSComp.SR.parsMissingKeyword("of"), rhs2 parseState 3 4)) + mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields $4) (rhs2 parseState 1 4) >> Choice2Of2 } | opt_attributes opt_access OF unionCaseRepr - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - let mOf = rhs parseState 3 + { let mOf = rhs parseState 3 let mId = mOf.StartRange errorR (Error(FSComp.SR.parsMissingUnionCaseName(), mOf)) - let mDecl = rhs2 parseState 1 4 - (fun (xmlDoc, mBar) -> - let id = SynIdent(mkSynId mId "", None) - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - Choice2Of2(SynUnionCase($1, id, SynUnionCaseKind.Fields $4, xmlDoc, None, mDecl, trivia))) } + mkSynUnionCase $1 $2 (SynIdent(mkSynId mId "", None)) (SynUnionCaseKind.Fields $4) (rhs2 parseState 1 4) >> Choice2Of2 } | opt_attributes opt_access OF recover - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - let mOf = rhs parseState 3 + { let mOf = rhs parseState 3 let mId = mOf.StartRange errorR (Error(FSComp.SR.parsMissingUnionCaseName(), mOf)) - let mDecl = rhs2 parseState 1 3 - (fun (xmlDoc, mBar) -> - let id = SynIdent(mkSynId mId "", None) - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - Choice2Of2(SynUnionCase($1, id, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) } + mkSynUnionCase $1 $2 (SynIdent(mkSynId mId "", None)) (SynUnionCaseKind.Fields []) (rhs2 parseState 1 3) >> Choice2Of2 } | opt_attributes opt_access unionCaseName OF recover - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - let mDecl = rhs2 parseState 1 4 - (fun (xmlDoc, mBar) -> - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.Fields [], xmlDoc, None, mDecl, trivia))) } + { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } | opt_attributes opt_access unionCaseName COLON topType - { if Option.isSome $2 then errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), rhs parseState 2)) - if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) - let mDecl = rhs2 parseState 1 5 - (fun (xmlDoc, mBar) -> - let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } - let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - Choice2Of2 (SynUnionCase ($1, $3, SynUnionCaseKind.FullType $5, xmlDoc, None, mDecl, trivia))) } + { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) + mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } | opt_attributes opt_access unionCaseName EQUALS atomicExpr { if Option.isSome $2 then errorR(Error(FSComp.SR.parsEnumFieldsCannotHaveVisibilityDeclarations(), rhs parseState 2)) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index e2ada2aeefc..f4366573047 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -822,6 +822,11 @@ Neúplný výraz operátoru (například^b) nebo volání kvalifikovaného typu (příklad: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index df2b1f967f0..d3eb75f23b4 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -822,6 +822,11 @@ Unvollständiger Operatorausdruck (Beispiel: a^b) oder qualifizierter Typaufruf (Beispiel: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 0c480da0223..17516c49bd6 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -822,6 +822,11 @@ Expresión de operador incompleta (ejemplo, a^b) o invocación de tipo calificada (ejemplo: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index fb6f9624aa8..00b0960329d 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -822,6 +822,11 @@ Expression d’opérateur incomplète (exemple a^b) ou appel de type qualifié (exemple : ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 2854baa4e04..c3fb396d4ec 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -822,6 +822,11 @@ Espressione operatore incompleta (ad esempio a^b) o chiamata di tipo qualificato (ad esempio: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index ea67c6bdb2b..b15e2852cab 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -822,6 +822,11 @@ 不完全な演算子式 (例 a^b) または修飾型の呼び出し (例: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 1a159133203..caee7e80309 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -822,6 +822,11 @@ 불완전한 연산자 식(예: a^b) 또는 정규화된 형식 호출(예: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 0000778b463..241df1d33f6 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -822,6 +822,11 @@ Niekompletne wyrażenie operatora (na przykład a^b) lub wywołanie typu kwalifikowanego (przykład: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 6fd3039fa99..454ddc430ce 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -822,6 +822,11 @@ Expressão de operador incompleta (exemplo a^b) ou invocação de tipo qualificado (exemplo: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 7fb971a92b9..51360520f9e 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -822,6 +822,11 @@ Неполное выражение оператора (например, a^b) или вызов квалифицированного типа (например, ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index cbb50b53421..5b05ea176a4 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -822,6 +822,11 @@ Eksik işleç ifadesi (örnek a^b) veya tam tür çağrısı (örnek: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 0d7b753c8b1..c693740e7b8 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -822,6 +822,11 @@ 运算符表达式不完整(示例: a^b)或限定类型调用(示例: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index ce97b003aac..99d08284a2d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -822,6 +822,11 @@ 不完整的運算子運算式 (範例 a^b) 或限定類型調用 (範例: ^T.Name) + + Missing keyword '{0}' + Missing keyword '{0}' + + Expecting member body Expecting member body diff --git a/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs new file mode 100644 index 00000000000..2b4863b0c71 --- /dev/null +++ b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs @@ -0,0 +1,7 @@ +module Module + +type U = + | Case1 + | Case2 string + | Case3 of int + | Case4 4 diff --git a/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl new file mode 100644 index 00000000000..4163caef7bf --- /dev/null +++ b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl @@ -0,0 +1,62 @@ +ImplFile + (ParsedImplFileInput + ("/root/UnionCase/Missing keyword of.fs", false, QualifiedNameOfFile Module, + [], [], + [SynModuleOrNamespace + ([Module], false, NamedModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [U], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (3,5--3,6)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (Case1, None), Fields [], + PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (4,6--4,11), { BarRange = Some (4,4--4,5) }); + SynUnionCase + ([], SynIdent (Case2, None), + Fields + [SynField + ([], false, None, + LongIdent + (SynLongIdent ([string], [], [None])), false, + PreXmlDoc ((5,12), FSharp.Compiler.Xml.XmlDocCollector), + None, (5,12--5,18), { LeadingKeyword = None })], + PreXmlDoc ((5,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (5,6--5,18), { BarRange = Some (5,4--5,5) }); + SynUnionCase + ([], SynIdent (Case3, None), + Fields + [SynField + ([], false, None, + LongIdent (SynLongIdent ([int], [], [None])), + false, + PreXmlDoc ((6,15), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,15--6,18), { LeadingKeyword = None })], + PreXmlDoc ((6,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,6--6,18), { BarRange = Some (6,4--6,5) }); + SynUnionCase + ([], SynIdent (Case4, None), + Fields + [SynField + ([], false, None, + StaticConstant (Int32 4, (7,12--7,13)), false, + PreXmlDoc ((7,12), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,12--7,13), { LeadingKeyword = None })], + PreXmlDoc ((7,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,6--7,13), { BarRange = Some (7,4--7,5) })], + (4,4--7,13)), (4,4--7,13)), [], None, (3,5--7,13), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--7,13))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--7,13), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(5,6)-(5,18) parse error Missing keyword 'of' +(7,6)-(7,13) parse error Missing keyword 'of' diff --git a/tests/service/data/SyntaxTree/UnionCase/Missing name 05.fs.bsl b/tests/service/data/SyntaxTree/UnionCase/Missing name 05.fs.bsl index a9b9069f2bf..a258d294e96 100644 --- a/tests/service/data/SyntaxTree/UnionCase/Missing name 05.fs.bsl +++ b/tests/service/data/SyntaxTree/UnionCase/Missing name 05.fs.bsl @@ -41,5 +41,5 @@ ImplFile { ConditionalDirectives = [] CodeComments = [] }, set [])) -(5,6)-(5,14) parse error Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation. (5,15)-(5,17) parse error Missing union case name +(5,6)-(5,14) parse error Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation. diff --git a/tests/service/data/SyntaxTree/UnionCase/Missing name 06.fs.bsl b/tests/service/data/SyntaxTree/UnionCase/Missing name 06.fs.bsl index 41a4bf12268..27516955a99 100644 --- a/tests/service/data/SyntaxTree/UnionCase/Missing name 06.fs.bsl +++ b/tests/service/data/SyntaxTree/UnionCase/Missing name 06.fs.bsl @@ -35,5 +35,5 @@ ImplFile CodeComments = [] }, set [])) (6,4)-(6,5) parse error Unexpected symbol '|' in union case -(5,6)-(5,14) parse error Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation. (5,15)-(5,17) parse error Missing union case name +(5,6)-(5,14) parse error Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation. From 5d2143dcdb7f08ce9bf8090a97e38fff9bb2d590 Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 22 Jun 2023 13:19:14 +0200 Subject: [PATCH 2/3] Obey Fantomas --- src/Compiler/SyntaxTree/ParseHelpers.fs | 4 ++-- src/Compiler/SyntaxTree/ParseHelpers.fsi | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index 8f6de486335..80929510001 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -1093,9 +1093,9 @@ let appendValToLeadingKeyword mVal leadingKeyword = let mkSynUnionCase attributes (access: SynAccess option) id kind mDecl (xmlDoc, mBar) = match access with - | Some access -> errorR(Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations(), access.Range)) + | Some access -> errorR (Error(FSComp.SR.parsUnionCasesCannotHaveVisibilityDeclarations (), access.Range)) | _ -> () let trivia: SynUnionCaseTrivia = { BarRange = Some mBar } let mDecl = unionRangeWithXmlDoc xmlDoc mDecl - SynUnionCase (attributes, id, kind, xmlDoc, None, mDecl, trivia) + SynUnionCase(attributes, id, kind, xmlDoc, None, mDecl, trivia) diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fsi b/src/Compiler/SyntaxTree/ParseHelpers.fsi index 748631836d3..326a806e131 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fsi +++ b/src/Compiler/SyntaxTree/ParseHelpers.fsi @@ -239,4 +239,11 @@ val rangeOfLongIdent: lid: LongIdent -> range val appendValToLeadingKeyword: mVal: range -> leadingKeyword: SynLeadingKeyword -> SynLeadingKeyword -val mkSynUnionCase: attributes: SynAttributes -> access: SynAccess option -> id: SynIdent -> kind: SynUnionCaseKind -> mDecl: range -> (PreXmlDoc * range) -> SynUnionCase +val mkSynUnionCase: + attributes: SynAttributes -> + access: SynAccess option -> + id: SynIdent -> + kind: SynUnionCaseKind -> + mDecl: range -> + (PreXmlDoc * range) -> + SynUnionCase From d84ea5c9ce8aa4f7b80ce9e93ec41cccd538c1b5 Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 22 Jun 2023 13:54:15 +0200 Subject: [PATCH 3/3] Extend test --- .../UnionCase/Missing keyword of.fs | 4 + .../UnionCase/Missing keyword of.fs.bsl | 74 ++++++++++++------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs index 2b4863b0c71..e44e99bbcbb 100644 --- a/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs +++ b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs @@ -1,7 +1,11 @@ module Module +let a = () + type U = | Case1 | Case2 string | Case3 of int | Case4 4 + +let b = () diff --git a/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl index 4163caef7bf..61ef3fc7998 100644 --- a/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl +++ b/tests/service/data/SyntaxTree/UnionCase/Missing keyword of.fs.bsl @@ -4,19 +4,31 @@ ImplFile [], [], [SynModuleOrNamespace ([Module], false, NamedModule, - [Types + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (a, None), false, None, (3,4--3,5)), None, + Const (Unit, (3,8--3,10)), (3,4--3,5), Yes (3,0--3,10), + { LeadingKeyword = Let (3,0--3,3) + InlineKeyword = None + EqualsRange = Some (3,6--3,7) })], (3,0--3,10)); + Types ([SynTypeDefn (SynComponentInfo ([], None, [], [U], - PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), - false, None, (3,5--3,6)), + PreXmlDoc ((5,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (5,5--5,6)), Simple (Union (None, [SynUnionCase ([], SynIdent (Case1, None), Fields [], - PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector), - None, (4,6--4,11), { BarRange = Some (4,4--4,5) }); + PreXmlDoc ((6,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,6--6,11), { BarRange = Some (6,4--6,5) }); SynUnionCase ([], SynIdent (Case2, None), Fields @@ -24,10 +36,10 @@ ImplFile ([], false, None, LongIdent (SynLongIdent ([string], [], [None])), false, - PreXmlDoc ((5,12), FSharp.Compiler.Xml.XmlDocCollector), - None, (5,12--5,18), { LeadingKeyword = None })], - PreXmlDoc ((5,4), FSharp.Compiler.Xml.XmlDocCollector), - None, (5,6--5,18), { BarRange = Some (5,4--5,5) }); + PreXmlDoc ((7,12), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,12--7,18), { LeadingKeyword = None })], + PreXmlDoc ((7,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,6--7,18), { BarRange = Some (7,4--7,5) }); SynUnionCase ([], SynIdent (Case3, None), Fields @@ -35,28 +47,40 @@ ImplFile ([], false, None, LongIdent (SynLongIdent ([int], [], [None])), false, - PreXmlDoc ((6,15), FSharp.Compiler.Xml.XmlDocCollector), - None, (6,15--6,18), { LeadingKeyword = None })], - PreXmlDoc ((6,4), FSharp.Compiler.Xml.XmlDocCollector), - None, (6,6--6,18), { BarRange = Some (6,4--6,5) }); + PreXmlDoc ((8,15), FSharp.Compiler.Xml.XmlDocCollector), + None, (8,15--8,18), { LeadingKeyword = None })], + PreXmlDoc ((8,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (8,6--8,18), { BarRange = Some (8,4--8,5) }); SynUnionCase ([], SynIdent (Case4, None), Fields [SynField ([], false, None, - StaticConstant (Int32 4, (7,12--7,13)), false, - PreXmlDoc ((7,12), FSharp.Compiler.Xml.XmlDocCollector), - None, (7,12--7,13), { LeadingKeyword = None })], - PreXmlDoc ((7,4), FSharp.Compiler.Xml.XmlDocCollector), - None, (7,6--7,13), { BarRange = Some (7,4--7,5) })], - (4,4--7,13)), (4,4--7,13)), [], None, (3,5--7,13), - { LeadingKeyword = Type (3,0--3,4) - EqualsRange = Some (3,7--3,8) - WithKeyword = None })], (3,0--7,13))], + StaticConstant (Int32 4, (9,12--9,13)), false, + PreXmlDoc ((9,12), FSharp.Compiler.Xml.XmlDocCollector), + None, (9,12--9,13), { LeadingKeyword = None })], + PreXmlDoc ((9,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (9,6--9,13), { BarRange = Some (9,4--9,5) })], + (6,4--9,13)), (6,4--9,13)), [], None, (5,5--9,13), + { LeadingKeyword = Type (5,0--5,4) + EqualsRange = Some (5,7--5,8) + WithKeyword = None })], (5,0--9,13)); + Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((11,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (b, None), false, None, (11,4--11,5)), None, + Const (Unit, (11,8--11,10)), (11,4--11,5), Yes (11,0--11,10), + { LeadingKeyword = Let (11,0--11,3) + InlineKeyword = None + EqualsRange = Some (11,6--11,7) })], (11,0--11,10))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, - (1,0--7,13), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + (1,0--11,10), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) -(5,6)-(5,18) parse error Missing keyword 'of' -(7,6)-(7,13) parse error Missing keyword 'of' +(7,6)-(7,18) parse error Missing keyword 'of' +(9,6)-(9,13) parse error Missing keyword 'of'