babel/src/types.js
Andy 2541ab5fda Simplify PrivateName and ClassPrivateProperty types (#532)
* Simplify PrivateName and ClassPrivateProperty types

* ClassPrivateProperty is not a ClassMemberBase; can't be static, can't be computed
2017-05-22 13:42:32 -04:00

727 lines
17 KiB
JavaScript

// @flow
import type { Token } from "./tokenizer";
import type { SourceLocation } from "./util/location";
/*
* If making any changes to the AST, update:
* - This repository:
* - This file
* - `ast` directory
* - Babel repository:
* - packages/babel-types/src/definitions
* - packages/babel-generators/src/generators
*/
export type Comment = {
type: "CommentBlock" | "CommentLine";
value: string;
start: number;
end: number;
loc: SourceLocation;
};
export interface NodeBase {
start: number;
end: number;
loc: SourceLocation;
range: [number, number];
leadingComments?: ?Array<Comment>;
trailingComments?: ?Array<Comment>;
innerComments?: ?Array<Comment>;
extra: { [key: string]: any };
}
// Using a union type for `Node` makes type-checking too slow.
// Instead, add an index signature to allow a Node to be treated as anything.
export type Node = NodeBase & { [key: string]: any };
export type Expression = Node;
export type Statement = Node;
export type Pattern =
| Identifier
| ObjectPattern
| ArrayPattern
| RestElement
| AssignmentPattern;
export type Declaration =
| VariableDeclaration
| ClassDeclaration
| FunctionDeclaration;
export type DeclarationBase = NodeBase;
// TODO: Not in spec
export type HasDecorators = NodeBase & {
decorators?: $ReadOnlyArray<Decorator>;
};
export type Identifier = PatternBase & {
type: "Identifier";
name: string;
__clone(): Identifier;
};
export type PrivateName = NodeBase & {
type: "PrivateName";
name: string;
};
// Literals
export type Literal = RegExpLiteral | NullLiteral | StringLiteral | BooleanLiteral | NumericLiteral;
export type RegExpLiteral = NodeBase & {
type: "RegExpLiteral";
pattern: string;
flags: RegExp$flags;
};
export type NullLiteral = NodeBase & {
type: "NullLiteral";
}
export type StringLiteral = NodeBase & {
type: "StringLiteral";
value: string;
};
export type BooleanLiteral = NodeBase & {
type: "BooleanLiteral";
value: boolean;
};
export type NumericLiteral = NodeBase & {
type: "NumericLiteral";
value: number;
};
// Programs
export type BlockStatementLike = Program | BlockStatement;
export type File = NodeBase & {
type: "File";
program: Program;
comments: $ReadOnlyArray<Comment>;
tokens: $ReadOnlyArray<Token | Comment>;
};
export type Program = NodeBase & {
type: "Program";
sourceType: "script" | "module";
body: Array<Statement | ModuleDeclaration>; // TODO: $ReadOnlyArray
directives: $ReadOnlyArray<Directive>; // TODO: Not in spec
};
// Functions
export type Function =
NormalFunction | ArrowFunctionExpression | ObjectMethod | ClassMethod;
export type NormalFunction =
FunctionDeclaration | FunctionExpression;
export type FunctionBase = HasDecorators & {
id: ?Identifier;
params: $ReadOnlyArray<Pattern>;
body: BlockStatement;
generator: boolean;
async: boolean;
expression: boolean; // TODO: Not in spec
typeParameters?: ?FlowTypeParameterDeclaration; // TODO: Not in spec
returnType?: ?FlowTypeAnnotation; // TODO: Not in spec
};
// Statements
export type ExpressionStatement = NodeBase & {
type: "ExpressionStatement";
expression: Expression;
};
export type BlockStatement = NodeBase & {
type: "BlockStatement";
body: Array<Statement>; // TODO: $ReadOnlyArray
directives: $ReadOnlyArray<Directive>;
};
export type EmptyStatement = NodeBase & {
type: "EmptyStatement"
};
export type DebuggerStatement = NodeBase & {
type: "DebuggerStatement"
};
export type WithStatement = NodeBase & {
type: "WithStatement";
object: Expression;
body: Statement;
};
export type ReturnStatement = NodeBase & {
type: "ReturnStatement";
argument: ?Expression;
};
export type LabeledStatement = NodeBase & {
type: "LabeledStatement";
label: Identifier;
body: Statement;
};
export type BreakStatement = NodeBase & {
type: "BreakStatement";
label: ?Identifier;
};
export type ContinueStatement = NodeBase & {
type: "ContinueStatement";
label: ?Identifier;
};
// Choice
export type IfStatement = NodeBase & {
type: "IfStatement";
test: Expression;
consequent: Statement;
alternate: ?Statement;
};
export type SwitchStatement = NodeBase & {
type: "SwitchStatement";
discriminant: Expression;
cases: $ReadOnlyArray<SwitchCase>;
};
export type SwitchCase = NodeBase & {
type: "SwitchCase";
test: ?Expression;
consequent: $ReadOnlyArray<Statement>;
};
// Exceptions
export type ThrowStatement = NodeBase & {
type: "ThrowStatement";
argument: Expression;
};
export type TryStatement = NodeBase & {
type: "TryStatement";
block: BlockStatement;
handler: CatchClause | null;
finalizer: BlockStatement | null;
guardedHandlers: $ReadOnlyArray<empty>; // TODO: Not in spec
};
export type CatchClause = NodeBase & {
type: "CatchClause";
param: Pattern;
body: BlockStatement;
};
// Loops
export type WhileStatement = NodeBase & {
type: "WhileStatement";
test: Expression;
body: Statement;
};
export type DoWhileStatement = NodeBase & {
type: "DoWhileStatement";
body: Statement;
test: Expression;
};
export type ForLike = ForStatement | ForInOf;
export type ForStatement = NodeBase & {
type: "ForStatement";
init: ?(VariableDeclaration | Expression);
test: ?Expression;
update: ?Expression;
body: Statement;
};
export type ForInOf = ForInStatement | ForOfStatement;
export type ForInOfBase = NodeBase & {
type: "ForInStatement";
left: VariableDeclaration | Expression;
right: Expression;
body: Statement;
};
export type ForInStatement = ForInOfBase & {
type: "ForInStatement";
// TODO: Shouldn't be here, but have to declare it because it's assigned to a ForInOf unconditionally.
await: boolean;
};
export type ForOfStatement = ForInOfBase & {
type: "ForOfStatement";
await: boolean;
};
// Declarations
export type OptFunctionDeclaration = FunctionBase & DeclarationBase & HasDecorators & {
type: "FunctionDeclaration";
};
export type FunctionDeclaration = OptFunctionDeclaration & {
id: Identifier;
}
export type VariableDeclaration = DeclarationBase & HasDecorators & {
type: "VariableDeclaration";
declarations: $ReadOnlyArray<VariableDeclarator>;
kind: "var" | "let" | "const";
};
export type VariableDeclarator = NodeBase & {
type: "VariableDeclarator";
id: Pattern;
init: ?Expression;
};
// Misc
export type Decorator = NodeBase & {
type: "Decorator";
expression: Expression;
};
export type Directive = NodeBase & {
type: "Directive";
value: DirectiveLiteral;
};
export type DirectiveLiteral = StringLiteral & { type: "DirectiveLiteral" };
// Expressions
export type Super = NodeBase & { type: "Super" };
export type Import = NodeBase & { type: "Import" };
export type ThisExpression = NodeBase & { type: "ThisExpression" };
export type ArrowFunctionExpression = FunctionBase & {
type: "ArrowFunctionExpression";
body: BlockStatement | Expression;
};
export type YieldExpression = NodeBase & {
type: "YieldExpression";
argument: ?Expression;
delegate: boolean;
};
export type AwaitExpression = NodeBase & {
type: "AwaitExpression";
argument: ?Expression;
};
export type ArrayExpression = NodeBase & {
type: "ArrayExpression";
elements: $ReadOnlyArray<?(Expression | SpreadElement)>;
};
export type ObjectExpression = NodeBase & {
type: "ObjectExpression";
properties: $ReadOnlyArray<ObjectProperty | ObjectMethod | SpreadElement>;
};
export type ObjectOrClassMember = ClassMethod | ClassProperty | ClassPrivateProperty | ObjectMember;
export type ObjectMember = ObjectProperty | ObjectMethod;
export type ObjectMemberBase = NodeBase & {
key: Expression;
computed: boolean;
value: Expression;
decorators: $ReadOnlyArray<Decorator>;
kind?: "get" | "set" | "method";
method: boolean; // TODO: Not in spec
variance?: ?FlowVariance; // TODO: Not in spec
};
export type ObjectProperty = ObjectMemberBase & {
type: "ObjectProperty";
shorthand: boolean;
};
export type ObjectMethod = ObjectMemberBase & MethodBase & {
type: "ObjectMethod";
kind: "get" | "set" | "method"; // Never "constructor"
};
export type FunctionExpression = MethodBase & {
kind?: void; // never set
type: "FunctionExpression";
};
// Unary operations
export type UnaryExpression = NodeBase & {
type: "UnaryExpression";
operator: UnaryOperator;
prefix: boolean;
argument: Expression;
};
export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete";
export type UpdateExpression = NodeBase & {
type: "UpdateExpression";
operator: UpdateOperator;
argument: Expression;
prefix: boolean;
};
export type UpdateOperator = "++" | "--";
// Binary operations
export type BinaryExpression = NodeBase & {
type: "BinaryExpression";
operator: BinaryOperator;
left: Expression;
right: Expression;
};
export type BinaryOperator =
| "==" | "!=" | "===" | "!=="
| "<" | "<=" | ">" | ">="
| "<<" | ">>" | ">>>"
| "+" | "-" | "*" | "/" | "%"
| "|" | "^" | "&" | "in"
| "instanceof";
export type AssignmentExpression = NodeBase & {
type: "AssignmentExpression";
operator: AssignmentOperator;
left: Pattern | Expression;
right: Expression;
};
export type AssignmentOperator =
| "=" | "+=" | "-=" | "*=" | "/=" | "%="
| "<<=" | ">>=" | ">>>="
| "|=" | "^=" | "&=";
export type LogicalExpression = NodeBase & {
type: "LogicalExpression";
operator: LogicalOperator;
left: Expression;
right: Expression;
};
export type LogicalOperator = "||" | "&&";
export type SpreadElement = NodeBase & {
type: "SpreadElement";
argument: Expression;
};
export type MemberExpression = NodeBase & {
type: "MemberExpression";
object: Expression | Super;
property: Expression;
computed: boolean;
}
export type BindExpression = NodeBase & {
type: "BindExpression";
object: $ReadOnlyArray<?Expression>;
callee: $ReadOnlyArray<Expression>;
};
export type ConditionalExpression = NodeBase & {
type: "ConditionalExpression";
test: Expression;
alternate: Expression;
consequent: Expression;
};
export type CallOrNewBase = NodeBase & {
callee: Expression | Super | Import;
arguments: Array<Expression | SpreadElement>; // TODO: $ReadOnlyArray
};
export type CallExpression = CallOrNewBase & {
type: "CallExpression";
};
export type NewExpression = CallOrNewBase & {
type: "NewExpression";
};
export type SequenceExpression = NodeBase & {
type: "SequenceExpression";
expressions: $ReadOnlyArray<Expression>;
};
// Template Literals
export type TemplateLiteral = NodeBase & {
type: "TemplateLiteral";
quasis: $ReadOnlyArray<TemplateElement>;
expressions: $ReadOnlyArray<Expression>;
};
export type TaggedTmplateExpression = NodeBase & {
type: "TaggedTemplateExpression";
tag: Expression;
quasi: TemplateLiteral;
};
export type TemplateElement = NodeBase & {
type: "TemplateElement";
tail: boolean;
value: {
cooked: string;
raw: string;
}
};
// Patterns
export type PatternBase = HasDecorators & {
// Flow only:
optional?: true;
typeAnnotation?: ?FlowTypeAnnotation;
};
export type AssignmentProperty = ObjectProperty & {
value: Pattern;
};
export type ObjectPattern = PatternBase & {
type: "ObjectPattern";
properties: $ReadOnlyArray<AssignmentProperty | RestElement>;
};
export type ArrayPattern = PatternBase & {
type: "ArrayPattern";
elements: $ReadOnlyArray<?Pattern>;
};
export type RestElement = PatternBase & {
type: "RestElement";
argument: Pattern;
};
export type AssignmentPattern = PatternBase & {
type: "AssignmentPattern";
left: Pattern;
right: Expression;
};
// Classes
export type Class = ClassDeclaration | ClassExpression;
export type ClassBase = HasDecorators & {
id: ?Identifier;
superClass: ?Expression;
body: ClassBody;
decorators: $ReadOnlyArray<Decorator>;
typeParameters?: ?FlowTypeParameterDeclaration; // TODO: Not in spec
superTypeParameters?: ?FlowTypeParameterInstantiation; // TODO: Not in spec
implements?: $ReadOnlyArray<FlowClassImplements>;
};
export type ClassBody = NodeBase & {
type: "ClassBody";
body: Array<ClassMember>; // TODO: $ReadOnlyArray
};
export type ClassMemberBase = NodeBase & HasDecorators & {
static: boolean;
computed: boolean;
// TypeScript only:
access?: ?Accessibility;
abstract?: ?true;
optional?: ?true;
}
export type Accessibility = "public" | "protected" | "private";
export type ClassMember = ClassMethod | ClassProperty | ClassPrivateProperty;
export type MethodLike = ObjectMethod | FunctionExpression | ClassMethod;
export type MethodBase = FunctionBase & {
+kind?: MethodKind;
};
export type MethodKind = "constructor" | "method" | "get" | "set";
export type ClassMethod = MethodBase & ClassMemberBase & {
type: "ClassMethod";
key: Expression;
kind: MethodKind;
static: boolean;
decorators: $ReadOnlyArray<Decorator>;
variance?: ?FlowVariance; // TODO: Not in spec
};
export type ClassProperty = ClassMemberBase & {
type: "ClassProperty";
key: Identifier;
value: ?Expression; // TODO: Not in spec that this is nullable.
typeAnnotation?: ?FlowTypeAnnotation; // TODO: Not in spec
variance?: ?FlowVariance; // TODO: Not in spec
// TypeScript only: (TODO: Not in spec)
readonly?: true;
};
export type ClassPrivateProperty = NodeBase & {
type: "ClassPrivateProperty";
key: Identifier;
value: ?Expression; // TODO: Not in spec that this is nullable.
};
export type OptClassDeclaration = ClassBase & DeclarationBase & HasDecorators & {
type: "ClassDeclaration";
// TypeScript only
abstract?: ?true;
};
export type ClassDeclaration = OptClassDeclaration & {
id: Identifier;
};
export type ClassExpression = ClassBase & { type: "ClassExpression" };
export type MetaProperty = NodeBase & {
type: "MetaProperty";
meta: Identifier;
property: Identifier;
};
// Modules
export type ModuleDeclaration = AnyImport | AnyExport;
export type AnyImport = ImportDeclaration;
export type AnyExport =
| ExportNamedDeclaration
| ExportDefaultDeclaration
| ExportAllDeclaration;
export type ModuleSpecifier = NodeBase & {
local: Identifier;
};
// Imports
export type ImportDeclaration = NodeBase & {
type: "ImportDeclaration";
// TODO: $ReadOnlyArray
specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>;
source: Literal;
importKind?: "type" | "typeof" | "value"; // TODO: Not in spec
};
export type ImportSpecifier = ModuleSpecifier & {
type: "ImportSpecifier";
imported: Identifier;
};
export type ImportDefaultSpecifier = ModuleSpecifier & {
type: "ImportDefaultSpecifier"
};
export type ImportNamespaceSpecifier = ModuleSpecifier & {
type: "ImportNamespaceSpecifier"
};
// Exports
export type ExportNamedDeclaration = NodeBase & {
type: "ExportNamedDeclaration";
declaration: ?Declaration;
specifiers: $ReadOnlyArray<ExportSpecifier>;
source: ?Literal;
exportKind?: "type" | "value"; // TODO: Not in spec
};
export type ExportSpecifier = NodeBase & {
type: "ExportSpecifier";
exported: Identifier;
};
export type ExportDefaultDeclaration = NodeBase & {
type: "ExportDefaultDeclaration";
declaration: OptFunctionDeclaration | OptClassDeclaration | Expression;
};
export type ExportAllDeclaration = NodeBase & {
type: "ExportAllDeclaration";
source: Literal;
};
// JSX (TODO: Not in spec)
export type JSXIdentifier = Node;
export type JSXNamespacedName = Node;
export type JSXMemberExpression = Node;
export type JSXEmptyExpression = Node;
export type JSXSpreadChild = Node;
export type JSXExpressionContainer = Node;
export type JSXAttribute = Node;
export type JSXOpeningElement = Node;
export type JSXClosingElement = Node;
export type JSXElement = Node;
// Flow (TODO: Not in spec)
export type FlowType = Node;
export type FlowPredicate = Node;
export type FlowDeclare = Node;
export type FlowDeclareClass = Node;
export type FlowDeclareExportDeclaration = Node;
export type FlowDeclareFunction = Node;
export type FlowDeclareVariable = Node;
export type FlowDeclareModule = Node;
export type FlowDeclareModuleExports = Node;
export type FlowDeclareTypeAlias = Node;
export type FlowDeclareInterface = Node;
export type FlowInterface = Node;
export type FlowInterfaceExtends = Node;
export type FlowTypeAlias = Node;
export type FlowTypeParameter = Node;
export type FlowTypeParameterDeclaration = Node;
export type FlowTypeParameterInstantiation = Node;
export type FlowObjectTypeIndexer = Node;
export type FlowFunctionTypeAnnotation = Node;
export type FlowObjectTypeProperty = Node;
export type FlowObjectTypeSpreadProperty = Node;
export type FlowObjectTypeCallProperty = Node;
export type FlowObjectTypeAnnotation = Node;
export type FlowQualifiedTypeIdentifier = Node;
export type FlowGenericTypeAnnotation = Node;
export type FlowTypeofTypeAnnotation = Node;
export type FlowTupleTypeAnnotation = Node;
export type FlowFunctionTypeParam = Node;
export type FlowTypeAnnotation = Node;
export type FlowVariance = Node;
export type FlowClassImplements = Node;