Skip to content

Commit 2d83551

Browse files
committed
Vendor latest parser/printer.
1 parent 862175e commit 2d83551

File tree

9 files changed

+219
-79
lines changed

9 files changed

+219
-79
lines changed

analysis/vendor/res_outcome_printer/res_core.ml

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ let uncurryAttr = (Location.mknoloc "bs", Parsetree.PStr [])
161161
let ternaryAttr = (Location.mknoloc "ns.ternary", Parsetree.PStr [])
162162
let ifLetAttr = (Location.mknoloc "ns.iflet", Parsetree.PStr [])
163163
let optionalAttr = (Location.mknoloc "ns.optional", Parsetree.PStr [])
164+
let makeAwaitAttr loc = (Location.mkloc "res.await" loc, Parsetree.PStr [])
165+
let makeAsyncAttr loc = (Location.mkloc "res.async" loc, Parsetree.PStr [])
164166

165167
let makeExpressionOptional ~optional (e : Parsetree.expression) =
166168
if optional then {e with pexp_attributes = optionalAttr :: e.pexp_attributes}
@@ -237,6 +239,9 @@ let rec goToClosing closingToken state =
237239
(* Madness *)
238240
let isEs6ArrowExpression ~inTernary p =
239241
Parser.lookahead p (fun state ->
242+
(match state.Parser.token with
243+
| Lident "async" -> Parser.next state
244+
| _ -> ());
240245
match state.Parser.token with
241246
| Lident _ | Underscore -> (
242247
Parser.next state;
@@ -611,35 +616,30 @@ let parseHashIdent ~startPos p =
611616
let parseValuePath p =
612617
let startPos = p.Parser.startPos in
613618
let rec aux p path =
614-
match p.Parser.token with
615-
| Lident ident -> Longident.Ldot (path, ident)
616-
| Uident uident ->
617-
Parser.next p;
618-
if p.Parser.token = Dot then (
619-
Parser.expect Dot p;
620-
aux p (Ldot (path, uident)))
621-
else (
622-
Parser.err p (Diagnostics.unexpected p.Parser.token p.breadcrumbs);
623-
path)
624-
| token ->
625-
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
626-
Longident.Ldot (path, "_")
619+
let startPos = p.Parser.startPos in
620+
let token = p.token in
621+
622+
Parser.next p;
623+
if p.Parser.token = Dot then (
624+
Parser.expect Dot p;
625+
626+
match p.Parser.token with
627+
| Lident ident -> Longident.Ldot (path, ident)
628+
| Uident uident -> aux p (Ldot (path, uident))
629+
| token ->
630+
Parser.err p (Diagnostics.unexpected token p.breadcrumbs);
631+
Longident.Ldot (path, "_"))
632+
else (
633+
Parser.err p ~startPos ~endPos:p.prevEndPos (Diagnostics.lident token);
634+
path)
627635
in
628636
let ident =
629637
match p.Parser.token with
630638
| Lident ident ->
631639
Parser.next p;
632640
Longident.Lident ident
633641
| Uident ident ->
634-
Parser.next p;
635-
let res =
636-
if p.Parser.token = Dot then (
637-
Parser.expect Dot p;
638-
aux p (Lident ident))
639-
else (
640-
Parser.err p (Diagnostics.unexpected p.Parser.token p.breadcrumbs);
641-
Longident.Lident ident)
642-
in
642+
let res = aux p (Lident ident) in
643643
Parser.nextUnsafe p;
644644
res
645645
| token ->
@@ -2031,6 +2031,16 @@ and parseOperandExpr ~context p =
20312031
let expr = parseUnaryExpr p in
20322032
let loc = mkLoc startPos p.prevEndPos in
20332033
Ast_helper.Exp.assert_ ~loc expr
2034+
| Lident "async"
2035+
(* we need to be careful when we're in a ternary true branch:
2036+
`condition ? ternary-true-branch : false-branch`
2037+
Arrow expressions could be of the form: `async (): int => stuff()`
2038+
But if we're in a ternary, the `:` of the ternary takes precedence
2039+
*)
2040+
when isEs6ArrowExpression ~inTernary:(context = TernaryTrueBranchExpr) p
2041+
->
2042+
parseAsyncArrowExpression p
2043+
| Await -> parseAwaitExpression p
20342044
| Lazy ->
20352045
Parser.next p;
20362046
let expr = parseUnaryExpr p in
@@ -2744,6 +2754,21 @@ and parseBracedOrRecordExpr p =
27442754
let expr = parseRecordExpr ~startPos [] p in
27452755
Parser.expect Rbrace p;
27462756
expr
2757+
(*
2758+
The branch below takes care of the "braced" expression {async}.
2759+
The big reason that we need all these branches is that {x} isn't a record with a punned field x, but a braced expression… There's lots of "ambiguity" between a record with a single punned field and a braced expression…
2760+
What is {x}?
2761+
1) record {x: x}
2762+
2) expression x which happens to wrapped in braces
2763+
Due to historical reasons, we always follow 2
2764+
*)
2765+
| Lident "async" when isEs6ArrowExpression ~inTernary:false p ->
2766+
let expr = parseAsyncArrowExpression p in
2767+
let expr = parseExprBlock ~first:expr p in
2768+
Parser.expect Rbrace p;
2769+
let loc = mkLoc startPos p.prevEndPos in
2770+
let braces = makeBracesAttr loc in
2771+
{expr with pexp_attributes = braces :: expr.pexp_attributes}
27472772
| Uident _ | Lident _ -> (
27482773
let startToken = p.token in
27492774
let valueOrConstructor = parseValueOrConstructor p in
@@ -3099,6 +3124,28 @@ and parseExprBlock ?first p =
30993124
Parser.eatBreadcrumb p;
31003125
overParseConstrainedOrCoercedOrArrowExpression p blockExpr
31013126

3127+
and parseAsyncArrowExpression p =
3128+
let startPos = p.Parser.startPos in
3129+
Parser.expect (Lident "async") p;
3130+
let asyncAttr = makeAsyncAttr (mkLoc startPos p.prevEndPos) in
3131+
let expr = parseEs6ArrowExpression p in
3132+
{
3133+
expr with
3134+
pexp_attributes = asyncAttr :: expr.pexp_attributes;
3135+
pexp_loc = {expr.pexp_loc with loc_start = startPos};
3136+
}
3137+
3138+
and parseAwaitExpression p =
3139+
let awaitLoc = mkLoc p.Parser.startPos p.endPos in
3140+
let awaitAttr = makeAwaitAttr awaitLoc in
3141+
Parser.expect Await p;
3142+
let expr = parseUnaryExpr p in
3143+
{
3144+
expr with
3145+
pexp_attributes = awaitAttr :: expr.pexp_attributes;
3146+
pexp_loc = {expr.pexp_loc with loc_start = awaitLoc.loc_start};
3147+
}
3148+
31023149
and parseTryExpression p =
31033150
let startPos = p.Parser.startPos in
31043151
Parser.expect Try p;

analysis/vendor/res_outcome_printer/res_grammar.ml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ let isAtomicTypExprStart = function
147147
| _ -> false
148148

149149
let isExprStart = function
150-
| Token.True | False | Int _ | String _ | Float _ | Codepoint _ | Backtick
151-
| Underscore (* _ => doThings() *)
152-
| Uident _ | Lident _ | Hash | Lparen | List | Module | Lbracket | Lbrace
153-
| LessThan | Minus | MinusDot | Plus | PlusDot | Bang | Percent | At | If
154-
| Switch | While | For | Assert | Lazy | Try ->
150+
| Token.Assert | At | Await | Backtick | Bang | Codepoint _ | False | Float _
151+
| For | Hash | If | Int _ | Lazy | Lbrace | Lbracket | LessThan | Lident _
152+
| List | Lparen | Minus | MinusDot | Module | Percent | Plus | PlusDot
153+
| String _ | Switch | True | Try | Uident _ | Underscore (* _ => doThings() *)
154+
| While ->
155155
true
156156
| _ -> false
157157

@@ -255,11 +255,11 @@ let isAttributeStart = function
255255
let isJsxChildStart = isAtomicExprStart
256256

257257
let isBlockExprStart = function
258-
| Token.At | Hash | Percent | Minus | MinusDot | Plus | PlusDot | Bang | True
259-
| False | Float _ | Int _ | String _ | Codepoint _ | Lident _ | Uident _
260-
| Lparen | List | Lbracket | Lbrace | Forwardslash | Assert | Lazy | If | For
261-
| While | Switch | Open | Module | Exception | Let | LessThan | Backtick | Try
262-
| Underscore ->
258+
| Token.Assert | At | Await | Backtick | Bang | Codepoint _ | Exception
259+
| False | Float _ | For | Forwardslash | Hash | If | Int _ | Lazy | Lbrace
260+
| Lbracket | LessThan | Let | Lident _ | List | Lparen | Minus | MinusDot
261+
| Module | Open | Percent | Plus | PlusDot | String _ | Switch | True | Try
262+
| Uident _ | Underscore | While ->
263263
true
264264
| _ -> false
265265

analysis/vendor/res_outcome_printer/res_parens.ml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ let callExpr expr =
4545
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
4646
} ->
4747
Parenthesized
48+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
49+
Parenthesized
4850
| _ -> Nothing)
4951

5052
let structureExpr expr =
@@ -96,6 +98,8 @@ let unaryExprOperand expr =
9698
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
9799
} ->
98100
Parenthesized
101+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
102+
Parenthesized
99103
| _ -> Nothing)
100104

101105
let binaryExprOperand ~isLhs expr =
@@ -120,6 +124,8 @@ let binaryExprOperand ~isLhs expr =
120124
| expr when ParsetreeViewer.isBinaryExpression expr -> Parenthesized
121125
| expr when ParsetreeViewer.isTernaryExpr expr -> Parenthesized
122126
| {pexp_desc = Pexp_lazy _ | Pexp_assert _} when isLhs -> Parenthesized
127+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
128+
Parenthesized
123129
| {Parsetree.pexp_attributes = attrs} ->
124130
if ParsetreeViewer.hasPrintableAttributes attrs then Parenthesized
125131
else Nothing)
@@ -169,7 +175,7 @@ let flattenOperandRhs parentOperator rhs =
169175
| _ when ParsetreeViewer.isTernaryExpr rhs -> true
170176
| _ -> false
171177

172-
let lazyOrAssertExprRhs expr =
178+
let lazyOrAssertOrAwaitExprRhs expr =
173179
let optBraces, _ = ParsetreeViewer.processBracesAttr expr in
174180
match optBraces with
175181
| Some ({Location.loc = bracesLoc}, _) -> Braced bracesLoc
@@ -196,6 +202,8 @@ let lazyOrAssertExprRhs expr =
196202
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_ifthenelse _ );
197203
} ->
198204
Parenthesized
205+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
206+
Parenthesized
199207
| _ -> Nothing)
200208

201209
let isNegativeConstant constant =
@@ -240,6 +248,8 @@ let fieldExpr expr =
240248
| Pexp_ifthenelse _ );
241249
} ->
242250
Parenthesized
251+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
252+
Parenthesized
243253
| _ -> Nothing)
244254

245255
let setFieldExprRhs expr =
@@ -302,6 +312,8 @@ let jsxPropExpr expr =
302312
}
303313
when startsWithMinus x ->
304314
Parenthesized
315+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
316+
Parenthesized
305317
| {
306318
Parsetree.pexp_desc =
307319
( Pexp_ident _ | Pexp_constant _ | Pexp_field _ | Pexp_construct _
@@ -338,6 +350,8 @@ let jsxChildExpr expr =
338350
}
339351
when startsWithMinus x ->
340352
Parenthesized
353+
| _ when ParsetreeViewer.hasAwaitAttribute expr.pexp_attributes ->
354+
Parenthesized
341355
| {
342356
Parsetree.pexp_desc =
343357
( Pexp_ident _ | Pexp_constant _ | Pexp_field _ | Pexp_construct _

analysis/vendor/res_outcome_printer/res_parens.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ val subBinaryExprOperand : string -> string -> bool
1010
val rhsBinaryExprOperand : string -> Parsetree.expression -> bool
1111
val flattenOperandRhs : string -> Parsetree.expression -> bool
1212

13-
val lazyOrAssertExprRhs : Parsetree.expression -> kind
13+
val lazyOrAssertOrAwaitExprRhs : Parsetree.expression -> kind
1414

1515
val fieldExpr : Parsetree.expression -> kind
1616

analysis/vendor/res_outcome_printer/res_parsetree_viewer.ml

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let arrowType ct =
1111
process attrsBefore (arg :: acc) typ2
1212
| {
1313
ptyp_desc = Ptyp_arrow ((Nolabel as lbl), typ1, typ2);
14-
ptyp_attributes = [({txt = "bs"}, _)] as attrs;
14+
ptyp_attributes = [({txt = "bs" | "res.async"}, _)] as attrs;
1515
} ->
1616
let arg = (attrs, lbl, typ1) in
1717
process attrsBefore (arg :: acc) typ2
@@ -55,6 +55,30 @@ let processUncurriedAttribute attrs =
5555
in
5656
process false [] attrs
5757

58+
type functionAttributesInfo = {
59+
async: bool;
60+
uncurried: bool;
61+
attributes: Parsetree.attributes;
62+
}
63+
64+
let processFunctionAttributes attrs =
65+
let rec process async uncurried acc attrs =
66+
match attrs with
67+
| [] -> {async; uncurried; attributes = List.rev acc}
68+
| ({Location.txt = "bs"}, _) :: rest -> process async true acc rest
69+
| ({Location.txt = "res.async"}, _) :: rest ->
70+
process true uncurried acc rest
71+
| attr :: rest -> process async uncurried (attr :: acc) rest
72+
in
73+
process false false [] attrs
74+
75+
let hasAwaitAttribute attrs =
76+
List.exists
77+
(function
78+
| {Location.txt = "res.await"}, _ -> true
79+
| _ -> false)
80+
attrs
81+
5882
let collectListExpressions expr =
5983
let rec collect acc expr =
6084
match expr.pexp_desc with
@@ -168,8 +192,9 @@ let filterParsingAttrs attrs =
168192
match attr with
169193
| ( {
170194
Location.txt =
171-
( "ns.ternary" | "ns.braces" | "res.template" | "bs" | "ns.iflet"
172-
| "ns.namedArgLoc" | "ns.optional" );
195+
( "bs" | "ns.braces" | "ns.iflet" | "ns.namedArgLoc"
196+
| "ns.optional" | "ns.ternary" | "res.async" | "res.await"
197+
| "res.template" );
173198
},
174199
_ ) ->
175200
false
@@ -316,7 +341,8 @@ let hasAttributes attrs =
316341
match attr with
317342
| ( {
318343
Location.txt =
319-
"bs" | "res.template" | "ns.ternary" | "ns.braces" | "ns.iflet";
344+
( "bs" | "ns.braces" | "ns.iflet" | "ns.ternary" | "res.async"
345+
| "res.await" | "res.template" );
320346
},
321347
_ ) ->
322348
false
@@ -497,8 +523,8 @@ let isPrintableAttribute attr =
497523
match attr with
498524
| ( {
499525
Location.txt =
500-
( "bs" | "res.template" | "ns.ternary" | "ns.braces" | "ns.iflet"
501-
| "JSX" );
526+
( "bs" | "ns.iflet" | "ns.braces" | "JSX" | "res.async" | "res.await"
527+
| "res.template" | "ns.ternary" );
502528
},
503529
_ ) ->
504530
false

analysis/vendor/res_outcome_printer/res_parsetree_viewer.mli

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ val functorType :
1717
val processUncurriedAttribute :
1818
Parsetree.attributes -> bool * Parsetree.attributes
1919

20+
type functionAttributesInfo = {
21+
async: bool;
22+
uncurried: bool;
23+
attributes: Parsetree.attributes;
24+
}
25+
26+
(* determines whether a function is async and/or uncurried based on the given attributes *)
27+
val processFunctionAttributes : Parsetree.attributes -> functionAttributesInfo
28+
29+
val hasAwaitAttribute : Parsetree.attributes -> bool
30+
2031
type ifConditionKind =
2132
| If of Parsetree.expression
2233
| IfLet of Parsetree.pattern * Parsetree.expression

0 commit comments

Comments
 (0)