Skip to content

Commit

Permalink
Parse TypeScript primitive and literal types. (#1115)
Browse files Browse the repository at this point in the history
Summary:
Original Author: seonggun@amazon.com
Original Git: 600b7ae

TypeScript built-in type primitives: `boolean`, `string`, `number`, `undefined`, `any`, `unknown`, `never`, `void`, `bigint`, `symbol`.

TypeScript literal types: `null`, `boolean`, `string`, `number`, `bigint` literals.

Pull Request resolved: #1115

Original Reviewed By: tmikov

Original Revision: D49053990

Reviewed By: tmikov

Differential Revision: D49156875

fbshipit-source-id: 65b54ae723dfafa42e356ed6550b751b9fbf558a
  • Loading branch information
avp authored and facebook-github-bot committed Sep 14, 2023
1 parent 18a9965 commit 28a6a70
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 7 deletions.
18 changes: 11 additions & 7 deletions include/hermes/AST/ESTree.def
Original file line number Diff line number Diff line change
Expand Up @@ -1060,13 +1060,17 @@ ESTREE_NODE_1_ARGS(
TSTypeAnnotation, TS,
NodePtr, typeAnnotation, false)

ESTREE_NODE_0_ARGS(TSAnyKeyword, Base)
ESTREE_NODE_0_ARGS(TSNumberKeyword, Base)
ESTREE_NODE_0_ARGS(TSBooleanKeyword, Base)
ESTREE_NODE_0_ARGS(TSStringKeyword, Base)
ESTREE_NODE_0_ARGS(TSSymbolKeyword, Base)
ESTREE_NODE_0_ARGS(TSVoidKeyword, Base)
ESTREE_NODE_0_ARGS(TSThisType, Base)
ESTREE_NODE_0_ARGS(TSAnyKeyword, TS)
ESTREE_NODE_0_ARGS(TSNumberKeyword, TS)
ESTREE_NODE_0_ARGS(TSBooleanKeyword, TS)
ESTREE_NODE_0_ARGS(TSStringKeyword, TS)
ESTREE_NODE_0_ARGS(TSSymbolKeyword, TS)
ESTREE_NODE_0_ARGS(TSVoidKeyword, TS)
ESTREE_NODE_0_ARGS(TSUndefinedKeyword, TS)
ESTREE_NODE_0_ARGS(TSUnknownKeyword, TS)
ESTREE_NODE_0_ARGS(TSNeverKeyword, TS)
ESTREE_NODE_0_ARGS(TSBigIntKeyword, TS)
ESTREE_NODE_0_ARGS(TSThisType, TS)
ESTREE_NODE_1_ARGS(
TSLiteralType, TS,
NodePtr, literal, false)
Expand Down
54 changes: 54 additions & 0 deletions lib/Parser/JSParserImpl-ts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,30 @@ Optional<ESTree::Node *> JSParserImpl::parseTSPrimaryType() {
advance(JSLexer::GrammarContext::Type).End,
new (context_) ESTree::TSStringKeywordNode());
}
if (tok_->getResWordOrIdentifier() == bigintIdent_) {
return setLocation(
start,
advance(JSLexer::GrammarContext::Type).End,
new (context_) ESTree::TSBigIntKeywordNode());
}
if (tok_->getResWordOrIdentifier() == neverIdent_) {
return setLocation(
start,
advance(JSLexer::GrammarContext::Type).End,
new (context_) ESTree::TSNeverKeywordNode());
}
if (tok_->getResWordOrIdentifier() == undefinedIdent_) {
return setLocation(
start,
advance(JSLexer::GrammarContext::Type).End,
new (context_) ESTree::TSUndefinedKeywordNode());
}
if (tok_->getResWordOrIdentifier() == unknownIdent_) {
return setLocation(
start,
advance(JSLexer::GrammarContext::Type).End,
new (context_) ESTree::TSUnknownKeywordNode());
}

{
auto optRef = parseTSTypeReference();
Expand All @@ -943,6 +967,15 @@ Optional<ESTree::Node *> JSParserImpl::parseTSPrimaryType() {
return *optRef;
}

case TokenKind::rw_null: {
SMLoc end = advance(JSLexer::GrammarContext::Type).End;
return setLocation(
start,
end,
new (context_) ESTree::TSLiteralTypeNode(setLocation(
start, end, new (context_) ESTree::NullLiteralNode())));
}

case TokenKind::rw_void:
return setLocation(
start,
Expand All @@ -969,6 +1002,27 @@ Optional<ESTree::Node *> JSParserImpl::parseTSPrimaryType() {
start, end, new (context_) ESTree::NumericLiteralNode(str))));
}

case TokenKind::bigint_literal: {
UniqueString *raw = tok_->getBigIntLiteral();
SMLoc end = advance(JSLexer::GrammarContext::Type).End;
return setLocation(
start,
end,
new (context_) ESTree::TSLiteralTypeNode(setLocation(
start, end, new (context_) ESTree::BigIntLiteralNode(raw))));
}

case TokenKind::rw_true:
case TokenKind::rw_false: {
bool value = check(TokenKind::rw_true);
SMLoc end = advance(JSLexer::GrammarContext::Type).End;
return setLocation(
start,
end,
new (context_) ESTree::TSLiteralTypeNode(setLocation(
start, end, new (context_) ESTree::BooleanLiteralNode(value))));
}

default:
if (tok_->isResWord()) {
auto optRef = parseTSTypeReference();
Expand Down
3 changes: 3 additions & 0 deletions lib/Parser/JSParserImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ void JSParserImpl::initializeIdentifiers() {

namespaceIdent_ = lexer_.getIdentifier("namespace");
readonlyIdent_ = lexer_.getIdentifier("readonly");
neverIdent_ = lexer_.getIdentifier("never");
undefinedIdent_ = lexer_.getIdentifier("undefined");
unknownIdent_ = lexer_.getIdentifier("unknown");

#endif

Expand Down
3 changes: 3 additions & 0 deletions lib/Parser/JSParserImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,9 @@ class JSParserImpl {
#if HERMES_PARSE_TS
UniqueString *namespaceIdent_;
UniqueString *readonlyIdent_;
UniqueString *neverIdent_;
UniqueString *undefinedIdent_;
UniqueString *unknownIdent_;
#endif

#if HERMES_PARSE_FLOW || HERMES_PARSE_TS
Expand Down
117 changes: 117 additions & 0 deletions test/Parser/ts/literal-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

// RUN: %hermesc -parse-ts -dump-ast -pretty-json %s | %FileCheck %s --match-full-lines

// CHECK-LABEL: {
// CHECK-NEXT: "type": "Program",
// CHECK-NEXT: "body": [

type A = null;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSLiteralType",
// CHECK-NEXT: "literal": {
// CHECK-NEXT: "type": "NullLiteral"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = true;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSLiteralType",
// CHECK-NEXT: "literal": {
// CHECK-NEXT: "type": "BooleanLiteral",
// CHECK-NEXT: "value": true
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = false;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSLiteralType",
// CHECK-NEXT: "literal": {
// CHECK-NEXT: "type": "BooleanLiteral",
// CHECK-NEXT: "value": false
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = "foo";
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSLiteralType",
// CHECK-NEXT: "literal": {
// CHECK-NEXT: "type": "StringLiteral",
// CHECK-NEXT: "value": "foo"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = 42;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSLiteralType",
// CHECK-NEXT: "literal": {
// CHECK-NEXT: "type": "NumericLiteral",
// CHECK-NEXT: "value": 42,
// CHECK-NEXT: "raw": "42"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = 42n;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSLiteralType",
// CHECK-NEXT: "literal": {
// CHECK-NEXT: "type": "BigIntLiteral",
// CHECK-NEXT: "bigint": "42n"
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }

// CHECK-NEXT: ]
// CHECK-NEXT: }
145 changes: 145 additions & 0 deletions test/Parser/ts/primtive-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

// RUN: %hermesc -parse-ts -dump-ast -pretty-json %s | %FileCheck %s --match-full-lines

// CHECK-LABEL: {
// CHECK-NEXT: "type": "Program",
// CHECK-NEXT: "body": [

type A = boolean;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSBooleanKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = string;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSStringKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = number;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSNumberKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = undefined;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSUndefinedKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = any;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSAnyKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = unknown;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSUnknownKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = never;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSNeverKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = void;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSVoidKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = bigint;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSBigIntKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: },

type A = symbol;
// CHECK-NEXT: {
// CHECK-NEXT: "type": "TSTypeAliasDeclaration",
// CHECK-NEXT: "id": {
// CHECK-NEXT: "type": "Identifier",
// CHECK-NEXT: "name": "A"
// CHECK-NEXT: },
// CHECK-NEXT: "typeParameters": null,
// CHECK-NEXT: "typeAnnotation": {
// CHECK-NEXT: "type": "TSSymbolKeyword"
// CHECK-NEXT: }
// CHECK-NEXT: }

// CHECK-NEXT: ]
// CHECK-NEXT: }

0 comments on commit 28a6a70

Please sign in to comment.