Add ES2020 nodes

master
Yury Kurlykov 2020-04-28 18:41:51 +10:00
parent 85aa1b2a34
commit c504830928
Signed by: t1meshift
GPG Key ID: B133F3167ABF94D8
1 changed files with 76 additions and 21 deletions

View File

@ -19,7 +19,8 @@ The module lacks support of:
* for-await-of statement * for-await-of statement
* template literals * template literals
* ES2019 features * ES2019 features
* ES2020 features * catch binding omission.
The only ES2019 feature.
More about ESTree standard: More about ESTree standard:
https://github.com/estree/estree/ https://github.com/estree/estree/
@ -29,7 +30,7 @@ Todo:
* Make another attempt to split up this module * Make another attempt to split up this module
""" """
from typing import List, Union, Optional, Literal as TypeLiteral, TypedDict, Any from typing import List, Union, Optional, Literal as TypeLiteral, Any
from enum import Enum from enum import Enum
from collections import OrderedDict from collections import OrderedDict
@ -38,8 +39,11 @@ from collections import OrderedDict
# Custom types used in the nodes # Custom types used in the nodes
number = Union[int, float] number = float
"""A type union consisting of int and float Python types. Consider it as Number type from JavaScript.""" """A type representing Number type in JavaScript."""
bigint = int
"""A type representing BigInt type in JavaScript."""
SourceTypeLiteral = TypeLiteral["script", "module"] SourceTypeLiteral = TypeLiteral["script", "module"]
"""The type for the `sourceType` field.""" """The type for the `sourceType` field."""
@ -123,6 +127,7 @@ class LogicalOperator(Enum):
OR = "||" OR = "||"
AND = "&&" AND = "&&"
NULLISH_COALESCING = "??"
# Nodes forward declarations # Nodes forward declarations
@ -158,6 +163,10 @@ class Identifier:
... ...
class Literal:
...
# "Node objects" block # "Node objects" block
@ -231,20 +240,6 @@ class Node:
return self._fields return self._fields
# "Literal" block
class Literal(Expression):
"""A literal token. Note that a literal can be an expression."""
def __init__(
self, loc: Optional[SourceLocation], value: Union[str, bool, number, None]
):
super().__init__("Literal", loc)
self.value = value
self._fields.update({"value": self.value})
# "Programs" block # "Programs" block
@ -1026,6 +1021,42 @@ OrLogicExpression = _generate_logical_expression(
AndLogicExpression = _generate_logical_expression( AndLogicExpression = _generate_logical_expression(
LogicalOperator.AND, """An "and" logical expression.""" LogicalOperator.AND, """An "and" logical expression."""
) )
NullishCoalescingLogicExpression = _generate_logical_expression(
LogicalOperator.NULLISH_COALESCING, """A nullish coalescing logical expression."""
)
# "Literal" block
class Literal(Expression):
"""A literal token. Note that a literal can be an expression."""
def __init__(
self,
loc: Optional[SourceLocation],
value: Union[str, bool, number, bigint, None],
):
super().__init__("Literal", loc)
self.value = value
self._fields.update({"value": self.value})
class BigIntLiteral(Literal):
"""`bigint` property is the string representation of the ``BigInt`` value. It doesn't include the suffix ``n``.
In environments that don't support ``BigInt`` values, value property will be `None` as the ``BigInt`` value can't
be represented natively.
"""
def __init__(
self,
loc: Optional[SourceLocation],
value: Union[str, bool, number, bigint, None],
bigint: str,
):
super().__init__(loc, value)
self.bigint = bigint
self._fields.update({"bigint": self.bigint})
# "Property" block # "Property" block
@ -1069,7 +1100,7 @@ class AssignmentProperty(Property):
def __init__( def __init__(
self, self,
loc: Optional[SourceLocation], loc: Optional[SourceLocation],
key: Union[Literal, Identifier], key: Expression,
value: Pattern, value: Pattern,
shorthand: bool, shorthand: bool,
computed: bool, computed: bool,
@ -1300,6 +1331,18 @@ class ImportDeclaration(ModuleDeclaration):
self._fields.update({"specifiers": self.specifiers, "source": self.source}) self._fields.update({"specifiers": self.specifiers, "source": self.source})
class ImportExpression(Expression):
"""`ImportExpression` node represents Dynamic Imports such as ``import(source)``.
The `source` property is the importing source as similar to ImportDeclaration node,
but it can be an arbitrary expression node.
"""
def __init__(self, loc: Optional[SourceLocation], source: Expression):
super().__init__("ImportExpression", loc)
self.source = source
self._fields.update({"source": self.source})
class ExportSpecifier(ModuleSpecifier): class ExportSpecifier(ModuleSpecifier):
"""An exported variable binding, e.g., ``{foo}`` in ``export {foo}`` or ``{bar as foo}`` """An exported variable binding, e.g., ``{foo}`` in ``export {foo}`` or ``{bar as foo}``
in ``export {bar as foo}``. The `exported` field refers to the name exported in the module. in ``export {bar as foo}``. The `exported` field refers to the name exported in the module.
@ -1384,7 +1427,19 @@ class ExportDefaultDeclaration(ModuleDeclaration):
class ExportAllDeclaration(ModuleDeclaration): class ExportAllDeclaration(ModuleDeclaration):
def __init__(self, loc: Optional[SourceLocation], source: Literal): """An export batch declaration, e.g., ``export * from "mod";``.
The `exported` property contains an `Identifier` when a different exported
name is specified using ``as``, e.g., ``export * as foo from "mod";``.
"""
def __init__(
self,
loc: Optional[SourceLocation],
source: Literal,
exported: Optional[Identifier],
):
super().__init__("ExportAllDeclaration", loc) super().__init__("ExportAllDeclaration", loc)
self.source = source self.source = source
self._fields.update({"source": self.source}) self.exported = exported
self._fields.update({"source": self.source, "exported": self.exported})