diff --git a/src/plugins/flow.js b/src/plugins/flow.js index 8927bed198..2793f618da 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -28,6 +28,45 @@ pp.flowParseTypeInitialiser = function (tok) { return type; }; +pp.flowParsePredicate = function() { + const node = this.startNode(); + const moduloLoc = this.state.startLoc; + const moduloPos = this.state.start; + this.expect(tt.modulo); + const checksLoc = this.state.startLoc; + this.expectContextual("checks"); + // Force '%' and 'checks' to be adjacent + if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) { + this.raise(moduloPos, "Spaces between ´%´ and ´checks´ are not allowed here."); + } + if (this.eat(tt.parenL)) { + node.expression = this.parseExpression(); + this.expect(tt.parenR); + return this.finishNode(node, "DeclaredPredicate"); + } else { + return this.finishNode(node, "InferredPredicate"); + } +}; + +pp.flowParseTypeAndPredicateInitialiser = function () { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(tt.colon); + let type = null; + let predicate = null; + if (this.match(tt.modulo)) { + this.state.inType = oldInType; + predicate = this.flowParsePredicate(); + } else { + type = this.flowParseType(); + this.state.inType = oldInType; + if (this.match(tt.modulo)) { + predicate = this.flowParsePredicate(); + } + } + return [type, predicate]; +}; + pp.flowParseDeclareClass = function (node) { this.next(); this.flowParseInterfaceish(node, true); @@ -53,9 +92,10 @@ pp.flowParseDeclareFunction = function (node) { typeNode.params = tmp.params; typeNode.rest = tmp.rest; this.expect(tt.parenR); - typeNode.returnType = this.flowParseTypeInitialiser(); - + let predicate = null; + [typeNode.returnType, predicate] = this.flowParseTypeAndPredicateInitialiser(); typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); + typeContainer.predicate = predicate; id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); this.finishNode(id, id.type); @@ -789,6 +829,12 @@ pp.flowParseTypeAnnotation = function () { return this.finishNode(node, "TypeAnnotation"); }; +pp.flowParseTypeAndPredicateAnnotation = function () { + const node = this.startNode(); + [node.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + return this.finishNode(node, "TypeAnnotation"); +}; + pp.flowParseTypeAnnotatableIdentifier = function () { const ident = this.flowParseRestrictedIdentifier(); if (this.match(tt.colon)) { @@ -829,7 +875,7 @@ export default function (instance) { if (this.match(tt.colon) && !allowExpression) { // if allowExpression is true then we're parsing an arrow function and if // there's a return type then it's been handled elsewhere - node.returnType = this.flowParseTypeAnnotation(); + node.returnType = this.flowParseTypeAndPredicateAnnotation(); } return inner.call(this, node, allowExpression); @@ -1378,7 +1424,7 @@ export default function (instance) { try { const oldNoAnonFunctionType = this.state.noAnonFunctionType; this.state.noAnonFunctionType = true; - const returnType = this.flowParseTypeAnnotation(); + const returnType = this.flowParseTypeAndPredicateAnnotation(); this.state.noAnonFunctionType = oldNoAnonFunctionType; if (this.canInsertSemicolon()) this.unexpected(); diff --git a/test/fixtures/flow/predicates/1/actual.js b/test/fixtures/flow/predicates/1/actual.js new file mode 100644 index 0000000000..d1a1d71ebb --- /dev/null +++ b/test/fixtures/flow/predicates/1/actual.js @@ -0,0 +1 @@ +declare function foo(x: mixed): boolean %checks(x !== null); diff --git a/test/fixtures/flow/predicates/1/expected.json b/test/fixtures/flow/predicates/1/expected.json new file mode 100644 index 0000000000..eb81514fc4 --- /dev/null +++ b/test/fixtures/flow/predicates/1/expected.json @@ -0,0 +1,226 @@ +{ + "type": "File", + "start": 0, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 60 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 60 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareFunction", + "start": 0, + "end": 60, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 60 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 59 + }, + "identifierName": "foo" + }, + "name": "foo", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 20, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "typeAnnotation": { + "type": "FunctionTypeAnnotation", + "start": 20, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "typeParameters": null, + "params": [ + { + "type": "FunctionTypeParam", + "start": 21, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 29 + } + }, + "name": { + "type": "Identifier", + "start": 21, + "end": 22, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 22 + }, + "identifierName": "x" + }, + "name": "x" + }, + "optional": false, + "typeAnnotation": { + "type": "MixedTypeAnnotation", + "start": 24, + "end": 29, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 29 + } + } + } + } + ], + "rest": null, + "returnType": { + "type": "BooleanTypeAnnotation", + "start": 32, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 39 + } + } + } + }, + "predicate": { + "type": "DeclaredPredicate", + "start": 40, + "end": 59, + "loc": { + "start": { + "line": 1, + "column": 40 + }, + "end": { + "line": 1, + "column": 59 + } + }, + "expression": { + "type": "BinaryExpression", + "start": 48, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 58 + } + }, + "left": { + "type": "Identifier", + "start": 48, + "end": 49, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 49 + }, + "identifierName": "x" + }, + "name": "x" + }, + "operator": "!==", + "right": { + "type": "NullLiteral", + "start": 54, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 54 + }, + "end": { + "line": 1, + "column": 58 + } + } + } + } + } + } + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/flow/predicates/2/actual.js b/test/fixtures/flow/predicates/2/actual.js new file mode 100644 index 0000000000..e080d2b2c6 --- /dev/null +++ b/test/fixtures/flow/predicates/2/actual.js @@ -0,0 +1 @@ +var f = (x: mixed): %checks => typeof x === "string"; diff --git a/test/fixtures/flow/predicates/2/expected.json b/test/fixtures/flow/predicates/2/expected.json new file mode 100644 index 0000000000..64df4c2006 --- /dev/null +++ b/test/fixtures/flow/predicates/2/expected.json @@ -0,0 +1,256 @@ +{ + "type": "File", + "start": 0, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "sourceType": "module", + "body": [ + { + "type": "VariableDeclaration", + "start": 0, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "declarations": [ + { + "type": "VariableDeclarator", + "start": 4, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "id": { + "type": "Identifier", + "start": 4, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 5 + }, + "identifierName": "f" + }, + "name": "f" + }, + "init": { + "type": "ArrowFunctionExpression", + "start": 8, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "returnType": { + "type": "TypeAnnotation", + "start": 18, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 27 + } + }, + "typeAnnotation": null, + "predicate": { + "type": "InferredPredicate", + "start": 20, + "end": 27, + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 27 + } + } + } + }, + "id": null, + "generator": false, + "expression": true, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 9, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 17 + }, + "identifierName": "x" + }, + "name": "x", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 10, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 10 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "typeAnnotation": { + "type": "MixedTypeAnnotation", + "start": 12, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 17 + } + } + } + } + } + ], + "body": { + "type": "BinaryExpression", + "start": 31, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "left": { + "type": "UnaryExpression", + "start": 31, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 39 + } + }, + "operator": "typeof", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 38, + "end": 39, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 39 + }, + "identifierName": "x" + }, + "name": "x" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "operator": "===", + "right": { + "type": "StringLiteral", + "start": 44, + "end": 52, + "loc": { + "start": { + "line": 1, + "column": 44 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "extra": { + "rawValue": "string", + "raw": "\"string\"" + }, + "value": "string" + } + } + } + } + ], + "kind": "var" + } + ], + "directives": [] + } +} diff --git a/test/fixtures/flow/predicates/3/actual.js b/test/fixtures/flow/predicates/3/actual.js new file mode 100644 index 0000000000..adf3488a60 --- /dev/null +++ b/test/fixtures/flow/predicates/3/actual.js @@ -0,0 +1 @@ +function foo(x: mixed): %checks { return typeof x === "string"; }; diff --git a/test/fixtures/flow/predicates/3/expected.json b/test/fixtures/flow/predicates/3/expected.json new file mode 100644 index 0000000000..8553cc335f --- /dev/null +++ b/test/fixtures/flow/predicates/3/expected.json @@ -0,0 +1,270 @@ +{ + "type": "File", + "start": 0, + "end": 66, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 66 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 66, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 66 + } + }, + "sourceType": "module", + "body": [ + { + "type": "FunctionDeclaration", + "start": 0, + "end": 65, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 65 + } + }, + "id": { + "type": "Identifier", + "start": 9, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 12 + }, + "identifierName": "foo" + }, + "name": "foo" + }, + "generator": false, + "expression": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start": 13, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 21 + }, + "identifierName": "x" + }, + "name": "x", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 14, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 14 + }, + "end": { + "line": 1, + "column": 21 + } + }, + "typeAnnotation": { + "type": "MixedTypeAnnotation", + "start": 16, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 21 + } + } + } + } + } + ], + "returnType": { + "type": "TypeAnnotation", + "start": 22, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 22 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "typeAnnotation": null, + "predicate": { + "type": "InferredPredicate", + "start": 24, + "end": 31, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 31 + } + } + } + }, + "body": { + "type": "BlockStatement", + "start": 32, + "end": 65, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 65 + } + }, + "body": [ + { + "type": "ReturnStatement", + "start": 34, + "end": 63, + "loc": { + "start": { + "line": 1, + "column": 34 + }, + "end": { + "line": 1, + "column": 63 + } + }, + "argument": { + "type": "BinaryExpression", + "start": 41, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 41 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "left": { + "type": "UnaryExpression", + "start": 41, + "end": 49, + "loc": { + "start": { + "line": 1, + "column": 41 + }, + "end": { + "line": 1, + "column": 49 + } + }, + "operator": "typeof", + "prefix": true, + "argument": { + "type": "Identifier", + "start": 48, + "end": 49, + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 49 + }, + "identifierName": "x" + }, + "name": "x" + }, + "extra": { + "parenthesizedArgument": false + } + }, + "operator": "===", + "right": { + "type": "StringLiteral", + "start": 54, + "end": 62, + "loc": { + "start": { + "line": 1, + "column": 54 + }, + "end": { + "line": 1, + "column": 62 + } + }, + "extra": { + "rawValue": "string", + "raw": "\"string\"" + }, + "value": "string" + } + } + } + ], + "directives": [] + } + }, + { + "type": "EmptyStatement", + "start": 65, + "end": 66, + "loc": { + "start": { + "line": 1, + "column": 65 + }, + "end": { + "line": 1, + "column": 66 + } + } + } + ], + "directives": [] + } +} diff --git a/test/fixtures/flow/predicates/4/actual.js b/test/fixtures/flow/predicates/4/actual.js new file mode 100644 index 0000000000..3c8bac89c9 --- /dev/null +++ b/test/fixtures/flow/predicates/4/actual.js @@ -0,0 +1 @@ +var f = (x: mixed): % checks => typeof x === "string"; diff --git a/test/fixtures/flow/predicates/4/options.json b/test/fixtures/flow/predicates/4/options.json new file mode 100644 index 0000000000..69dd7eb745 --- /dev/null +++ b/test/fixtures/flow/predicates/4/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Unexpected token, expected ; (1:18)" +} diff --git a/test/fixtures/flow/predicates/5/actual.js b/test/fixtures/flow/predicates/5/actual.js new file mode 100644 index 0000000000..35fc1dbfa8 --- /dev/null +++ b/test/fixtures/flow/predicates/5/actual.js @@ -0,0 +1,3 @@ +function foo(x): % checks { + return typeof x === "string"; +} diff --git a/test/fixtures/flow/predicates/5/options.json b/test/fixtures/flow/predicates/5/options.json new file mode 100644 index 0000000000..dbdc7697ac --- /dev/null +++ b/test/fixtures/flow/predicates/5/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Spaces between ´%´ and ´checks´ are not allowed here. (1:17)" +} diff --git a/test/fixtures/flow/predicates/6/actual.js b/test/fixtures/flow/predicates/6/actual.js new file mode 100644 index 0000000000..f1fbd33e6d --- /dev/null +++ b/test/fixtures/flow/predicates/6/actual.js @@ -0,0 +1 @@ +declare function my_filter>(v: Array, cb: P): Array<$Refine>; diff --git a/test/fixtures/flow/predicates/6/expected.json b/test/fixtures/flow/predicates/6/expected.json new file mode 100644 index 0000000000..0805a80bd3 --- /dev/null +++ b/test/fixtures/flow/predicates/6/expected.json @@ -0,0 +1,599 @@ +{ + "type": "File", + "start": 0, + "end": 86, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 86 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 86, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 86 + } + }, + "sourceType": "module", + "body": [ + { + "type": "DeclareFunction", + "start": 0, + "end": 86, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 86 + } + }, + "id": { + "type": "Identifier", + "start": 17, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 85 + }, + "identifierName": "my_filter" + }, + "name": "my_filter", + "typeAnnotation": { + "type": "TypeAnnotation", + "start": 26, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 85 + } + }, + "typeAnnotation": { + "type": "FunctionTypeAnnotation", + "start": 26, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 85 + } + }, + "typeParameters": { + "type": "TypeParameterDeclaration", + "start": 26, + "end": 42, + "loc": { + "start": { + "line": 1, + "column": 26 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "params": [ + { + "type": "TypeParameter", + "start": 27, + "end": 28, + "loc": { + "start": { + "line": 1, + "column": 27 + }, + "end": { + "line": 1, + "column": 28 + } + }, + "name": "T", + "variance": null + }, + { + "type": "TypeParameter", + "start": 30, + "end": 41, + "loc": { + "start": { + "line": 1, + "column": 30 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "name": "P", + "variance": null, + "bound": { + "type": "TypeAnnotation", + "start": 31, + "end": 41, + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 33, + "end": 41, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "typeParameters": { + "type": "TypeParameterInstantiation", + "start": 38, + "end": 41, + "loc": { + "start": { + "line": 1, + "column": 38 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "params": [ + { + "type": "NumericLiteralTypeAnnotation", + "start": 39, + "end": 40, + "loc": { + "start": { + "line": 1, + "column": 39 + }, + "end": { + "line": 1, + "column": 40 + } + }, + "value": 1, + "extra": { + "rawValue": 1, + "raw": "1" + } + } + ] + }, + "id": { + "type": "Identifier", + "start": 33, + "end": 38, + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 38 + }, + "identifierName": "$Pred" + }, + "name": "$Pred" + } + } + } + } + ] + }, + "params": [ + { + "type": "FunctionTypeParam", + "start": 43, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 43 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "name": { + "type": "Identifier", + "start": 43, + "end": 44, + "loc": { + "start": { + "line": 1, + "column": 43 + }, + "end": { + "line": 1, + "column": 44 + }, + "identifierName": "v" + }, + "name": "v" + }, + "optional": false, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 46, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 46 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "typeParameters": { + "type": "TypeParameterInstantiation", + "start": 51, + "end": 54, + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 54 + } + }, + "params": [ + { + "type": "GenericTypeAnnotation", + "start": 52, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 52 + }, + "end": { + "line": 1, + "column": 53 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 52, + "end": 53, + "loc": { + "start": { + "line": 1, + "column": 52 + }, + "end": { + "line": 1, + "column": 53 + }, + "identifierName": "T" + }, + "name": "T" + } + } + ] + }, + "id": { + "type": "Identifier", + "start": 46, + "end": 51, + "loc": { + "start": { + "line": 1, + "column": 46 + }, + "end": { + "line": 1, + "column": 51 + }, + "identifierName": "Array" + }, + "name": "Array" + } + } + }, + { + "type": "FunctionTypeParam", + "start": 56, + "end": 61, + "loc": { + "start": { + "line": 1, + "column": 56 + }, + "end": { + "line": 1, + "column": 61 + } + }, + "name": { + "type": "Identifier", + "start": 56, + "end": 58, + "loc": { + "start": { + "line": 1, + "column": 56 + }, + "end": { + "line": 1, + "column": 58 + }, + "identifierName": "cb" + }, + "name": "cb" + }, + "optional": false, + "typeAnnotation": { + "type": "GenericTypeAnnotation", + "start": 60, + "end": 61, + "loc": { + "start": { + "line": 1, + "column": 60 + }, + "end": { + "line": 1, + "column": 61 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 60, + "end": 61, + "loc": { + "start": { + "line": 1, + "column": 60 + }, + "end": { + "line": 1, + "column": 61 + }, + "identifierName": "P" + }, + "name": "P" + } + } + } + ], + "rest": null, + "returnType": { + "type": "GenericTypeAnnotation", + "start": 64, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 64 + }, + "end": { + "line": 1, + "column": 85 + } + }, + "typeParameters": { + "type": "TypeParameterInstantiation", + "start": 69, + "end": 85, + "loc": { + "start": { + "line": 1, + "column": 69 + }, + "end": { + "line": 1, + "column": 85 + } + }, + "params": [ + { + "type": "GenericTypeAnnotation", + "start": 70, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "typeParameters": { + "type": "TypeParameterInstantiation", + "start": 77, + "end": 84, + "loc": { + "start": { + "line": 1, + "column": 77 + }, + "end": { + "line": 1, + "column": 84 + } + }, + "params": [ + { + "type": "GenericTypeAnnotation", + "start": 78, + "end": 79, + "loc": { + "start": { + "line": 1, + "column": 78 + }, + "end": { + "line": 1, + "column": 79 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 78, + "end": 79, + "loc": { + "start": { + "line": 1, + "column": 78 + }, + "end": { + "line": 1, + "column": 79 + }, + "identifierName": "T" + }, + "name": "T" + } + }, + { + "type": "GenericTypeAnnotation", + "start": 80, + "end": 81, + "loc": { + "start": { + "line": 1, + "column": 80 + }, + "end": { + "line": 1, + "column": 81 + } + }, + "typeParameters": null, + "id": { + "type": "Identifier", + "start": 80, + "end": 81, + "loc": { + "start": { + "line": 1, + "column": 80 + }, + "end": { + "line": 1, + "column": 81 + }, + "identifierName": "P" + }, + "name": "P" + } + }, + { + "type": "NumericLiteralTypeAnnotation", + "start": 82, + "end": 83, + "loc": { + "start": { + "line": 1, + "column": 82 + }, + "end": { + "line": 1, + "column": 83 + } + }, + "value": 1, + "extra": { + "rawValue": 1, + "raw": "1" + } + } + ] + }, + "id": { + "type": "Identifier", + "start": 70, + "end": 77, + "loc": { + "start": { + "line": 1, + "column": 70 + }, + "end": { + "line": 1, + "column": 77 + }, + "identifierName": "$Refine" + }, + "name": "$Refine" + } + } + ] + }, + "id": { + "type": "Identifier", + "start": 64, + "end": 69, + "loc": { + "start": { + "line": 1, + "column": 64 + }, + "end": { + "line": 1, + "column": 69 + }, + "identifierName": "Array" + }, + "name": "Array" + } + } + } + } + } + } + ], + "directives": [] + } +}