Skip to content

Commit e06e079

Browse files
authored
Print empty namespace or module. (dotnet#13813)
1 parent 919d0e7 commit e06e079

11 files changed

Lines changed: 146 additions & 11 deletions

File tree

src/Compiler/Checking/NicePrint.fs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2420,7 +2420,23 @@ module InferredSigPrinting =
24202420
modNameEqualsL @@* basic
24212421
layoutXmlDoc denv true mspec.XmlDoc basicL
24222422

2423-
imdefL denv expr
2423+
let emptyModuleOrNamespace mspec =
2424+
let innerPath = (fullCompPathOfModuleOrNamespace mspec).AccessPath
2425+
let pathL = innerPath |> List.map (fst >> ConvertLogicalNameToDisplayLayout (tagNamespace >> wordL))
2426+
2427+
let keyword =
2428+
if not mspec.IsImplicitNamespace && mspec.IsNamespace then
2429+
"namespace"
2430+
else
2431+
"module"
2432+
2433+
wordL (tagKeyword keyword) ^^ sepListL SepL.dot pathL
2434+
2435+
match expr with
2436+
| EmptyModuleOrNamespaces mspecs ->
2437+
List.map emptyModuleOrNamespace mspecs
2438+
|> aboveListL
2439+
| expr -> imdefL denv expr
24242440

24252441
//--------------------------------------------------------------------------
24262442

src/Compiler/TypedTree/TypedTreeOps.fs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10360,3 +10360,35 @@ let isFSharpExceptionTy g ty =
1036010360
| ValueSome tcref -> tcref.IsFSharpException
1036110361
| _ -> false
1036210362

10363+
let (|EmptyModuleOrNamespaces|_|) (moduleOrNamespaceContents: ModuleOrNamespaceContents) =
10364+
match moduleOrNamespaceContents with
10365+
| TMDefs(defs = defs) ->
10366+
let mdDefsLength =
10367+
defs
10368+
|> List.count (function
10369+
| ModuleOrNamespaceContents.TMDefRec _
10370+
| ModuleOrNamespaceContents.TMDefs _ -> true
10371+
| _ -> false)
10372+
10373+
let emptyModuleOrNamespaces =
10374+
defs
10375+
|> List.choose (function
10376+
| ModuleOrNamespaceContents.TMDefRec _ as defRec
10377+
| ModuleOrNamespaceContents.TMDefs(defs = [ ModuleOrNamespaceContents.TMDefRec _ as defRec ]) ->
10378+
match defRec with
10379+
| TMDefRec(bindings = [ ModuleOrNamespaceBinding.Module(mspec, ModuleOrNamespaceContents.TMDefs(defs = defs)) ]) ->
10380+
defs
10381+
|> List.forall (function
10382+
| ModuleOrNamespaceContents.TMDefOpens _
10383+
| ModuleOrNamespaceContents.TMDefDo _
10384+
| ModuleOrNamespaceContents.TMDefRec (isRec = true; tycons = []; bindings = []) -> true
10385+
| _ -> false)
10386+
|> fun isEmpty -> if isEmpty then Some mspec else None
10387+
| _ -> None
10388+
| _ -> None)
10389+
10390+
if mdDefsLength = emptyModuleOrNamespaces.Length then
10391+
Some emptyModuleOrNamespaces
10392+
else
10393+
None
10394+
| _ -> None

src/Compiler/TypedTree/TypedTreeOps.fsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2676,3 +2676,9 @@ type TraitConstraintInfo with
26762676

26772677
/// Get the key associated with the member constraint.
26782678
member GetWitnessInfo: unit -> TraitWitnessInfo
2679+
2680+
/// Matches a ModuleOrNamespaceContents that is empty from a signature printing point of view.
2681+
/// Signatures printed via the typed tree in NicePrint don't print TMDefOpens or TMDefDo.
2682+
/// This will match anything that does not have any types or bindings.
2683+
val (|EmptyModuleOrNamespaces|_|):
2684+
moduleOrNamespaceContents: ModuleOrNamespaceContents -> (ModuleOrNamespace list) option

tests/FSharp.Compiler.ComponentTests/Signatures/ModuleOrNamespaceTests.fs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,58 @@ namespace Fantomas.Core
142142
val genExpr: e: FSharp.Compiler.Syntax.SynExpr -> ctx: Context.Context -> Context.Context
143143
144144
val genLambdaArrowWithTrivia: bodyExpr: (FSharp.Compiler.Syntax.SynExpr -> Context.Context -> Context.Context) -> body: FSharp.Compiler.Syntax.SynExpr -> arrowRange: FSharp.Compiler.Text.Range option -> (Context.Context -> Context.Context)"""
145+
146+
[<Fact>]
147+
let ``Empty namespace`` () =
148+
FSharp
149+
"""
150+
namespace System
151+
152+
open System.Runtime.CompilerServices
153+
154+
[<assembly: InternalsVisibleTo("Fantomas.Core.Tests")>]
155+
156+
do ()
157+
"""
158+
|> printSignatures
159+
|> should equal "namespace System"
160+
161+
[<Fact>]
162+
let ``Empty module`` () =
163+
FSharp
164+
"""
165+
module Foobar
166+
167+
do ()
168+
"""
169+
|> printSignatures
170+
|> should equal "module Foobar"
171+
172+
[<Fact>]
173+
let ``Two empty namespaces`` () =
174+
FSharp
175+
"""
176+
namespace Foo
177+
178+
do ()
179+
180+
namespace Bar
181+
182+
do ()
183+
"""
184+
|> printSignatures
185+
|> prependNewline
186+
|> should equal """
187+
namespace Foo
188+
namespace Bar"""
189+
190+
[<Fact>]
191+
let ``Empty namespace module`` () =
192+
FSharp
193+
"""
194+
namespace rec Foobar
195+
196+
do ()
197+
"""
198+
|> printSignatures
199+
|> should equal "namespace Foobar"

tests/fsharp/core/load-script/out.stdout.bsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ World
1616
-the end
1717
Test 3=================================================
1818

19-
> [Loading D:\staging\staging\src\tests\fsharp\core\load-script\1.fsx
19+
> module FSI_0001
20+
21+
[Loading D:\staging\staging\src\tests\fsharp\core\load-script\1.fsx
2022
Loading D:\staging\staging\src\tests\fsharp\core\load-script\2.fsx
2123
Loading D:\staging\staging\src\tests\fsharp\core\load-script\3.fsx]
2224
Hello

tests/fsharp/core/printing/output.1000.stdout.bsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
module FSI_0001
3+
24
> val it: unit = ()
35

46
> val repeatId: string = "A"
@@ -234,7 +236,9 @@ module D1 =
234236
val words: System.Collections.Generic.IDictionary<string,int>
235237
val words2000: System.Collections.Generic.IDictionary<int,string>
236238

237-
> > module D2 =
239+
> module FSI_0020
240+
241+
> module D2 =
238242
val words: IDictionary<string,int>
239243
val words2000: IDictionary<int,string>
240244
val opt1: 'a option

tests/fsharp/core/printing/output.200.stdout.bsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
module FSI_0001
3+
24
> val it: unit = ()
35

46
> val repeatId: string = "A"
@@ -129,7 +131,9 @@ module D1 =
129131
val words: System.Collections.Generic.IDictionary<string,int>
130132
val words2000: System.Collections.Generic.IDictionary<int,string>
131133

132-
> > module D2 =
134+
> module FSI_0020
135+
136+
> module D2 =
133137
val words: IDictionary<string,int>
134138
val words2000: IDictionary<int,string>
135139
val opt1: 'a option

tests/fsharp/core/printing/output.47.stdout.bsl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11

2-
> val repeatId: string = "A"
2+
> module FSI_0001
3+
4+
val repeatId: string = "A"
35

46
> val repeatId: string = "B"
57

@@ -249,7 +251,9 @@ module D1 =
249251
val words: System.Collections.Generic.IDictionary<string,int>
250252
val words2000: System.Collections.Generic.IDictionary<int,string>
251253

252-
> > module D2 =
254+
> module FSI_0019
255+
256+
> module D2 =
253257
val words: IDictionary<string,int>
254258
val words2000: IDictionary<int,string>
255259
val opt1: 'a option

tests/fsharp/core/printing/output.multiemit.stdout.bsl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11

2-
> val repeatId: string = "A"
2+
> module FSI_0001
3+
4+
val repeatId: string = "A"
35

46
> val repeatId: string = "B"
57

@@ -249,7 +251,9 @@ module D1 =
249251
val words: System.Collections.Generic.IDictionary<string,int>
250252
val words2000: System.Collections.Generic.IDictionary<int,string>
251253

252-
> > module D2 =
254+
> module FSI_0019
255+
256+
> module D2 =
253257
val words: IDictionary<string,int>
254258
val words2000: IDictionary<int,string>
255259
val opt1: 'a option

tests/fsharp/core/printing/output.off.stdout.bsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
module FSI_0001
3+
24
> val it: unit = ()
35

46
> val repeatId: string
@@ -94,7 +96,9 @@ module D1 =
9496
val words: System.Collections.Generic.IDictionary<string,int>
9597
val words2000: System.Collections.Generic.IDictionary<int,string>
9698

97-
> > module D2 =
99+
> module FSI_0020
100+
101+
> module D2 =
98102
val words: IDictionary<string,int>
99103
val words2000: IDictionary<int,string>
100104
val opt1: 'a option

0 commit comments

Comments
 (0)