Implement ES5 part of JavaScript AST

master
Yury Kurlykov 2020-04-26 23:10:26 +10:00
parent 124d299d23
commit dc7502aa57
Signed by: t1meshift
GPG Key ID: B133F3167ABF94D8
12 changed files with 1151 additions and 0 deletions

View File

@ -0,0 +1,3 @@
"""AST module."""
from . import nodes, visitors

View File

@ -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."""

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = "&&"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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