Skip to content

Commit d6c6d3c

Browse files
committed
Parser: recover on unfinished namespaces and top level modules
1 parent fd05137 commit d6c6d3c

29 files changed

+255
-2
lines changed

src/Compiler/pars.fsy

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,13 +527,22 @@ moduleIntro:
527527
let mModule = rhs parseState 1
528528
mModule, $4, [], $3, $2 }
529529

530+
| moduleKeyword opt_attributes opt_access opt_rec recover
531+
{ if not (isNil $2) then
532+
parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AttributesToRightOfModuleKeyword (rhs parseState 4)
533+
let mModule = rhs parseState 1
534+
mModule, $4, [], $3, $2 }
530535

531536
/* The start of a namespace declaration */
532537
namespaceIntro:
533538
| NAMESPACE opt_rec path
534539
{ let mNamespace = rhs parseState 1
535540
mNamespace, $2, $3.LongIdent, grabXmlDoc(parseState, [], 1) }
536541

542+
| NAMESPACE opt_rec recover
543+
{ let mNamespace = rhs parseState 1
544+
mNamespace, $2, [], grabXmlDoc(parseState, [], 1) }
545+
537546

538547
/* The contents of a signature file */
539548
fileNamespaceSpecs:
@@ -1138,8 +1147,8 @@ fileModuleImpl:
11381147
| moduleDefnsOrExprPossiblyEmptyOrBlock
11391148
{ let m = (rhs parseState 1)
11401149
(fun (mNamespaceOpt, isRec, path, xml) ->
1141-
match path with
1142-
| [] -> ParsedImplFileFragment.AnonModule($1, m)
1150+
match path, mNamespaceOpt with
1151+
| [], None -> ParsedImplFileFragment.AnonModule($1, m)
11431152
| _ ->
11441153
let lastDeclRange = List.tryLast $1 |> Option.map (fun decl -> decl.Range) |> Option.defaultValue (rhs parseState 1)
11451154
let m = mkRange lastDeclRange.FileName (lhs parseState).Start lastDeclRange.End
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/ModuleOrNamespace/Anon module 01.fs", false,
4+
QualifiedNameOfFile Anon module 01, [], [],
5+
[SynModuleOrNamespace
6+
([Anon module 01], false, AnonModule,
7+
[Expr (Const (Unit, (1,0--1,2)), (1,0--1,2))], PreXmlDocEmpty, [],
8+
None, (1,0--1,2), { LeadingKeyword = None })], (true, true),
9+
{ ConditionalDirectives = []
10+
CodeComments = [] }, set []))
11+
12+
(1,0)-(1,2) parse warning The declarations in this file will be placed in an implicit module 'Anon module 01' based on the file name 'Anon module 01.fs'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/ModuleOrNamespace/Anon module 02.fsx", true,
4+
QualifiedNameOfFile Anon module 02$fsx, [], [],
5+
[SynModuleOrNamespace
6+
([Anon module 02], false, AnonModule,
7+
[Expr (Const (Unit, (1,0--1,2)), (1,0--1,2))], PreXmlDocEmpty, [],
8+
None, (1,0--1,2), { LeadingKeyword = None })], (true, true),
9+
{ ConditionalDirectives = []
10+
CodeComments = [] }, set []))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module A.
2+
3+
()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/ModuleOrNamespace/Module 05.fs", false, QualifiedNameOfFile A, [],
4+
[],
5+
[SynModuleOrNamespace
6+
([A], false, NamedModule, [Expr (Const (Unit, (3,0--3,2)), (3,0--3,2))],
7+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
8+
(1,0--3,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
9+
{ ConditionalDirectives = []
10+
CodeComments = [] }, set []))
11+
12+
(3,0)-(3,1) parse error Unexpected start of structured construct in definition
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module
2+
3+
()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/ModuleOrNamespace/Module 06.fs", false, QualifiedNameOfFile , [],
4+
[],
5+
[SynModuleOrNamespace
6+
([], false, NamedModule, [Expr (Const (Unit, (3,0--3,2)), (3,0--3,2))],
7+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
8+
(1,0--3,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
9+
{ ConditionalDirectives = []
10+
CodeComments = [] }, set []))
11+
12+
(3,0)-(3,1) parse error Unexpected start of structured construct in definition. Expected identifier, 'global' or other token.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module rec
2+
3+
()

0 commit comments

Comments
 (0)