Skip to content

Commit 73d6cd7

Browse files
fix: type constraint should not be generated when the type is a "return type"
[converter] === changelog === ```ts class A {} class User<T extends A = A> {} ``` ```fs [<AbstractClass>] [<Erase>] type Exports = [<Import("User", "REPLACE_ME_WITH_MODULE_NAME"); EmitConstructor>] static member User<'T when 'T :> A> () : User<'T> = nativeOnly [<AllowNullLiteral>] [<Interface>] type A = interface end [<AllowNullLiteral>] [<Interface>] type User<'T when 'T :> A> = interface end ``` === changelog === Co-authored-by: Maxime Mangel <[email protected]>
1 parent 247036f commit 73d6cd7

File tree

3 files changed

+85
-42
lines changed

3 files changed

+85
-42
lines changed

src/Glutinum.Converter/Printer.fs

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -163,68 +163,74 @@ let private printAttributes
163163
printer.NewLine
164164
)
165165

166-
let rec private tryTransformTypeParametersToText
166+
let rec printTypeParametersDeclaration
167+
(printer: Printer)
167168
(typeParameters: FSharpTypeParameter list)
168169
=
169-
let printer = new Printer()
170+
let innterPrinter = new Printer()
170171

171172
if not typeParameters.IsEmpty then
172-
printer.WriteInline("<")
173+
innterPrinter.WriteInline("<")
173174

174175
typeParameters
175176
|> List.iteri (fun index typeParameter ->
176177
if index <> 0 then
177-
printer.WriteInline(", ")
178+
innterPrinter.WriteInline(", ")
178179

179-
printer.WriteInline($"'{typeParameter.Name}")
180+
innterPrinter.WriteInline($"'{typeParameter.Name}")
180181
)
181182

183+
// Print the constraints only if we are in the initial declaration.
184+
// We want to avoid situations like the following:
185+
// static member User<'T when 'T :> A> () : User<'T when 'T :> A> = nativeOnly
186+
// Which should be:
187+
// static member User<'T when 'T :> A> () : User<'T> = nativeOnly
182188
typeParameters
183189
|> List.filter _.Constraint.IsSome
184190
|> List.iteri (fun index typeParameter ->
185191
match typeParameter.Constraint with
186192
| Some constraint_ ->
187193
if index = 0 then
188-
printer.WriteInline(" when ")
194+
innterPrinter.WriteInline(" when ")
189195
else
190-
printer.WriteInline(" and ")
196+
innterPrinter.WriteInline(" and ")
191197

192-
printer.WriteInline($"'{typeParameter.Name}")
193-
printer.WriteInline(" :> ")
194-
printer.WriteInline(printType constraint_)
198+
innterPrinter.WriteInline($"'{typeParameter.Name}")
199+
innterPrinter.WriteInline(" :> ")
200+
innterPrinter.WriteInline(printType constraint_)
195201
| None -> ()
196202
)
197203

198-
printer.WriteInline(">")
199-
200-
printer.ToStringWithoutTrailNewLine() |> Some
204+
innterPrinter.WriteInline(">")
201205

202-
else
203-
None
206+
innterPrinter.ToStringWithoutTrailNewLine() |> printer.WriteInline
204207

205-
and printTypeParameters
206-
(printer: Printer)
208+
and printTypeNameWithTypeParameters
209+
(name: string)
207210
(typeParameters: FSharpTypeParameter list)
208211
=
209-
match tryTransformTypeParametersToText typeParameters with
210-
| Some typeParameters -> printer.WriteInline(typeParameters)
211-
| None -> ()
212+
let printer = new Printer()
212213

213-
and printType (fsharpType: FSharpType) =
214-
let printTypeNameWithTypeParemeters
215-
(name: string)
216-
(typeParameters: FSharpTypeParameter list)
217-
=
218-
match tryTransformTypeParametersToText typeParameters with
219-
| Some typeParameters -> $"{name}{typeParameters}"
220-
| None -> name
214+
if not typeParameters.IsEmpty then
215+
printer.WriteInline("<")
221216

217+
typeParameters
218+
|> List.iteri (fun index typeParameter ->
219+
if index <> 0 then
220+
printer.WriteInline(", ")
221+
222+
printer.WriteInline($"'{typeParameter.Name}")
223+
)
224+
225+
printer.WriteInline(">")
226+
227+
$"{name}{printer.ToStringWithoutTrailNewLine()}"
228+
229+
and printType (fsharpType: FSharpType) =
222230
match fsharpType with
223231
| FSharpType.Object -> "obj"
224232
| FSharpType.Mapped info ->
225-
match tryTransformTypeParametersToText info.TypeParameters with
226-
| Some typeParameters -> $"{info.Name}{typeParameters}"
227-
| None -> info.Name
233+
printTypeNameWithTypeParameters info.Name info.TypeParameters
228234

229235
| FSharpType.SingleErasedCaseUnion info -> info.Name
230236

@@ -247,7 +253,7 @@ and printType (fsharpType: FSharpType) =
247253
$"{info.Name}<{cases}>{option}"
248254

249255
| FSharpType.ThisType thisTypeInfo ->
250-
printTypeNameWithTypeParemeters
256+
printTypeNameWithTypeParameters
251257
thisTypeInfo.Name
252258
thisTypeInfo.TypeParameters
253259

@@ -309,14 +315,14 @@ and printType (fsharpType: FSharpType) =
309315
match apiInfo with
310316
| FSharpJSApi.ReadonlyArray typ -> $"ReadonlyArray<{printType typ}>"
311317
| FSharpType.Interface interfaceInfo ->
312-
printTypeNameWithTypeParemeters
318+
printTypeNameWithTypeParameters
313319
interfaceInfo.Name
314320
interfaceInfo.TypeParameters
315321
| FSharpType.Class classInfo -> classInfo.Name
316322
| FSharpType.TypeAlias aliasInfo ->
317-
printTypeNameWithTypeParemeters aliasInfo.Name aliasInfo.TypeParameters
323+
printTypeNameWithTypeParameters aliasInfo.Name aliasInfo.TypeParameters
318324
| FSharpType.Delegate delegateInfo ->
319-
printTypeNameWithTypeParemeters
325+
printTypeNameWithTypeParameters
320326
delegateInfo.Name
321327
delegateInfo.TypeParameters
322328
| FSharpType.Module _
@@ -503,7 +509,7 @@ let private printInterface (printer: Printer) (interfaceInfo: FSharpInterface) =
503509
printAttributes printer interfaceInfo.Attributes
504510

505511
printer.Write($"type {interfaceInfo.Name}")
506-
printTypeParameters printer interfaceInfo.TypeParameters
512+
printTypeParametersDeclaration printer interfaceInfo.TypeParameters
507513
printer.WriteInline(" =")
508514
printer.NewLine
509515

@@ -532,7 +538,7 @@ let private printInterface (printer: Printer) (interfaceInfo: FSharpInterface) =
532538

533539
printer.WriteInline($"member {methodInfo.Name}")
534540

535-
printTypeParameters printer methodInfo.TypeParameters
541+
printTypeParametersDeclaration printer methodInfo.TypeParameters
536542

537543
if methodInfo.IsStatic then
538544
printer.WriteInline(" ")
@@ -704,7 +710,9 @@ import {{ %s{interfaceInfo.OriginalName} }} from \"{Naming.MODULE_PLACEHOLDER}\"
704710

705711
printer.Write($"static member inline {staticMemberInfo.Name} ")
706712

707-
printTypeParameters printer staticMemberInfo.TypeParameters
713+
printTypeParametersDeclaration
714+
printer
715+
staticMemberInfo.TypeParameters
708716

709717
if staticMemberInfo.Parameters.IsEmpty then
710718
printer.WriteInline("() : ")
@@ -811,7 +819,7 @@ let private printClass (printer: Printer) (classInfo: FSharpClass) =
811819
printAttributes printer classInfo.Attributes
812820

813821
printer.Write($"type {classInfo.Name}")
814-
printTypeParameters printer classInfo.TypeParameters
822+
printTypeParametersDeclaration printer classInfo.TypeParameters
815823
printer.NewLine
816824
printer.Indent
817825
printPrimaryConstructor printer classInfo.PrimaryConstructor
@@ -897,7 +905,7 @@ let private printTypeAlias (printer: Printer) (aliasInfo: FSharpTypeAlias) =
897905
printAttributes printer aliasInfo.Attributes
898906

899907
printer.Write($"type {aliasInfo.Name}")
900-
printTypeParameters printer aliasInfo.TypeParameters
908+
printTypeParametersDeclaration printer aliasInfo.TypeParameters
901909
printer.WriteInline(" =")
902910

903911
printer.NewLine
@@ -908,7 +916,7 @@ let private printTypeAlias (printer: Printer) (aliasInfo: FSharpTypeAlias) =
908916

909917
let private printDelegate (printer: Printer) (delegateInfo: FSharpDelegate) =
910918
printer.Write($"type {delegateInfo.Name}")
911-
printTypeParameters printer delegateInfo.TypeParameters
919+
printTypeParametersDeclaration printer delegateInfo.TypeParameters
912920
printer.WriteInline(" =")
913921

914922
printer.NewLine
@@ -992,7 +1000,11 @@ let rec private print (printer: Printer) (fsharpTypes: FSharpType list) =
9921000
(FSharpAttribute.Erase :: erasedCaseUnionInfo.Attributes)
9931001

9941002
printer.Write($"type {erasedCaseUnionInfo.Name}")
995-
printTypeParameters printer [ erasedCaseUnionInfo.TypeParameter ]
1003+
1004+
printTypeParametersDeclaration
1005+
printer
1006+
[ erasedCaseUnionInfo.TypeParameter ]
1007+
9961008
printer.WriteInline(" =")
9971009

9981010
printer.NewLine
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class A {}
2+
3+
class User<T extends A = A> {}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module rec Glutinum
2+
3+
open Fable.Core
4+
open Fable.Core.JsInterop
5+
open System
6+
7+
[<AbstractClass>]
8+
[<Erase>]
9+
type Exports =
10+
[<Import("A", "REPLACE_ME_WITH_MODULE_NAME"); EmitConstructor>]
11+
static member A () : A = nativeOnly
12+
[<Import("User", "REPLACE_ME_WITH_MODULE_NAME"); EmitConstructor>]
13+
static member User<'T when 'T :> A> () : User<'T> = nativeOnly
14+
15+
[<AllowNullLiteral>]
16+
[<Interface>]
17+
type A =
18+
interface end
19+
20+
[<AllowNullLiteral>]
21+
[<Interface>]
22+
type User<'T when 'T :> A> =
23+
interface end
24+
25+
(***)
26+
#r "nuget: Fable.Core"
27+
#r "nuget: Glutinum.Types"
28+
(***)

0 commit comments

Comments
 (0)