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

Commit

Permalink
Implement printing of parens for rhs of await expression correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim authored and cristianoc committed Jul 11, 2022
1 parent 46d3d59 commit b2cbd5d
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/res_parens.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ let flattenOperandRhs parentOperator rhs =
| _ when ParsetreeViewer.isTernaryExpr rhs -> true
| _ -> false

let lazyOrAssertExprRhs expr =
let lazyOrAssertOrAwaitExprRhs expr =
let optBraces, _ = ParsetreeViewer.processBracesAttr expr in
match optBraces with
| Some ({Location.loc = bracesLoc}, _) -> Braced bracesLoc
Expand Down
2 changes: 1 addition & 1 deletion src/res_parens.mli
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ val subBinaryExprOperand : string -> string -> bool
val rhsBinaryExprOperand : string -> Parsetree.expression -> bool
val flattenOperandRhs : string -> Parsetree.expression -> bool

val lazyOrAssertExprRhs : Parsetree.expression -> kind
val lazyOrAssertOrAwaitExprRhs : Parsetree.expression -> kind

val fieldExpr : Parsetree.expression -> kind

Expand Down
2 changes: 2 additions & 0 deletions src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ let isPrintableAttribute attr =

let hasPrintableAttributes attrs = List.exists isPrintableAttribute attrs

let filterPrintableAttributes attrs = List.filter isPrintableAttribute attrs

let partitionPrintableAttributes attrs =
List.partition isPrintableAttribute attrs

Expand Down
1 change: 1 addition & 0 deletions src/res_parsetree_viewer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ val hasOptionalAttribute : Parsetree.attributes -> bool
val shouldIndentBinaryExpr : Parsetree.expression -> bool
val shouldInlineRhsBinaryExpr : Parsetree.expression -> bool
val hasPrintableAttributes : Parsetree.attributes -> bool
val filterPrintableAttributes : Parsetree.attributes -> Parsetree.attributes
val partitionPrintableAttributes :
Parsetree.attributes -> Parsetree.attributes * Parsetree.attributes

Expand Down
29 changes: 21 additions & 8 deletions src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3095,7 +3095,7 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl =
| Pexp_assert expr ->
let rhs =
let doc = printExpressionWithComments ~customLayout expr cmtTbl in
match Parens.lazyOrAssertExprRhs expr with
match Parens.lazyOrAssertOrAwaitExprRhs expr with
| Parens.Parenthesized -> addParens doc
| Braced braces -> printBraces doc expr braces
| Nothing -> doc
Expand All @@ -3104,7 +3104,7 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl =
| Pexp_lazy expr ->
let rhs =
let doc = printExpressionWithComments ~customLayout expr cmtTbl in
match Parens.lazyOrAssertExprRhs expr with
match Parens.lazyOrAssertOrAwaitExprRhs expr with
| Parens.Parenthesized -> addParens doc
| Braced braces -> printBraces doc expr braces
| Nothing -> doc
Expand Down Expand Up @@ -3282,7 +3282,24 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl =
in
let exprWithAwait =
if ParsetreeViewer.hasAwaitAttribute e.pexp_attributes then
Doc.concat [Doc.text "await "; printedExpression]
let rhs =
match
Parens.lazyOrAssertOrAwaitExprRhs
{
e with
pexp_attributes =
List.filter
(function
| {Location.txt = "res.await" | "ns.braces"}, _ -> false
| _ -> true)
e.pexp_attributes;
}
with
| Parens.Parenthesized -> addParens printedExpression
| Braced braces -> printBraces printedExpression e braces
| Nothing -> printedExpression
in
Doc.concat [Doc.text "await "; rhs]
else printedExpression
in
let shouldPrintItsOwnAttributes =
Expand Down Expand Up @@ -3680,11 +3697,7 @@ and printBinaryExpression ~customLayout (expr : Parsetree.expression) cmtTbl =
{
expr with
pexp_attributes =
List.filter
(fun attr ->
match attr with
| {Location.txt = "ns.braces"}, _ -> false
| _ -> true)
ParsetreeViewer.filterPrintableAttributes
expr.pexp_attributes;
}
with
Expand Down
46 changes: 46 additions & 0 deletions tests/printer/expr/asyncAwait.res
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,50 @@ user.data = await fetch()
let inBinaryExpression = await x->Js.Promise.resolve + 1
let inBinaryExpression = await x->Js.Promise.resolve + await y->Js.Promise.resolve

let withCallback = async (. ()) => {
async (. x) => await (x->Js.promise.resolve) + 1
}

let () = await (await fetch(url))->(await resolve)

let _ = await (1 + 1)
let _ = await 1 + 1
let _ = await (-1)
let _ = await - 1
let _ = await !ref
let _ = await f
let _ = await %extension
let _ = await "test"
let _ = await ((a, b) => a + b)
let _ = await (async (a, b) => a + b)
let _ = await (switch x { | A => () | B => ()})
let _ = await [1, 2, 3]
let _ = await (1, 2, 3)
let _ = await {name: "Steve", age: 32}
let _ = await (user.name = "Steve")
let _ = await (if 20 { true } else {false})
let _ = await (condition() ? true : false)
let _ = await f(x)
let _ = await f(. x)
let _ = await (f(x) : Js.Promise.t<unit>)
let _ = await (while true { infiniteLoop() })
let _ = await (try ok() catch { | _ => logError() })
let _ = await (for i in 0 to 10 { sideEffect()})
let _ = await (lazy x)
let _ = await (assert x)
let _ = await promises[0]
let _ = await promises["resolved"]
let _ = await (promises["resolved"] = sideEffect())
let _ = await (@attr expr)
let _ = await module(Foo)
let _ = await module(Foo: Bar)
let _ = await Promise
let _ = await Promise(status)

// braces are being dropped, because the ast only has space to record braces surrounding the await
let _ = await {x}
// here braces stay, because of precedence
let _ = await {
let x = 1
Js.Promise.resolve(x)
}
69 changes: 69 additions & 0 deletions tests/printer/expr/expected/asyncAwait.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,73 @@ user.data = await fetch()
let inBinaryExpression = (await x)->Js.Promise.resolve + 1
let inBinaryExpression = (await x)->Js.Promise.resolve + (await y)->Js.Promise.resolve

let withCallback = async (. ()) => {
async (. x) => await (x->Js.promise.resolve) + 1
}

let () = (await fetch(url))->(await resolve)

let _ = await (1 + 1)
let _ = (await 1) + 1
let _ = await -1
let _ = await -1
let _ = await !ref
let _ = await f
let _ = await %extension
let _ = await "test"
let _ = await ((a, b) => a + b)
let _ = await (async (a, b) => a + b)
let _ = await (
switch x {
| A => ()
| B => ()
}
)
let _ = await [1, 2, 3]
let _ = await (1, 2, 3)
let _ = await {name: "Steve", age: 32}
let _ = await (user.name = "Steve")
let _ = await (
if 20 {
true
} else {
false
}
)
let _ = await (condition() ? true : false)
let _ = await f(x)
let _ = await f(. x)
let _ = (await (f(x): Js.Promise.t<unit>))
let _ = await (
while true {
infiniteLoop()
}
)
let _ = await (
try ok() catch {
| _ => logError()
}
)
let _ = await (
for i in 0 to 10 {
sideEffect()
}
)
let _ = await (lazy x)
let _ = await (assert x)
let _ = await promises[0]
let _ = await promises["resolved"]
let _ = await promises["resolved"] = sideEffect()
let _ = @attr await (expr)
let _ = await module(Foo)
let _ = await module(Foo: Bar)
let _ = await Promise
let _ = await Promise(status)

// braces are being dropped, because the ast only has space to record braces surrounding the await
let _ = await x
// here braces stay, because of precedence
let _ = await {
let x = 1
Js.Promise.resolve(x)
}

0 comments on commit b2cbd5d

Please sign in to comment.