From 3bdcefcf14962bedc80eb95558f5346abb115df2 Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 13 Dec 2023 18:31:42 +0200 Subject: [PATCH 1/3] In GenType Add mutual recursive test Signed-Off-By: Jono Prest --- .../package-lock.json | 35 +++++++------------ .../src/NonrecursiveTypes.gen.tsx | 4 +++ .../src/NonrecursiveTypes.res | 4 +++ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/jscomp/gentype_tests/typescript-react-example/package-lock.json b/jscomp/gentype_tests/typescript-react-example/package-lock.json index c02269dfe5..2dd8fbba05 100644 --- a/jscomp/gentype_tests/typescript-react-example/package-lock.json +++ b/jscomp/gentype_tests/typescript-react-example/package-lock.json @@ -22,26 +22,6 @@ "typescript": "^5.2.2" } }, - "../../..": { - "name": "rescript", - "version": "11.0.0-rc.8", - "dev": true, - "hasInstallScript": true, - "license": "SEE LICENSE IN LICENSE", - "bin": { - "bsc": "bsc", - "bstracing": "lib/bstracing", - "rescript": "rescript" - }, - "devDependencies": { - "mocha": "10.1.0", - "nyc": "15.0.0", - "prettier": "2.7.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -1419,8 +1399,19 @@ } }, "node_modules/rescript": { - "resolved": "../../..", - "link": true + "version": "11.0.0-rc.8", + "resolved": "file:../../..", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE", + "bin": { + "bsc": "bsc", + "bstracing": "lib/bstracing", + "rescript": "rescript" + }, + "engines": { + "node": ">=10" + } }, "node_modules/resolve-from": { "version": "4.0.0", diff --git a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx index 51366a0640..9842501a0a 100644 --- a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx +++ b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.gen.tsx @@ -8,3 +8,7 @@ export type notRecursive = number; export type M_notRecursive = notRecursive[]; export type M_recursive = { readonly self: M_recursive }; + +export type M_mutualRecursive = { readonly a: M_a }; + +export type M_a = { readonly self: M_mutualRecursive }; diff --git a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res index 1fc81532d3..9c76dc27e7 100644 --- a/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res +++ b/jscomp/gentype_tests/typescript-react-example/src/NonrecursiveTypes.res @@ -7,4 +7,8 @@ module M = { @genType type rec recursive = {self: recursive} + + @genType + type rec mutualRecursive = {a: a} + and a = {self: mutualRecursive} } From 3fac89e526d6c893b177b0d2360ae21b91ef9a6c Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Wed, 13 Dec 2023 18:33:27 +0200 Subject: [PATCH 2/3] In GenType add support for mutual recursion Signed-Off-By: Jono Prest --- CHANGELOG.md | 1 + jscomp/gentype/TranslateSignature.ml | 6 +++++- jscomp/gentype/TranslateStructure.ml | 7 +++++-- jscomp/gentype/TranslateTypeDeclarations.ml | 8 +++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0ef88301..90aca5bf13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Add missing check that the runtime representation of variants matches implementation and interface. https://github.com/rescript-lang/rescript-compiler/pull/6513/files - GenType: only export types (not values) from module types. https://github.com/rescript-lang/rescript-compiler/pull/6516 - Fix compiler crash with unboxed variant definition with only 1 constructor. https://github.com/rescript-lang/rescript-compiler/pull/6523 +- GenType: support mutual recursive types inside modules. https://github.com/rescript-lang/rescript-compiler/pull/6528 # 11.0.0-rc.7 diff --git a/jscomp/gentype/TranslateSignature.ml b/jscomp/gentype/TranslateSignature.ml index a38890a36c..1cf8df9012 100644 --- a/jscomp/gentype/TranslateSignature.ml +++ b/jscomp/gentype/TranslateSignature.ml @@ -98,13 +98,17 @@ and translateSignatureItem ~config ~outputFileRelative ~resolver ~typeEnv signatureItem : Translation.t = match signatureItem with | {Typedtree.sig_desc = Typedtree.Tsig_type (recFlag, typeDeclarations)} -> + let recursive = recFlag = Recursive in + if recursive then + typeDeclarations + |> TranslateTypeDeclarations.addRecursiveTypesToTypEnv ~typeEnv; { importTypes = []; codeItems = []; typeDeclarations = typeDeclarations |> TranslateTypeDeclarations.translateTypeDeclarations ~config - ~outputFileRelative ~recursive:(recFlag = Recursive) ~resolver + ~outputFileRelative ~recursive ~resolver ~typeEnv; } | {Typedtree.sig_desc = Tsig_value valueDescription} -> diff --git a/jscomp/gentype/TranslateStructure.ml b/jscomp/gentype/TranslateStructure.ml index 1fd23b0fb0..3388671ff4 100644 --- a/jscomp/gentype/TranslateStructure.ml +++ b/jscomp/gentype/TranslateStructure.ml @@ -260,14 +260,17 @@ and translateStructureItem ~config ~outputFileRelative ~resolver ~typeEnv (structItem : Typedtree.structure_item) : Translation.t = match structItem with | {str_desc = Tstr_type (recFlag, typeDeclarations)} -> + let recursive = recFlag = Recursive in + if recursive then + typeDeclarations + |> TranslateTypeDeclarations.addRecursiveTypesToTypEnv ~typeEnv; { importTypes = []; codeItems = []; typeDeclarations = typeDeclarations |> TranslateTypeDeclarations.translateTypeDeclarations ~config - ~outputFileRelative ~recursive:(recFlag = Recursive) ~resolver - ~typeEnv; + ~outputFileRelative ~recursive ~resolver ~typeEnv; } | {str_desc = Tstr_value (_loc, valueBindings)} -> valueBindings diff --git a/jscomp/gentype/TranslateTypeDeclarations.ml b/jscomp/gentype/TranslateTypeDeclarations.ml index 5999d4b4fa..0586043a51 100644 --- a/jscomp/gentype/TranslateTypeDeclarations.ml +++ b/jscomp/gentype/TranslateTypeDeclarations.ml @@ -313,13 +313,19 @@ let hasSomeGADTLeaf constructorDeclarations = (fun declaration -> declaration.Types.cd_res != None) constructorDeclarations +let addRecursiveTypesToTypEnv ~typeEnv typeDeclarations = + typeDeclarations + |> List.map (fun ({typ_id} : Typedtree.type_declaration) -> typ_id) + |> List.iter (fun type_id -> + typeEnv |> TypeEnv.newType ~name:(type_id |> Ident.name)) + let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver ~typeEnv ({typ_attributes; typ_id; typ_loc; typ_manifest; typ_params; typ_type} : Typedtree.type_declaration) : CodeItem.typeDeclaration list = if !Debug.translation then Log_.item "Translate Type Declaration %s\n" (typ_id |> Ident.name); - if recursive then typeEnv |> TypeEnv.newType ~name:(typ_id |> Ident.name); + let typeName = Ident.name typ_id in let typeVars = typ_params From 191587b0f6189bba64eba344f67238caec13aa38 Mon Sep 17 00:00:00 2001 From: Jono Prest Date: Thu, 14 Dec 2023 13:54:03 +0200 Subject: [PATCH 3/3] Refactor GenType support mutual type recursion Signed-Off-By: Jono Prest --- jscomp/gentype/TranslateSignature.ml | 6 +--- jscomp/gentype/TranslateStructure.ml | 7 ++-- jscomp/gentype/TranslateTypeDeclarations.ml | 37 +++++++++++---------- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/jscomp/gentype/TranslateSignature.ml b/jscomp/gentype/TranslateSignature.ml index 1cf8df9012..a38890a36c 100644 --- a/jscomp/gentype/TranslateSignature.ml +++ b/jscomp/gentype/TranslateSignature.ml @@ -98,17 +98,13 @@ and translateSignatureItem ~config ~outputFileRelative ~resolver ~typeEnv signatureItem : Translation.t = match signatureItem with | {Typedtree.sig_desc = Typedtree.Tsig_type (recFlag, typeDeclarations)} -> - let recursive = recFlag = Recursive in - if recursive then - typeDeclarations - |> TranslateTypeDeclarations.addRecursiveTypesToTypEnv ~typeEnv; { importTypes = []; codeItems = []; typeDeclarations = typeDeclarations |> TranslateTypeDeclarations.translateTypeDeclarations ~config - ~outputFileRelative ~recursive ~resolver + ~outputFileRelative ~recursive:(recFlag = Recursive) ~resolver ~typeEnv; } | {Typedtree.sig_desc = Tsig_value valueDescription} -> diff --git a/jscomp/gentype/TranslateStructure.ml b/jscomp/gentype/TranslateStructure.ml index 3388671ff4..1fd23b0fb0 100644 --- a/jscomp/gentype/TranslateStructure.ml +++ b/jscomp/gentype/TranslateStructure.ml @@ -260,17 +260,14 @@ and translateStructureItem ~config ~outputFileRelative ~resolver ~typeEnv (structItem : Typedtree.structure_item) : Translation.t = match structItem with | {str_desc = Tstr_type (recFlag, typeDeclarations)} -> - let recursive = recFlag = Recursive in - if recursive then - typeDeclarations - |> TranslateTypeDeclarations.addRecursiveTypesToTypEnv ~typeEnv; { importTypes = []; codeItems = []; typeDeclarations = typeDeclarations |> TranslateTypeDeclarations.translateTypeDeclarations ~config - ~outputFileRelative ~recursive ~resolver ~typeEnv; + ~outputFileRelative ~recursive:(recFlag = Recursive) ~resolver + ~typeEnv; } | {str_desc = Tstr_value (_loc, valueBindings)} -> valueBindings diff --git a/jscomp/gentype/TranslateTypeDeclarations.ml b/jscomp/gentype/TranslateTypeDeclarations.ml index 0586043a51..64e103fce7 100644 --- a/jscomp/gentype/TranslateTypeDeclarations.ml +++ b/jscomp/gentype/TranslateTypeDeclarations.ml @@ -313,14 +313,7 @@ let hasSomeGADTLeaf constructorDeclarations = (fun declaration -> declaration.Types.cd_res != None) constructorDeclarations -let addRecursiveTypesToTypEnv ~typeEnv typeDeclarations = - typeDeclarations - |> List.map (fun ({typ_id} : Typedtree.type_declaration) -> typ_id) - |> List.iter (fun type_id -> - typeEnv |> TypeEnv.newType ~name:(type_id |> Ident.name)) - -let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver - ~typeEnv +let translateTypeDeclaration ~config ~outputFileRelative ~resolver ~typeEnv ({typ_attributes; typ_id; typ_loc; typ_manifest; typ_params; typ_type} : Typedtree.type_declaration) : CodeItem.typeDeclaration list = if !Debug.translation then @@ -341,19 +334,27 @@ let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver | Type_abstract -> GeneralDeclaration typ_manifest | _ -> NoDeclaration in - let res = - declarationKind - |> traslateDeclarationKind ~config ~loc:typ_loc ~outputFileRelative - ~resolver ~typeAttributes:typ_attributes ~typeEnv ~typeName ~typeVars - in - if not recursive then typeEnv |> TypeEnv.newType ~name:(typ_id |> Ident.name); - res + declarationKind + |> traslateDeclarationKind ~config ~loc:typ_loc ~outputFileRelative ~resolver + ~typeAttributes:typ_attributes ~typeEnv ~typeName ~typeVars + +let addTypeDeclarationIdToTypeEnv ~typeEnv + ({typ_id} : Typedtree.type_declaration) = + typeEnv |> TypeEnv.newType ~name:(typ_id |> Ident.name) let translateTypeDeclarations ~config ~outputFileRelative ~recursive ~resolver ~typeEnv (typeDeclarations : Typedtree.type_declaration list) : CodeItem.typeDeclaration list = + if recursive then + typeDeclarations |> List.iter (addTypeDeclarationIdToTypeEnv ~typeEnv); typeDeclarations - |> List.map - (translateTypeDeclaration ~config ~outputFileRelative ~recursive - ~resolver ~typeEnv) + |> List.map (fun typeDeclaration -> + let res = + typeDeclaration + |> translateTypeDeclaration ~config ~outputFileRelative ~resolver + ~typeEnv + in + if not recursive then + typeDeclaration |> addTypeDeclarationIdToTypeEnv ~typeEnv; + res) |> List.concat