From f2ce0f1dc38dc3dbb0a1a59227b5078c1b237251 Mon Sep 17 00:00:00 2001 From: kerams Date: Tue, 3 May 2022 18:13:47 +0200 Subject: [PATCH 01/13] Don't show completions on nested module identifier --- src/fsharp/service/ServiceParsedInputOps.fs | 6 ++++++ .../UnitTests/CompletionProviderTests.fs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/fsharp/service/ServiceParsedInputOps.fs b/src/fsharp/service/ServiceParsedInputOps.fs index 4d170c88e9..b309be558f 100644 --- a/src/fsharp/service/ServiceParsedInputOps.fs +++ b/src/fsharp/service/ServiceParsedInputOps.fs @@ -1127,6 +1127,12 @@ module ParsedInput = Some (CompletionContext.OpenDeclaration isOpenType) else None + + // module Namespace.Top + // module Neste| + | SynModuleDecl.NestedModule (moduleInfo = SynComponentInfo (longId = [ ident ])) when rangeContainsPos ident.idRange pos -> + Some CompletionContext.Invalid + | _ -> defaultTraverse decl member _.VisitType(_path, defaultTraverse, ty) = diff --git a/vsintegration/tests/UnitTests/CompletionProviderTests.fs b/vsintegration/tests/UnitTests/CompletionProviderTests.fs index 52193afac4..258738f3a6 100644 --- a/vsintegration/tests/UnitTests/CompletionProviderTests.fs +++ b/vsintegration/tests/UnitTests/CompletionProviderTests.fs @@ -498,6 +498,25 @@ open type System.Ma let expected = ["Management"; "Math"] // both namespace and static type VerifyCompletionList(fileContents, "System.Ma", expected, []) +[] +let ``No completion on nested module identifier``() = + let fileContents = """ +module Namespace.Top + +module Nest +""" + VerifyNoCompletionList(fileContents, "Nest") + +[] +let ``No completion on nested module identifier2``() = + let fileContents = """ +namespace N + +module Nested = + do () +""" + VerifyNoCompletionList(fileContents, "Nested") + [] let ``No completion on type name at declaration site``() = let fileContents = """ From c3241adaba63b138c11207c6f6dd78606567b28d Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 9 Feb 2023 19:39:39 +0100 Subject: [PATCH 02/13] Recover from incomplete module declaration --- src/Compiler/FSComp.txt | 1 + src/Compiler/SyntaxTree/LexFilter.fs | 35 ++++++++++++------- src/Compiler/pars.fsy | 10 ++++++ src/Compiler/xlf/FSComp.txt.cs.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.de.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.es.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.it.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 8 +++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 8 +++-- .../CompletionProviderTests.fs | 21 +++++++++++ 17 files changed, 119 insertions(+), 52 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 063a6b973c..717ff6a495 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1677,3 +1677,4 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form 3558,chkExplicitFieldsDeclarationsOnStaticClasses,"If a type uses both [] and [] 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." diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 09f0bafbea..dd4559155e 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -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 -> @@ -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 diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 15f45e7af9..0c8cb3ca67 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -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)) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index b6ad7c62f3..827e420d85 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -382,19 +382,16 @@ reprezentace struktury aktivních vzorů - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Vyvolá upozornění, když se použije „let inline ... =“ společně s atributem [<MethodImpl(MethodImplOptions.NoInlining)>]. Funkce není vkládána. @@ -735,6 +732,11 @@ Očekává se vzorek. + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Neúplný znakový literál (příklad: Q) nebo volání kvalifikovaného typu (příklad: T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 52f3d52cf2..582b049013 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -382,19 +382,16 @@ Strukturdarstellung für aktive Muster - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Löst Warnungen aus, wenn „let inline ... =“ zusammen mit dem Attribut [<MethodImpl(MethodImplOptions.NoInlining)>] verwendet wird. Die Funktion wird nicht inline gesetzt. @@ -735,6 +732,11 @@ Muster wird erwartet + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Unvollständiges Zeichenliteral (Beispiel: „Q“) oder qualifizierter Typaufruf (Beispiel: „T.Name“) diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 298deb3113..38baf73b46 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -382,19 +382,16 @@ representación de struct para modelos activos - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Genera advertencias cuando se usa "let inline ... =" junto con el atributo [<MethodImpl(MethodImplOptions.NoInlining)>]. La función no se está insertando. @@ -735,6 +732,11 @@ Se espera un patrón + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Literal de carácter incompleto (ejemplo: 'Q') o invocación de tipo completo (ejemplo: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index d41d7f0576..5058240a41 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -382,19 +382,16 @@ représentation de structure pour les modèles actifs - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Génère des avertissements lorsque « let inline ... = » est utilisé avec l’attribut [<MethodImpl(MethodImplOptions.NoInlining)>]. La fonction n’est pas inlined. @@ -735,6 +732,11 @@ Modèle attendu + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Littéral de caractère incomplet (exemple : 'Q') ou appel de type qualifié (exemple : 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 083f98e4df..4c8b93dca3 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -382,19 +382,16 @@ rappresentazione struct per criteri attivi - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Genera avvisi quando 'let inline ... =' viene usato insieme all'attributo [<MethodImpl(MethodImplOptions.NoInlining)>]. La funzione non viene resa inline. @@ -735,6 +732,11 @@ Criterio previsto + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Valore letterale carattere incompleto (ad esempio: 'Q') o chiamata di tipo qualificato (ad esempio: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 85735c3b4e..fe500fa525 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -382,19 +382,16 @@ アクティブなパターンの構造体表現 - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 'let inline ... =' が [<MethodImpl(MethodImplOptions.NoInlining)>] 属性と一緒に使用されるときに警告を生成します。関数はインライン化されていません。 @@ -735,6 +732,11 @@ 必要なパターン + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 2b32dd6594..278a64fb83 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -382,19 +382,16 @@ 활성 패턴에 대한 구조체 표현 - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 'let inline ... ='을(를) [<MethodImpl(MethodImplOptions.NoInlining)>] 특성과 함께 사용하는 경우 경고를 발생합니다. 함수가 인라인되지 않습니다. @@ -735,6 +732,11 @@ 예상되는 패턴 + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) 불완전한 문자 리터럴(예: 'Q') 또는 정규화된 형식 호출(예: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index ee6b6afe9a..6d48ba348a 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -382,19 +382,16 @@ reprezentacja struktury aktywnych wzorców - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Zgłasza ostrzeżenia, gdy element „let inline ... =” jest używany razem z atrybutem [<MethodImpl(MethodImplOptions.NoInlining)>]. Funkcja nie jest wstawiana. @@ -735,6 +732,11 @@ Oczekiwano wzorca + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Niekompletny literał znaku (przykład: „Q”) lub wywołanie typu kwalifikowanego (przykład: „T.Name”) diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 8ad44f41ea..4eb04b0043 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -382,19 +382,16 @@ representação estrutural para padrões ativos - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Gera avisos quando 'let inline ... =' é usado junto com o atributo [<MethodImpl(MethodImplOptions.NoInlining)>]. A função não está sendo embutida. @@ -735,6 +732,11 @@ Padrão esperado + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Literal de caractere incompleto (exemplo: 'Q') ou invocação de tipo qualificado (exemplo: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 0cbd637dd4..f916086cc9 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -382,19 +382,16 @@ представление структуры для активных шаблонов - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. Выдает предупреждения, когда используется параметр "let inline ... =" вместе с атрибутом [<MethodImpl(MethodImplOptions.NoInlining)>]. Функция не встраивается. @@ -735,6 +732,11 @@ Ожидается шаблон + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Неполный символьный литерал (например: "Q") или вызов квалифицированного типа (например: "T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index c9713648da..aaa3affd72 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -382,19 +382,16 @@ etkin desenler için yapı gösterimi - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. [<MethodImpl(MethodImplOptions.NoInlining)>] özniteliği ile birlikte 'let inline ... =' kullanıldığında uyarı verir. İşlev satır içine alınmıyor. @@ -735,6 +732,11 @@ Desen bekleniyor + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Eksik karakter değişmez değeri (örnek: 'Q') veya tam tür çağrısı (örnek: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 4072aaad79..f2bd6d558f 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -382,19 +382,16 @@ 活动模式的结构表示形式 - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 当 "let inline ... =" 与 [<MethodImpl(MethodImplOptions.NoInlining)>] 属性一起使用时引发警告。函数未内联。 @@ -735,6 +732,11 @@ 预期模式 + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) 字符文本不完整(示例: "Q")或限定类型调用(示例: "T.Name") diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index bd871bbba4..285a895107 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -382,19 +382,16 @@ 現用模式的結構表示法 - Support for try-with in sequence expressions Support for try-with in sequence expressions - Raises warnings when an copy-and-update record expression changes all fields of a record. Raises warnings when an copy-and-update record expression changes all fields of a record. - Raises warnings when 'let inline ... =' is used together with [<MethodImpl(MethodImplOptions.NoInlining)>] attribute. Function is not getting inlined. 當 'let inline ... =' 與 [<MethodImpl(MethodImplOptions.NoInlining)>] 屬性一起使用時引發警告。函數未內嵌。 @@ -735,6 +732,11 @@ 必須是模式 + + 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. + 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. + + Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index 2be760394f..6bfbff3208 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -732,6 +732,27 @@ open type System.Ma let expected = [ "Management"; "Math" ] // both namespace and static type VerifyCompletionList(fileContents, "System.Ma", expected, []) + [] + let ``No completion on nested module identifier, incomplete`` () = + let fileContents = """ + module Namespace.Top + + module Nest + + let a = () + """ + VerifyNoCompletionList(fileContents, "Nest") + + [] + let ``No completion on nested module identifier`` () = + let fileContents = """ + namespace N + + module Nested = + do () + """ + VerifyNoCompletionList(fileContents, "Nested") + [] let ``No completion on type name at declaration site`` () = let fileContents = From 5b56e6a7c083e7e7d7ba0eb029c90176787ccc66 Mon Sep 17 00:00:00 2001 From: kerams Date: Fri, 10 Feb 2023 11:21:51 +0100 Subject: [PATCH 03/13] Blah --- src/Compiler/SyntaxTree/LexFilter.fs | 2 +- src/Compiler/pars.fsy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index dd4559155e..f0fc084b78 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -1605,7 +1605,7 @@ type LexFilterImpl ( | _ -> // 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" + if debug then dprintf "CtxtModuleHead: not start of file, popping CtxtModuleHead\n" popCtxt() reprocessWithoutBlockRule() diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 0c8cb3ca67..a184ef9df2 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1288,7 +1288,7 @@ moduleDefn: 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)] } + [ SynModuleDecl.NestedModule(info, isRec, [], false, mWhole, trivia) ] } /* unattached custom attributes */ | attributes recover From 9c36b93f9a3cdc9b4bc73b30f13ff8cb5cf6efe1 Mon Sep 17 00:00:00 2001 From: kerams Date: Fri, 10 Feb 2023 17:16:31 +0100 Subject: [PATCH 04/13] Fixes --- src/Compiler/FSComp.txt | 1 - src/Compiler/pars.fsy | 3 +-- 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 ----- 15 files changed, 1 insertion(+), 68 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 717ff6a495..063a6b973c 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1677,4 +1677,3 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form 3558,chkExplicitFieldsDeclarationsOnStaticClasses,"If a type uses both [] and [] 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." diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index a184ef9df2..f43300038f 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1281,10 +1281,9 @@ moduleDefn: [ 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 + | opt_attributes opt_access moduleIntro recover { 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 } diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 827e420d85..cfe671818a 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -732,11 +732,6 @@ Očekává se vzorek. - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Neúplný znakový literál (příklad: Q) nebo volání kvalifikovaného typu (příklad: T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 582b049013..ee3281736c 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -732,11 +732,6 @@ Muster wird erwartet - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Unvollständiges Zeichenliteral (Beispiel: „Q“) oder qualifizierter Typaufruf (Beispiel: „T.Name“) diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 38baf73b46..21e5fcde49 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -732,11 +732,6 @@ Se espera un patrón - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Literal de carácter incompleto (ejemplo: 'Q') o invocación de tipo completo (ejemplo: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 5058240a41..a2d6420e83 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -732,11 +732,6 @@ Modèle attendu - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Littéral de caractère incomplet (exemple : 'Q') ou appel de type qualifié (exemple : 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 4c8b93dca3..28c7a31059 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -732,11 +732,6 @@ Criterio previsto - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Valore letterale carattere incompleto (ad esempio: 'Q') o chiamata di tipo qualificato (ad esempio: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index fe500fa525..97163eb86f 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -732,11 +732,6 @@ 必要なパターン - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 278a64fb83..5dcd6f6fb1 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -732,11 +732,6 @@ 예상되는 패턴 - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) 불완전한 문자 리터럴(예: 'Q') 또는 정규화된 형식 호출(예: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 6d48ba348a..8843ef99c9 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -732,11 +732,6 @@ Oczekiwano wzorca - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Niekompletny literał znaku (przykład: „Q”) lub wywołanie typu kwalifikowanego (przykład: „T.Name”) diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 4eb04b0043..4ffbb56dfd 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -732,11 +732,6 @@ Padrão esperado - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Literal de caractere incompleto (exemplo: 'Q') ou invocação de tipo qualificado (exemplo: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index f916086cc9..53889e7034 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -732,11 +732,6 @@ Ожидается шаблон - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Неполный символьный литерал (например: "Q") или вызов квалифицированного типа (например: "T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index aaa3affd72..9ac1f91a7b 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -732,11 +732,6 @@ Desen bekleniyor - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Eksik karakter değişmez değeri (örnek: 'Q') veya tam tür çağrısı (örnek: 'T.Name) diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index f2bd6d558f..cb3c02cb65 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -732,11 +732,6 @@ 预期模式 - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) 字符文本不完整(示例: "Q")或限定类型调用(示例: "T.Name") diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 285a895107..915902d327 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -732,11 +732,6 @@ 必須是模式 - - 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. - 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. - - Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) Incomplete character literal (example: 'Q') or qualified type invocation (example: 'T.Name) From 7f275a2a6c8a76c74cd73923b3533b9cefb9632f Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 11 Feb 2023 13:37:48 +0100 Subject: [PATCH 05/13] Fix parser --- src/Compiler/pars.fsy | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 83769e2392..4cf7e3dcde 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1281,13 +1281,16 @@ moduleDefn: [ 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 recover - { let xmlDoc = grabXmlDoc(parseState, $1, 1) + /* 'moduleIntro' is expanded here and 'path' replaced with 'ident' */ + /* This is so that we don't fall in here when the entire file consists of a top-level module declaration including a namespace */ + | opt_attributes opt_access moduleKeyword opt_attributes opt_access opt_rec ident recover + { if not (isNil $4) then + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AttributesToRightOfModuleKeyword (rhs parseState 4) + let xmlDoc = grabXmlDoc(parseState, $1, 1) let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc - 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) ] } + let info = SynComponentInfo($1 @ $4, None, [], [ $7 ], xmlDoc, false, $5, rhs2 parseState 3 7) + let trivia: SynModuleDeclNestedModuleTrivia = { ModuleKeyword = Some (rhs parseState 3); EqualsRange = None } + [ SynModuleDecl.NestedModule(info, $6, [], false, mWhole, trivia) ] } /* unattached custom attributes */ | attributes recover From b8375c5072aeff3a889a213f193b25a589d258ca Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 11 Feb 2023 14:41:01 +0100 Subject: [PATCH 06/13] Fix parser --- src/Compiler/pars.fsy | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 4cf7e3dcde..6cfd678c1c 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -665,6 +665,17 @@ moduleSpfn: let trivia: SynModuleSigDeclNestedModuleTrivia = { ModuleKeyword = Some mModule; EqualsRange = $4 } SynModuleSigDecl.NestedModule(info, isRec, $5, m, trivia) } + | opt_attributes opt_access moduleIntro error + { let mModule, isRec, path, vis, attribs2 = $3 + let xmlDoc = grabXmlDoc(parseState, $1, 1) + if not (isSingleton path) then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsModuleDefnMustBeSimpleName()) + if isRec then raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsInvalidUseOfRec()) + let info = SynComponentInfo($1 @ attribs2, None, [], path, xmlDoc, false, vis, rhs parseState 3) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) + let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc + let trivia: SynModuleSigDeclNestedModuleTrivia = { ModuleKeyword = Some mModule; EqualsRange = None } + SynModuleSigDecl.NestedModule(info, isRec, [], mWhole, trivia) } + | opt_attributes opt_access typeKeyword tyconSpfn tyconSpfnList { if Option.isSome $2 then errorR (Error (FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) let leadingKeyword = SynTypeDefnLeadingKeyword.Type (rhs parseState 3) @@ -1281,16 +1292,13 @@ moduleDefn: [ SynModuleDecl.NestedModule(info, isRec, def, false, ((rhs2 parseState 1 4, def) ||> unionRangeWithListBy (fun d -> d.Range) |> unionRangeWithXmlDoc xmlDoc), trivia)] } /* incomplete 'module' definitions */ - /* 'moduleIntro' is expanded here and 'path' replaced with 'ident' */ - /* This is so that we don't fall in here when the entire file consists of a top-level module declaration including a namespace */ - | opt_attributes opt_access moduleKeyword opt_attributes opt_access opt_rec ident recover - { if not (isNil $4) then - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AttributesToRightOfModuleKeyword (rhs parseState 4) - let xmlDoc = grabXmlDoc(parseState, $1, 1) + | opt_attributes opt_access moduleIntro error + { let xmlDoc = grabXmlDoc(parseState, $1, 1) let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc - let info = SynComponentInfo($1 @ $4, None, [], [ $7 ], xmlDoc, false, $5, rhs2 parseState 3 7) - let trivia: SynModuleDeclNestedModuleTrivia = { ModuleKeyword = Some (rhs parseState 3); EqualsRange = None } - [ SynModuleDecl.NestedModule(info, $6, [], false, mWhole, trivia) ] } + 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 From f184f4a08343488430fb38ccea494d8673a9e1c4 Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 11 Feb 2023 14:47:03 +0100 Subject: [PATCH 07/13] Format --- src/Compiler/Service/ServiceParsedInputOps.fs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index bf1605ebb0..581fe62645 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1477,9 +1477,7 @@ module ParsedInput = // module Namespace.Top // module Neste| - | SynModuleDecl.NestedModule(moduleInfo = SynComponentInfo(longId = [ ident ])) when - rangeContainsPos ident.idRange pos - -> + | SynModuleDecl.NestedModule(moduleInfo = SynComponentInfo(longId = [ ident ])) when rangeContainsPos ident.idRange pos -> Some CompletionContext.Invalid | _ -> defaultTraverse decl From c8a5550dd34aab01042a6b7aefa7f14b9f8d4ebd Mon Sep 17 00:00:00 2001 From: kerams Date: Sat, 11 Feb 2023 16:39:38 +0100 Subject: [PATCH 08/13] Add AST tests --- .../EmptyModuleOrNamespaceShouldBePresent.fs | 1 + ...ptyModuleOrNamespaceShouldBePresent.fs.bsl | 13 +++++ .../IncompleteNestedModuleShouldBePresent.fs | 5 ++ ...completeNestedModuleShouldBePresent.fs.bsl | 50 +++++++++++++++++++ ...completeNestedModuleSigShouldBePresent.fsi | 5 ++ ...leteNestedModuleSigShouldBePresent.fsi.bsl | 40 +++++++++++++++ 6 files changed, 114 insertions(+) create mode 100644 tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs create mode 100644 tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl create mode 100644 tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs create mode 100644 tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl create mode 100644 tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi create mode 100644 tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl diff --git a/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs b/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs new file mode 100644 index 0000000000..74cc0b6fce --- /dev/null +++ b/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs @@ -0,0 +1 @@ +module A.B.C \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl b/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl new file mode 100644 index 0000000000..50cfe7db48 --- /dev/null +++ b/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl @@ -0,0 +1,13 @@ +ImplFile + (ParsedImplFileInput + ("/root/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs", false, + QualifiedNameOfFile A.B.C, [], [], + [SynModuleOrNamespace + ([A; B; C], false, NamedModule, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + /root/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs (1,0--1,12), + { LeadingKeyword = + Module + /root/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs (1,0--1,6) })], + (true, false), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs new file mode 100644 index 0000000000..30cb557e09 --- /dev/null +++ b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs @@ -0,0 +1,5 @@ +module A.B + +module C + +let a = () \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl new file mode 100644 index 0000000000..ac91b09152 --- /dev/null +++ b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl @@ -0,0 +1,50 @@ +ImplFile + (ParsedImplFileInput + ("/root/NestedModule/IncompleteNestedModuleShouldBePresent.fs", false, + QualifiedNameOfFile A.B, [], [], + [SynModuleOrNamespace + ([A; B], false, NamedModule, + [NestedModule + (SynComponentInfo + ([], None, [], [C], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, + None, + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (3,0--3,8)), + false, [], false, + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (3,0--3,8), + { ModuleKeyword = + Some + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (3,0--3,6) + EqualsRange = None }); + Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((5,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named + (SynIdent (a, None), false, None, + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,4--5,5)), + None, + Const + (Unit, + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,8--5,10)), + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,4--5,5), + Yes + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,0--5,10), + { LeadingKeyword = + Let + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,0--5,3) + InlineKeyword = None + EqualsRange = + Some + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,6--5,7) })], + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,0--5,10))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (1,0--5,10), + { LeadingKeyword = + Module + /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (1,0--1,6) })], + (true, false), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi new file mode 100644 index 0000000000..e1949a861e --- /dev/null +++ b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi @@ -0,0 +1,5 @@ +module A.B + +module C + +val a: unit \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl new file mode 100644 index 0000000000..7d751046f5 --- /dev/null +++ b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl @@ -0,0 +1,40 @@ +SigFile + (ParsedSigFileInput + ("/root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi", + QualifiedNameOfFile A.B, [], [], + [SynModuleOrNamespaceSig + ([A; B], false, NamedModule, + [NestedModule + (SynComponentInfo + ([], None, [], [C], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, + None, + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (3,0--3,8)), + false, [], + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (3,0--3,8), + { ModuleKeyword = + Some + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (3,0--3,6) + EqualsRange = None }); + Val + (SynValSig + ([], SynIdent (a, None), SynValTyparDecls (None, true), + LongIdent (SynLongIdent ([unit], [], [None])), + SynValInfo ([], SynArgInfo ([], false, None)), false, false, + PreXmlDoc ((5,0), FSharp.Compiler.Xml.XmlDocCollector), None, + None, + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (5,0--5,11), + { LeadingKeyword = + Val + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (5,0--5,3) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (5,0--5,11))], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (1,0--5,11), + { LeadingKeyword = + Module + /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (1,0--1,6) })], + { ConditionalDirectives = [] + CodeComments = [] }, set [])) From f00b3e9003c293619df7352fb3b7bd03f5a13ed0 Mon Sep 17 00:00:00 2001 From: kerams Date: Mon, 13 Feb 2023 11:59:29 +0100 Subject: [PATCH 09/13] Revert LexFilter changes --- src/Compiler/SyntaxTree/LexFilter.fs | 33 ++++++++++------------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index f0fc084b78..29a9bbe47e 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -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) :: rest -> + | _, CtxtModuleHead (moduleTokenPos, prevToken, lexingModuleAttributes) :: _ -> match prevToken, token with | _, GREATER_RBRACK when lexingModuleAttributes = LexingModuleAttributes && moduleTokenPos.Column < tokenStartPos.Column -> @@ -1588,27 +1588,18 @@ type LexFilterImpl ( pushCtxtSeqBlock(true, AddBlockEnd) 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 + 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 | _ -> - // Adding a new nested module, EQUALS hasn't been typed yet - // and we've encountered declarations below - if debug then dprintf "CtxtModuleHead: not start of file, popping CtxtModuleHead\n" - popCtxt() - reprocessWithoutBlockRule() - + // 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 // Offside rule for SeqBlock. // f x // g x From 0e0c51e291d68862a87bac3ce234efa04f7f5bbd Mon Sep 17 00:00:00 2001 From: kerams Date: Mon, 13 Feb 2023 12:32:41 +0100 Subject: [PATCH 10/13] Readd LexFilter --- src/Compiler/SyntaxTree/LexFilter.fs | 33 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 29a9bbe47e..f0fc084b78 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -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 -> @@ -1588,18 +1588,27 @@ type LexFilterImpl ( 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: not start of file, popping CtxtModuleHead\n" + popCtxt() + reprocessWithoutBlockRule() + // Offside rule for SeqBlock. // f x // g x From 287347f79af5b7293fd606a6553d058f5a3ea9c3 Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 16 Feb 2023 12:21:09 +0100 Subject: [PATCH 11/13] Update baselines --- ...ptyModuleOrNamespaceShouldBePresent.fs.bsl | 9 ++--- ...completeNestedModuleShouldBePresent.fs.bsl | 39 +++++-------------- ...leteNestedModuleSigShouldBePresent.fsi.bsl | 27 ++++--------- 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl b/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl index 50cfe7db48..a6190fada5 100644 --- a/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl +++ b/tests/service/data/SyntaxTree/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs.bsl @@ -5,9 +5,6 @@ ImplFile [SynModuleOrNamespace ([A; B; C], false, NamedModule, [], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, - /root/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs (1,0--1,12), - { LeadingKeyword = - Module - /root/ModuleOrNamespace/EmptyModuleOrNamespaceShouldBePresent.fs (1,0--1,6) })], - (true, false), { ConditionalDirectives = [] - CodeComments = [] }, set [])) + (1,0--1,12), { LeadingKeyword = Module (1,0--1,6) })], (true, false), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl index ac91b09152..4b9df81e4d 100644 --- a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl +++ b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleShouldBePresent.fs.bsl @@ -8,13 +8,8 @@ ImplFile (SynComponentInfo ([], None, [], [C], PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, - None, - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (3,0--3,8)), - false, [], false, - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (3,0--3,8), - { ModuleKeyword = - Some - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (3,0--3,6) + None, (3,0--3,8)), false, [], false, (3,0--3,8), + { ModuleKeyword = Some (3,0--3,6) EqualsRange = None }); Let (false, @@ -23,28 +18,12 @@ ImplFile PreXmlDoc ((5,0), FSharp.Compiler.Xml.XmlDocCollector), SynValData (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Named - (SynIdent (a, None), false, None, - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,4--5,5)), - None, - Const - (Unit, - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,8--5,10)), - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,4--5,5), - Yes - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,0--5,10), - { LeadingKeyword = - Let - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,0--5,3) + Named (SynIdent (a, None), false, None, (5,4--5,5)), None, + Const (Unit, (5,8--5,10)), (5,4--5,5), Yes (5,0--5,10), + { LeadingKeyword = Let (5,0--5,3) InlineKeyword = None - EqualsRange = - Some - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,6--5,7) })], - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (5,0--5,10))], + EqualsRange = Some (5,6--5,7) })], (5,0--5,10))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (1,0--5,10), - { LeadingKeyword = - Module - /root/NestedModule/IncompleteNestedModuleShouldBePresent.fs (1,0--1,6) })], - (true, false), { ConditionalDirectives = [] - CodeComments = [] }, set [])) + (1,0--5,10), { LeadingKeyword = Module (1,0--1,6) })], (true, false), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl index 7d751046f5..e41e7f656c 100644 --- a/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl +++ b/tests/service/data/SyntaxTree/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi.bsl @@ -8,13 +8,8 @@ SigFile (SynComponentInfo ([], None, [], [C], PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, - None, - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (3,0--3,8)), - false, [], - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (3,0--3,8), - { ModuleKeyword = - Some - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (3,0--3,6) + None, (3,0--3,8)), false, [], (3,0--3,8), + { ModuleKeyword = Some (3,0--3,6) EqualsRange = None }); Val (SynValSig @@ -22,19 +17,11 @@ SigFile LongIdent (SynLongIdent ([unit], [], [None])), SynValInfo ([], SynArgInfo ([], false, None)), false, false, PreXmlDoc ((5,0), FSharp.Compiler.Xml.XmlDocCollector), None, - None, - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (5,0--5,11), - { LeadingKeyword = - Val - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (5,0--5,3) - InlineKeyword = None - WithKeyword = None - EqualsRange = None }), - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (5,0--5,11))], + None, (5,0--5,11), { LeadingKeyword = Val (5,0--5,3) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), (5,0--5,11))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (1,0--5,11), - { LeadingKeyword = - Module - /root/NestedModule/IncompleteNestedModuleSigShouldBePresent.fsi (1,0--1,6) })], + (1,0--5,11), { LeadingKeyword = Module (1,0--1,6) })], { ConditionalDirectives = [] CodeComments = [] }, set [])) From 117151685799ee26e5622ba629fee11906579d80 Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 9 Mar 2023 14:33:46 +0100 Subject: [PATCH 12/13] Format --- .../tests/FSharp.Editor.Tests/CompletionProviderTests.fs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs index b569ba1ad6..81c34d547a 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/CompletionProviderTests.fs @@ -738,23 +738,27 @@ open type System.Ma [] let ``No completion on nested module identifier, incomplete`` () = - let fileContents = """ + let fileContents = + """ module Namespace.Top module Nest let a = () """ + VerifyNoCompletionList(fileContents, "Nest") [] let ``No completion on nested module identifier`` () = - let fileContents = """ + let fileContents = + """ namespace N module Nested = do () """ + VerifyNoCompletionList(fileContents, "Nested") [] From de969cbf4b0ae226c19889fd382e0b875cf32e84 Mon Sep 17 00:00:00 2001 From: kerams Date: Thu, 9 Mar 2023 21:47:07 +0100 Subject: [PATCH 13/13] Update baselines --- tests/fsharp/typecheck/sigs/neg41.bsl | 4 +--- tests/fsharp/typecheck/sigs/neg42.bsl | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg41.bsl b/tests/fsharp/typecheck/sigs/neg41.bsl index 0ebbdcd886..18115064cc 100644 --- a/tests/fsharp/typecheck/sigs/neg41.bsl +++ b/tests/fsharp/typecheck/sigs/neg41.bsl @@ -1,4 +1,2 @@ -neg41.fs(3,1,3,5): parse error FS0010: Unexpected start of structured construct in definition. Expected '=' or other token. - -neg41.fs(4,1,4,1): parse error FS0010: Incomplete structured construct at or before this point in implementation file +neg41.fs(3,1,3,5): parse error FS0010: Unexpected keyword 'type' in definition. Expected '=' or other token. diff --git a/tests/fsharp/typecheck/sigs/neg42.bsl b/tests/fsharp/typecheck/sigs/neg42.bsl index 4ae7c49829..3dec6d2329 100644 --- a/tests/fsharp/typecheck/sigs/neg42.bsl +++ b/tests/fsharp/typecheck/sigs/neg42.bsl @@ -1,4 +1,2 @@ -neg42.fsi(3,1,3,5): parse error FS0010: Unexpected start of structured construct in signature file. Expected ':', '=' or other token. - -neg42.fsi(4,1,4,1): parse error FS0010: Incomplete structured construct at or before this point in signature file +neg42.fsi(3,1,3,5): parse error FS0010: Unexpected keyword 'type' in signature file. Expected ':', '=' or other token.