mirror of https://github.com/t1meshift/js.git
Implement ES5 part of JavaScript AST
parent
124d299d23
commit
dc7502aa57
|
@ -0,0 +1,3 @@
|
|||
"""AST module."""
|
||||
|
||||
from . import nodes, visitors
|
|
@ -0,0 +1,73 @@
|
|||
"""The module with AST nodes declaration. They are ESTree compliant.
|
||||
|
||||
The module lacks support of:
|
||||
* ES5 features:
|
||||
* labelled statements
|
||||
* switch statements
|
||||
* try-catch statements
|
||||
* debugger statement
|
||||
* with statement
|
||||
* RegExp
|
||||
* ES6+
|
||||
|
||||
More about ESTree standard:
|
||||
https://github.com/estree/estree/
|
||||
|
||||
Todo:
|
||||
* Add support for lacking features
|
||||
"""
|
||||
|
||||
from typing import Optional, Union
|
||||
|
||||
|
||||
class Position:
|
||||
"""The class for an object consisting of a line number (1-indexed) and a column number (0-indexed)."""
|
||||
|
||||
def __init__(self, line: int, column: int):
|
||||
if line < 1 or column < 0:
|
||||
raise ValueError(
|
||||
"L{}:C{} is not valid ESTree position!".format(line, column)
|
||||
)
|
||||
|
||||
self.line = line
|
||||
self.column = column
|
||||
|
||||
|
||||
class SourceLocation:
|
||||
"""
|
||||
The class for the source location information of a node.
|
||||
|
||||
Consists of a start position (the position of the first character of the parsed source region) and an end
|
||||
position (the position of the first character after the parsed source region).
|
||||
|
||||
See Also:
|
||||
Position
|
||||
"""
|
||||
|
||||
def __init__(self, source: Optional[str], start: Position, end: Position):
|
||||
self.source = source
|
||||
self.start = start
|
||||
self.end = end
|
||||
|
||||
|
||||
class Node:
|
||||
"""ESTree AST nodes are represented as Node objects, which may have any prototype inheritance but which implement
|
||||
this interface.
|
||||
|
||||
The `type` field is a string representing the AST variant type. Each subtype of `Node` is documented below with
|
||||
the specific string of its `type` field. You can use this field to determine which interface a node implements.
|
||||
|
||||
The `loc` field represents the source location information of the node. If the node contains no information about
|
||||
the source location, the field is `None`; otherwise it contains a `SourceLocation` object.
|
||||
|
||||
See Also:
|
||||
SourceLocation
|
||||
"""
|
||||
|
||||
def __init__(self, node_type: str, loc: Optional[SourceLocation]):
|
||||
self.type = node_type
|
||||
self.loc = loc
|
||||
|
||||
|
||||
number = Union[int, float]
|
||||
"""A type union consisting of int and float Python types. Consider it as Number type from JavaScript."""
|
|
@ -0,0 +1,52 @@
|
|||
"""The module of AST nodes for declarations."""
|
||||
|
||||
from typing import List
|
||||
|
||||
from . import *
|
||||
from .identifiers import Identifier
|
||||
from .patterns import Pattern
|
||||
from .statements import Statement, FunctionBody
|
||||
from .functions import Function
|
||||
|
||||
|
||||
class Declaration(Statement):
|
||||
"""Any declaration node. Note that declarations are considered statements; this is because declarations can
|
||||
appear in any statement context. """
|
||||
|
||||
def __init__(self, node_type: str, loc: Optional[SourceLocation]):
|
||||
super().__init__(node_type, loc)
|
||||
|
||||
|
||||
class FunctionDeclaration(Function, Declaration):
|
||||
"""A function declaration. Note that unlike in the parent interface `Function`, the `id` cannot be `None`."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
function_id: Identifier,
|
||||
params: List[Pattern],
|
||||
body: FunctionBody,
|
||||
):
|
||||
super().__init__("FunctionDeclaration", loc, function_id, params, body)
|
||||
|
||||
|
||||
class VariableDeclarator(Node):
|
||||
"""A variable declarator."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], var_id: Pattern, init: Optional[Exception]
|
||||
):
|
||||
super().__init__("VariableDeclarator", loc)
|
||||
self.id = var_id
|
||||
self.init = init
|
||||
|
||||
|
||||
class VariableDeclaration(Declaration):
|
||||
"""A variable declaration."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], declarations: List[VariableDeclarator]
|
||||
):
|
||||
super().__init__("VariableDeclaration", loc)
|
||||
self.declarations = declarations
|
||||
self.kind = "var"
|
|
@ -0,0 +1,669 @@
|
|||
"""The module of AST nodes for expressions."""
|
||||
|
||||
from typing import List, Literal as TypeLiteral
|
||||
|
||||
from . import *
|
||||
from .functions import Function
|
||||
from .identifiers import Identifier
|
||||
from .literals import Literal
|
||||
from .operator_enums import (
|
||||
UnaryOperator,
|
||||
UpdateOperator,
|
||||
BinaryOperator,
|
||||
AssignmentOperator,
|
||||
LogicalOperator,
|
||||
)
|
||||
from .patterns import Pattern
|
||||
from .statements import FunctionBody
|
||||
|
||||
|
||||
class Expression(Node):
|
||||
"""Any expression node. Since the left-hand side of an assignment may be any expression in general, an expression
|
||||
can also be a pattern.
|
||||
|
||||
See Also:
|
||||
Pattern
|
||||
"""
|
||||
|
||||
def __init__(self, node_type: str, loc: Optional[SourceLocation]):
|
||||
super().__init__(node_type, loc)
|
||||
|
||||
|
||||
class ThisExpression(Expression):
|
||||
"""A `this` expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation]):
|
||||
super().__init__("ThisExpression", loc)
|
||||
|
||||
|
||||
class ArrayExpression(Expression):
|
||||
"""An array expression. An element might be `None` if it represents a hole in a sparse array. E.g. ``[1,,2]``."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], elements: List[Optional[Expression]]
|
||||
):
|
||||
super().__init__("ArrayExpression", loc)
|
||||
self.elements = elements
|
||||
|
||||
|
||||
PropKind = TypeLiteral["init", "get", "set"]
|
||||
"""A type for a `kind` field of `Property`."""
|
||||
|
||||
|
||||
class Property(Node):
|
||||
"""A literal property in an object expression can have either a string or number as its `value`. Ordinary
|
||||
property initializers have a `kind` value ``"init"``; getters and setters have the kind values ``"get"`` and
|
||||
``"set"``, respectively. """
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
key: Union[Literal, Identifier],
|
||||
value: Expression,
|
||||
kind: PropKind,
|
||||
):
|
||||
super().__init__("Property", loc)
|
||||
self.key = key
|
||||
self.value = value
|
||||
self.kind = kind
|
||||
|
||||
|
||||
class ObjectExpression(Expression):
|
||||
"""An object expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], properties: List[Property]):
|
||||
super().__init__("ObjectExpression", loc)
|
||||
self.properties = properties
|
||||
|
||||
|
||||
class FunctionExpression(Function, Expression):
|
||||
"""A function expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
function_id: Optional[Identifier],
|
||||
params: List[Pattern],
|
||||
body: FunctionBody,
|
||||
):
|
||||
super().__init__("FunctionExpression", loc, function_id, params, body)
|
||||
|
||||
|
||||
class UnaryExpression(Expression):
|
||||
"""A unary operator expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
operator: UnaryOperator,
|
||||
prefix: bool,
|
||||
argument: Expression,
|
||||
):
|
||||
super().__init__("UnaryExpression", loc)
|
||||
self.operator = operator
|
||||
self.prefix = prefix
|
||||
self.argument = argument
|
||||
|
||||
|
||||
class UpdateExpression(Expression):
|
||||
"""An update (increment or decrement) operator expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
operator: UpdateOperator,
|
||||
argument: Expression,
|
||||
prefix: bool,
|
||||
):
|
||||
super().__init__("UpdateExpression", loc)
|
||||
self.operator = operator
|
||||
self.argument = argument
|
||||
self.prefix = prefix
|
||||
|
||||
|
||||
class BinaryExpression(Expression):
|
||||
"""A binary operator expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
operator: BinaryOperator,
|
||||
left: Expression,
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__("BinaryExpression", loc)
|
||||
self.operator = operator
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
|
||||
class AssignmentExpression(Expression):
|
||||
"""An assignment operator expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
operator: AssignmentOperator,
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__("AssignmentExpression", loc)
|
||||
self.operator = operator
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
|
||||
class LogicalExpression(Expression):
|
||||
"""A logical operator expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
operator: LogicalOperator,
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__("LogicalExpression", loc)
|
||||
self.operator = operator
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
|
||||
class UnaryMinusExpression(UnaryExpression):
|
||||
"""A unary minus expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.MINUS, True, argument)
|
||||
|
||||
|
||||
class UnaryPlusExpression(UnaryExpression):
|
||||
"""A unary plus expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.PLUS, True, argument)
|
||||
|
||||
|
||||
class UnaryLogicNotExpression(UnaryExpression):
|
||||
"""A unary logic "not" expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.NOT_LOGIC, True, argument)
|
||||
|
||||
|
||||
class UnaryBitNotExpression(UnaryExpression):
|
||||
"""A unary bit "not" expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.NOT_BIT, True, argument)
|
||||
|
||||
|
||||
class TypeofExpression(UnaryExpression):
|
||||
"""A `typeof` expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.TYPEOF, True, argument)
|
||||
|
||||
|
||||
class VoidExpression(UnaryExpression):
|
||||
"""A `void` expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.VOID, True, argument)
|
||||
|
||||
|
||||
class DeleteExpression(UnaryExpression):
|
||||
"""A `delete` expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Expression):
|
||||
super().__init__(loc, UnaryOperator.DELETE, True, argument)
|
||||
|
||||
|
||||
class PreIncrementExpression(UpdateExpression):
|
||||
"""A pre-increment expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], argument: Expression,
|
||||
):
|
||||
super().__init__(loc, UpdateOperator.INCREMENT, argument, True)
|
||||
|
||||
|
||||
class PostIncrementExpression(UpdateExpression):
|
||||
"""A post-increment expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], argument: Expression,
|
||||
):
|
||||
super().__init__(loc, UpdateOperator.INCREMENT, argument, False)
|
||||
|
||||
|
||||
class PreDecrementExpression(UpdateExpression):
|
||||
"""A pre-decrement expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], argument: Expression,
|
||||
):
|
||||
super().__init__(loc, UpdateOperator.DECREMENT, argument, True)
|
||||
|
||||
|
||||
class PostDecrementExpression(UpdateExpression):
|
||||
"""A post-decrement expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], argument: Expression,
|
||||
):
|
||||
super().__init__(loc, UpdateOperator.DECREMENT, argument, False)
|
||||
|
||||
|
||||
class EqualityExpression(BinaryExpression):
|
||||
"""An equality expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.EQ, left, right)
|
||||
|
||||
|
||||
class NotEqualityExpression(BinaryExpression):
|
||||
"""A "not equality" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.NEQ, left, right)
|
||||
|
||||
|
||||
class IdentityEqualityExpression(BinaryExpression):
|
||||
"""An identity equality expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.EQ_IDENTITY, left, right)
|
||||
|
||||
|
||||
class NotIdentityEqualityExpression(BinaryExpression):
|
||||
"""A "not identity equality" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.NEQ_IDENTITY, left, right)
|
||||
|
||||
|
||||
class LowerThanRelationExpression(BinaryExpression):
|
||||
"""A "lower than" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.LT, left, right)
|
||||
|
||||
|
||||
class LowerThanEqualRelationExpression(BinaryExpression):
|
||||
"""A "lower than or equal" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.LTE, left, right)
|
||||
|
||||
|
||||
class GreaterThanRelationExpression(BinaryExpression):
|
||||
"""A "greater than" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.GT, left, right)
|
||||
|
||||
|
||||
class GreaterThanEqualRelationExpression(BinaryExpression):
|
||||
"""A "greater than or equal" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.GTE, left, right)
|
||||
|
||||
|
||||
class LeftBitShiftExpression(BinaryExpression):
|
||||
"""A "left bit shift" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.SHL, left, right)
|
||||
|
||||
|
||||
class RightBitShiftExpression(BinaryExpression):
|
||||
"""A "right bit shift" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.SHR, left, right)
|
||||
|
||||
|
||||
class LogicRightBitShiftExpression(BinaryExpression):
|
||||
"""A "logical right bit shift" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.SHR_LOGIC, left, right)
|
||||
|
||||
|
||||
class AddArithmeticExpression(BinaryExpression):
|
||||
"""An addition arithmetical expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.ADD, left, right)
|
||||
|
||||
|
||||
class SubArithmeticExpression(BinaryExpression):
|
||||
"""A subtraction arithmetical expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.SUB, left, right)
|
||||
|
||||
|
||||
class MulArithmeticExpression(BinaryExpression):
|
||||
"""A multiplication arithmetical expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.MUL, left, right)
|
||||
|
||||
|
||||
class DivArithmeticExpression(BinaryExpression):
|
||||
"""A division arithmetical expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.DIV, left, right)
|
||||
|
||||
|
||||
class ModArithmeticExpression(BinaryExpression):
|
||||
"""A modulo arithmetical expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.MOD, left, right)
|
||||
|
||||
|
||||
class OrBitExpression(BinaryExpression):
|
||||
"""An "or" bit expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.OR, left, right)
|
||||
|
||||
|
||||
class XorBitExpression(BinaryExpression):
|
||||
"""A "xor" bit expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.XOR, left, right)
|
||||
|
||||
|
||||
class AndBitExpression(BinaryExpression):
|
||||
"""An "and" bit expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.AND, left, right)
|
||||
|
||||
|
||||
class InExpression(BinaryExpression):
|
||||
"""An "in" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.IN, left, right)
|
||||
|
||||
|
||||
class InstanceofExpression(BinaryExpression):
|
||||
"""An "instanceof" expression."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], left: Expression, right: Expression
|
||||
):
|
||||
super().__init__(loc, BinaryOperator.INSTANCEOF, left, right)
|
||||
|
||||
|
||||
class SimpleAssignExpression(AssignmentExpression):
|
||||
"""An assignment done with operator ``=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.ASSIGN, left, right)
|
||||
|
||||
|
||||
class AddAssignExpression(AssignmentExpression):
|
||||
"""An addition assignment done with operator ``+=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.ADD, left, right)
|
||||
|
||||
|
||||
class SubAssignExpression(AssignmentExpression):
|
||||
"""A subtraction assignment done with operator ``-=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.SUB, left, right)
|
||||
|
||||
|
||||
class MulAssignExpression(AssignmentExpression):
|
||||
"""A multiplication assignment done with operator ``*=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.MUL, left, right)
|
||||
|
||||
|
||||
class ModAssignExpression(AssignmentExpression):
|
||||
"""A modulo assignment done with operator ``%=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.MOD, left, right)
|
||||
|
||||
|
||||
class ShlAssignExpression(AssignmentExpression):
|
||||
"""A left shift assignment done with operator ``<<=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.SHL, left, right)
|
||||
|
||||
|
||||
class ShrAssignExpression(AssignmentExpression):
|
||||
"""A right shift assignment done with operator ``>>=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.SHR, left, right)
|
||||
|
||||
|
||||
class LogicShrAssignExpression(AssignmentExpression):
|
||||
"""A logical right shift assignment done with operator ``>>>=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.SHR_LOGIC, left, right)
|
||||
|
||||
|
||||
class OrAssignExpression(AssignmentExpression):
|
||||
"""A "bit or" assignment done with operator ``|=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.OR, left, right)
|
||||
|
||||
|
||||
class XorAssignExpression(AssignmentExpression):
|
||||
"""A "bit xor" assignment done with operator ``^=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.XOR, left, right)
|
||||
|
||||
|
||||
class AndAssignExpression(AssignmentExpression):
|
||||
"""A "bit and" assignment done with operator ``&=`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, AssignmentOperator.AND, left, right)
|
||||
|
||||
|
||||
class OrLogicExpression(LogicalExpression):
|
||||
"""An "or" logical expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, LogicalOperator.OR, left, right)
|
||||
|
||||
|
||||
class AndLogicExpression(LogicalExpression):
|
||||
"""An "and" logical expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[Pattern, Expression],
|
||||
right: Expression,
|
||||
):
|
||||
super().__init__(loc, LogicalOperator.AND, left, right)
|
||||
|
||||
|
||||
class MemberExpression(Expression, Pattern):
|
||||
"""A member expression. If `computed` is ``True``, the node corresponds to a computed (``a[b]``) member
|
||||
expression and `property` is an `Expression`. If `computed` is `False`, the node corresponds to a static
|
||||
(``a.b``) member expression and `property` is an `Identifier`. """
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
member_object: Expression,
|
||||
member_property: Expression,
|
||||
computed: bool,
|
||||
):
|
||||
super().__init__("MemberExpression", loc)
|
||||
self.object = member_object
|
||||
self.property = member_property
|
||||
self.computed = computed
|
||||
|
||||
|
||||
class ConditionalExpression(Expression):
|
||||
"""A conditional expression, i.e., a ternary ``?``/``:`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
test: Expression,
|
||||
alternate: Expression,
|
||||
consequent: Expression,
|
||||
):
|
||||
super().__init__("ConditionalExpression", loc)
|
||||
self.test = test
|
||||
self.alternate = alternate
|
||||
self.consequent = consequent
|
||||
|
||||
|
||||
class CallExpression(Expression):
|
||||
"""A function or method call expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
callee: Expression,
|
||||
arguments: List[Expression],
|
||||
):
|
||||
super().__init__("CallExpression", loc)
|
||||
self.callee = callee
|
||||
self.arguments = arguments
|
||||
|
||||
|
||||
class NewExpression(Expression):
|
||||
"""A ``new`` expression."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
callee: Expression,
|
||||
arguments: List[Expression],
|
||||
):
|
||||
super().__init__("NewExpression", loc)
|
||||
self.callee = callee
|
||||
self.arguments = arguments
|
||||
|
||||
|
||||
class SequenceExpression(Expression):
|
||||
"""A sequence expression, i.e., a comma-separated sequence of expressions."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], expressions: List[Expression]):
|
||||
super().__init__("SequenceExpression", loc)
|
||||
self.expressions = expressions
|
|
@ -0,0 +1,31 @@
|
|||
"""The module of AST nodes for functions."""
|
||||
|
||||
from typing import List
|
||||
|
||||
from . import *
|
||||
from .identifiers import Identifier
|
||||
from .patterns import Pattern
|
||||
from .statements import FunctionBody
|
||||
|
||||
|
||||
class Function(Node):
|
||||
"""A function declaration or expression.
|
||||
|
||||
See Also:
|
||||
FunctionDeclaration
|
||||
FunctionExpression
|
||||
FunctionBody
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
node_type: str,
|
||||
loc: Optional[SourceLocation],
|
||||
function_id: Optional[Identifier],
|
||||
params: List[Pattern],
|
||||
body: FunctionBody,
|
||||
):
|
||||
super().__init__(node_type, loc)
|
||||
self.id = function_id
|
||||
self.params = params
|
||||
self.body = body
|
|
@ -0,0 +1,13 @@
|
|||
"""The module of AST nodes for identifiers."""
|
||||
|
||||
from . import *
|
||||
from .patterns import Pattern
|
||||
from .expressions import Expression
|
||||
|
||||
|
||||
class Identifier(Expression, Pattern):
|
||||
"""An identifier. Note that an identifier may be an expression or a destructuring pattern."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], name: str):
|
||||
super(Identifier, self).__init__("Identifier", loc)
|
||||
self.name = name
|
|
@ -0,0 +1,14 @@
|
|||
"""The module of AST nodes for literals."""
|
||||
|
||||
from . import *
|
||||
from .expressions import Expression
|
||||
|
||||
|
||||
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
|
|
@ -0,0 +1,72 @@
|
|||
"""The module representing enums for JavaScript operators."""
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class UnaryOperator(Enum):
|
||||
"""A unary operator token."""
|
||||
|
||||
MINUS = "-"
|
||||
PLUS = "+"
|
||||
NOT_LOGIC = "!"
|
||||
NOT_BIT = "~"
|
||||
TYPEOF = "typeof"
|
||||
VOID = "void"
|
||||
DELETE = "delete"
|
||||
|
||||
|
||||
class UpdateOperator(Enum):
|
||||
"""An update (increment or decrement) operator token."""
|
||||
|
||||
INCREMENT = "++"
|
||||
DECREMENT = "--"
|
||||
|
||||
|
||||
class BinaryOperator(Enum):
|
||||
"""A binary operator token."""
|
||||
|
||||
EQ = "=="
|
||||
NEQ = "!="
|
||||
EQ_IDENTITY = "==="
|
||||
NEQ_IDENTITY = "!=="
|
||||
LT = "<"
|
||||
LTE = "<="
|
||||
GT = ">"
|
||||
GTE = ">="
|
||||
SHL = "<<"
|
||||
SHR = ">>"
|
||||
SHR_LOGIC = ">>>"
|
||||
ADD = "+"
|
||||
SUB = "-"
|
||||
MUL = "*"
|
||||
DIV = "/"
|
||||
MOD = "%"
|
||||
OR = "|"
|
||||
XOR = "^"
|
||||
AND = "&"
|
||||
IN = "in"
|
||||
INSTANCEOF = "instanceof"
|
||||
|
||||
|
||||
class AssignmentOperator(Enum):
|
||||
"""An assignment operator token."""
|
||||
|
||||
ASSIGN = "="
|
||||
ADD = "+="
|
||||
SUB = "-="
|
||||
MUL = "*="
|
||||
DIV = "/="
|
||||
MOD = "%="
|
||||
SHL = "<<="
|
||||
SHR = ">>="
|
||||
SHR_LOGIC = ">>>="
|
||||
OR = "|="
|
||||
XOR = "^="
|
||||
AND = "&="
|
||||
|
||||
|
||||
class LogicalOperator(Enum):
|
||||
"""A logical operator token."""
|
||||
|
||||
OR = "||"
|
||||
AND = "&&"
|
|
@ -0,0 +1,39 @@
|
|||
"""The module of AST nodes for patterns.
|
||||
|
||||
Destructuring binding and assignment are not part of ES5, but all binding positions accept `Pattern` to allow for
|
||||
destructuring in ES6. Nevertheless, for ES5, the only `Pattern` subtype is `Identifier`.
|
||||
|
||||
See Also:
|
||||
Identifier
|
||||
"""
|
||||
|
||||
from typing import TypedDict, Union, List
|
||||
from . import *
|
||||
from .literals import Literal
|
||||
from .identifiers import Identifier
|
||||
|
||||
|
||||
class Pattern(Node):
|
||||
"""A pattern."""
|
||||
|
||||
def __init__(self, node_type: str, loc: Optional[SourceLocation]):
|
||||
super().__init__(node_type, loc)
|
||||
|
||||
|
||||
class ObjectKeyValue(TypedDict):
|
||||
key: Union[Literal, Identifier]
|
||||
value: Pattern
|
||||
|
||||
|
||||
class ObjectPattern(Pattern):
|
||||
def __init__(self, loc: Optional[SourceLocation], properties: List[ObjectKeyValue]):
|
||||
super().__init__("ObjectPattern", loc)
|
||||
self.properties = properties
|
||||
|
||||
|
||||
class ArrayPattern(Pattern):
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], elements: List[Optional[Pattern]]
|
||||
):
|
||||
super().__init__("ArrayPattern", loc)
|
||||
self.elements = elements
|
|
@ -0,0 +1,15 @@
|
|||
"""The module of Program AST node."""
|
||||
|
||||
from typing import List
|
||||
from . import *
|
||||
from .statements import Statement, Directive
|
||||
|
||||
|
||||
class Program(Node):
|
||||
"""A complete program source tree."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], body: List[Union[Directive, Statement]]
|
||||
):
|
||||
super().__init__("Program", loc)
|
||||
self.body = body
|
|
@ -0,0 +1,158 @@
|
|||
"""The module of AST nodes for statements."""
|
||||
|
||||
from typing import List
|
||||
|
||||
from . import *
|
||||
from .expressions import Expression
|
||||
from .literals import Literal
|
||||
from .identifiers import Identifier
|
||||
from .declarations import VariableDeclaration
|
||||
from .patterns import Pattern
|
||||
|
||||
|
||||
class Statement(Node):
|
||||
"""Any statement."""
|
||||
|
||||
def __init__(self, node_type: str, loc: Optional[SourceLocation]):
|
||||
super().__init__(node_type, loc)
|
||||
|
||||
|
||||
class EmptyStatement(Statement):
|
||||
"""An empty statement, i.e., a solitary semicolon."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation]):
|
||||
super().__init__("EmptyStatement", loc)
|
||||
|
||||
|
||||
class BlockStatement(Statement):
|
||||
"""A block statement, i.e., a sequence of statements surrounded by braces."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], body: List[Statement]):
|
||||
super().__init__("BlockStatement", loc)
|
||||
self.body = body
|
||||
|
||||
|
||||
class ExpressionStatement(Statement):
|
||||
"""An expression statement, i.e., a statement consisting of a single expression."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], expression: Expression):
|
||||
super().__init__("ExpressionStatement", loc)
|
||||
self.expression = expression
|
||||
|
||||
|
||||
class Directive(Node):
|
||||
"""A directive from the directive prologue of a script or function. The `directive` property is the raw string
|
||||
source of the directive without quotes.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], expression: Literal, directive: str
|
||||
):
|
||||
super().__init__("Directive", loc)
|
||||
self.expression = expression
|
||||
self.directive = directive
|
||||
|
||||
|
||||
class FunctionBody(BlockStatement):
|
||||
"""The body of a function, which is a block statement that may begin with directives."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], body: List[Union[Directive, Statement]]
|
||||
):
|
||||
super().__init__(loc, body)
|
||||
|
||||
|
||||
class ReturnStatement(Statement):
|
||||
"""A `return` statement."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], argument: Optional[Expression]):
|
||||
super().__init__("ReturnStatement", loc)
|
||||
self.argument = argument
|
||||
|
||||
|
||||
class BreakStatement(Statement):
|
||||
"""A `break` statement."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], label: Optional[Identifier]):
|
||||
super().__init__("BreakStatement", loc)
|
||||
self.label = label
|
||||
|
||||
|
||||
class ContinueStatement(Statement):
|
||||
"""A `continue` statement."""
|
||||
|
||||
def __init__(self, loc: Optional[SourceLocation], label: Optional[Identifier]):
|
||||
super().__init__("ContinueStatement", loc)
|
||||
self.label = label
|
||||
|
||||
|
||||
class IfStatement(Statement):
|
||||
"""An `if` statement."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
test: Expression,
|
||||
consequent: Statement,
|
||||
alternate: Optional[Statement],
|
||||
):
|
||||
super().__init__("IfStatement", loc)
|
||||
self.test = test
|
||||
self.consequent = consequent
|
||||
self.alternate = alternate
|
||||
|
||||
|
||||
class WhileStatement(Statement):
|
||||
"""A `while` statement."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], test: Expression, body: Statement
|
||||
):
|
||||
super().__init__("WhileStatement", loc)
|
||||
self.test = test
|
||||
self.body = body
|
||||
|
||||
|
||||
class DoWhileStatement(Statement):
|
||||
"""A `do`/`while` statement."""
|
||||
|
||||
def __init__(
|
||||
self, loc: Optional[SourceLocation], body: Statement, test: Expression
|
||||
):
|
||||
super().__init__("DoWhileStatement", loc)
|
||||
self.body = body
|
||||
self.test = test
|
||||
|
||||
|
||||
class ForStatement(Statement):
|
||||
"""A `for` statement."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
init: Union[VariableDeclaration, Expression, None],
|
||||
test: Optional[Expression],
|
||||
update: Optional[Expression],
|
||||
body: Statement,
|
||||
):
|
||||
super().__init__("ForStatement", loc)
|
||||
self.init = init
|
||||
self.test = test
|
||||
self.update = update
|
||||
self.body = body
|
||||
|
||||
|
||||
class ForInStatement(Statement):
|
||||
"""A `for`/`in` statement."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
loc: Optional[SourceLocation],
|
||||
left: Union[VariableDeclaration, Pattern],
|
||||
right: Expression,
|
||||
body: Statement,
|
||||
):
|
||||
super().__init__("ForInStatement", loc)
|
||||
self.left = left
|
||||
self.right = right
|
||||
self.body = body
|
|
@ -0,0 +1,12 @@
|
|||
from lex import JavaScriptParserVisitor, JavaScriptParser
|
||||
import ast.nodes
|
||||
|
||||
JSBaseVisitor = JavaScriptParserVisitor.JavaScriptParserVisitor
|
||||
JSParser = JavaScriptParser.JavaScriptParser
|
||||
|
||||
|
||||
class JSASTVisitor(JSBaseVisitor):
|
||||
def visitVariableDeclarationList(
|
||||
self, ctx: JSParser.VariableDeclarationListContext
|
||||
):
|
||||
pass
|
Loading…
Reference in New Issue