Skip to content

Commit

Permalink
Recover from incomplete module declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
kerams committed Feb 9, 2023
1 parent b8bc941 commit c3241ad
Show file tree
Hide file tree
Showing 17 changed files with 119 additions and 52 deletions.
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1677,3 +1677,4 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form
3558,chkExplicitFieldsDeclarationsOnStaticClasses,"If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed."
3559,typrelNeverRefinedAwayFromTop,"A type has been implicitly inferred as 'obj', which may be unintended. Consider adding explicit type annotations. You can disable this warning by using '#nowarn \"3559\"' or '--nowarn:3559'."
3560,tcCopyAndUpdateRecordChangesAllFields,"This copy-and-update record expression changes all fields of record type '%s'. Consider using the record construction syntax instead."
3562,parsIncompleteNestedModule,"Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file."
35 changes: 22 additions & 13 deletions src/Compiler/SyntaxTree/LexFilter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1562,7 +1562,7 @@ type LexFilterImpl (
// Otherwise it's a 'head' module declaration, so ignore it

// Here prevToken is either 'module', 'rec', 'global' (invalid), '.', or ident, because we skip attribute tokens and access modifier tokens
| _, CtxtModuleHead (moduleTokenPos, prevToken, lexingModuleAttributes) :: _ ->
| _, CtxtModuleHead (moduleTokenPos, prevToken, lexingModuleAttributes) :: rest ->
match prevToken, token with
| _, GREATER_RBRACK when lexingModuleAttributes = LexingModuleAttributes
&& moduleTokenPos.Column < tokenStartPos.Column ->
Expand All @@ -1587,19 +1587,28 @@ type LexFilterImpl (
pushCtxt tokenTup (CtxtModuleBody (moduleTokenPos, false))
pushCtxtSeqBlock(true, AddBlockEnd)
returnToken tokenLexbufState token
| _ ->
if debug then dprintf "CtxtModuleHead: start of file, CtxtSeqBlock\n"
popCtxt()
// Don't push a new context if next token is EOF, since that raises an offside warning
match tokenTup.Token with
| EOF _ ->
returnToken tokenLexbufState token
| _ ->
match rest with
| [ CtxtSeqBlock _ ] ->
if debug then dprintf "CtxtModuleHead: start of file, CtxtSeqBlock\n"
popCtxt()
// Don't push a new context if next token is EOF, since that raises an offside warning
match tokenTup.Token with
| EOF _ ->
returnToken tokenLexbufState token
| _ ->
// We have reached other tokens without encountering '=' or ':', so this is a module declaration spanning the whole file
delayToken tokenTup
pushCtxt tokenTup (CtxtModuleBody (moduleTokenPos, true))
pushCtxtSeqBlockAt (tokenTup, true, AddBlockEnd)
hwTokenFetch false
| _ ->
// We have reached other tokens without encountering '=' or ':', so this is a module declaration spanning the whole file
delayToken tokenTup
pushCtxt tokenTup (CtxtModuleBody (moduleTokenPos, true))
pushCtxtSeqBlockAt (tokenTup, true, AddBlockEnd)
hwTokenFetch false
// Adding a new nested module, EQUALS hasn't been typed yet
// and we've encountered declarations below
if debug then dprintf "CtxtModuleHead: MODULE/LET, popping CtxtModuleHead\n"
popCtxt()
reprocessWithoutBlockRule()

// Offside rule for SeqBlock.
// f x
// g x
Expand Down
10 changes: 10 additions & 0 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,16 @@ moduleDefn:
let trivia: SynModuleDeclNestedModuleTrivia = { ModuleKeyword = Some mModule; EqualsRange = Some mEquals }
[ SynModuleDecl.NestedModule(info, isRec, def, false, ((rhs2 parseState 1 4, def) ||> unionRangeWithListBy (fun d -> d.Range) |> unionRangeWithXmlDoc xmlDoc), trivia)] }

/* incomplete 'module' definitions */
| opt_attributes opt_access moduleIntro
{ let xmlDoc = grabXmlDoc(parseState, $1, 1)
let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc
errorR(Error(FSComp.SR.parsIncompleteNestedModule(), mWhole))
let attribs, (mModule, isRec, path, vis, attribs2) = $1, $3
let info = SynComponentInfo(attribs @ attribs2, None, [], path, xmlDoc, false, vis, rhs parseState 3)
let trivia: SynModuleDeclNestedModuleTrivia = { ModuleKeyword = Some mModule; EqualsRange = None }
[ SynModuleDecl.NestedModule(info, isRec, [], false, mWhole, trivia)] }

/* unattached custom attributes */
| attributes recover
{ errorR(Error(FSComp.SR.parsAttributeOnIncompleteCode(), rhs parseState 1))
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/xlf/FSComp.txt.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -382,19 +382,16 @@
<target state="translated">reprezentace struktury aktivních vzorů</target>
<note />
</trans-unit>

<trans-unit id="featureTryWithInSeqExpressions">
<source>Support for try-with in sequence expressions</source>
<target state="new">Support for try-with in sequence expressions</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenCopyAndUpdateRecordChangesAllFields">
<source>Raises warnings when an copy-and-update record expression changes all fields of a record.</source>
<target state="new">Raises warnings when an copy-and-update record expression changes all fields of a record.</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenInliningMethodImplNoInlineMarkedFunction">
<source>Raises warnings when 'let inline ... =' is used together with [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] attribute. Function is not getting inlined.</source>
<target state="translated">Vyvolá upozornění, když se použije „let inline ... =“ společně s atributem [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;]. Funkce není vkládána.</target>
Expand Down Expand Up @@ -735,6 +732,11 @@
<target state="translated">Očekává se vzorek.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteNestedModule">
<source>Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</source>
<target state="new">Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteTyparExpr1">
<source>Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</source>
<target state="translated">Neúplný znakový literál (příklad: Q) nebo volání kvalifikovaného typu (příklad: T.Name)</target>
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/xlf/FSComp.txt.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -382,19 +382,16 @@
<target state="translated">Strukturdarstellung für aktive Muster</target>
<note />
</trans-unit>

<trans-unit id="featureTryWithInSeqExpressions">
<source>Support for try-with in sequence expressions</source>
<target state="new">Support for try-with in sequence expressions</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenCopyAndUpdateRecordChangesAllFields">
<source>Raises warnings when an copy-and-update record expression changes all fields of a record.</source>
<target state="new">Raises warnings when an copy-and-update record expression changes all fields of a record.</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenInliningMethodImplNoInlineMarkedFunction">
<source>Raises warnings when 'let inline ... =' is used together with [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] attribute. Function is not getting inlined.</source>
<target state="translated">Löst Warnungen aus, wenn „let inline ... =“ zusammen mit dem Attribut [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] verwendet wird. Die Funktion wird nicht inline gesetzt.</target>
Expand Down Expand Up @@ -735,6 +732,11 @@
<target state="translated">Muster wird erwartet</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteNestedModule">
<source>Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</source>
<target state="new">Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteTyparExpr1">
<source>Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</source>
<target state="translated">Unvollständiges Zeichenliteral (Beispiel: „Q“) oder qualifizierter Typaufruf (Beispiel: „T.Name“)</target>
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/xlf/FSComp.txt.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -382,19 +382,16 @@
<target state="translated">representación de struct para modelos activos</target>
<note />
</trans-unit>

<trans-unit id="featureTryWithInSeqExpressions">
<source>Support for try-with in sequence expressions</source>
<target state="new">Support for try-with in sequence expressions</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenCopyAndUpdateRecordChangesAllFields">
<source>Raises warnings when an copy-and-update record expression changes all fields of a record.</source>
<target state="new">Raises warnings when an copy-and-update record expression changes all fields of a record.</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenInliningMethodImplNoInlineMarkedFunction">
<source>Raises warnings when 'let inline ... =' is used together with [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] attribute. Function is not getting inlined.</source>
<target state="translated">Genera advertencias cuando se usa "let inline ... =" junto con el atributo [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;]. La función no se está insertando.</target>
Expand Down Expand Up @@ -735,6 +732,11 @@
<target state="translated">Se espera un patrón</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteNestedModule">
<source>Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</source>
<target state="new">Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteTyparExpr1">
<source>Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</source>
<target state="translated">Literal de carácter incompleto (ejemplo: 'Q') o invocación de tipo completo (ejemplo: 'T.Name)</target>
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/xlf/FSComp.txt.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -382,19 +382,16 @@
<target state="translated">représentation de structure pour les modèles actifs</target>
<note />
</trans-unit>

<trans-unit id="featureTryWithInSeqExpressions">
<source>Support for try-with in sequence expressions</source>
<target state="new">Support for try-with in sequence expressions</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenCopyAndUpdateRecordChangesAllFields">
<source>Raises warnings when an copy-and-update record expression changes all fields of a record.</source>
<target state="new">Raises warnings when an copy-and-update record expression changes all fields of a record.</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenInliningMethodImplNoInlineMarkedFunction">
<source>Raises warnings when 'let inline ... =' is used together with [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] attribute. Function is not getting inlined.</source>
<target state="translated">Génère des avertissements lorsque « let inline ... = » est utilisé avec l’attribut [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;]. La fonction n’est pas inlined.</target>
Expand Down Expand Up @@ -735,6 +732,11 @@
<target state="translated">Modèle attendu</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteNestedModule">
<source>Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</source>
<target state="new">Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteTyparExpr1">
<source>Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</source>
<target state="translated">Littéral de caractère incomplet (exemple : 'Q') ou appel de type qualifié (exemple : 'T.Name)</target>
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/xlf/FSComp.txt.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -382,19 +382,16 @@
<target state="translated">rappresentazione struct per criteri attivi</target>
<note />
</trans-unit>

<trans-unit id="featureTryWithInSeqExpressions">
<source>Support for try-with in sequence expressions</source>
<target state="new">Support for try-with in sequence expressions</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenCopyAndUpdateRecordChangesAllFields">
<source>Raises warnings when an copy-and-update record expression changes all fields of a record.</source>
<target state="new">Raises warnings when an copy-and-update record expression changes all fields of a record.</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenInliningMethodImplNoInlineMarkedFunction">
<source>Raises warnings when 'let inline ... =' is used together with [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] attribute. Function is not getting inlined.</source>
<target state="translated">Genera avvisi quando 'let inline ... =' viene usato insieme all'attributo [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;]. La funzione non viene resa inline.</target>
Expand Down Expand Up @@ -735,6 +732,11 @@
<target state="translated">Criterio previsto</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteNestedModule">
<source>Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</source>
<target state="new">Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteTyparExpr1">
<source>Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</source>
<target state="translated">Valore letterale carattere incompleto (ad esempio: 'Q') o chiamata di tipo qualificato (ad esempio: 'T.Name)</target>
Expand Down
8 changes: 5 additions & 3 deletions src/Compiler/xlf/FSComp.txt.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -382,19 +382,16 @@
<target state="translated">アクティブなパターンの構造体表現</target>
<note />
</trans-unit>

<trans-unit id="featureTryWithInSeqExpressions">
<source>Support for try-with in sequence expressions</source>
<target state="new">Support for try-with in sequence expressions</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenCopyAndUpdateRecordChangesAllFields">
<source>Raises warnings when an copy-and-update record expression changes all fields of a record.</source>
<target state="new">Raises warnings when an copy-and-update record expression changes all fields of a record.</target>
<note />
</trans-unit>

<trans-unit id="featureWarningWhenInliningMethodImplNoInlineMarkedFunction">
<source>Raises warnings when 'let inline ... =' is used together with [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] attribute. Function is not getting inlined.</source>
<target state="translated">'let inline ... =' が [&lt;MethodImpl(MethodImplOptions.NoInlining)&gt;] 属性と一緒に使用されるときに警告を生成します。関数はインライン化されていません。</target>
Expand Down Expand Up @@ -735,6 +732,11 @@
<target state="translated">必要なパターン</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteNestedModule">
<source>Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</source>
<target state="new">Local module declarations must include the '=' sign, and their contents are indented. If this is supposed to be a top-level module instead, it must appear as the first declaration in a file.</target>
<note />
</trans-unit>
<trans-unit id="parsIncompleteTyparExpr1">
<source>Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</source>
<target state="new">Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name)</target>
Expand Down
Loading

0 comments on commit c3241ad

Please sign in to comment.