From d67556c3383bba6cbb6983011fdbad2d938fcb4f Mon Sep 17 00:00:00 2001 From: Zach Ploskey Date: Fri, 16 Mar 2018 05:57:42 -0700 Subject: [PATCH] newline between doc comment and attr on external Forces a line break following doc comments before the first non-comment attribute on a BuckleScript external. Before: /** doc comment */ [@bs.send] external url : t => string = ""; /** * Short multiline doc comment */ [@bs.send] external url : t => string = ""; After: /** doc comment */ [@bs.send] external url : t => string = ""; /** * Short multiline doc comment */ [@bs.send] external url : t => string = ""; --- .../expected_output/reasonComments.re | 17 ++++++++++ .../typeCheckedTests/input/reasonComments.re | 17 ++++++++++ src/reason-parser/reason_pprint_ast.ml | 32 +++++++++++++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/formatTest/typeCheckedTests/expected_output/reasonComments.re b/formatTest/typeCheckedTests/expected_output/reasonComments.re index e92e6e2d7..202385b3f 100644 --- a/formatTest/typeCheckedTests/expected_output/reasonComments.re +++ b/formatTest/typeCheckedTests/expected_output/reasonComments.re @@ -727,3 +727,20 @@ let r = { fieldOne: (identifier: string), /*eol1*/ fieldTwo: (identifier: string) /* eol2 with trailing comma */ }; + +/** doc comment */ +[@bs.send] +external url : t => string = ""; + +/** + * Short multiline doc comment + */ +[@bs.send] +external url : t => string = ""; + +/** Longer doc comment before an attribute on an external. */ +[@bs.send] +external url : t => string = ""; + +/* normal comment */ +[@bs.send] external url : t => string = ""; diff --git a/formatTest/typeCheckedTests/input/reasonComments.re b/formatTest/typeCheckedTests/input/reasonComments.re index 82da64e0e..24ddf531d 100644 --- a/formatTest/typeCheckedTests/input/reasonComments.re +++ b/formatTest/typeCheckedTests/input/reasonComments.re @@ -711,3 +711,20 @@ let r = { fieldOne: (identifier : string), /*eol1*/ fieldTwo: (identifier : string), /* eol2 with trailing comma */ }; + +/** doc comment */ +[@bs.send] +external url : t => string = ""; + +/** + * Short multiline doc comment + */ +[@bs.send] +external url : t => string = ""; + +/** Longer doc comment before an attribute on an external. */ +[@bs.send] +external url : t => string = ""; + +/* normal comment */ +[@bs.send] external url : t => string = ""; diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index d2829acaf..b819adda5 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -317,6 +317,23 @@ let rec partitionAttributes ?(allowUncurry=true) attrs : attributesPartition = let partition = partitionAttributes ~allowUncurry atTl in {partition with stdAttrs=atHd::partition.stdAttrs} +type docAttributesPartition = { + docAttrs : attributes; + otherAttrs : attributes +} + +let rec partitionDocAttributes attrs : docAttributesPartition = + match attrs with + | [] -> + {docAttrs=[]; otherAttrs=[]} + | (({txt="ocaml.text"; loc}, _) as doc)::atTl + | (({txt="ocaml.doc"; loc}, _) as doc)::atTl -> + let partition = partitionDocAttributes atTl in + {partition with docAttrs=doc::partition.docAttrs} + | atHd :: atTl -> + let partition = partitionDocAttributes atTl in + {partition with otherAttrs=atHd::partition.otherAttrs} + let extractStdAttrs attrs = (partitionAttributes attrs).stdAttrs @@ -5315,7 +5332,8 @@ let printer = object(self:'self) | _ -> true (* - [@@bs.val] [@@bs.module "react-dom"] (* formattedAttrs *) + /** doc comment */ (* formattedDocs *) + [@bs.val] [@bs.module "react-dom"] (* formattedAttrs *) external render : reactElement => element => unit = (* frstHalf *) "render"; (* sndHalf *) @@ -5324,6 +5342,7 @@ let printer = object(self:'self) * combine that label with '=' in a list * consider the part after the '=' as a list * combine both parts as a label + * format the doc comment with a ~postSpace:true (inline, not inline) list * format the attributes with a ~postSpace:true (inline, inline) list * format everything together in a ~postSpace:true (inline, inline) list for nicer breaking @@ -5340,9 +5359,16 @@ let printer = object(self:'self) match vd.pval_attributes with | [] -> primDecl | attrs -> - let attrs = List.map (fun x -> self#item_attribute x) attrs in + let {docAttrs; otherAttrs} = partitionDocAttributes attrs in + let docs = List.map self#item_attribute docAttrs in + let formattedDocs = makeList ~postSpace:true docs in + let attrs = List.map self#item_attribute otherAttrs in let formattedAttrs = makeSpacedBreakableInlineList attrs in - makeSpacedBreakableInlineList [formattedAttrs; primDecl] + let layouts = match (docAttrs, otherAttrs) with + | ([], _) -> [formattedAttrs; primDecl] + | (_, []) -> [formattedDocs; primDecl] + | _ -> [formattedDocs; formattedAttrs; primDecl] in + makeSpacedBreakableInlineList layouts method class_instance_type x = match x.pcty_desc with