Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

Commit

Permalink
Cleanup gentype attribute.printing.
Browse files Browse the repository at this point in the history
There are some pretty early experiments to have tighter integration with genType, but those experiments are still ongoing, and not relevant for now.

This feature is by no means supposed to be exposed already, it unintentionally snuck through the release wrap-up. GenType’s example codebase is a pretty important testing ground for all kinds of features.
In an upcoming ReScript release the export syntax will be hidden again and your code will reprint back to @genType annotated let bindings (no breaking changes).
  • Loading branch information
Iwan committed Jan 12, 2021
1 parent f84c576 commit fe05e10
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 179 deletions.
2 changes: 1 addition & 1 deletion src/res_doc.mli
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ val question: t
val tilde: t
val equal: t
val trailingComma: t
val doubleQuote: t
val doubleQuote: t [@@live]

(*
* `willBreak doc` checks whether `doc` contains forced line breaks.
Expand Down
41 changes: 0 additions & 41 deletions src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -545,47 +545,6 @@ let rec isSinglePipeExpr expr = match expr.pexp_desc with
) when not (isSinglePipeExpr operand1) -> true
| _ -> false

let extractValueDescriptionFromModExpr modExpr =
let rec loop structure acc =
match structure with
| [] -> List.rev acc
| structureItem::structure ->
begin match structureItem.Parsetree.pstr_desc with
| Pstr_primitive vd -> loop structure (vd::acc)
| _ -> loop structure acc
end
in
match modExpr.pmod_desc with
| Pmod_structure structure -> loop structure []
| _ -> []

type jsImportScope =
| JsGlobalImport (* nothing *)
| JsModuleImport of string (* from "path" *)
| JsScopedImport of string list (* window.location *)

let classifyJsImport valueDescription =
let rec loop attrs =
let open Parsetree in
match attrs with
| [] -> JsGlobalImport
| ({Location.txt = "bs.scope"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string (s, _))}, _)}])::_ ->
JsScopedImport [s]
| ({Location.txt = "genType.import"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_string (s, _))}, _)}])::_ ->
JsModuleImport s
| ({Location.txt = "bs.scope"}, PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_tuple exprs}, _)}])::_ ->
let scopes = List.fold_left (fun acc curr ->
match curr.Parsetree.pexp_desc with
| Pexp_constant (Pconst_string (s, _)) -> s::acc
| _ -> acc
) [] exprs
in
JsScopedImport (List.rev scopes)
| _::attrs ->
loop attrs
in
loop valueDescription.pval_attributes

let isUnderscoreApplySugar expr =
match expr.pexp_desc with
| Pexp_fun (
Expand Down
9 changes: 0 additions & 9 deletions src/res_parsetree_viewer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,6 @@ val isBracedExpr : Parsetree.expression -> bool

val isSinglePipeExpr : Parsetree.expression -> bool

val extractValueDescriptionFromModExpr: Parsetree.module_expr -> Parsetree.value_description list

type jsImportScope =
| JsGlobalImport (* nothing *)
| JsModuleImport of string (* from "path" *)
| JsScopedImport of string list (* window.location *)

val classifyJsImport: Parsetree.value_description -> jsImportScope

(* (__x) => f(a, __x, c) -----> f(a, _, c) *)
val rewriteUnderscoreApply: Parsetree.expression -> Parsetree.expression

Expand Down
130 changes: 18 additions & 112 deletions src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -919,108 +919,17 @@ and printIncludeDescription (includeDescription: Parsetree.include_description)
]

and printIncludeDeclaration (includeDeclaration : Parsetree.include_declaration) cmtTbl =
let isJsFfiImport = List.exists (fun attr ->
match attr with
| ({Location.txt = "ns.jsFfi"}, _) -> true
| _ -> false
) includeDeclaration.pincl_attributes
in
if isJsFfiImport then
printJsFfiImportDeclaration includeDeclaration cmtTbl
else
Doc.concat [
printAttributes includeDeclaration.pincl_attributes cmtTbl;
Doc.text "include ";
let includeDoc =
printModExpr includeDeclaration.pincl_mod cmtTbl
in
if Parens.includeModExpr includeDeclaration.pincl_mod then
addParens includeDoc
else includeDoc;
]

and printJsFfiImport (valueDescription: Parsetree.value_description) cmtTbl =
let attrs = List.filter (fun attr ->
match attr with
| ({Location.txt = "bs.val" | "genType.import" | "bs.scope" }, _) -> false
| _ -> true
) valueDescription.pval_attributes in
let (ident, alias) = match valueDescription.pval_prim with
| primitive::_ ->
if primitive <> valueDescription.pval_name.txt then
(
printIdentLike primitive,
Doc.concat [
Doc.text " as ";
printIdentLike valueDescription.pval_name.txt;
]
)
else
(printIdentLike primitive, Doc.nil)
| _ ->
(printIdentLike valueDescription.pval_name.txt, Doc.nil)
in
Doc.concat [
printAttributes ~loc:valueDescription.pval_name.loc attrs cmtTbl;
ident;
alias;
Doc.text ": ";
printTypExpr valueDescription.pval_type cmtTbl;
printAttributes includeDeclaration.pincl_attributes cmtTbl;
Doc.text "include ";
let includeDoc =
printModExpr includeDeclaration.pincl_mod cmtTbl
in
if Parens.includeModExpr includeDeclaration.pincl_mod then
addParens includeDoc
else includeDoc;
]

and printJsFfiImportScope (scope: ParsetreeViewer.jsImportScope) =
match scope with
| JsGlobalImport -> Doc.nil
| JsModuleImport modName ->
Doc.concat [
Doc.text " from ";
Doc.doubleQuote;
Doc.text modName;
Doc.doubleQuote;
]
| JsScopedImport idents ->
Doc.concat [
Doc.text " from ";
Doc.join ~sep:Doc.dot (List.map Doc.text idents)
]

and printJsFfiImportDeclaration (includeDeclaration: Parsetree.include_declaration) cmtTbl =
let attrs = List.filter (fun attr ->
match attr with
| ({Location.txt = "ns.jsFfi"}, _) -> false
| _ -> true
) includeDeclaration.pincl_attributes
in
let imports = ParsetreeViewer.extractValueDescriptionFromModExpr includeDeclaration.pincl_mod in
let scope = match imports with
| vd::_ -> ParsetreeViewer.classifyJsImport vd
| [] -> ParsetreeViewer.JsGlobalImport
in
let scopeDoc = printJsFfiImportScope scope in
Doc.group (
Doc.concat [
printAttributes attrs cmtTbl;
Doc.text "import ";
Doc.group (
Doc.concat [
Doc.lbrace;
Doc.indent (
Doc.concat [
Doc.softLine;
Doc.join ~sep:(Doc.concat [Doc.comma; Doc.line]) (
List.map (fun vd -> printJsFfiImport vd cmtTbl) imports
)
]
);
Doc.trailingComma;
Doc.softLine;
Doc.rbrace;
]
);
scopeDoc;
]
)

and printValueBindings ~recFlag (vbs: Parsetree.value_binding list) cmtTbl =
printListi
~getLoc:(fun vb -> vb.Parsetree.pvb_loc)
Expand All @@ -1032,10 +941,14 @@ and printValueDescription valueDescription cmtTbl =
let isExternal =
match valueDescription.pval_prim with | [] -> false | _ -> true
in
let (hasGenType, attrs) = ParsetreeViewer.splitGenTypeAttr valueDescription.pval_attributes in
let attrs = printAttributes ~loc:valueDescription.pval_name.loc attrs cmtTbl in
let attrs =
printAttributes
~loc:valueDescription.pval_name.loc
valueDescription.pval_attributes
cmtTbl
in
let header =
if isExternal then "external " else (if hasGenType then "export " else "let ") in
if isExternal then "external " else "let " in
Doc.group (
Doc.concat [
attrs;
Expand Down Expand Up @@ -1109,18 +1022,11 @@ and printTypeDeclarations ~recFlag typeDeclarations cmtTbl =
* | Ptype_open
*)
and printTypeDeclaration ~name ~equalSign ~recFlag i (td: Parsetree.type_declaration) cmtTbl =
let (hasGenType, attrs) = ParsetreeViewer.splitGenTypeAttr td.ptype_attributes in
let attrs = printAttributes ~loc:td.ptype_loc attrs cmtTbl in
let attrs = printAttributes ~loc:td.ptype_loc td.ptype_attributes cmtTbl in
let prefix = if i > 0 then
Doc.concat [
Doc.text "and ";
if hasGenType then Doc.text "export " else Doc.nil
]
Doc.text "and "
else
Doc.concat [
Doc.text (if hasGenType then "export type " else "type ");
recFlag
]
Doc.concat [Doc.text "type "; recFlag]
in
let typeName = name in
let typeParams = printTypeParams td.ptype_params cmtTbl in
Expand Down
11 changes: 6 additions & 5 deletions tests/conversion/reason/__snapshots__/render.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1049,8 +1049,8 @@ exports[`gentype.re 1`] = `
@after
export type t
@after
export x: int
@genType @after
let x: int
@foo
type e = ..
Expand All @@ -1064,8 +1064,8 @@ module type MT = {
@after
export type t
@after
export x: int
@genType @after
let x: int
@foo
type e = ..
Expand All @@ -1077,7 +1077,8 @@ let x = 42
`;
exports[`gentype.rei 1`] = `
"export x: int
"@genType
let x: int
"
`;
Expand Down
30 changes: 19 additions & 11 deletions tests/printer/ffi/__snapshots__/render.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,26 @@ let x = \\"hello world\\" and export y = 2
`;

exports[`import.res 1`] = `
"import {
@disableGc @disableJit
delimiter: string,
cwd as currentWorkingDirectory: unit => string,
isAbsolute: string => bool,
toNamespacedPath as \\\\\\"ToNamespacedPath\\": string => string,
} from \\"path\\"
"@ns.jsFfi
include {
@genType.import(\\"path\\") @disableGc @disableJit
external delimiter: string = \\"delimiter\\"
@genType.import(\\"path\\")
external currentWorkingDirectory: unit => string = \\"cwd\\"
@genType.import(\\"path\\") external isAbsolute: string => bool = \\"isAbsolute\\"
@genType.import(\\"path\\")
external \\\\\\"ToNamespacedPath\\": string => string = \\"toNamespacedPath\\"
}
import {
\\\\\\"*crazy_string*\\" as crazyString: float => timestamp,
} from \\"firebase/app\\"
@ns.jsFfi
include {
@genType.import(\\"firebase/app\\")
external crazyString: float => timestamp = \\"*crazy_string*\\"
}
import {document: Dom.document}
@ns.jsFfi
include {
@bs.val external document: Dom.document = \\"document\\"
}
"
`;

0 comments on commit fe05e10

Please sign in to comment.