diff --git a/lib/Parser/JSParserImpl-flow.cpp b/lib/Parser/JSParserImpl-flow.cpp index bf9d2896736..f60f2df0b88 100644 --- a/lib/Parser/JSParserImpl-flow.cpp +++ b/lib/Parser/JSParserImpl-flow.cpp @@ -2345,7 +2345,7 @@ Optional JSParserImpl::parseReturnTypeAnnotationFlow( if (!optType) return None; - if (check(TokenKind::identifier)) { + if (check(TokenKind::identifier, TokenKind::rw_this)) { // Validate the "implies" token was an identifier not a more complex type. if (auto *generic = dyn_cast(*optType); !(generic && !generic->_typeParameters)) { @@ -2360,8 +2360,8 @@ Optional JSParserImpl::parseReturnTypeAnnotationFlow( ESTree::Node *id = setLocation( tok_, tok_, - new (context_) - ESTree::IdentifierNode(tok_->getIdentifier(), nullptr, false)); + new (context_) ESTree::IdentifierNode( + tok_->getResWordOrIdentifier(), nullptr, false)); advance(JSLexer::GrammarContext::Type); // implies IdentifierName is TypeAnnotation diff --git a/test/Parser/flow/predicate-implies.js b/test/Parser/flow/predicate-implies.js index 1bd26b0d596..ae172a980a9 100644 --- a/test/Parser/flow/predicate-implies.js +++ b/test/Parser/flow/predicate-implies.js @@ -540,7 +540,35 @@ type T = (empty: mixed) => implies empty is number; // CHECK-NEXT: "rest": null, // CHECK-NEXT: "typeParameters": null // CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK-NEXT: }, + +type T = () => implies this is number; +// CHECK-NEXT: { +// CHECK-NEXT: "type": "TypeAlias", +// CHECK-NEXT: "id": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "typeParameters": null, +// CHECK-NEXT: "right": { +// CHECK-NEXT: "type": "FunctionTypeAnnotation", +// CHECK-NEXT: "params": [], +// CHECK-NEXT: "this": null, +// CHECK-NEXT: "returnType": { +// CHECK-NEXT: "type": "TypePredicate", +// CHECK-NEXT: "parameterName": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "this" +// CHECK-NEXT: }, +// CHECK-NEXT: "typeAnnotation": { +// CHECK-NEXT: "type": "NumberTypeAnnotation" +// CHECK-NEXT: }, +// CHECK-NEXT: "kind": "implies" +// CHECK-NEXT: }, +// CHECK-NEXT: "rest": null, +// CHECK-NEXT: "typeParameters": null +// CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } diff --git a/test/Parser/flow/predicate-method-return.js b/test/Parser/flow/predicate-method-return.js index 48816031b68..3ca9fdd4012 100644 --- a/test/Parser/flow/predicate-method-return.js +++ b/test/Parser/flow/predicate-method-return.js @@ -326,6 +326,116 @@ class C { m(): this is T {} } // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } +// CHECK-NEXT: }, + +class C { m(): implies x is T {} } +// CHECK-NEXT: { +// CHECK-NEXT: "type": "ClassDeclaration", +// CHECK-NEXT: "id": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "C" +// CHECK-NEXT: }, +// CHECK-NEXT: "superClass": null, +// CHECK-NEXT: "body": { +// CHECK-NEXT: "type": "ClassBody", +// CHECK-NEXT: "body": [ +// CHECK-NEXT: { +// CHECK-NEXT: "type": "MethodDefinition", +// CHECK-NEXT: "key": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "m" +// CHECK-NEXT: }, +// CHECK-NEXT: "value": { +// CHECK-NEXT: "type": "FunctionExpression", +// CHECK-NEXT: "id": null, +// CHECK-NEXT: "params": [], +// CHECK-NEXT: "body": { +// CHECK-NEXT: "type": "BlockStatement", +// CHECK-NEXT: "body": [] +// CHECK-NEXT: }, +// CHECK-NEXT: "returnType": { +// CHECK-NEXT: "type": "TypeAnnotation", +// CHECK-NEXT: "typeAnnotation": { +// CHECK-NEXT: "type": "TypePredicate", +// CHECK-NEXT: "parameterName": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "x" +// CHECK-NEXT: }, +// CHECK-NEXT: "typeAnnotation": { +// CHECK-NEXT: "type": "GenericTypeAnnotation", +// CHECK-NEXT: "id": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "typeParameters": null +// CHECK-NEXT: }, +// CHECK-NEXT: "kind": "implies" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "generator": false, +// CHECK-NEXT: "async": false +// CHECK-NEXT: }, +// CHECK-NEXT: "kind": "method", +// CHECK-NEXT: "computed": false, +// CHECK-NEXT: "static": false +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: }, + +class C { m(): implies this is T {} } +// CHECK-NEXT: { +// CHECK-NEXT: "type": "ClassDeclaration", +// CHECK-NEXT: "id": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "C" +// CHECK-NEXT: }, +// CHECK-NEXT: "superClass": null, +// CHECK-NEXT: "body": { +// CHECK-NEXT: "type": "ClassBody", +// CHECK-NEXT: "body": [ +// CHECK-NEXT: { +// CHECK-NEXT: "type": "MethodDefinition", +// CHECK-NEXT: "key": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "m" +// CHECK-NEXT: }, +// CHECK-NEXT: "value": { +// CHECK-NEXT: "type": "FunctionExpression", +// CHECK-NEXT: "id": null, +// CHECK-NEXT: "params": [], +// CHECK-NEXT: "body": { +// CHECK-NEXT: "type": "BlockStatement", +// CHECK-NEXT: "body": [] +// CHECK-NEXT: }, +// CHECK-NEXT: "returnType": { +// CHECK-NEXT: "type": "TypeAnnotation", +// CHECK-NEXT: "typeAnnotation": { +// CHECK-NEXT: "type": "TypePredicate", +// CHECK-NEXT: "parameterName": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "this" +// CHECK-NEXT: }, +// CHECK-NEXT: "typeAnnotation": { +// CHECK-NEXT: "type": "GenericTypeAnnotation", +// CHECK-NEXT: "id": { +// CHECK-NEXT: "type": "Identifier", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "typeParameters": null +// CHECK-NEXT: }, +// CHECK-NEXT: "kind": "implies" +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "generator": false, +// CHECK-NEXT: "async": false +// CHECK-NEXT: }, +// CHECK-NEXT: "kind": "method", +// CHECK-NEXT: "computed": false, +// CHECK-NEXT: "static": false +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: ]