1487 lines
47 KiB
TypeScript
Raw Normal View History

2017-12-24 03:19:47 +01:00
import {
PATH_DELIMITER,
STATIC_DELIMITER,
INSTANCE_DELIMITER
} from "./constants";
import {
Token,
Tokenizer,
Range
} from "./tokenizer";
import {
I64
} from "./util/i64";
import {
normalize as normalizePath,
resolve as resolvePath
} from "./util/path";
2017-09-28 13:08:25 +02:00
export {
Token,
Range
};
2017-09-28 13:08:25 +02:00
2017-12-16 17:54:53 +01:00
/** Indicates the kind of a node. */
2017-09-28 13:08:25 +02:00
export enum NodeKind {
SOURCE,
// types
TYPE,
TYPEPARAMETER,
// expressions
IDENTIFIER,
ASSERTION,
BINARY,
CALL,
2018-01-05 01:55:59 +01:00
COMMA,
2017-09-28 13:08:25 +02:00
ELEMENTACCESS,
2017-10-07 14:29:43 +02:00
FALSE,
2017-09-28 13:08:25 +02:00
LITERAL,
NEW,
2017-10-07 14:29:43 +02:00
NULL,
2017-09-28 13:08:25 +02:00
PARENTHESIZED,
PROPERTYACCESS,
TERNARY,
2017-10-07 14:29:43 +02:00
SUPER,
THIS,
TRUE,
2017-12-16 02:27:39 +01:00
CONSTRUCTOR,
2017-09-28 13:08:25 +02:00
UNARYPOSTFIX,
UNARYPREFIX,
// statements
BLOCK,
BREAK,
CONTINUE,
DO,
EMPTY,
EXPORT,
EXPORTIMPORT,
EXPRESSION,
FOR,
IF,
IMPORT,
2017-09-28 13:08:25 +02:00
RETURN,
SWITCH,
THROW,
TRY,
VARIABLE,
WHILE,
// declaration statements
CLASSDECLARATION,
ENUMDECLARATION,
ENUMVALUEDECLARATION,
FIELDDECLARATION,
FUNCTIONDECLARATION,
IMPORTDECLARATION,
INTERFACEDECLARATION,
METHODDECLARATION,
NAMESPACEDECLARATION,
TYPEDECLARATION,
2017-09-28 13:08:25 +02:00
VARIABLEDECLARATION,
2017-12-18 03:46:36 +01:00
// other
DECORATOR,
EXPORTMEMBER,
2017-12-18 03:46:36 +01:00
MODIFIER,
PARAMETER,
SWITCHCASE
2017-09-28 13:08:25 +02:00
}
2017-12-16 17:54:53 +01:00
/** Base class of all nodes. */
export abstract class Node {
2017-09-28 13:08:25 +02:00
2017-12-16 17:54:53 +01:00
/** Node kind indicator. */
kind: NodeKind;
/** Source range. */
range: Range;
/** Parent node. */
parent: Node | null = null;
2017-09-28 13:08:25 +02:00
2017-12-16 17:54:53 +01:00
// types
2017-09-28 13:08:25 +02:00
2017-12-16 17:54:53 +01:00
static createType(identifier: IdentifierExpression, typeArguments: TypeNode[], isNullable: bool, range: Range): TypeNode {
var type = new TypeNode();
2017-09-28 13:08:25 +02:00
type.range = range;
type.identifier = identifier;
2017-12-16 17:54:53 +01:00
type.typeArguments = typeArguments;
type.isNullable = isNullable;
2017-09-28 13:08:25 +02:00
return type;
}
2017-12-16 17:54:53 +01:00
// expressions
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createIdentifierExpression(name: string, range: Range): IdentifierExpression {
var expr = new IdentifierExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.name = name;
return expr;
}
2018-01-05 01:55:59 +01:00
static createArrayLiteralExpression(elementExpressions: (Expression | null)[], range: Range): ArrayLiteralExpression {
var expr = new ArrayLiteralExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
for (var i = 0, k = (expr.elementExpressions = elementExpressions).length; i < k; ++i)
if (elementExpressions[i])
(<Expression>elementExpressions[i]).parent = expr;
2017-09-28 13:08:25 +02:00
return expr;
}
2018-01-05 01:55:59 +01:00
static createAssertionExpression(assertionKind: AssertionKind, expression: Expression, toType: TypeNode, range: Range): AssertionExpression {
var expr = new AssertionExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.assertionKind = assertionKind;
(expr.expression = expression).parent = expr;
(expr.toType = toType).parent = expr;
return expr;
}
2018-01-05 01:55:59 +01:00
static createBinaryExpression(operator: Token, left: Expression, right: Expression, range: Range): BinaryExpression {
var expr = new BinaryExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.operator = operator;
(expr.left = left).parent = expr;
(expr.right = right).parent = expr;
return expr;
}
2018-01-05 01:55:59 +01:00
static createCallExpression(expression: Expression, typeArguments: TypeNode[] | null, args: Expression[], range: Range): CallExpression {
var expr = new CallExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
(expr.expression = expression).parent = expr;
if (expr.typeArguments = typeArguments)
for (var i = 0, k = (<TypeNode[]>typeArguments).length; i < k; ++i)
(<TypeNode[]>typeArguments)[i].parent = expr;
for (i = 0, k = (expr.arguments = args).length; i < k; ++i)
args[i].parent = expr;
2017-09-28 13:08:25 +02:00
return expr;
}
2018-01-05 01:55:59 +01:00
static createCommaExpression(expressions: Expression[], range: Range): CommaExpression {
var expr = new CommaExpression();
expr.range = range;
for (var i = 0, k = (expr.expressions = expressions).length; i < k; ++i)
expressions[i].parent = expr;
return expr;
}
static createConstructorExpression(range: Range): ConstructorExpression {
var expr = new ConstructorExpression();
2017-12-16 02:27:39 +01:00
expr.range = range;
return expr;
}
2018-01-05 01:55:59 +01:00
static createElementAccessExpression(expression: Expression, element: Expression, range: Range): ElementAccessExpression {
var expr = new ElementAccessExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
(expr.expression = expression).parent = expr;
(expr.elementExpression = element).parent = expr;
return expr;
}
2018-01-05 01:55:59 +01:00
static createFalseExpression(range: Range): FalseExpression {
var expr = new FalseExpression();
2017-10-07 14:29:43 +02:00
expr.range = range;
return expr;
}
2018-01-05 01:55:59 +01:00
static createFloatLiteralExpression(value: f64, range: Range): FloatLiteralExpression {
var expr = new FloatLiteralExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.value = value;
return expr;
}
2018-01-05 01:55:59 +01:00
static createIntegerLiteralExpression(value: I64, range: Range): IntegerLiteralExpression {
var expr = new IntegerLiteralExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.value = value;
return expr;
}
2018-01-05 01:55:59 +01:00
static createNewExpression(expression: Expression, typeArguments: TypeNode[] | null, args: Expression[], range: Range): NewExpression {
var expr = new NewExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
(expr.expression = expression).parent = expr;
if (expr.typeArguments = typeArguments)
for (var i = 0, k = (<TypeNode[]>typeArguments).length; i < k; ++i)
(<TypeNode[]>typeArguments)[i].parent = expr;
for (i = 0, k = (expr.arguments = args).length; i < k; ++i)
args[i].parent = expr;
2017-09-28 13:08:25 +02:00
return expr;
}
2018-01-05 01:55:59 +01:00
static createNullExpression(range: Range): NullExpression {
var expr = new NullExpression();
2017-10-07 14:29:43 +02:00
expr.range = range;
return expr;
}
2018-01-05 01:55:59 +01:00
static createParenthesizedExpression(expression: Expression, range: Range): ParenthesizedExpression {
var expr = new ParenthesizedExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
(expr.expression = expression).parent = expr;
return expr;
}
2018-01-05 01:55:59 +01:00
static createPropertyAccessExpression(expression: Expression, property: IdentifierExpression, range: Range): PropertyAccessExpression {
var expr = new PropertyAccessExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
(expr.expression = expression).parent = expr;
(expr.property = property).parent = expr;
return expr;
}
2018-01-07 18:15:21 +01:00
static createRegexpLiteralExpression(pattern: string, flags: string, range: Range): RegexpLiteralExpression {
var expr = new RegexpLiteralExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.pattern = pattern;
2018-01-07 18:15:21 +01:00
expr.patternFlags = flags;
2017-09-28 13:08:25 +02:00
return expr;
}
2018-01-05 01:55:59 +01:00
static createTernaryExpression(condition: Expression, ifThen: Expression, ifElse: Expression, range: Range): TernaryExpression {
var expr = new TernaryExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
(expr.condition = condition).parent = expr;
(expr.ifThen = ifThen).parent = expr;
(expr.ifElse = ifElse).parent = expr;
return expr;
}
2018-01-05 01:55:59 +01:00
static createStringLiteralExpression(value: string, range: Range): StringLiteralExpression {
var expr = new StringLiteralExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.value = value;
return expr;
}
2018-01-05 01:55:59 +01:00
static createSuperExpression(range: Range): SuperExpression {
var expr = new SuperExpression();
2017-10-07 14:29:43 +02:00
expr.range = range;
return expr;
}
2018-01-05 01:55:59 +01:00
static createThisExpression(range: Range): ThisExpression {
var expr = new ThisExpression();
2017-10-07 14:29:43 +02:00
expr.range = range;
return expr;
}
2018-01-05 01:55:59 +01:00
static createTrueExpression(range: Range): TrueExpression {
var expr = new TrueExpression();
2017-10-07 14:29:43 +02:00
expr.range = range;
return expr;
}
2018-01-05 01:55:59 +01:00
static createUnaryPostfixExpression(operator: Token, expression: Expression, range: Range): UnaryPostfixExpression {
var expr = new UnaryPostfixExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.operator = operator;
2017-12-18 03:46:36 +01:00
(expr.operand = expression).parent = expr;
2017-09-28 13:08:25 +02:00
return expr;
}
2018-01-05 01:55:59 +01:00
static createUnaryPrefixExpression(operator: Token, expression: Expression, range: Range): UnaryPrefixExpression {
var expr = new UnaryPrefixExpression();
2017-09-28 13:08:25 +02:00
expr.range = range;
expr.operator = operator;
2017-12-18 03:46:36 +01:00
(expr.operand = expression).parent = expr;
2017-09-28 13:08:25 +02:00
return expr;
}
2017-12-16 17:54:53 +01:00
// statements
2017-12-16 02:27:39 +01:00
2018-01-05 01:55:59 +01:00
static createBlockStatement(statements: Statement[], range: Range): BlockStatement {
var stmt = new BlockStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
for (var i: i32 = 0, k: i32 = (stmt.statements = statements).length; i < k; ++i)
statements[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
2017-12-16 02:27:39 +01:00
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createBreakStatement(label: IdentifierExpression | null, range: Range): BreakStatement {
var stmt = new BreakStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
if (stmt.label = label)
(<IdentifierExpression>label).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createClassDeclaration(identifier: IdentifierExpression, typeParameters: TypeParameter[], extendsType: TypeNode | null, implementsTypes: TypeNode[], members: DeclarationStatement[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): ClassDeclaration {
var stmt = new ClassDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
for (var i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i)
typeParameters[i].parent = stmt;
if (stmt.extendsType = extendsType)
(<TypeNode>extendsType).parent = stmt;
for (i = 0, k = (stmt.implementsTypes = implementsTypes).length; i < k; ++i)
implementsTypes[i].parent = stmt;
for (i = 0, k = (stmt.members = members).length; i < k; ++i)
members[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createContinueStatement(label: IdentifierExpression | null, range: Range): ContinueStatement {
var stmt = new ContinueStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
if (stmt.label = label)
(<IdentifierExpression>label).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
static createDecorator(expression: Expression, args: Expression[] | null, range: Range): Decorator {
var stmt = new Decorator();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = expression).parent = stmt;
if (stmt.arguments = args)
for (var i: i32 = 0, k: i32 = (<Expression[]>args).length; i < k; ++i)
(<Expression[]>args)[i].parent = stmt;
2018-01-06 10:20:38 +01:00
if (expression.kind == NodeKind.IDENTIFIER) {
switch ((<IdentifierExpression>expression).name) {
case "global":
stmt.decoratorKind = DecoratorKind.GLOBAL;
break;
case "operator":
stmt.decoratorKind = DecoratorKind.OPERATOR;
break;
case "explicit":
stmt.decoratorKind = DecoratorKind.EXPLICIT;
2018-01-06 10:20:38 +01:00
break;
case "offset":
stmt.decoratorKind = DecoratorKind.OFFSET;
2018-01-06 10:20:38 +01:00
break;
default:
stmt.decoratorKind = DecoratorKind.CUSTOM;
break;
}
} else
stmt.decoratorKind = DecoratorKind.CUSTOM;
2017-12-16 17:54:53 +01:00
return stmt;
2017-09-28 13:08:25 +02:00
}
2018-01-05 01:55:59 +01:00
static createDoStatement(statement: Statement, condition: Expression, range: Range): DoStatement {
var stmt = new DoStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
(stmt.statement = statement).parent = stmt;
(stmt.condition = condition).parent = stmt;
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createEmptyStatement(range: Range): EmptyStatement {
var stmt = new EmptyStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createEnumDeclaration(identifier: IdentifierExpression, members: EnumValueDeclaration[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): EnumDeclaration {
var stmt = new EnumDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
for (var i = 0, k = (stmt.values = members).length; i < k; ++i)
members[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createEnumValueDeclaration(identifier: IdentifierExpression, value: Expression | null, range: Range): EnumValueDeclaration {
var stmt = new EnumValueDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
if (stmt.value = value)
(<Expression>value).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
2017-09-28 13:08:25 +02:00
}
2018-01-05 01:55:59 +01:00
static createExportStatement(members: ExportMember[], path: StringLiteralExpression | null, modifiers: Modifier[] | null, range: Range): ExportStatement {
var stmt = new ExportStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
for (var i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
2017-12-16 17:54:53 +01:00
stmt.path = path;
stmt.normalizedPath = path ? resolvePath(normalizePath(path.value), range.source.normalizedPath) : null;
stmt.internalPath = stmt.normalizedPath ? mangleInternalPath(stmt.normalizedPath) : null;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createExportImportStatement(identifier: IdentifierExpression, asIdentifier: IdentifierExpression, range: Range): ExportImportStatement {
var stmt = new ExportImportStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
(stmt.identifier = identifier).parent = stmt;
2017-12-18 03:46:36 +01:00
(stmt.externalIdentifier = asIdentifier).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
2017-12-16 17:54:53 +01:00
static createExportMember(identifier: IdentifierExpression, externalIdentifier: IdentifierExpression | null, range: Range): ExportMember {
var elem = new ExportMember();
2017-12-16 17:54:53 +01:00
elem.range = range;
(elem.identifier = identifier).parent = elem;
(elem.externalIdentifier = externalIdentifier ? <IdentifierExpression>externalIdentifier : identifier).parent = elem;
return elem;
2017-09-28 13:08:25 +02:00
}
2018-01-05 01:55:59 +01:00
static createExpressionStatement(expression: Expression): ExpressionStatement {
var stmt = new ExpressionStatement();
2017-12-16 17:54:53 +01:00
stmt.range = expression.range;
(stmt.expression = expression).parent = stmt;
return stmt;
}
2017-09-28 13:08:25 +02:00
2018-01-05 01:55:59 +01:00
static createIfStatement(condition: Expression, ifTrue: Statement, ifFalse: Statement | null, range: Range): IfStatement {
var stmt = new IfStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
(stmt.condition = condition).parent = stmt;
(stmt.ifTrue = ifTrue).parent = stmt;
if (stmt.ifFalse = ifFalse)
(<Statement>ifFalse).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2017-09-28 13:08:25 +02:00
static createImportStatement(declarations: ImportDeclaration[] | null, path: StringLiteralExpression, range: Range): ImportStatement {
var stmt = new ImportStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
if (stmt.declarations = declarations)
for (var i: i32 = 0, k: i32 = (<ImportDeclaration[]>declarations).length; i < k; ++i)
(<ImportDeclaration[]>declarations)[i].parent = stmt;
stmt.namespaceName = null;
stmt.path = path;
stmt.normalizedPath = resolvePath(normalizePath(path.value), range.source.normalizedPath);
stmt.internalPath = mangleInternalPath(stmt.normalizedPath);
return stmt;
}
2018-01-05 01:55:59 +01:00
static createImportStatementWithWildcard(identifier: IdentifierExpression, path: StringLiteralExpression, range: Range): ImportStatement {
var stmt = new ImportStatement();
stmt.range = range;
stmt.declarations = null;
stmt.namespaceName = identifier;
2017-12-16 17:54:53 +01:00
stmt.path = path;
stmt.normalizedPath = resolvePath(normalizePath(path.value), range.source.normalizedPath);
stmt.internalPath = mangleInternalPath(stmt.normalizedPath);
return stmt;
2017-09-28 13:08:25 +02:00
}
2017-12-16 17:54:53 +01:00
static createImportDeclaration(externalIdentifier: IdentifierExpression, identifier: IdentifierExpression | null, range: Range): ImportDeclaration {
var elem = new ImportDeclaration();
2017-12-16 17:54:53 +01:00
elem.range = range;
2017-12-18 03:46:36 +01:00
(elem.name = identifier ? <IdentifierExpression>identifier : externalIdentifier).parent = elem;
2017-12-16 17:54:53 +01:00
(elem.externalIdentifier = externalIdentifier).parent = elem;
return elem;
}
2018-01-05 01:55:59 +01:00
static createInterfaceDeclaration(identifier: IdentifierExpression, extendsType: TypeNode | null, members: DeclarationStatement[], modifiers: Modifier[] | null, range: Range): InterfaceDeclaration {
var stmt = new InterfaceDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
if (stmt.extendsType = extendsType)
(<TypeNode>extendsType).parent = stmt;
for (var i = 0, k = (stmt.members = members).length; i < k; ++i)
members[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2018-01-05 01:55:59 +01:00
static createFieldDeclaration(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): FieldDeclaration {
var stmt = new FieldDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
if (stmt.type = type)
(<TypeNode>type).parent = stmt;
if (stmt.initializer = initializer)
(<Expression>initializer).parent = stmt;
if (stmt.modifiers = modifiers)
for (var i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2018-01-05 01:55:59 +01:00
static createForStatement(initializer: Statement | null, condition: Expression | null, incrementor: Expression | null, statement: Statement, range: Range): ForStatement {
var stmt = new ForStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
if (stmt.initializer = initializer)
(<Statement>initializer).parent = stmt;
if (stmt.condition = condition)
(<Expression>condition).parent = stmt;
if (stmt.incrementor = incrementor)
(<Expression>incrementor).parent = stmt;
2017-12-16 17:54:53 +01:00
(stmt.statement = statement).parent = stmt;
return stmt;
}
static createTypeParameter(identifier: IdentifierExpression, extendsType: TypeNode | null, range: Range): TypeParameter {
var elem = new TypeParameter();
2017-12-16 17:54:53 +01:00
elem.range = range;
(elem.identifier = identifier).parent = elem;
if (elem.extendsType = extendsType)
(<TypeNode>extendsType).parent = elem;
2017-12-16 17:54:53 +01:00
return elem;
}
2017-12-18 03:46:36 +01:00
static createParameter(identifier: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, isRest: bool, range: Range): Parameter {
var elem = new Parameter();
2017-12-16 17:54:53 +01:00
elem.range = range;
2017-12-18 03:46:36 +01:00
(elem.name = identifier).parent = elem;
if (elem.type = type)
(<TypeNode>type).parent = elem;
if (elem.initializer = initializer)
(<Expression>initializer).parent = elem;
2017-12-18 03:46:36 +01:00
elem.isRest = isRest;
2017-12-16 17:54:53 +01:00
return elem;
}
2018-01-05 01:55:59 +01:00
static createFunctionDeclaration(identifier: IdentifierExpression, typeParameters: TypeParameter[], parameters: Parameter[], returnType: TypeNode | null, statements: Statement[] | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): FunctionDeclaration {
var stmt = new FunctionDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
for (var i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i)
typeParameters[i].parent = stmt;
for (i = 0, k = (stmt.parameters = parameters).length; i < k; ++i)
parameters[i].parent = stmt;
if (stmt.returnType = returnType)
(<TypeNode>returnType).parent = stmt;
if (stmt.statements = statements)
for (i = 0, k = (<Statement[]>statements).length; i < k; ++i)
(<Statement[]>statements)[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2018-01-05 01:55:59 +01:00
static createMethodDeclaration(identifier: IdentifierExpression, typeParameters: TypeParameter[], parameters: Parameter[], returnType: TypeNode | null, statements: Statement[] | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): MethodDeclaration {
var stmt = new MethodDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
for (var i = 0, k = (stmt.typeParameters = typeParameters).length; i < k; ++i)
typeParameters[i].parent = stmt;
for (i = 0, k = (stmt.parameters = parameters).length; i < k; ++i)
parameters[i].parent = stmt;
if (stmt.returnType = returnType)
(<TypeNode>returnType).parent = stmt;
if (stmt.statements = statements)
for (i = 0, k = (<Statement[]>statements).length; i < k; ++i)
(<Statement[]>statements)[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
static createModifier(kind: ModifierKind, range: Range): Modifier {
var elem = new Modifier();
2017-12-16 17:54:53 +01:00
elem.range = range;
elem.modifierKind = kind;
return elem;
}
2018-01-05 01:55:59 +01:00
static createNamespaceDeclaration(identifier: IdentifierExpression, members: Statement[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): NamespaceDeclaration {
var stmt = new NamespaceDeclaration();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.name = identifier).parent = stmt;
for (var i = 0, k = (stmt.members = members).length; i < k; ++i)
members[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2018-01-05 01:55:59 +01:00
static createReturnStatement(expression: Expression | null, range: Range): ReturnStatement {
var stmt = new ReturnStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
if (stmt.value = expression)
(<Expression>expression).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2018-01-05 01:55:59 +01:00
static createSwitchStatement(expression: Expression, cases: SwitchCase[], range: Range): SwitchStatement {
var stmt = new SwitchStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.condition = expression).parent = stmt;
for (var i: i32 = 0, k: i32 = (stmt.cases = cases).length; i < k; ++i)
cases[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
static createSwitchCase(label: Expression | null, statements: Statement[], range: Range): SwitchCase {
var elem = new SwitchCase();
2017-12-16 17:54:53 +01:00
elem.range = range;
if (elem.label = label)
(<Expression>label).parent = elem;
for (var i: i32 = 0, k: i32 = (elem.statements = statements).length; i < k; ++i)
statements[i].parent = elem;
2017-12-16 17:54:53 +01:00
return elem;
}
2018-01-05 01:55:59 +01:00
static createThrowStatement(expression: Expression, range: Range): ThrowStatement {
var stmt = new ThrowStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
2017-12-18 03:46:36 +01:00
(stmt.value = expression).parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
2018-01-05 01:55:59 +01:00
static createTryStatement(statements: Statement[], catchVariable: IdentifierExpression | null, catchStatements: Statement[] | null, finallyStatements: Statement[] | null, range: Range): TryStatement {
var stmt = new TryStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
for (var i = 0, k = (stmt.statements = statements).length; i < k; ++i)
statements[i].parent = stmt;
if (stmt.catchVariable = catchVariable)
(<IdentifierExpression>catchVariable).parent = stmt;
if (stmt.catchStatements = catchStatements)
for (i = 0, k = (<Statement[]>catchStatements).length; i < k; ++i)
(<Statement[]>catchStatements)[i].parent = stmt;
if (stmt.finallyStatements = finallyStatements)
for (i = 0, k = (<Statement[]>finallyStatements).length; i < k; ++i)
(<Statement[]>finallyStatements)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
static createTypeDeclaration(identifier: IdentifierExpression, alias: TypeNode, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): TypeDeclaration {
var stmt = new TypeDeclaration();
stmt.range = range;
(stmt.name = identifier).parent = stmt;
(stmt.alias = alias).parent = stmt;
if (stmt.modifiers = modifiers)
for (var i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
return stmt;
}
2018-01-05 01:55:59 +01:00
static createVariableStatement(declarations: VariableDeclaration[], modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): VariableStatement {
var stmt = new VariableStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
for (var i = 0, k = (stmt.declarations = declarations).length; i < k; ++i)
declarations[i].parent = stmt;
if (stmt.modifiers = modifiers)
for (i = 0, k = (<Modifier[]>modifiers).length; i < k; ++i)
(<Modifier[]>modifiers)[i].parent = stmt;
if (stmt.decorators = decorators)
for (i = 0, k = (<Decorator[]>decorators).length; i < k; ++i)
(<Decorator[]>decorators)[i].parent = stmt;
2017-12-16 17:54:53 +01:00
return stmt;
}
static createVariableDeclaration(name: IdentifierExpression, type: TypeNode | null, initializer: Expression | null, modifiers: Modifier[] | null, decorators: Decorator[] | null, range: Range): VariableDeclaration {
var elem = new VariableDeclaration();
2017-12-16 17:54:53 +01:00
elem.range = range;
(elem.name = name).parent = elem;
if (elem.type = type)
(<TypeNode>type).parent = elem;
if (elem.initializer = initializer)
(<Expression>initializer).parent = elem;
2017-12-16 17:54:53 +01:00
elem.modifiers = modifiers;
elem.decorators = decorators;
return elem;
}
2018-01-05 01:55:59 +01:00
static createWhileStatement(condition: Expression, statement: Statement, range: Range): WhileStatement {
var stmt = new WhileStatement();
2017-12-16 17:54:53 +01:00
stmt.range = range;
(stmt.condition = condition).parent = stmt;
(stmt.statement = statement).parent = stmt;
return stmt;
}
}
// types
/** Represents a type annotation. */
export class TypeNode extends Node {
kind = NodeKind.TYPE;
/** Identifier reference. */
identifier: IdentifierExpression;
/** Type argument references. */
typeArguments: TypeNode[];
/** Whether nullable or not. */
isNullable: bool;
}
/** Represents a type parameter. */
export class TypeParameter extends Node {
kind = NodeKind.TYPEPARAMETER;
/** Identifier reference. */
identifier: IdentifierExpression;
/** Extended type reference, if any. */
extendsType: TypeNode | null;
}
// expressions
/** Base class of all expression nodes. */
export abstract class Expression extends Node { }
2017-12-18 03:46:36 +01:00
/** Represents an identifier expression. */
2017-12-16 17:54:53 +01:00
export class IdentifierExpression extends Expression {
kind = NodeKind.IDENTIFIER;
2017-12-18 03:46:36 +01:00
/** Textual name. */
2017-12-16 17:54:53 +01:00
name: string;
}
2017-12-18 03:46:36 +01:00
/** Indicates the kind of a literal. */
2017-12-16 17:54:53 +01:00
export const enum LiteralKind {
FLOAT,
INTEGER,
STRING,
REGEXP,
ARRAY,
OBJECT
}
2017-12-18 03:46:36 +01:00
/** Base class of all literal expressions. */
2017-12-16 17:54:53 +01:00
export abstract class LiteralExpression extends Expression {
kind = NodeKind.LITERAL;
2017-12-18 03:46:36 +01:00
/** Specific literal kind. */
2017-12-16 17:54:53 +01:00
literalKind: LiteralKind;
}
2017-12-18 03:46:36 +01:00
/** Represents an `[]` literal expression. */
2017-12-16 17:54:53 +01:00
export class ArrayLiteralExpression extends LiteralExpression {
literalKind = LiteralKind.ARRAY;
2017-12-18 03:46:36 +01:00
/** Nested element expressions. */
2017-12-16 17:54:53 +01:00
elementExpressions: (Expression | null)[];
}
2017-12-18 03:46:36 +01:00
/** Indicates the kind of an assertion. */
2017-12-16 17:54:53 +01:00
export const enum AssertionKind {
PREFIX,
AS
}
2017-12-18 03:46:36 +01:00
/** Represents an assertion expression. */
2017-12-16 17:54:53 +01:00
export class AssertionExpression extends Expression {
kind = NodeKind.ASSERTION;
2017-12-18 03:46:36 +01:00
/** Specific kind of this assertion. */
2017-12-16 17:54:53 +01:00
assertionKind: AssertionKind;
2017-12-18 03:46:36 +01:00
/** Expression being asserted. */
2017-12-16 17:54:53 +01:00
expression: Expression;
2017-12-18 03:46:36 +01:00
/** Target type. */
2017-12-16 17:54:53 +01:00
toType: TypeNode;
}
2017-12-18 03:46:36 +01:00
/** Represents a binary expression. */
2017-12-16 17:54:53 +01:00
export class BinaryExpression extends Expression {
kind = NodeKind.BINARY;
2017-12-18 03:46:36 +01:00
/** Operator token. */
2017-12-16 17:54:53 +01:00
operator: Token;
2017-12-18 03:46:36 +01:00
/** Left-hand side expression */
2017-12-16 17:54:53 +01:00
left: Expression;
2017-12-18 03:46:36 +01:00
/** Right-hand side expression. */
2017-12-16 17:54:53 +01:00
right: Expression;
}
2017-12-18 03:46:36 +01:00
/** Represents a call expression. */
2017-12-16 17:54:53 +01:00
export class CallExpression extends Expression {
kind = NodeKind.CALL;
2017-12-18 03:46:36 +01:00
/** Called expression. Usually an identifier or property access expression. */
2017-12-16 17:54:53 +01:00
expression: Expression;
2017-12-18 03:46:36 +01:00
/** Provided type arguments. */
typeArguments: TypeNode[] | null;
2017-12-18 03:46:36 +01:00
/** Provided arguments. */
2017-12-16 17:54:53 +01:00
arguments: Expression[];
}
2018-01-05 01:55:59 +01:00
/** Represents a comma expression composed of multiple sequential expressions. */
export class CommaExpression extends Expression {
kind = NodeKind.COMMA;
/** Sequential expressions. */
expressions: Expression[];
}
2017-12-18 03:46:36 +01:00
/** Represents a `constructor` expression. */
2017-12-16 17:54:53 +01:00
export class ConstructorExpression extends IdentifierExpression {
kind = NodeKind.CONSTRUCTOR;
name = "constructor";
2017-12-16 02:27:39 +01:00
}
2017-12-18 03:46:36 +01:00
/** Represents an element access expression, e.g., array access. */
2017-09-28 13:08:25 +02:00
export class ElementAccessExpression extends Expression {
kind = NodeKind.ELEMENTACCESS;
2017-12-18 03:46:36 +01:00
/** Expression being accessed. */
2017-09-28 13:08:25 +02:00
expression: Expression;
2017-12-18 03:46:36 +01:00
/** Element of the expression being accessed. */
2017-09-28 13:08:25 +02:00
elementExpression: Expression;
}
2017-12-18 03:46:36 +01:00
/** Represents a float literal expression. */
2017-09-28 13:08:25 +02:00
export class FloatLiteralExpression extends LiteralExpression {
literalKind = LiteralKind.FLOAT;
2017-12-18 03:46:36 +01:00
/** Float value. */
2017-09-28 13:08:25 +02:00
value: f64;
}
2017-12-18 03:46:36 +01:00
/** Represents an integer literal expression. */
2017-09-28 13:08:25 +02:00
export class IntegerLiteralExpression extends LiteralExpression {
literalKind = LiteralKind.INTEGER;
2017-12-18 03:46:36 +01:00
/** Integer value. */
2017-09-28 13:08:25 +02:00
value: I64;
}
2017-12-18 03:46:36 +01:00
/** Represents a `new` expression. Like a call but with its own kind. */
2017-09-28 13:08:25 +02:00
export class NewExpression extends CallExpression {
kind = NodeKind.NEW;
}
2017-12-18 03:46:36 +01:00
/** Represents a `null` expression. */
2017-10-07 14:29:43 +02:00
export class NullExpression extends IdentifierExpression {
kind = NodeKind.NULL;
name = "null";
}
2017-12-18 03:46:36 +01:00
/** Represents a parenthesized expression. */
2017-09-28 13:08:25 +02:00
export class ParenthesizedExpression extends Expression {
kind = NodeKind.PARENTHESIZED;
2017-12-18 03:46:36 +01:00
/** Expression in parenthesis. */
2017-09-28 13:08:25 +02:00
expression: Expression;
2017-12-16 17:54:53 +01:00
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a property access expression. */
2017-12-16 17:54:53 +01:00
export class PropertyAccessExpression extends Expression {
kind = NodeKind.PROPERTYACCESS;
2017-12-18 03:46:36 +01:00
/** Expression being accessed. */
2017-12-16 17:54:53 +01:00
expression: Expression;
2017-12-18 03:46:36 +01:00
/** Property of the expression being accessed. */
2017-12-16 17:54:53 +01:00
property: IdentifierExpression;
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a regular expression literal expression. */
2017-12-16 17:54:53 +01:00
export class RegexpLiteralExpression extends LiteralExpression {
literalKind = LiteralKind.REGEXP;
2017-12-18 03:46:36 +01:00
/** Regular expression pattern. */
pattern: string;
2018-01-07 18:15:21 +01:00
/** Regular expression flags. */
patternFlags: string;
2017-12-16 17:54:53 +01:00
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a ternary expression, i.e., short if notation. */
2017-12-16 17:54:53 +01:00
export class TernaryExpression extends Expression {
kind = NodeKind.TERNARY;
2017-12-18 03:46:36 +01:00
/** Condition expression. */
2017-12-16 17:54:53 +01:00
condition: Expression;
2017-12-18 03:46:36 +01:00
/** Expression executed when condition is `true`. */
2017-12-16 17:54:53 +01:00
ifThen: Expression;
2017-12-18 03:46:36 +01:00
/** Expression executed when condition is `false`. */
2017-12-16 17:54:53 +01:00
ifElse: Expression;
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a string literal expression. */
2017-12-16 17:54:53 +01:00
export class StringLiteralExpression extends LiteralExpression {
literalKind = LiteralKind.STRING;
2017-12-18 03:46:36 +01:00
/** String value without quotes. */
2017-12-16 17:54:53 +01:00
value: string;
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a `super` expression. */
2017-12-16 17:54:53 +01:00
export class SuperExpression extends IdentifierExpression {
kind = NodeKind.SUPER;
name = "super";
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a `this` expression. */
2017-12-16 17:54:53 +01:00
export class ThisExpression extends IdentifierExpression {
kind = NodeKind.THIS;
name = "this";
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a `true` expression. */
2017-12-16 17:54:53 +01:00
export class TrueExpression extends IdentifierExpression {
kind = NodeKind.TRUE;
name = "true";
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a `false` expression. */
2017-12-16 17:54:53 +01:00
export class FalseExpression extends IdentifierExpression {
kind = NodeKind.FALSE;
name = "false";
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Base class of all unary expressions. */
2017-12-16 17:54:53 +01:00
export abstract class UnaryExpression extends Expression {
2017-12-18 03:46:36 +01:00
/** Operator token. */
2017-12-16 17:54:53 +01:00
operator: Token;
2017-12-18 03:46:36 +01:00
/** Operand expression. */
operand: Expression;
2017-12-16 17:54:53 +01:00
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a unary postfix expression, e.g. a postfix increment. */
2017-12-16 17:54:53 +01:00
export class UnaryPostfixExpression extends UnaryExpression {
kind = NodeKind.UNARYPOSTFIX;
}
2017-09-28 13:08:25 +02:00
2017-12-18 03:46:36 +01:00
/** Represents a unary prefix expression, e.g. a negation. */
2017-12-16 17:54:53 +01:00
export class UnaryPrefixExpression extends UnaryExpression {
kind = NodeKind.UNARYPREFIX;
2017-09-28 13:08:25 +02:00
}
2017-12-16 17:54:53 +01:00
// statements
2017-12-18 03:46:36 +01:00
/** Indicates the specific kind of a modifier. */
2017-12-16 17:54:53 +01:00
export enum ModifierKind {
ASYNC,
CONST,
DECLARE,
EXPORT,
IMPORT,
STATIC,
ABSTRACT,
PUBLIC,
PRIVATE,
PROTECTED,
READONLY,
GET,
SET,
}
/** Base class of all statement nodes. */
export abstract class Statement extends Node { }
export enum SourceKind {
DEFAULT,
ENTRY,
STDLIB
}
2017-12-18 03:46:36 +01:00
/** A top-level source node. */
2017-10-02 12:52:15 +02:00
export class Source extends Node {
2017-09-28 13:08:25 +02:00
kind = NodeKind.SOURCE;
parent = null;
2017-12-18 03:46:36 +01:00
/** Source kind. */
sourceKind: SourceKind;
2017-12-18 03:46:36 +01:00
/** Path as provided to the parser. */
2017-09-28 13:08:25 +02:00
path: string;
2017-12-18 03:46:36 +01:00
/** Normalized path. */
2017-10-02 12:52:15 +02:00
normalizedPath: string;
2017-12-18 03:46:36 +01:00
/** Path used internally. */
internalPath: string;
2017-12-18 03:46:36 +01:00
/** Contained statements. */
2017-09-28 13:08:25 +02:00
statements: Statement[];
2017-12-18 03:46:36 +01:00
/** Full source text. */
2017-10-02 12:52:15 +02:00
text: string;
2017-12-18 03:46:36 +01:00
/** Tokenizer reference. */
2017-10-02 12:52:15 +02:00
tokenizer: Tokenizer | null = null;
2017-12-18 03:46:36 +01:00
/** Constructs a new source node. */
constructor(path: string, text: string, kind: SourceKind = SourceKind.DEFAULT) {
2017-10-02 12:52:15 +02:00
super();
this.sourceKind = kind;
2017-10-02 12:52:15 +02:00
this.path = path;
this.normalizedPath = normalizePath(path, true);
this.internalPath = mangleInternalPath(this.normalizedPath);
2017-10-02 12:52:15 +02:00
this.statements = new Array();
this.range = new Range(this, 0, text.length);
this.text = text;
}
/** Tests if this source is an entry file. */
get isEntry(): bool { return this.sourceKind == SourceKind.ENTRY; }
/** Tests if this source is a stdlib file. */
get isStdlib(): bool { return this.sourceKind == SourceKind.STDLIB; }
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Base class of all declaration statements. */
2017-09-28 13:08:25 +02:00
export abstract class DeclarationStatement extends Statement {
2017-12-18 03:46:36 +01:00
/** Simple name being declared. */
name: IdentifierExpression;
/** Array of modifiers. */
modifiers: Modifier[] | null;
2017-12-18 03:46:36 +01:00
/** Array of decorators. */
decorators: Decorator[] | null = null;
protected _cachedInternalName: string | null = null;
2017-12-18 03:46:36 +01:00
/** Gets the mangled internal name of this declaration. */
get internalName(): string { return this._cachedInternalName === null ? this._cachedInternalName = mangleInternalName(this) : this._cachedInternalName; }
/** Tests if this is a top-level declaration. */
get isTopLevel(): bool { return this.parent != null && this.parent.kind == NodeKind.SOURCE; }
}
2017-12-18 03:46:36 +01:00
/** Base class of all variable-like declaration statements with a type and initializer. */
export abstract class VariableLikeDeclarationStatement extends DeclarationStatement {
2017-12-18 03:46:36 +01:00
/** Variable type. */
type: TypeNode | null;
2017-12-18 03:46:36 +01:00
/** Variable initializer. */
initializer: Expression | null;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a block statement. */
2017-09-28 13:08:25 +02:00
export class BlockStatement extends Statement {
kind = NodeKind.BLOCK;
2017-12-18 03:46:36 +01:00
/** Contained statements. */
2017-09-28 13:08:25 +02:00
statements: Statement[];
}
2017-12-18 03:46:36 +01:00
/** Represents a `break` statement. */
2017-09-28 13:08:25 +02:00
export class BreakStatement extends Statement {
kind = NodeKind.BREAK;
2017-12-18 03:46:36 +01:00
/** Target label, if applicable. */
2017-09-28 13:08:25 +02:00
label: IdentifierExpression | null;
}
2017-12-18 03:46:36 +01:00
/** Represents a `class` declaration. */
2017-09-28 13:08:25 +02:00
export class ClassDeclaration extends DeclarationStatement {
kind = NodeKind.CLASSDECLARATION;
2017-12-18 03:46:36 +01:00
/** Accepted type parameters. */
2017-09-28 13:08:25 +02:00
typeParameters: TypeParameter[];
2017-12-18 03:46:36 +01:00
/** Base class type being extended. */
2017-09-28 13:08:25 +02:00
extendsType: TypeNode | null;
2017-12-18 03:46:36 +01:00
/** Interface types being implemented. */
2017-09-28 13:08:25 +02:00
implementsTypes: TypeNode[];
2017-12-18 03:46:36 +01:00
/** Class member declarations. */
2017-09-28 13:08:25 +02:00
members: DeclarationStatement[];
}
2017-12-18 03:46:36 +01:00
/** Represents a `continue` statement. */
2017-09-28 13:08:25 +02:00
export class ContinueStatement extends Statement {
kind = NodeKind.CONTINUE;
2017-12-18 03:46:36 +01:00
/** Target label, if applicable. */
2017-09-28 13:08:25 +02:00
label: IdentifierExpression | null;
}
2018-01-06 10:20:38 +01:00
/** Built-in decorator kinds. */
export const enum DecoratorKind {
CUSTOM,
GLOBAL,
OPERATOR,
EXPLICIT,
OFFSET
2018-01-06 10:20:38 +01:00
}
2017-12-18 03:46:36 +01:00
/** Depresents a decorator. */
export class Decorator extends Statement {
2017-10-02 12:52:15 +02:00
kind = NodeKind.DECORATOR;
2017-12-18 03:46:36 +01:00
/** Name expression. */
name: Expression;
/** Argument expressions. */
arguments: Expression[] | null;
2018-01-06 10:20:38 +01:00
/** Built-in kind, if applicable. */
decoratorKind: DecoratorKind;
2017-10-02 12:52:15 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a `do` statement. */
2017-09-28 13:08:25 +02:00
export class DoStatement extends Statement {
kind = NodeKind.DO;
2017-12-18 03:46:36 +01:00
/** Statement being looped over. */
2017-09-28 13:08:25 +02:00
statement: Statement;
2017-12-18 03:46:36 +01:00
/** Condition when to repeat. */
2017-09-28 13:08:25 +02:00
condition: Expression;
}
2017-12-18 03:46:36 +01:00
/** Represents an empty statement, i.e., a semicolon terminating nothing. */
2017-09-28 13:08:25 +02:00
export class EmptyStatement extends Statement {
kind = NodeKind.EMPTY;
}
2017-12-18 03:46:36 +01:00
/** Represents an `enum` declaration. */
2017-09-28 13:08:25 +02:00
export class EnumDeclaration extends DeclarationStatement {
kind = NodeKind.ENUMDECLARATION;
2017-12-18 03:46:36 +01:00
/** Enum value declarations. */
values: EnumValueDeclaration[];
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a value of an `enum` declaration. */
2017-09-28 13:08:25 +02:00
export class EnumValueDeclaration extends DeclarationStatement {
kind = NodeKind.ENUMVALUEDECLARATION;
modifiers = null;
2017-12-18 03:46:36 +01:00
// name is inherited
/** Value expression. */
2017-09-28 13:08:25 +02:00
value: Expression | null;
}
2017-12-18 03:46:36 +01:00
/** Represents an `export import` statement of an interface. */
2017-09-28 13:08:25 +02:00
export class ExportImportStatement extends Node {
kind = NodeKind.EXPORTIMPORT;
2017-12-18 03:46:36 +01:00
/** Identifier being imported. */
2017-09-28 13:08:25 +02:00
identifier: IdentifierExpression;
2017-12-18 03:46:36 +01:00
/** Identifier being exported. */
externalIdentifier: IdentifierExpression;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a member of an `export` statement. */
2017-09-28 13:08:25 +02:00
export class ExportMember extends Node {
kind = NodeKind.EXPORTMEMBER;
2017-12-18 03:46:36 +01:00
/** Identifier being exported. */
2017-09-28 13:08:25 +02:00
identifier: IdentifierExpression;
2017-12-18 03:46:36 +01:00
/** Identifier seen when imported again. */
externalIdentifier: IdentifierExpression;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents an `export` statement. */
2017-09-28 13:08:25 +02:00
export class ExportStatement extends Statement {
kind = NodeKind.EXPORT;
2017-12-18 03:46:36 +01:00
/** Array of modifiers. */
modifiers: Modifier[] | null;
2017-12-18 03:46:36 +01:00
/** Array of members. */
2017-09-28 13:08:25 +02:00
members: ExportMember[];
2017-12-18 03:46:36 +01:00
/** Path being exported from, if applicable. */
path: StringLiteralExpression | null;
2017-12-18 03:46:36 +01:00
/** Normalized path, if `path` is set. */
2017-10-02 12:52:15 +02:00
normalizedPath: string | null;
2017-12-18 03:46:36 +01:00
/** Mangled internal path being referenced, if `path` is set. */
internalPath: string | null;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents an expression statement, i.e., an expression being used as a statement */
2017-09-28 13:08:25 +02:00
export class ExpressionStatement extends Statement {
kind = NodeKind.EXPRESSION;
2017-12-18 03:46:36 +01:00
/** Expression being used as a statement.*/
2017-09-28 13:08:25 +02:00
expression: Expression;
}
2017-12-18 03:46:36 +01:00
/** Represents a field declaration within a `class`. */
export class FieldDeclaration extends VariableLikeDeclarationStatement {
kind = NodeKind.FIELDDECLARATION;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a `for` statement. */
2017-09-28 13:08:25 +02:00
export class ForStatement extends Statement {
kind = NodeKind.FOR;
2017-12-18 03:46:36 +01:00
/** Initializer statement, if present. Either a {@link VariableStatement} or {@link ExpressionStatement}. */
2017-09-28 13:08:25 +02:00
initializer: Statement | null;
2017-12-18 03:46:36 +01:00
/** Condition expression, if present. */
2017-09-28 13:08:25 +02:00
condition: Expression | null;
2017-12-18 03:46:36 +01:00
/** Incrementor expression, if present. */
2017-09-28 13:08:25 +02:00
incrementor: Expression | null;
2017-12-18 03:46:36 +01:00
/** Statement being looped over. */
2017-09-28 13:08:25 +02:00
statement: Statement;
}
2017-12-18 03:46:36 +01:00
/** Represents a `function` declaration. */
2017-09-28 13:08:25 +02:00
export class FunctionDeclaration extends DeclarationStatement {
kind = NodeKind.FUNCTIONDECLARATION;
2017-12-18 03:46:36 +01:00
/** Accepted type parameters. */
2017-09-28 13:08:25 +02:00
typeParameters: TypeParameter[];
2017-12-18 03:46:36 +01:00
/** Accepted parameters. */
2017-09-28 13:08:25 +02:00
parameters: Parameter[];
2017-12-18 03:46:36 +01:00
/** Return type. */
2017-09-28 13:08:25 +02:00
returnType: TypeNode | null;
2017-12-18 03:46:36 +01:00
/** Contained statements. */
2017-09-28 13:08:25 +02:00
statements: Statement[] | null;
}
2017-12-18 03:46:36 +01:00
/** Represents an `if` statement. */
2017-09-28 13:08:25 +02:00
export class IfStatement extends Statement {
kind = NodeKind.IF;
2017-12-18 03:46:36 +01:00
/** Condition. */
2017-09-28 13:08:25 +02:00
condition: Expression;
2017-12-18 03:46:36 +01:00
/** Statement executed when condition is `true`. */
ifTrue: Statement;
/** Statement executed when condition is `false`. */
ifFalse: Statement | null;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents an `import` declaration, a single member within an {@link ImportStatement}. */
2017-09-28 13:08:25 +02:00
export class ImportDeclaration extends DeclarationStatement {
kind = NodeKind.IMPORTDECLARATION;
modifiers = null;
2017-12-18 03:46:36 +01:00
/** Identifier being imported. */
2017-09-28 13:08:25 +02:00
externalIdentifier: IdentifierExpression;
}
2017-12-18 03:46:36 +01:00
/** Represents an `import` statement. */
2017-09-28 13:08:25 +02:00
export class ImportStatement extends Statement {
kind = NodeKind.IMPORT;
2017-12-18 03:46:36 +01:00
/** Array of member declarations or `null` if an asterisk import. */
declarations: ImportDeclaration[] | null;
/** Name of the local namespace, if an asterisk import. */
namespaceName: IdentifierExpression | null;
2017-12-18 03:46:36 +01:00
/** Path being imported from. */
path: StringLiteralExpression;
2017-12-18 03:46:36 +01:00
/** Normalized path. */
2017-10-02 12:52:15 +02:00
normalizedPath: string;
2017-12-18 03:46:36 +01:00
/** Mangled internal path being referenced. */
internalPath: string;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents an `interfarce` declaration. */
export class InterfaceDeclaration extends ClassDeclaration {
kind = NodeKind.INTERFACEDECLARATION;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a method declaration within a `class`. */
2017-09-28 13:08:25 +02:00
export class MethodDeclaration extends FunctionDeclaration {
kind = NodeKind.METHODDECLARATION;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a `namespace` declaration. */
2017-09-28 13:08:25 +02:00
export class NamespaceDeclaration extends DeclarationStatement {
kind = NodeKind.NAMESPACEDECLARATION;
2017-12-18 03:46:36 +01:00
/** Array of namespace members. */
2017-10-07 14:29:43 +02:00
members: Statement[];
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a function parameter. */
2017-09-28 13:08:25 +02:00
export class Parameter extends Node {
2017-12-18 03:46:36 +01:00
kind = NodeKind.PARAMETER;
/** Parameter name. */
name: IdentifierExpression;
/** Parameter type. */
2017-09-28 13:08:25 +02:00
type: TypeNode | null;
2017-12-18 03:46:36 +01:00
/** Initializer expression, if present. */
2017-09-28 13:08:25 +02:00
initializer: Expression | null;
2017-12-18 03:46:36 +01:00
/** Whether a rest parameter or not. */
isRest: bool;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a single modifier. */
2017-09-28 13:08:25 +02:00
export class Modifier extends Node {
2017-12-18 03:46:36 +01:00
kind = NodeKind.MODIFIER;
/** Specific modifier kind. */
2017-09-28 13:08:25 +02:00
modifierKind: ModifierKind;
}
2017-12-18 03:46:36 +01:00
/** Represents a `return` statement. */
2017-09-28 13:08:25 +02:00
export class ReturnStatement extends Statement {
kind = NodeKind.RETURN;
2017-12-18 03:46:36 +01:00
/** Value expression being returned, if present. */
value: Expression | null;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a single `case` within a `switch` statement. */
2017-09-28 13:08:25 +02:00
export class SwitchCase extends Node {
kind = NodeKind.SWITCHCASE;
2017-12-18 03:46:36 +01:00
/** Label expression. `null` indicates the default case. */
label: Expression | null;
/** Contained statements. */
2017-09-28 13:08:25 +02:00
statements: Statement[];
}
2017-12-18 03:46:36 +01:00
/** Represents a `switch` statement. */
2017-09-28 13:08:25 +02:00
export class SwitchStatement extends Statement {
kind = NodeKind.SWITCH;
2017-12-18 03:46:36 +01:00
/** Condition expression. */
condition: Expression;
/** Contained cases. */
2017-09-28 13:08:25 +02:00
cases: SwitchCase[];
}
2017-12-18 03:46:36 +01:00
/** Represents a `throw` statement. */
2017-09-28 13:08:25 +02:00
export class ThrowStatement extends Statement {
kind = NodeKind.THROW;
2017-12-18 03:46:36 +01:00
/** Value expression being thrown. */
value: Expression;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a `try` statement. */
2017-09-28 13:08:25 +02:00
export class TryStatement extends Statement {
kind = NodeKind.TRY;
2017-12-18 03:46:36 +01:00
/** Contained statements. */
2017-09-28 13:08:25 +02:00
statements: Statement[];
2017-12-18 03:46:36 +01:00
/** Variable identifier for a caught exception, if a `catch` clause is present. */
2017-10-07 14:29:43 +02:00
catchVariable: IdentifierExpression | null;
2017-12-18 03:46:36 +01:00
/** Statements being executed when an exception has been caught, if a `catch` clause is present. */
2017-10-07 14:29:43 +02:00
catchStatements: Statement[] | null;
2017-12-18 03:46:36 +01:00
/** Statements being executed in any case, if a `finally` clause is present. */
2017-10-07 14:29:43 +02:00
finallyStatements: Statement[] | null;
2017-09-28 13:08:25 +02:00
}
/** Represents a `type` declaration. */
export class TypeDeclaration extends DeclarationStatement {
kind = NodeKind.TYPEDECLARATION;
/** Type being aliased. */
alias: TypeNode;
}
2017-12-18 03:46:36 +01:00
/** Represents a single variable declaration within a {@link VariableStatement}. */
export class VariableDeclaration extends VariableLikeDeclarationStatement {
2017-09-28 13:08:25 +02:00
kind = NodeKind.VARIABLEDECLARATION;
2017-12-18 03:46:36 +01:00
/** Array of modifiers. */
modifiers: Modifier[] | null;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a variable statement, i.e., a `var`, `let` or `const` statement. */
2017-09-28 13:08:25 +02:00
export class VariableStatement extends Statement {
kind = NodeKind.VARIABLE;
2017-12-18 03:46:36 +01:00
/** Array of modifiers. */
modifiers: Modifier[] | null;
2017-12-18 03:46:36 +01:00
/** Array of decorators. */
decorators: Decorator[] | null;
2017-12-18 03:46:36 +01:00
/** Array of member declarations. */
2017-10-02 12:52:15 +02:00
declarations: VariableDeclaration[];
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Represents a `while` statement. */
2017-09-28 13:08:25 +02:00
export class WhileStatement extends Statement {
kind = NodeKind.WHILE;
2017-12-18 03:46:36 +01:00
/** Condition expression. */
2017-09-28 13:08:25 +02:00
condition: Expression;
2017-12-18 03:46:36 +01:00
/** Statement being looped over. */
2017-09-28 13:08:25 +02:00
statement: Statement;
}
2017-12-18 03:46:36 +01:00
/** Cached unused modifiers for reuse. */
var reusableModifiers: Modifier[] | null = null;
2017-12-18 03:46:36 +01:00
export function setReusableModifiers(modifiers: Modifier[]) {
reusableModifiers = modifiers;
}
/** Creates a new modifiers array. */
export function createModifiers(): Modifier[] {
var ret: Modifier[];
2017-12-18 03:46:36 +01:00
if (reusableModifiers != null) {
ret = reusableModifiers;
reusableModifiers = null;
} else
ret = new Array(1);
ret.length = 0;
return ret;
}
/** Adds a modifier to a modifiers array. Creates and returns a new array if `null`. */
export function addModifier(modifier: Modifier, modifiers: Modifier[] | null): Modifier[] {
if (modifiers == null)
modifiers = createModifiers();
modifiers.push(modifier);
return modifiers;
}
/** Gets a specific modifier from the specified array of modifiers. */
export function getModifier(kind: ModifierKind, modifiers: Modifier[] | null): Modifier | null {
if (modifiers)
for (var i = 0, k = modifiers.length; i < k; ++i)
2017-12-18 03:46:36 +01:00
if (modifiers[i].modifierKind == kind)
return modifiers[i];
return null;
2017-09-28 13:08:25 +02:00
}
2017-12-18 03:46:36 +01:00
/** Tests whether a specific modifier exists in the specified array of modifiers. */
export function hasModifier(kind: ModifierKind, modifiers: Modifier[] | null): bool {
return getModifier(kind, modifiers) != null;
}
/** Gets a specific decorator within the specified decorators, if present. */
2018-01-06 10:20:38 +01:00
export function getFirstDecorator(name: string, decorators: Decorator[] | null): Decorator | null {
2017-12-16 02:27:39 +01:00
if (decorators)
for (var i = 0, k = decorators.length; i < k; ++i) {
var decorator = decorators[i];
var expression = decorator.name;
2017-12-16 02:27:39 +01:00
if (expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>expression).name == name)
return decorator;
}
return null;
}
2017-12-18 03:46:36 +01:00
/** Tests if a specific decorator is present within the specified decorators. */
2017-12-16 02:27:39 +01:00
export function hasDecorator(name: string, decorators: Decorator[] | null): bool {
2018-01-06 10:20:38 +01:00
return getFirstDecorator(name, decorators) != null;
2017-12-16 02:27:39 +01:00
}
2017-12-18 03:46:36 +01:00
/** Mangles a path to an internal path. */
export function mangleInternalPath(path: string): string {
// not necessary with current config
// if (PATH_DELIMITER.charCodeAt(0) != CharCode.SLASH)
// path = path.replace("/", PATH_DELIMITER);
// if (PARENT_SUBST != "..")
// path = path.replace("..", PARENT_SUBST);
return path;
}
2017-12-18 03:46:36 +01:00
/** Mangles a declaration's name to an internal name. */
export function mangleInternalName(declaration: DeclarationStatement): string {
var name = declaration.name.name;
var parent = declaration.parent;
2017-12-13 23:24:13 +01:00
if (!parent)
return name;
2017-12-13 23:24:13 +01:00
if (declaration.kind == NodeKind.VARIABLEDECLARATION && parent.kind == NodeKind.VARIABLE) // skip over
if (!(parent = parent.parent))
return name;
if (parent.kind == NodeKind.CLASSDECLARATION)
2017-12-13 23:24:13 +01:00
return (<ClassDeclaration>parent).internalName + (hasModifier(ModifierKind.STATIC, declaration.modifiers) ? STATIC_DELIMITER : INSTANCE_DELIMITER) + name;
if (parent.kind == NodeKind.NAMESPACEDECLARATION || parent.kind == NodeKind.ENUMDECLARATION)
2017-12-13 23:24:13 +01:00
return (<DeclarationStatement>parent).internalName + STATIC_DELIMITER + name;
return declaration.range.source.internalPath + PATH_DELIMITER + name;
}