Last active
December 23, 2018 04:38
-
-
Save reverofevil/255e0de2b2629145aa85e8f94e3e61b5 to your computer and use it in GitHub Desktop.
Attempt at proper Mozilla AST typings for ES6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// if you've found this in Google, take a look into https://github.com/babel/babel/tree/master/packages/babel-types first | |
export type Node = AssignmentProperty | |
| CatchClause | |
| ClassBody | |
| ExportAllDeclaration | |
| ExportDefaultDeclaration | |
| ExportNamedDeclaration | |
| Expression | |
| Identifier | |
| ImportDeclaration | |
| Literal | |
| MethodDefinition | |
| Pattern | |
| Program | |
| Property | |
| SpreadElement | |
| Statement | |
| Super | |
| SwitchCase | |
| TemplateElement | |
| VariableDeclarator; | |
export type Statement = BlockStatement | |
| BreakStatement | |
| ContinueStatement | |
| DebuggerStatement | |
| Declaration | |
| DoWhileStatement | |
| EmptyStatement | |
| ExpressionStatement | |
| ForInStatement | |
| ForOfStatement | |
| ForStatement | |
| IfStatement | |
| LabeledStatement | |
| ReturnStatement | |
| SwitchStatement | |
| ThrowStatement | |
| TryStatement | |
| WhileStatement | |
| WithStatement; | |
export type Declaration = ClassDeclaration | |
| FunctionDeclaration | |
| VariableDeclaration; | |
export type Expression = ArrayExpression | |
| ArrowFunctionExpression | |
| AssignmentExpression | |
| BinaryExpression | |
| CallExpression | |
| ClassExpression | |
| ConditionalExpression | |
| FunctionExpression | |
| Identifier | |
| Literal | |
| LogicalExpression | |
| MemberExpression | |
| MetaProperty | |
| NewExpression | |
| ObjectExpression | |
| SequenceExpression | |
| TaggedTemplateExpression | |
| TemplateLiteral | |
| ThisExpression | |
| UnaryExpression | |
| UpdateExpression | |
| YieldExpression; | |
export type Pattern = ArrayPattern | |
| AssignmentPattern | |
| Identifier | |
| MemberExpression | |
| ObjectPattern | |
| RestElement; | |
export interface SourceLocation { | |
source: string | null; | |
start: Position; | |
end: Position; | |
} | |
export const mkSourceLocation = ({ | |
source, | |
start, | |
end, | |
}: { | |
source: string | null, | |
start: Position, | |
end: Position, | |
}): SourceLocation => ({ | |
source, | |
start, | |
end, | |
}); | |
export interface Position { | |
line: number; | |
column: number; | |
} | |
export const mkPosition = ({ | |
line, | |
column, | |
}: { | |
line: number, | |
column: number, | |
}): Position => ({ | |
line, | |
column, | |
}); | |
export interface Program { | |
type: "Program"; | |
body: Statement[]; | |
sourceType: "script" | "module"; | |
} | |
export const mkProgram = ({ | |
body, | |
sourceType, | |
}: { | |
body: Statement[], | |
sourceType: "script" | "module", | |
}): Program => ({ | |
type: "Program", | |
body, | |
sourceType, | |
}); | |
export interface EmptyStatement { | |
type: "EmptyStatement"; | |
} | |
export const mkEmptyS = (): EmptyStatement => ({ | |
type: "EmptyStatement", | |
}); | |
export interface BlockStatement { | |
type: "BlockStatement"; | |
body: Statement[]; | |
} | |
export const mkBlockS = ({ | |
body, | |
}: { | |
body: Statement[], | |
}): BlockStatement => ({ | |
type: "BlockStatement", | |
body, | |
}); | |
export interface ExpressionStatement { | |
type: "ExpressionStatement"; | |
expression: Expression; | |
} | |
export const mkES = ({ | |
expression, | |
}: { | |
expression: Expression, | |
}): ExpressionStatement => ({ | |
type: "ExpressionStatement", | |
expression, | |
}); | |
export interface IfStatement { | |
type: "IfStatement"; | |
test: Expression; | |
consequent: Statement; | |
alternate: Statement | null; | |
} | |
export const mkIfS = ({ | |
test, | |
consequent, | |
alternate, | |
}: { | |
test: Expression, | |
consequent: Statement, | |
alternate: Statement | null, | |
}): IfStatement => ({ | |
type: "IfStatement", | |
test, | |
consequent, | |
alternate, | |
}); | |
export interface LabeledStatement { | |
type: "LabeledStatement"; | |
label: Identifier; | |
body: Statement; | |
} | |
export const mkLabeledS = ({ | |
label, | |
body, | |
}: { | |
label: Identifier, | |
body: Statement, | |
}): LabeledStatement => ({ | |
type: "LabeledStatement", | |
label, | |
body, | |
}); | |
export interface BreakStatement { | |
type: "BreakStatement"; | |
label: Identifier | null; | |
} | |
export const mkBreakS = ({ | |
label, | |
}: { | |
label: Identifier | null, | |
}): BreakStatement => ({ | |
type: "BreakStatement", | |
label, | |
}); | |
export interface ContinueStatement { | |
type: "ContinueStatement"; | |
label: Identifier | null; | |
} | |
export const mkContinueS = ({ | |
label, | |
}: { | |
label: Identifier | null, | |
}): ContinueStatement => ({ | |
type: "ContinueStatement", | |
label, | |
}); | |
export interface WithStatement { | |
type: "WithStatement"; | |
object: Expression; | |
body: Statement; | |
} | |
export const mkWithS = ({ | |
object, | |
body, | |
}: { | |
object: Expression, | |
body: Statement, | |
}): WithStatement => ({ | |
type: "WithStatement", | |
object, | |
body, | |
}); | |
export interface SwitchStatement { | |
type: "SwitchStatement"; | |
discriminant: Expression; | |
cases: SwitchCase[]; | |
lexical: false; | |
} | |
export const mkSwitchS = ({ | |
discriminant, | |
cases, | |
}: { | |
discriminant: Expression, | |
cases: SwitchCase[], | |
}): SwitchStatement => ({ | |
type: "SwitchStatement", | |
discriminant, | |
cases, | |
lexical: false, | |
}); | |
export interface ReturnStatement { | |
type: "ReturnStatement"; | |
argument: Expression | null; | |
} | |
export const mkReturnS = ({ | |
argument, | |
}: { | |
argument: Expression | null, | |
}): ReturnStatement => ({ | |
type: "ReturnStatement", | |
argument, | |
}); | |
export interface ThrowStatement { | |
type: "ThrowStatement"; | |
argument: Expression; | |
} | |
export const mkThrowS = ({ | |
argument, | |
}: { | |
argument: Expression, | |
}): ThrowStatement => ({ | |
type: "ThrowStatement", | |
argument, | |
}); | |
export interface TryStatement { | |
type: "TryStatement"; | |
block: BlockStatement; | |
handler: CatchClause | null; | |
finalizer: BlockStatement | null; | |
} | |
export const mkTryS = ({ | |
block, | |
handler, | |
finalizer, | |
}: { | |
block: BlockStatement, | |
handler: CatchClause | null, | |
finalizer: BlockStatement | null, | |
}): TryStatement => ({ | |
type: "TryStatement", | |
block, | |
handler, | |
finalizer, | |
}); | |
export interface WhileStatement { | |
type: "WhileStatement"; | |
test: Expression; | |
body: Statement; | |
} | |
export const mkWhileS = ({ | |
test, | |
body, | |
}: { | |
test: Expression, | |
body: Statement, | |
}): WhileStatement => ({ | |
type: "WhileStatement", | |
test, | |
body, | |
}); | |
export interface DoWhileStatement { | |
type: "DoWhileStatement"; | |
body: Statement; | |
test: Expression; | |
} | |
export const mkDoWhileS = ({ | |
body, | |
test, | |
}: { | |
body: Statement, | |
test: Expression, | |
}): DoWhileStatement => ({ | |
type: "DoWhileStatement", | |
body, | |
test, | |
}); | |
export interface ForStatement { | |
type: "ForStatement"; | |
init: VariableDeclaration | Expression | null; | |
test: Expression | null; | |
update: Expression | null; | |
body: Statement; | |
} | |
export const mkForS = ({ | |
init, | |
test, | |
update, | |
body, | |
}: { | |
init: VariableDeclaration | Expression | null, | |
test: Expression | null, | |
update: Expression | null, | |
body: Statement, | |
}): ForStatement => ({ | |
type: "ForStatement", | |
init, | |
test, | |
update, | |
body, | |
}); | |
export interface ForInStatement extends AbstractForStatement { | |
type: "ForInStatement"; | |
} | |
export const mkForInS = ({ | |
left, | |
right, | |
body, | |
}: { | |
left: VariableDeclaration | Expression, | |
right: Expression, | |
body: Statement, | |
}): ForInStatement => ({ | |
left, | |
right, | |
body, | |
type: "ForInStatement", | |
}); | |
export interface DebuggerStatement { | |
type: "DebuggerStatement"; | |
} | |
export const mkDebuggerS = (): DebuggerStatement => ({ | |
type: "DebuggerStatement", | |
}); | |
export interface FunctionDeclaration extends AbstractFunction { | |
type: "FunctionDeclaration"; | |
id: Identifier; | |
body: BlockStatement; | |
} | |
export const mkFunctionDeclaration = ({ | |
id, | |
params, | |
generator, | |
body, | |
}: { | |
id: Identifier, | |
params: Pattern[], | |
generator: boolean, | |
body: BlockStatement, | |
}): FunctionDeclaration => ({ | |
id, | |
params, | |
generator, | |
type: "FunctionDeclaration", | |
body, | |
}); | |
export interface VariableDeclaration { | |
type: "VariableDeclaration"; | |
declarations: VariableDeclarator[]; | |
kind: "var" | "let" | "const"; | |
} | |
export const mkVariableDeclaration = ({ | |
declarations, | |
kind, | |
}: { | |
declarations: VariableDeclarator[], | |
kind: "var" | "let" | "const", | |
}): VariableDeclaration => ({ | |
type: "VariableDeclaration", | |
declarations, | |
kind, | |
}); | |
export interface VariableDeclarator { | |
type: "VariableDeclarator"; | |
id: Pattern; | |
init: Expression | null; | |
} | |
export const mkVariableDeclarator = ({ | |
id, | |
init, | |
}: { | |
id: Pattern, | |
init: Expression | null, | |
}): VariableDeclarator => ({ | |
type: "VariableDeclarator", | |
id, | |
init, | |
}); | |
export interface ThisExpression { | |
type: "ThisExpression"; | |
} | |
export const mkThisE = (): ThisExpression => ({ | |
type: "ThisExpression", | |
}); | |
export interface ArrayExpression { | |
type: "ArrayExpression"; | |
elements: (Expression | SpreadElement | null)[]; | |
} | |
export const mkArrayE = ({ | |
elements, | |
}: { | |
elements: (Expression | SpreadElement | null)[], | |
}): ArrayExpression => ({ | |
type: "ArrayExpression", | |
elements, | |
}); | |
export interface ObjectExpression { | |
type: "ObjectExpression"; | |
properties: Property[]; | |
} | |
export const mkObjectE = ({ | |
properties, | |
}: { | |
properties: Property[], | |
}): ObjectExpression => ({ | |
type: "ObjectExpression", | |
properties, | |
}); | |
export interface Property extends AbstractProperty { | |
type: "Property"; | |
value: Expression; | |
} | |
export const mkProperty = ({ | |
key, | |
kind, | |
method, | |
shorthand, | |
computed, | |
value, | |
}: { | |
key: Expression, | |
kind: "init" | "get" | "set", | |
method: boolean, | |
shorthand: boolean, | |
computed: boolean, | |
value: Expression, | |
}): Property => ({ | |
key, | |
kind, | |
method, | |
shorthand, | |
computed, | |
type: "Property", | |
value, | |
}); | |
export interface FunctionExpression extends AbstractFunction { | |
type: "FunctionExpression"; | |
body: BlockStatement; | |
} | |
export const mkFunctionE = ({ | |
id, | |
params, | |
generator, | |
body, | |
}: { | |
id: Identifier | null, | |
params: Pattern[], | |
generator: boolean, | |
body: BlockStatement, | |
}): FunctionExpression => ({ | |
id, | |
params, | |
generator, | |
type: "FunctionExpression", | |
body, | |
}); | |
export interface SequenceExpression { | |
type: "SequenceExpression"; | |
expressions: Expression[]; | |
} | |
export const mkSequenceE = ({ | |
expressions, | |
}: { | |
expressions: Expression[], | |
}): SequenceExpression => ({ | |
type: "SequenceExpression", | |
expressions, | |
}); | |
export interface UnaryExpression { | |
type: "UnaryExpression"; | |
operator: UnaryOperator; | |
prefix: boolean; | |
argument: Expression; | |
} | |
export const mkUnaryE = ({ | |
operator, | |
prefix, | |
argument, | |
}: { | |
operator: UnaryOperator, | |
prefix: boolean, | |
argument: Expression, | |
}): UnaryExpression => ({ | |
type: "UnaryExpression", | |
operator, | |
prefix, | |
argument, | |
}); | |
export interface BinaryExpression { | |
type: "BinaryExpression"; | |
operator: BinaryOperator; | |
left: Expression; | |
right: Expression; | |
} | |
export const mkBinaryE = ({ | |
operator, | |
left, | |
right, | |
}: { | |
operator: BinaryOperator, | |
left: Expression, | |
right: Expression, | |
}): BinaryExpression => ({ | |
type: "BinaryExpression", | |
operator, | |
left, | |
right, | |
}); | |
export interface AssignmentExpression { | |
type: "AssignmentExpression"; | |
operator: AssignmentOperator; | |
left: Pattern | MemberExpression; | |
right: Expression; | |
} | |
export const mkAssignmentE = ({ | |
operator, | |
left, | |
right, | |
}: { | |
operator: AssignmentOperator, | |
left: Pattern | MemberExpression, | |
right: Expression, | |
}): AssignmentExpression => ({ | |
type: "AssignmentExpression", | |
operator, | |
left, | |
right, | |
}); | |
export interface UpdateExpression { | |
type: "UpdateExpression"; | |
operator: UpdateOperator; | |
argument: Expression; | |
prefix: boolean; | |
} | |
export const mkUpdateE = ({ | |
operator, | |
argument, | |
prefix, | |
}: { | |
operator: UpdateOperator, | |
argument: Expression, | |
prefix: boolean, | |
}): UpdateExpression => ({ | |
type: "UpdateExpression", | |
operator, | |
argument, | |
prefix, | |
}); | |
export interface LogicalExpression { | |
type: "LogicalExpression"; | |
operator: LogicalOperator; | |
left: Expression; | |
right: Expression; | |
} | |
export const mkLogicalE = ({ | |
operator, | |
left, | |
right, | |
}: { | |
operator: LogicalOperator, | |
left: Expression, | |
right: Expression, | |
}): LogicalExpression => ({ | |
type: "LogicalExpression", | |
operator, | |
left, | |
right, | |
}); | |
export interface ConditionalExpression { | |
type: "ConditionalExpression"; | |
test: Expression; | |
alternate: Expression; | |
consequent: Expression; | |
} | |
export const mkConditionalE = ({ | |
test, | |
alternate, | |
consequent, | |
}: { | |
test: Expression, | |
alternate: Expression, | |
consequent: Expression, | |
}): ConditionalExpression => ({ | |
type: "ConditionalExpression", | |
test, | |
alternate, | |
consequent, | |
}); | |
export interface CallExpression extends AbstractCallExpression { | |
type: "CallExpression"; | |
} | |
export const mkCallE = ({ | |
callee, | |
args, | |
}: { | |
callee: Expression | Super, | |
args: (Expression | SpreadElement)[], | |
}): CallExpression => ({ | |
callee, | |
"arguments": args, | |
type: "CallExpression", | |
}); | |
export interface NewExpression extends AbstractCallExpression { | |
type: "NewExpression"; | |
} | |
export const mkNewE = ({ | |
callee, | |
args, | |
}: { | |
callee: Expression | Super, | |
args: (Expression | SpreadElement)[], | |
}): NewExpression => ({ | |
callee, | |
"arguments": args, | |
type: "NewExpression", | |
}); | |
export interface MemberExpression { | |
type: "MemberExpression"; | |
object: Expression | Super; | |
property: Expression; | |
computed: boolean; | |
} | |
export const mkMemberE = ({ | |
object, | |
property, | |
computed, | |
}: { | |
object: Expression | Super, | |
property: Expression, | |
computed: boolean, | |
}): MemberExpression => ({ | |
type: "MemberExpression", | |
object, | |
property, | |
computed, | |
}); | |
export interface SwitchCase { | |
type: "SwitchCase"; | |
test: Expression | null; | |
consequent: Statement[]; | |
} | |
export const mkSwitchCase = ({ | |
test, | |
consequent, | |
}: { | |
test: Expression | null, | |
consequent: Statement[], | |
}): SwitchCase => ({ | |
type: "SwitchCase", | |
test, | |
consequent, | |
}); | |
export interface CatchClause { | |
type: "CatchClause"; | |
param: Pattern; | |
guard: null; | |
body: BlockStatement; | |
} | |
export const mkCatchClause = ({ | |
param, | |
body, | |
}: { | |
param: Pattern, | |
body: BlockStatement, | |
}): CatchClause => ({ | |
type: "CatchClause", | |
param, | |
guard: null, | |
body, | |
}); | |
export interface Identifier { | |
type: "Identifier"; | |
name: string; | |
} | |
export const mkIdentifier = ({ | |
name, | |
}: { | |
name: string, | |
}): Identifier => ({ | |
type: "Identifier", | |
name, | |
}); | |
export interface Literal { | |
type: "Literal"; | |
value: string | boolean | null | number | RegExp; | |
} | |
export const mkLiteral = ({ | |
value, | |
}: { | |
value: string | boolean | null | number | RegExp, | |
}): Literal => ({ | |
type: "Literal", | |
value, | |
}); | |
export interface RegexLiteral extends Literal { | |
regex: { | |
pattern: string; | |
flags: string; | |
}; | |
} | |
export const mkRegexLiteral = ({ | |
value, | |
regex, | |
}: { | |
value: string | boolean | null | number | RegExp, | |
regex: { | |
pattern: string; | |
flags: string; | |
}, | |
}): RegexLiteral => ({ | |
type: "Literal", | |
value, | |
regex, | |
}); | |
export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"; | |
export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof"; | |
export type LogicalOperator = "||" | "&&"; | |
export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&="; | |
export type UpdateOperator = "++" | "--"; | |
export interface ForOfStatement extends AbstractForStatement { | |
type: "ForOfStatement"; | |
} | |
export const mkForOfS = ({ | |
left, | |
right, | |
body, | |
}: { | |
left: VariableDeclaration | Expression, | |
right: Expression, | |
body: Statement, | |
}): ForOfStatement => ({ | |
left, | |
right, | |
body, | |
type: "ForOfStatement", | |
}); | |
export interface Super { | |
type: "Super"; | |
} | |
export const mkSuper = (): Super => ({ | |
type: "Super", | |
}); | |
export interface SpreadElement { | |
type: "SpreadElement"; | |
argument: Expression; | |
} | |
export const mkSpreadElement = ({ | |
argument, | |
}: { | |
argument: Expression, | |
}): SpreadElement => ({ | |
type: "SpreadElement", | |
argument, | |
}); | |
export interface ArrowFunctionExpression extends AbstractFunction { | |
type: "ArrowFunctionExpression"; | |
body: BlockStatement | Expression; | |
expression: boolean; | |
} | |
export const mkArrowFunctionE = ({ | |
id, | |
params, | |
generator, | |
body, | |
expression, | |
}: { | |
id: Identifier | null, | |
params: Pattern[], | |
generator: boolean, | |
body: BlockStatement | Expression, | |
expression: boolean, | |
}): ArrowFunctionExpression => ({ | |
id, | |
params, | |
generator, | |
type: "ArrowFunctionExpression", | |
body, | |
expression, | |
}); | |
export interface YieldExpression { | |
type: "YieldExpression"; | |
argument: Expression | null; | |
} | |
export const mkYieldE = ({ | |
argument, | |
}: { | |
argument: Expression | null, | |
}): YieldExpression => ({ | |
type: "YieldExpression", | |
argument, | |
}); | |
export interface TemplateLiteral { | |
type: "TemplateLiteral"; | |
quasis: TemplateElement[]; | |
expressions: Expression[]; | |
} | |
export const mkTemplateLiteral = ({ | |
quasis, | |
expressions, | |
}: { | |
quasis: TemplateElement[], | |
expressions: Expression[], | |
}): TemplateLiteral => ({ | |
type: "TemplateLiteral", | |
quasis, | |
expressions, | |
}); | |
export interface TaggedTemplateExpression { | |
type: "TaggedTemplateExpression"; | |
tag: Expression; | |
quasi: TemplateLiteral; | |
} | |
export const mkTaggedTemplateE = ({ | |
tag, | |
quasi, | |
}: { | |
tag: Expression, | |
quasi: TemplateLiteral, | |
}): TaggedTemplateExpression => ({ | |
type: "TaggedTemplateExpression", | |
tag, | |
quasi, | |
}); | |
export interface TemplateElement { | |
type: "TemplateElement"; | |
tail: boolean; | |
value: { | |
cooked: string; | |
value: string; | |
}; | |
} | |
export const mkTemplateElement = ({ | |
tail, | |
value, | |
}: { | |
tail: boolean, | |
value: { | |
cooked: string; | |
value: string; | |
}, | |
}): TemplateElement => ({ | |
type: "TemplateElement", | |
tail, | |
value, | |
}); | |
export interface AssignmentProperty extends AbstractProperty { | |
type: "Property"; | |
value: Pattern; | |
kind: "init"; | |
method: false; | |
} | |
export const mkAssignmentProperty = ({ | |
key, | |
shorthand, | |
computed, | |
value, | |
}: { | |
key: Expression, | |
shorthand: boolean, | |
computed: boolean, | |
value: Pattern, | |
}): AssignmentProperty => ({ | |
key, | |
kind: "init", | |
method: false, | |
shorthand, | |
computed, | |
type: "Property", | |
value, | |
}); | |
export interface ObjectPattern { | |
type: "ObjectPattern"; | |
properties: AssignmentProperty[]; | |
} | |
export const mkObjectPattern = ({ | |
properties, | |
}: { | |
properties: AssignmentProperty[], | |
}): ObjectPattern => ({ | |
type: "ObjectPattern", | |
properties, | |
}); | |
export interface ArrayPattern { | |
type: "ArrayPattern"; | |
elements: (Pattern | null)[]; | |
} | |
export const mkArrayPattern = ({ | |
elements, | |
}: { | |
elements: (Pattern | null)[], | |
}): ArrayPattern => ({ | |
type: "ArrayPattern", | |
elements, | |
}); | |
export interface RestElement { | |
type: "RestElement"; | |
argument: Pattern; | |
} | |
export const mkRestElement = ({ | |
argument, | |
}: { | |
argument: Pattern, | |
}): RestElement => ({ | |
type: "RestElement", | |
argument, | |
}); | |
export interface AssignmentPattern { | |
type: "AssignmentPattern"; | |
left: Pattern; | |
right: Expression; | |
} | |
export const mkAssignmentPattern = ({ | |
left, | |
right, | |
}: { | |
left: Pattern, | |
right: Expression, | |
}): AssignmentPattern => ({ | |
type: "AssignmentPattern", | |
left, | |
right, | |
}); | |
export interface ClassBody { | |
type: "ClassBody"; | |
body: MethodDefinition[]; | |
} | |
export const mkClassBody = ({ | |
body, | |
}: { | |
body: MethodDefinition[], | |
}): ClassBody => ({ | |
type: "ClassBody", | |
body, | |
}); | |
export interface MethodDefinition { | |
type: "MethodDefinition"; | |
key: Identifier; | |
value: FunctionExpression; | |
kind: "constructor" | "method" | "get" | "set"; | |
computed: boolean; | |
static: boolean; | |
} | |
export const mkMethodDefinition = ({ | |
key, | |
value, | |
kind, | |
computed, | |
isStatic, | |
}: { | |
key: Identifier, | |
value: FunctionExpression, | |
kind: "constructor" | "method" | "get" | "set", | |
computed: boolean, | |
isStatic: boolean, | |
}): MethodDefinition => ({ | |
type: "MethodDefinition", | |
key, | |
value, | |
kind, | |
computed, | |
"static": isStatic, | |
}); | |
export interface ClassDeclaration extends AbstractClass { | |
type: "ClassDeclaration"; | |
id: Identifier; | |
} | |
export const mkClassDeclaration = ({ | |
id, | |
superClass, | |
body, | |
}: { | |
id: Identifier, | |
superClass: Expression, | |
body: ClassBody, | |
}): ClassDeclaration => ({ | |
id, | |
superClass, | |
body, | |
type: "ClassDeclaration", | |
}); | |
export interface ClassExpression extends AbstractClass { | |
type: "ClassExpression"; | |
} | |
export const mkClassE = ({ | |
id, | |
superClass, | |
body, | |
}: { | |
id: Identifier | null, | |
superClass: Expression, | |
body: ClassBody, | |
}): ClassExpression => ({ | |
id, | |
superClass, | |
body, | |
type: "ClassExpression", | |
}); | |
export interface MetaProperty { | |
type: "MetaProperty"; | |
meta: Identifier; | |
property: Identifier; | |
} | |
export const mkMetaProperty = ({ | |
meta, | |
property, | |
}: { | |
meta: Identifier, | |
property: Identifier, | |
}): MetaProperty => ({ | |
type: "MetaProperty", | |
meta, | |
property, | |
}); | |
export interface ImportDeclaration { | |
type: "ImportDeclaration"; | |
specifiers: (ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier)[]; | |
source: Literal; | |
} | |
export const mkImportDeclaration = ({ | |
specifiers, | |
source, | |
}: { | |
specifiers: (ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier)[], | |
source: Literal, | |
}): ImportDeclaration => ({ | |
type: "ImportDeclaration", | |
specifiers, | |
source, | |
}); | |
export interface ImportSpecifier { | |
type: "ImportSpecifier"; | |
imported: Identifier; | |
local: Identifier; | |
} | |
export const mkImportSpecifier = ({ | |
imported, | |
local, | |
}: { | |
imported: Identifier, | |
local: Identifier, | |
}): ImportSpecifier => ({ | |
type: "ImportSpecifier", | |
imported, | |
local, | |
}); | |
export interface ImportDefaultSpecifier { | |
type: "ImportDefaultSpecifier"; | |
local: Identifier; | |
} | |
export const mkImportDefaultSpecifier = ({ | |
local, | |
}: { | |
local: Identifier, | |
}): ImportDefaultSpecifier => ({ | |
type: "ImportDefaultSpecifier", | |
local, | |
}); | |
export interface ImportNamespaceSpecifier { | |
type: "ImportNamespaceSpecifier"; | |
local: Identifier; | |
} | |
export const mkImportNamespaceSpecifier = ({ | |
local, | |
}: { | |
local: Identifier, | |
}): ImportNamespaceSpecifier => ({ | |
type: "ImportNamespaceSpecifier", | |
local, | |
}); | |
export interface ExportNamedDeclaration { | |
type: "ExportNamedDeclaration"; | |
declaration: Declaration | null; | |
specifiers: ExportSpecifier[]; | |
source: Literal | null; | |
} | |
export const mkExportNamedDeclaration = ({ | |
declaration, | |
specifiers, | |
source, | |
}: { | |
declaration: Declaration | null, | |
specifiers: ExportSpecifier[], | |
source: Literal | null, | |
}): ExportNamedDeclaration => ({ | |
type: "ExportNamedDeclaration", | |
declaration, | |
specifiers, | |
source, | |
}); | |
export interface ExportSpecifier { | |
type: "ExportSpecifier"; | |
exported: Identifier; | |
local: Identifier; | |
} | |
export const mkExportSpecifier = ({ | |
exported, | |
local, | |
}: { | |
exported: Identifier, | |
local: Identifier, | |
}): ExportSpecifier => ({ | |
type: "ExportSpecifier", | |
exported, | |
local, | |
}); | |
export interface ExportDefaultDeclaration { | |
type: "ExportDefaultDeclaration"; | |
declaration: Declaration | Expression; | |
} | |
export const mkExportDefaultDeclaration = ({ | |
declaration, | |
}: { | |
declaration: Declaration | Expression, | |
}): ExportDefaultDeclaration => ({ | |
type: "ExportDefaultDeclaration", | |
declaration, | |
}); | |
export interface ExportAllDeclaration { | |
type: "ExportAllDeclaration"; | |
source: Literal; | |
} | |
export const mkExportAllDeclaration = ({ | |
source, | |
}: { | |
source: Literal, | |
}): ExportAllDeclaration => ({ | |
type: "ExportAllDeclaration", | |
source, | |
}); | |
export interface AbstractClass { | |
id: Identifier | null; | |
superClass: Expression; | |
body: ClassBody; | |
} | |
export interface AbstractFunction { | |
id: Identifier | null; | |
params: Pattern[]; | |
generator: boolean; | |
} | |
export interface AbstractForStatement { | |
left: VariableDeclaration | Expression; | |
right: Expression; | |
body: Statement; | |
} | |
export interface AbstractProperty { | |
key: Expression; | |
kind: "init" | "get" | "set"; | |
method: boolean; | |
shorthand: boolean; | |
computed: boolean; | |
} | |
export interface AbstractCallExpression { | |
callee: Expression | Super; | |
arguments: (Expression | SpreadElement)[]; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const esSchema = require('estree-formal/formal-data/es6.json'); | |
const clone = o => JSON.parse(JSON.stringify(o)); | |
const replace = (a, b, c) => { | |
a.forEach((x, i) => { | |
if (x === b) a[i] = c; | |
}); | |
return a; | |
}; | |
delete esSchema.Node.props.loc; | |
delete esSchema.Node.props.type; | |
const body = esSchema.Function.props.body; | |
delete esSchema.Function.props.body; | |
esSchema.AbstractClass = esSchema.Class; | |
esSchema.AbstractClass.base = []; | |
delete esSchema.Class; | |
esSchema.ClassExpression.base = ['Expression', 'AbstractClass']; | |
esSchema.ClassDeclaration.base = ['Declaration', 'AbstractClass']; | |
esSchema.AbstractFunction = clone(esSchema.Function); | |
esSchema.AbstractFunction.base = []; | |
delete esSchema.Function; | |
replace(esSchema.FunctionDeclaration.base, 'Function', 'AbstractFunction'); | |
esSchema.FunctionDeclaration.props.body = body; | |
replace(esSchema.FunctionExpression.base, 'Function', 'AbstractFunction'); | |
esSchema.FunctionExpression.props.body = body; | |
replace(esSchema.ArrowFunctionExpression.base, 'Function', 'AbstractFunction'); | |
esSchema.AbstractForStatement = clone(esSchema.ForInStatement); | |
esSchema.AbstractForStatement.base = []; | |
delete esSchema.AbstractForStatement.props.type; | |
esSchema.ForInStatement.base = ['Statement', 'AbstractForStatement']; | |
esSchema.ForInStatement.props = {type: esSchema.ForInStatement.props.type}; | |
esSchema.ForOfStatement.base = ['Statement', 'AbstractForStatement']; | |
esSchema.AbstractProperty = clone(esSchema.Property); | |
esSchema.AbstractProperty.base = []; | |
delete esSchema.AbstractProperty.props.type; | |
delete esSchema.AbstractProperty.props.value; | |
esSchema.AssignmentProperty.base = ['Node', 'AbstractProperty']; | |
esSchema.Property.base = ['Node', 'AbstractProperty']; | |
esSchema.Property.props = { | |
type: esSchema.Property.props.type, | |
value: esSchema.Property.props.value, | |
}; | |
esSchema.AbstractCallExpression = clone(esSchema.CallExpression); | |
esSchema.AbstractCallExpression.base = []; | |
delete esSchema.AbstractCallExpression.props.type; | |
esSchema.NewExpression.base = ['Expression', 'AbstractCallExpression']; | |
esSchema.CallExpression.base = ['Expression', 'AbstractCallExpression']; | |
esSchema.CallExpression.props = {type: esSchema.CallExpression.props.type}; | |
const badTypes = { | |
Node: ['Node'], | |
Statement: ['Statement'], | |
Declaration: ['Declaration'], | |
Expression: ['Expression'], | |
Pattern: ['Pattern'], | |
}; | |
const withType = { | |
Node: {Statement: 1, Expression: 1, Pattern: 1}, | |
Statement: {Declaration: 1}, | |
Declaration: {}, | |
Expression: {}, | |
Pattern: {}, | |
}; | |
const resolveProps = ({kind, props, base}, ruleName) => { | |
if (kind !== 'interface') { | |
throw new Error('WUT2'); | |
} | |
const baseProps = base.map(base => resolveProps(esSchema[base], base)) | |
baseProps.push(props); | |
return baseProps.reduce((res, props) => { | |
const out = {...res, ...props}; | |
return out; | |
}, {}); | |
}; | |
const printType = ({kind, name, value, types, base, items}, depth) => { | |
switch (kind) { | |
case 'reference': | |
return name; | |
case 'literal': | |
return JSON.stringify(value); | |
case 'union': | |
return types.map(type => printType(type, depth)).join(' | '); | |
case 'array': | |
return base.kind === 'reference' | |
? `${printType(base, depth)}[]` | |
: `(${printType(base, depth)})[]`; | |
case 'object': | |
return printObj(items, depth + 1); | |
default: | |
throw new Error(); | |
} | |
}; | |
const printObj = (props, depth) => { | |
const space = new Array(depth + 1).join('\t'); | |
const space1 = new Array(depth).join('\t'); | |
const propsStr = Object.keys(props).map(name => { | |
const type = printType(props[name], depth); | |
return `${space}${name}: ${type};\n`; | |
}).join(''); | |
return `{\n${propsStr}${space1}}`; | |
}; | |
const RENAMES = { | |
'arguments': 'args', | |
'static': 'isStatic', | |
}; | |
const res = []; | |
for (const ruleName of Object.keys(esSchema)) { | |
const rule = esSchema[ruleName]; | |
if (rule.kind === 'enum') { | |
const values = rule.values.map(value => JSON.stringify(value)); | |
res.push(`export type ${ruleName} = ${values.join(' | ')};\n`); | |
} else if (rule.kind === 'interface') { | |
if (badTypes[ruleName]) | |
continue; | |
rule.base.map(base => (badTypes[base] || []).map(base => {withType[base][ruleName] = true})); | |
rule.base = rule.base.filter(base => !badTypes[base]); | |
const allProps = resolveProps(rule, ruleName); | |
const props = clone(allProps); | |
Object.keys(props).forEach(key => {if (props[key].kind === 'literal') delete props[key] }); | |
const extend = rule.base.length > 0 ? ` extends ${rule.base.join(', ')}` : ''; | |
res.push(`export interface ${ruleName}${extend} ${printObj(rule.props, 1)}\n\n`); | |
if (!ruleName.startsWith('Abstract')) { | |
const argNames = Object.keys(props) | |
.map(name => `\t${RENAMES[name] || name},\n`) | |
.join(''); | |
const propNames = Object.keys(allProps) | |
.map(name => { | |
const resName = allProps[name].kind === 'literal' | |
? `${name}: ${JSON.stringify(allProps[name].value)}` | |
: RENAMES[name] | |
? `"${name}": ${RENAMES[name]}` | |
: name; | |
return `\t${resName},\n`; | |
}) | |
.join(''); | |
const shortName = ruleName.replace('Statement', 'S').replace('Expression', 'E'); | |
const propTypes = Object.keys(props) | |
.map(name => `\t${RENAMES[name] || name}: ${printType(props[name], 1)},\n`) | |
.join(''); | |
const args = Object.keys(props).length > 0 ? `{\n${argNames}}: {\n${propTypes}}` : ''; | |
res.push(`export const mk${shortName} = (${args}): ${ruleName} => ({\n${propNames}});\n\n`); | |
} | |
} else { | |
throw new Error('WUT'); | |
} | |
} | |
for (const type of Object.keys(withType).reverse()) { | |
res.unshift(`export type ${type} = ${Object.keys(withType[type]).sort().join('\n\t| ')};\n\n`); | |
} | |
require('fs').writeFileSync('result.ts', res.join('')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment