@angular/compiler
Version:
Angular - the compiler library
1,215 lines • 184 kB
JavaScript
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
//// Types
export var TypeModifier;
(function (TypeModifier) {
TypeModifier[TypeModifier["Const"] = 0] = "Const";
})(TypeModifier || (TypeModifier = {}));
export class Type {
constructor(modifiers = null) {
this.modifiers = modifiers;
if (!modifiers) {
this.modifiers = [];
}
}
hasModifier(modifier) { return this.modifiers.indexOf(modifier) !== -1; }
}
export var BuiltinTypeName;
(function (BuiltinTypeName) {
BuiltinTypeName[BuiltinTypeName["Dynamic"] = 0] = "Dynamic";
BuiltinTypeName[BuiltinTypeName["Bool"] = 1] = "Bool";
BuiltinTypeName[BuiltinTypeName["String"] = 2] = "String";
BuiltinTypeName[BuiltinTypeName["Int"] = 3] = "Int";
BuiltinTypeName[BuiltinTypeName["Number"] = 4] = "Number";
BuiltinTypeName[BuiltinTypeName["Function"] = 5] = "Function";
BuiltinTypeName[BuiltinTypeName["Inferred"] = 6] = "Inferred";
BuiltinTypeName[BuiltinTypeName["None"] = 7] = "None";
})(BuiltinTypeName || (BuiltinTypeName = {}));
export class BuiltinType extends Type {
constructor(name, modifiers = null) {
super(modifiers);
this.name = name;
}
visitType(visitor, context) {
return visitor.visitBuiltinType(this, context);
}
}
export class ExpressionType extends Type {
constructor(value, modifiers = null, typeParams = null) {
super(modifiers);
this.value = value;
this.typeParams = typeParams;
}
visitType(visitor, context) {
return visitor.visitExpressionType(this, context);
}
}
export class ArrayType extends Type {
constructor(of, modifiers = null) {
super(modifiers);
this.of = of;
}
visitType(visitor, context) {
return visitor.visitArrayType(this, context);
}
}
export class MapType extends Type {
constructor(valueType, modifiers = null) {
super(modifiers);
this.valueType = valueType || null;
}
visitType(visitor, context) { return visitor.visitMapType(this, context); }
}
export const DYNAMIC_TYPE = new BuiltinType(BuiltinTypeName.Dynamic);
export const INFERRED_TYPE = new BuiltinType(BuiltinTypeName.Inferred);
export const BOOL_TYPE = new BuiltinType(BuiltinTypeName.Bool);
export const INT_TYPE = new BuiltinType(BuiltinTypeName.Int);
export const NUMBER_TYPE = new BuiltinType(BuiltinTypeName.Number);
export const STRING_TYPE = new BuiltinType(BuiltinTypeName.String);
export const FUNCTION_TYPE = new BuiltinType(BuiltinTypeName.Function);
export const NONE_TYPE = new BuiltinType(BuiltinTypeName.None);
///// Expressions
export var BinaryOperator;
(function (BinaryOperator) {
BinaryOperator[BinaryOperator["Equals"] = 0] = "Equals";
BinaryOperator[BinaryOperator["NotEquals"] = 1] = "NotEquals";
BinaryOperator[BinaryOperator["Identical"] = 2] = "Identical";
BinaryOperator[BinaryOperator["NotIdentical"] = 3] = "NotIdentical";
BinaryOperator[BinaryOperator["Minus"] = 4] = "Minus";
BinaryOperator[BinaryOperator["Plus"] = 5] = "Plus";
BinaryOperator[BinaryOperator["Divide"] = 6] = "Divide";
BinaryOperator[BinaryOperator["Multiply"] = 7] = "Multiply";
BinaryOperator[BinaryOperator["Modulo"] = 8] = "Modulo";
BinaryOperator[BinaryOperator["And"] = 9] = "And";
BinaryOperator[BinaryOperator["Or"] = 10] = "Or";
BinaryOperator[BinaryOperator["BitwiseAnd"] = 11] = "BitwiseAnd";
BinaryOperator[BinaryOperator["Lower"] = 12] = "Lower";
BinaryOperator[BinaryOperator["LowerEquals"] = 13] = "LowerEquals";
BinaryOperator[BinaryOperator["Bigger"] = 14] = "Bigger";
BinaryOperator[BinaryOperator["BiggerEquals"] = 15] = "BiggerEquals";
})(BinaryOperator || (BinaryOperator = {}));
export function nullSafeIsEquivalent(base, other) {
if (base == null || other == null) {
return base == other;
}
return base.isEquivalent(other);
}
export function areAllEquivalent(base, other) {
const len = base.length;
if (len !== other.length) {
return false;
}
for (let i = 0; i < len; i++) {
if (!base[i].isEquivalent(other[i])) {
return false;
}
}
return true;
}
export class Expression {
constructor(type, sourceSpan) {
this.type = type || null;
this.sourceSpan = sourceSpan || null;
}
prop(name, sourceSpan) {
return new ReadPropExpr(this, name, null, sourceSpan);
}
key(index, type, sourceSpan) {
return new ReadKeyExpr(this, index, type, sourceSpan);
}
callMethod(name, params, sourceSpan) {
return new InvokeMethodExpr(this, name, params, null, sourceSpan);
}
callFn(params, sourceSpan) {
return new InvokeFunctionExpr(this, params, null, sourceSpan);
}
instantiate(params, type, sourceSpan) {
return new InstantiateExpr(this, params, type, sourceSpan);
}
conditional(trueCase, falseCase = null, sourceSpan) {
return new ConditionalExpr(this, trueCase, falseCase, null, sourceSpan);
}
equals(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Equals, this, rhs, null, sourceSpan);
}
notEquals(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.NotEquals, this, rhs, null, sourceSpan);
}
identical(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Identical, this, rhs, null, sourceSpan);
}
notIdentical(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.NotIdentical, this, rhs, null, sourceSpan);
}
minus(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Minus, this, rhs, null, sourceSpan);
}
plus(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Plus, this, rhs, null, sourceSpan);
}
divide(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Divide, this, rhs, null, sourceSpan);
}
multiply(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Multiply, this, rhs, null, sourceSpan);
}
modulo(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Modulo, this, rhs, null, sourceSpan);
}
and(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.And, this, rhs, null, sourceSpan);
}
bitwiseAnd(rhs, sourceSpan, parens = true) {
return new BinaryOperatorExpr(BinaryOperator.BitwiseAnd, this, rhs, null, sourceSpan, parens);
}
or(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Or, this, rhs, null, sourceSpan);
}
lower(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Lower, this, rhs, null, sourceSpan);
}
lowerEquals(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.LowerEquals, this, rhs, null, sourceSpan);
}
bigger(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.Bigger, this, rhs, null, sourceSpan);
}
biggerEquals(rhs, sourceSpan) {
return new BinaryOperatorExpr(BinaryOperator.BiggerEquals, this, rhs, null, sourceSpan);
}
isBlank(sourceSpan) {
// Note: We use equals by purpose here to compare to null and undefined in JS.
// We use the typed null to allow strictNullChecks to narrow types.
return this.equals(TYPED_NULL_EXPR, sourceSpan);
}
cast(type, sourceSpan) {
return new CastExpr(this, type, sourceSpan);
}
toStmt() { return new ExpressionStatement(this, null); }
}
export var BuiltinVar;
(function (BuiltinVar) {
BuiltinVar[BuiltinVar["This"] = 0] = "This";
BuiltinVar[BuiltinVar["Super"] = 1] = "Super";
BuiltinVar[BuiltinVar["CatchError"] = 2] = "CatchError";
BuiltinVar[BuiltinVar["CatchStack"] = 3] = "CatchStack";
})(BuiltinVar || (BuiltinVar = {}));
export class ReadVarExpr extends Expression {
constructor(name, type, sourceSpan) {
super(type, sourceSpan);
if (typeof name === 'string') {
this.name = name;
this.builtin = null;
}
else {
this.name = null;
this.builtin = name;
}
}
isEquivalent(e) {
return e instanceof ReadVarExpr && this.name === e.name && this.builtin === e.builtin;
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitReadVarExpr(this, context);
}
set(value) {
if (!this.name) {
throw new Error(`Built in variable ${this.builtin} can not be assigned to.`);
}
return new WriteVarExpr(this.name, value, null, this.sourceSpan);
}
}
export class TypeofExpr extends Expression {
constructor(expr, type, sourceSpan) {
super(type, sourceSpan);
this.expr = expr;
}
visitExpression(visitor, context) {
return visitor.visitTypeofExpr(this, context);
}
isEquivalent(e) {
return e instanceof TypeofExpr && e.expr.isEquivalent(this.expr);
}
isConstant() { return this.expr.isConstant(); }
}
export class WrappedNodeExpr extends Expression {
constructor(node, type, sourceSpan) {
super(type, sourceSpan);
this.node = node;
}
isEquivalent(e) {
return e instanceof WrappedNodeExpr && this.node === e.node;
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitWrappedNodeExpr(this, context);
}
}
export class WriteVarExpr extends Expression {
constructor(name, value, type, sourceSpan) {
super(type || value.type, sourceSpan);
this.name = name;
this.value = value;
}
isEquivalent(e) {
return e instanceof WriteVarExpr && this.name === e.name && this.value.isEquivalent(e.value);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitWriteVarExpr(this, context);
}
toDeclStmt(type, modifiers) {
return new DeclareVarStmt(this.name, this.value, type, modifiers, this.sourceSpan);
}
}
export class WriteKeyExpr extends Expression {
constructor(receiver, index, value, type, sourceSpan) {
super(type || value.type, sourceSpan);
this.receiver = receiver;
this.index = index;
this.value = value;
}
isEquivalent(e) {
return e instanceof WriteKeyExpr && this.receiver.isEquivalent(e.receiver) &&
this.index.isEquivalent(e.index) && this.value.isEquivalent(e.value);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitWriteKeyExpr(this, context);
}
}
export class WritePropExpr extends Expression {
constructor(receiver, name, value, type, sourceSpan) {
super(type || value.type, sourceSpan);
this.receiver = receiver;
this.name = name;
this.value = value;
}
isEquivalent(e) {
return e instanceof WritePropExpr && this.receiver.isEquivalent(e.receiver) &&
this.name === e.name && this.value.isEquivalent(e.value);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitWritePropExpr(this, context);
}
}
export var BuiltinMethod;
(function (BuiltinMethod) {
BuiltinMethod[BuiltinMethod["ConcatArray"] = 0] = "ConcatArray";
BuiltinMethod[BuiltinMethod["SubscribeObservable"] = 1] = "SubscribeObservable";
BuiltinMethod[BuiltinMethod["Bind"] = 2] = "Bind";
})(BuiltinMethod || (BuiltinMethod = {}));
export class InvokeMethodExpr extends Expression {
constructor(receiver, method, args, type, sourceSpan) {
super(type, sourceSpan);
this.receiver = receiver;
this.args = args;
if (typeof method === 'string') {
this.name = method;
this.builtin = null;
}
else {
this.name = null;
this.builtin = method;
}
}
isEquivalent(e) {
return e instanceof InvokeMethodExpr && this.receiver.isEquivalent(e.receiver) &&
this.name === e.name && this.builtin === e.builtin && areAllEquivalent(this.args, e.args);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitInvokeMethodExpr(this, context);
}
}
export class InvokeFunctionExpr extends Expression {
constructor(fn, args, type, sourceSpan) {
super(type, sourceSpan);
this.fn = fn;
this.args = args;
}
isEquivalent(e) {
return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) &&
areAllEquivalent(this.args, e.args);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitInvokeFunctionExpr(this, context);
}
}
export class InstantiateExpr extends Expression {
constructor(classExpr, args, type, sourceSpan) {
super(type, sourceSpan);
this.classExpr = classExpr;
this.args = args;
}
isEquivalent(e) {
return e instanceof InstantiateExpr && this.classExpr.isEquivalent(e.classExpr) &&
areAllEquivalent(this.args, e.args);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitInstantiateExpr(this, context);
}
}
export class LiteralExpr extends Expression {
constructor(value, type, sourceSpan) {
super(type, sourceSpan);
this.value = value;
}
isEquivalent(e) {
return e instanceof LiteralExpr && this.value === e.value;
}
isConstant() { return true; }
visitExpression(visitor, context) {
return visitor.visitLiteralExpr(this, context);
}
}
export class ExternalExpr extends Expression {
constructor(value, type, typeParams = null, sourceSpan) {
super(type, sourceSpan);
this.value = value;
this.typeParams = typeParams;
}
isEquivalent(e) {
return e instanceof ExternalExpr && this.value.name === e.value.name &&
this.value.moduleName === e.value.moduleName && this.value.runtime === e.value.runtime;
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitExternalExpr(this, context);
}
}
export class ExternalReference {
constructor(moduleName, name, runtime) {
this.moduleName = moduleName;
this.name = name;
this.runtime = runtime;
}
}
export class ConditionalExpr extends Expression {
constructor(condition, trueCase, falseCase = null, type, sourceSpan) {
super(type || trueCase.type, sourceSpan);
this.condition = condition;
this.falseCase = falseCase;
this.trueCase = trueCase;
}
isEquivalent(e) {
return e instanceof ConditionalExpr && this.condition.isEquivalent(e.condition) &&
this.trueCase.isEquivalent(e.trueCase) && nullSafeIsEquivalent(this.falseCase, e.falseCase);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitConditionalExpr(this, context);
}
}
export class NotExpr extends Expression {
constructor(condition, sourceSpan) {
super(BOOL_TYPE, sourceSpan);
this.condition = condition;
}
isEquivalent(e) {
return e instanceof NotExpr && this.condition.isEquivalent(e.condition);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitNotExpr(this, context);
}
}
export class AssertNotNull extends Expression {
constructor(condition, sourceSpan) {
super(condition.type, sourceSpan);
this.condition = condition;
}
isEquivalent(e) {
return e instanceof AssertNotNull && this.condition.isEquivalent(e.condition);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitAssertNotNullExpr(this, context);
}
}
export class CastExpr extends Expression {
constructor(value, type, sourceSpan) {
super(type, sourceSpan);
this.value = value;
}
isEquivalent(e) {
return e instanceof CastExpr && this.value.isEquivalent(e.value);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitCastExpr(this, context);
}
}
export class FnParam {
constructor(name, type = null) {
this.name = name;
this.type = type;
}
isEquivalent(param) { return this.name === param.name; }
}
export class FunctionExpr extends Expression {
constructor(params, statements, type, sourceSpan, name) {
super(type, sourceSpan);
this.params = params;
this.statements = statements;
this.name = name;
}
isEquivalent(e) {
return e instanceof FunctionExpr && areAllEquivalent(this.params, e.params) &&
areAllEquivalent(this.statements, e.statements);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitFunctionExpr(this, context);
}
toDeclStmt(name, modifiers = null) {
return new DeclareFunctionStmt(name, this.params, this.statements, this.type, modifiers, this.sourceSpan);
}
}
export class BinaryOperatorExpr extends Expression {
constructor(operator, lhs, rhs, type, sourceSpan, parens = true) {
super(type || lhs.type, sourceSpan);
this.operator = operator;
this.rhs = rhs;
this.parens = parens;
this.lhs = lhs;
}
isEquivalent(e) {
return e instanceof BinaryOperatorExpr && this.operator === e.operator &&
this.lhs.isEquivalent(e.lhs) && this.rhs.isEquivalent(e.rhs);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitBinaryOperatorExpr(this, context);
}
}
export class ReadPropExpr extends Expression {
constructor(receiver, name, type, sourceSpan) {
super(type, sourceSpan);
this.receiver = receiver;
this.name = name;
}
isEquivalent(e) {
return e instanceof ReadPropExpr && this.receiver.isEquivalent(e.receiver) &&
this.name === e.name;
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitReadPropExpr(this, context);
}
set(value) {
return new WritePropExpr(this.receiver, this.name, value, null, this.sourceSpan);
}
}
export class ReadKeyExpr extends Expression {
constructor(receiver, index, type, sourceSpan) {
super(type, sourceSpan);
this.receiver = receiver;
this.index = index;
}
isEquivalent(e) {
return e instanceof ReadKeyExpr && this.receiver.isEquivalent(e.receiver) &&
this.index.isEquivalent(e.index);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitReadKeyExpr(this, context);
}
set(value) {
return new WriteKeyExpr(this.receiver, this.index, value, null, this.sourceSpan);
}
}
export class LiteralArrayExpr extends Expression {
constructor(entries, type, sourceSpan) {
super(type, sourceSpan);
this.entries = entries;
}
isConstant() { return this.entries.every(e => e.isConstant()); }
isEquivalent(e) {
return e instanceof LiteralArrayExpr && areAllEquivalent(this.entries, e.entries);
}
visitExpression(visitor, context) {
return visitor.visitLiteralArrayExpr(this, context);
}
}
export class LiteralMapEntry {
constructor(key, value, quoted) {
this.key = key;
this.value = value;
this.quoted = quoted;
}
isEquivalent(e) {
return this.key === e.key && this.value.isEquivalent(e.value);
}
}
export class LiteralMapExpr extends Expression {
constructor(entries, type, sourceSpan) {
super(type, sourceSpan);
this.entries = entries;
this.valueType = null;
if (type) {
this.valueType = type.valueType;
}
}
isEquivalent(e) {
return e instanceof LiteralMapExpr && areAllEquivalent(this.entries, e.entries);
}
isConstant() { return this.entries.every(e => e.value.isConstant()); }
visitExpression(visitor, context) {
return visitor.visitLiteralMapExpr(this, context);
}
}
export class CommaExpr extends Expression {
constructor(parts, sourceSpan) {
super(parts[parts.length - 1].type, sourceSpan);
this.parts = parts;
}
isEquivalent(e) {
return e instanceof CommaExpr && areAllEquivalent(this.parts, e.parts);
}
isConstant() { return false; }
visitExpression(visitor, context) {
return visitor.visitCommaExpr(this, context);
}
}
export const THIS_EXPR = new ReadVarExpr(BuiltinVar.This, null, null);
export const SUPER_EXPR = new ReadVarExpr(BuiltinVar.Super, null, null);
export const CATCH_ERROR_VAR = new ReadVarExpr(BuiltinVar.CatchError, null, null);
export const CATCH_STACK_VAR = new ReadVarExpr(BuiltinVar.CatchStack, null, null);
export const NULL_EXPR = new LiteralExpr(null, null, null);
export const TYPED_NULL_EXPR = new LiteralExpr(null, INFERRED_TYPE, null);
//// Statements
export var StmtModifier;
(function (StmtModifier) {
StmtModifier[StmtModifier["Final"] = 0] = "Final";
StmtModifier[StmtModifier["Private"] = 1] = "Private";
StmtModifier[StmtModifier["Exported"] = 2] = "Exported";
StmtModifier[StmtModifier["Static"] = 3] = "Static";
})(StmtModifier || (StmtModifier = {}));
export class Statement {
constructor(modifiers, sourceSpan) {
this.modifiers = modifiers || [];
this.sourceSpan = sourceSpan || null;
}
hasModifier(modifier) { return this.modifiers.indexOf(modifier) !== -1; }
}
export class DeclareVarStmt extends Statement {
constructor(name, value, type, modifiers = null, sourceSpan) {
super(modifiers, sourceSpan);
this.name = name;
this.value = value;
this.type = type || (value && value.type) || null;
}
isEquivalent(stmt) {
return stmt instanceof DeclareVarStmt && this.name === stmt.name &&
(this.value ? !!stmt.value && this.value.isEquivalent(stmt.value) : !stmt.value);
}
visitStatement(visitor, context) {
return visitor.visitDeclareVarStmt(this, context);
}
}
export class DeclareFunctionStmt extends Statement {
constructor(name, params, statements, type, modifiers = null, sourceSpan) {
super(modifiers, sourceSpan);
this.name = name;
this.params = params;
this.statements = statements;
this.type = type || null;
}
isEquivalent(stmt) {
return stmt instanceof DeclareFunctionStmt && areAllEquivalent(this.params, stmt.params) &&
areAllEquivalent(this.statements, stmt.statements);
}
visitStatement(visitor, context) {
return visitor.visitDeclareFunctionStmt(this, context);
}
}
export class ExpressionStatement extends Statement {
constructor(expr, sourceSpan) {
super(null, sourceSpan);
this.expr = expr;
}
isEquivalent(stmt) {
return stmt instanceof ExpressionStatement && this.expr.isEquivalent(stmt.expr);
}
visitStatement(visitor, context) {
return visitor.visitExpressionStmt(this, context);
}
}
export class ReturnStatement extends Statement {
constructor(value, sourceSpan) {
super(null, sourceSpan);
this.value = value;
}
isEquivalent(stmt) {
return stmt instanceof ReturnStatement && this.value.isEquivalent(stmt.value);
}
visitStatement(visitor, context) {
return visitor.visitReturnStmt(this, context);
}
}
export class AbstractClassPart {
constructor(type, modifiers) {
this.modifiers = modifiers;
if (!modifiers) {
this.modifiers = [];
}
this.type = type || null;
}
hasModifier(modifier) { return this.modifiers.indexOf(modifier) !== -1; }
}
export class ClassField extends AbstractClassPart {
constructor(name, type, modifiers = null, initializer) {
super(type, modifiers);
this.name = name;
this.initializer = initializer;
}
isEquivalent(f) { return this.name === f.name; }
}
export class ClassMethod extends AbstractClassPart {
constructor(name, params, body, type, modifiers = null) {
super(type, modifiers);
this.name = name;
this.params = params;
this.body = body;
}
isEquivalent(m) {
return this.name === m.name && areAllEquivalent(this.body, m.body);
}
}
export class ClassGetter extends AbstractClassPart {
constructor(name, body, type, modifiers = null) {
super(type, modifiers);
this.name = name;
this.body = body;
}
isEquivalent(m) {
return this.name === m.name && areAllEquivalent(this.body, m.body);
}
}
export class ClassStmt extends Statement {
constructor(name, parent, fields, getters, constructorMethod, methods, modifiers = null, sourceSpan) {
super(modifiers, sourceSpan);
this.name = name;
this.parent = parent;
this.fields = fields;
this.getters = getters;
this.constructorMethod = constructorMethod;
this.methods = methods;
}
isEquivalent(stmt) {
return stmt instanceof ClassStmt && this.name === stmt.name &&
nullSafeIsEquivalent(this.parent, stmt.parent) &&
areAllEquivalent(this.fields, stmt.fields) &&
areAllEquivalent(this.getters, stmt.getters) &&
this.constructorMethod.isEquivalent(stmt.constructorMethod) &&
areAllEquivalent(this.methods, stmt.methods);
}
visitStatement(visitor, context) {
return visitor.visitDeclareClassStmt(this, context);
}
}
export class IfStmt extends Statement {
constructor(condition, trueCase, falseCase = [], sourceSpan) {
super(null, sourceSpan);
this.condition = condition;
this.trueCase = trueCase;
this.falseCase = falseCase;
}
isEquivalent(stmt) {
return stmt instanceof IfStmt && this.condition.isEquivalent(stmt.condition) &&
areAllEquivalent(this.trueCase, stmt.trueCase) &&
areAllEquivalent(this.falseCase, stmt.falseCase);
}
visitStatement(visitor, context) {
return visitor.visitIfStmt(this, context);
}
}
export class CommentStmt extends Statement {
constructor(comment, multiline = false, sourceSpan) {
super(null, sourceSpan);
this.comment = comment;
this.multiline = multiline;
}
isEquivalent(stmt) { return stmt instanceof CommentStmt; }
visitStatement(visitor, context) {
return visitor.visitCommentStmt(this, context);
}
}
export class JSDocCommentStmt extends Statement {
constructor(tags = [], sourceSpan) {
super(null, sourceSpan);
this.tags = tags;
}
isEquivalent(stmt) {
return stmt instanceof JSDocCommentStmt && this.toString() === stmt.toString();
}
visitStatement(visitor, context) {
return visitor.visitJSDocCommentStmt(this, context);
}
toString() { return serializeTags(this.tags); }
}
export class TryCatchStmt extends Statement {
constructor(bodyStmts, catchStmts, sourceSpan) {
super(null, sourceSpan);
this.bodyStmts = bodyStmts;
this.catchStmts = catchStmts;
}
isEquivalent(stmt) {
return stmt instanceof TryCatchStmt && areAllEquivalent(this.bodyStmts, stmt.bodyStmts) &&
areAllEquivalent(this.catchStmts, stmt.catchStmts);
}
visitStatement(visitor, context) {
return visitor.visitTryCatchStmt(this, context);
}
}
export class ThrowStmt extends Statement {
constructor(error, sourceSpan) {
super(null, sourceSpan);
this.error = error;
}
isEquivalent(stmt) {
return stmt instanceof TryCatchStmt && this.error.isEquivalent(stmt.error);
}
visitStatement(visitor, context) {
return visitor.visitThrowStmt(this, context);
}
}
export class AstTransformer {
transformExpr(expr, context) { return expr; }
transformStmt(stmt, context) { return stmt; }
visitReadVarExpr(ast, context) { return this.transformExpr(ast, context); }
visitWrappedNodeExpr(ast, context) {
return this.transformExpr(ast, context);
}
visitTypeofExpr(expr, context) {
return this.transformExpr(new TypeofExpr(expr.expr.visitExpression(this, context), expr.type, expr.sourceSpan), context);
}
visitWriteVarExpr(expr, context) {
return this.transformExpr(new WriteVarExpr(expr.name, expr.value.visitExpression(this, context), expr.type, expr.sourceSpan), context);
}
visitWriteKeyExpr(expr, context) {
return this.transformExpr(new WriteKeyExpr(expr.receiver.visitExpression(this, context), expr.index.visitExpression(this, context), expr.value.visitExpression(this, context), expr.type, expr.sourceSpan), context);
}
visitWritePropExpr(expr, context) {
return this.transformExpr(new WritePropExpr(expr.receiver.visitExpression(this, context), expr.name, expr.value.visitExpression(this, context), expr.type, expr.sourceSpan), context);
}
visitInvokeMethodExpr(ast, context) {
const method = ast.builtin || ast.name;
return this.transformExpr(new InvokeMethodExpr(ast.receiver.visitExpression(this, context), method, this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), context);
}
visitInvokeFunctionExpr(ast, context) {
return this.transformExpr(new InvokeFunctionExpr(ast.fn.visitExpression(this, context), this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), context);
}
visitInstantiateExpr(ast, context) {
return this.transformExpr(new InstantiateExpr(ast.classExpr.visitExpression(this, context), this.visitAllExpressions(ast.args, context), ast.type, ast.sourceSpan), context);
}
visitLiteralExpr(ast, context) { return this.transformExpr(ast, context); }
visitExternalExpr(ast, context) {
return this.transformExpr(ast, context);
}
visitConditionalExpr(ast, context) {
return this.transformExpr(new ConditionalExpr(ast.condition.visitExpression(this, context), ast.trueCase.visitExpression(this, context), ast.falseCase.visitExpression(this, context), ast.type, ast.sourceSpan), context);
}
visitNotExpr(ast, context) {
return this.transformExpr(new NotExpr(ast.condition.visitExpression(this, context), ast.sourceSpan), context);
}
visitAssertNotNullExpr(ast, context) {
return this.transformExpr(new AssertNotNull(ast.condition.visitExpression(this, context), ast.sourceSpan), context);
}
visitCastExpr(ast, context) {
return this.transformExpr(new CastExpr(ast.value.visitExpression(this, context), ast.type, ast.sourceSpan), context);
}
visitFunctionExpr(ast, context) {
return this.transformExpr(new FunctionExpr(ast.params, this.visitAllStatements(ast.statements, context), ast.type, ast.sourceSpan), context);
}
visitBinaryOperatorExpr(ast, context) {
return this.transformExpr(new BinaryOperatorExpr(ast.operator, ast.lhs.visitExpression(this, context), ast.rhs.visitExpression(this, context), ast.type, ast.sourceSpan), context);
}
visitReadPropExpr(ast, context) {
return this.transformExpr(new ReadPropExpr(ast.receiver.visitExpression(this, context), ast.name, ast.type, ast.sourceSpan), context);
}
visitReadKeyExpr(ast, context) {
return this.transformExpr(new ReadKeyExpr(ast.receiver.visitExpression(this, context), ast.index.visitExpression(this, context), ast.type, ast.sourceSpan), context);
}
visitLiteralArrayExpr(ast, context) {
return this.transformExpr(new LiteralArrayExpr(this.visitAllExpressions(ast.entries, context), ast.type, ast.sourceSpan), context);
}
visitLiteralMapExpr(ast, context) {
const entries = ast.entries.map((entry) => new LiteralMapEntry(entry.key, entry.value.visitExpression(this, context), entry.quoted));
const mapType = new MapType(ast.valueType, null);
return this.transformExpr(new LiteralMapExpr(entries, mapType, ast.sourceSpan), context);
}
visitCommaExpr(ast, context) {
return this.transformExpr(new CommaExpr(this.visitAllExpressions(ast.parts, context), ast.sourceSpan), context);
}
visitAllExpressions(exprs, context) {
return exprs.map(expr => expr.visitExpression(this, context));
}
visitDeclareVarStmt(stmt, context) {
const value = stmt.value && stmt.value.visitExpression(this, context);
return this.transformStmt(new DeclareVarStmt(stmt.name, value, stmt.type, stmt.modifiers, stmt.sourceSpan), context);
}
visitDeclareFunctionStmt(stmt, context) {
return this.transformStmt(new DeclareFunctionStmt(stmt.name, stmt.params, this.visitAllStatements(stmt.statements, context), stmt.type, stmt.modifiers, stmt.sourceSpan), context);
}
visitExpressionStmt(stmt, context) {
return this.transformStmt(new ExpressionStatement(stmt.expr.visitExpression(this, context), stmt.sourceSpan), context);
}
visitReturnStmt(stmt, context) {
return this.transformStmt(new ReturnStatement(stmt.value.visitExpression(this, context), stmt.sourceSpan), context);
}
visitDeclareClassStmt(stmt, context) {
const parent = stmt.parent.visitExpression(this, context);
const getters = stmt.getters.map(getter => new ClassGetter(getter.name, this.visitAllStatements(getter.body, context), getter.type, getter.modifiers));
const ctorMethod = stmt.constructorMethod &&
new ClassMethod(stmt.constructorMethod.name, stmt.constructorMethod.params, this.visitAllStatements(stmt.constructorMethod.body, context), stmt.constructorMethod.type, stmt.constructorMethod.modifiers);
const methods = stmt.methods.map(method => new ClassMethod(method.name, method.params, this.visitAllStatements(method.body, context), method.type, method.modifiers));
return this.transformStmt(new ClassStmt(stmt.name, parent, stmt.fields, getters, ctorMethod, methods, stmt.modifiers, stmt.sourceSpan), context);
}
visitIfStmt(stmt, context) {
return this.transformStmt(new IfStmt(stmt.condition.visitExpression(this, context), this.visitAllStatements(stmt.trueCase, context), this.visitAllStatements(stmt.falseCase, context), stmt.sourceSpan), context);
}
visitTryCatchStmt(stmt, context) {
return this.transformStmt(new TryCatchStmt(this.visitAllStatements(stmt.bodyStmts, context), this.visitAllStatements(stmt.catchStmts, context), stmt.sourceSpan), context);
}
visitThrowStmt(stmt, context) {
return this.transformStmt(new ThrowStmt(stmt.error.visitExpression(this, context), stmt.sourceSpan), context);
}
visitCommentStmt(stmt, context) {
return this.transformStmt(stmt, context);
}
visitJSDocCommentStmt(stmt, context) {
return this.transformStmt(stmt, context);
}
visitAllStatements(stmts, context) {
return stmts.map(stmt => stmt.visitStatement(this, context));
}
}
export class RecursiveAstVisitor {
visitType(ast, context) { return ast; }
visitExpression(ast, context) {
if (ast.type) {
ast.type.visitType(this, context);
}
return ast;
}
visitBuiltinType(type, context) { return this.visitType(type, context); }
visitExpressionType(type, context) {
type.value.visitExpression(this, context);
if (type.typeParams !== null) {
type.typeParams.forEach(param => this.visitType(param, context));
}
return this.visitType(type, context);
}
visitArrayType(type, context) { return this.visitType(type, context); }
visitMapType(type, context) { return this.visitType(type, context); }
visitWrappedNodeExpr(ast, context) { return ast; }
visitTypeofExpr(ast, context) { return this.visitExpression(ast, context); }
visitReadVarExpr(ast, context) {
return this.visitExpression(ast, context);
}
visitWriteVarExpr(ast, context) {
ast.value.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitWriteKeyExpr(ast, context) {
ast.receiver.visitExpression(this, context);
ast.index.visitExpression(this, context);
ast.value.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitWritePropExpr(ast, context) {
ast.receiver.visitExpression(this, context);
ast.value.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitInvokeMethodExpr(ast, context) {
ast.receiver.visitExpression(this, context);
this.visitAllExpressions(ast.args, context);
return this.visitExpression(ast, context);
}
visitInvokeFunctionExpr(ast, context) {
ast.fn.visitExpression(this, context);
this.visitAllExpressions(ast.args, context);
return this.visitExpression(ast, context);
}
visitInstantiateExpr(ast, context) {
ast.classExpr.visitExpression(this, context);
this.visitAllExpressions(ast.args, context);
return this.visitExpression(ast, context);
}
visitLiteralExpr(ast, context) {
return this.visitExpression(ast, context);
}
visitExternalExpr(ast, context) {
if (ast.typeParams) {
ast.typeParams.forEach(type => type.visitType(this, context));
}
return this.visitExpression(ast, context);
}
visitConditionalExpr(ast, context) {
ast.condition.visitExpression(this, context);
ast.trueCase.visitExpression(this, context);
ast.falseCase.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitNotExpr(ast, context) {
ast.condition.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitAssertNotNullExpr(ast, context) {
ast.condition.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitCastExpr(ast, context) {
ast.value.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitFunctionExpr(ast, context) {
this.visitAllStatements(ast.statements, context);
return this.visitExpression(ast, context);
}
visitBinaryOperatorExpr(ast, context) {
ast.lhs.visitExpression(this, context);
ast.rhs.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitReadPropExpr(ast, context) {
ast.receiver.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitReadKeyExpr(ast, context) {
ast.receiver.visitExpression(this, context);
ast.index.visitExpression(this, context);
return this.visitExpression(ast, context);
}
visitLiteralArrayExpr(ast, context) {
this.visitAllExpressions(ast.entries, context);
return this.visitExpression(ast, context);
}
visitLiteralMapExpr(ast, context) {
ast.entries.forEach((entry) => entry.value.visitExpression(this, context));
return this.visitExpression(ast, context);
}
visitCommaExpr(ast, context) {
this.visitAllExpressions(ast.parts, context);
return this.visitExpression(ast, context);
}
visitAllExpressions(exprs, context) {
exprs.forEach(expr => expr.visitExpression(this, context));
}
visitDeclareVarStmt(stmt, context) {
if (stmt.value) {
stmt.value.visitExpression(this, context);
}
if (stmt.type) {
stmt.type.visitType(this, context);
}
return stmt;
}
visitDeclareFunctionStmt(stmt, context) {
this.visitAllStatements(stmt.statements, context);
if (stmt.type) {
stmt.type.visitType(this, context);
}
return stmt;
}
visitExpressionStmt(stmt, context) {
stmt.expr.visitExpression(this, context);
return stmt;
}
visitReturnStmt(stmt, context) {
stmt.value.visitExpression(this, context);
return stmt;
}
visitDeclareClassStmt(stmt, context) {
stmt.parent.visitExpression(this, context);
stmt.getters.forEach(getter => this.visitAllStatements(getter.body, context));
if (stmt.constructorMethod) {
this.visitAllStatements(stmt.constructorMethod.body, context);
}
stmt.methods.forEach(method => this.visitAllStatements(method.body, context));
return stmt;
}
visitIfStmt(stmt, context) {
stmt.condition.visitExpression(this, context);
this.visitAllStatements(stmt.trueCase, context);
this.visitAllStatements(stmt.falseCase, context);
return stmt;
}
visitTryCatchStmt(stmt, context) {
this.visitAllStatements(stmt.bodyStmts, context);
this.visitAllStatements(stmt.catchStmts, context);
return stmt;
}
visitThrowStmt(stmt, context) {
stmt.error.visitExpression(this, context);
return stmt;
}
visitCommentStmt(stmt, context) { return stmt; }
visitJSDocCommentStmt(stmt, context) { return stmt; }
visitAllStatements(stmts, context) {
stmts.forEach(stmt => stmt.visitStatement(this, context));
}
}
export function findReadVarNames(stmts) {
const visitor = new _ReadVarVisitor();
visitor.visitAllStatements(stmts, null);
return visitor.varNames;
}
class _ReadVarVisitor extends RecursiveAstVisitor {
constructor() {
super(...arguments);
this.varNames = new Set();
}
visitDeclareFunctionStmt(stmt, context) {
// Don't descend into nested functions
return stmt;
}
visitDeclareClassStmt(stmt, context) {
// Don't descend into nested classes
return stmt;
}
visitReadVarExpr(ast, context) {
if (ast.name) {
this.varNames.add(ast.name);
}
return null;
}
}
export function collectExternalReferences(stmts) {
const visitor = new _FindExternalReferencesVisitor();
visitor.visitAllStatements(stmts, null);
return visitor.externalReferences;
}
class _FindExternalReferencesVisitor extends RecursiveAstVisitor {
constructor() {
super(...arguments);
this.externalReferences = [];
}
visitExternalExpr(e, context) {
this.externalReferences.push(e.value);
return super.visitExternalExpr(e, context);
}
}
export function applySourceSpanToStatementIfNeeded(stmt, sourceSpan) {
if (!sourceSpan) {
return stmt;
}
const transformer = new _ApplySourceSpanTransformer(sourceSpan);
return stmt.visitStatement(transformer, null);
}
export function applySourceSpanToExpressionIfNeeded(expr, sourceSpan) {
if (!sourceSpan) {
return expr;
}
const transformer = new _ApplySourceSpanTransformer(sourceSpan);
return expr.visitExpression(transformer, null);
}
class _ApplySourceSpanTransformer extends AstTransformer {
constructor(sourceSpan) {
super();
this.sourceSpan = sourceSpan;
}
_clone(obj) {
const clone = Object.create(obj.constructor.prototype);
for (let prop in obj) {
clone[prop] = obj[prop];
}
return clone;
}
transformExpr(expr, context) {
if (!expr.sourceSpan) {
expr = this._clone(expr);
expr.sourceSpan = this.sourceSpan;
}
return expr;
}
transformStmt(stmt, context) {
if (!stmt.sourceSpan) {
stmt = this._clone(stmt);
stmt.sourceSpan = this.sourceSpan;
}
return stmt;
}
}
export function variable(name, type, sourceSpan) {
return new ReadVarExpr(name, type, sourceSpan);
}
export function importExpr(id, typeParams = null, sourceSpan) {
return new ExternalExpr(id, null, typeParams, sourceSpan);
}
export function importType(id, typeParams = null, typeModifiers = null) {
return id != null ? expressionType(importExpr(id, typeParams, null), typeModifiers) : null;
}
export function expressionType(expr, typeModifiers = null, typeParams = null) {
return new ExpressionType(expr, typeModifiers, typeParams);
}
export function typeofExpr(expr) {
return new TypeofExpr(expr);
}
export function literalArr(values, type, sourceSpan) {
return new LiteralArrayExpr(values, type, sourceSpan);
}
export function literalMap(values, type = null) {
return new LiteralMapExpr(values.map(e => new LiteralMapEntry(e.key, e.value, e.quoted)), type, null);
}
export function not(expr, sourceSpan) {
return new NotExpr(expr, sourceSpan);
}
export function assertNotNull(expr, sourceSpan) {
return new AssertNotNull(expr, sourceSpan);
}
export function fn(params, body, type, sourceSpan, name) {
return new FunctionExpr(params, body, type, sourceSpan, name);
}
export function ifStmt(condition, thenClause, elseClause) {
return new IfStmt(condition, thenClause, elseClause);
}
export function literal(value, type, sourceSpan) {
return new LiteralExpr(value, type, sourceSpan);
}
export function isNull(exp) {
return exp instanceof LiteralExpr && exp.value === null;
}
/*
* Serializes a `Tag` into a string.
* Returns a string like " @foo {bar} baz" (note the leading whitespace before `@foo`).
*/
function tagToString(tag) {
let out = '';
if (tag.tagName) {
out += ` @${tag.tagName}`;
}
if (tag.text) {
if (tag.text.match(/\/\*|\*\//)) {
throw new Error('JSDoc text cannot contain "/*" and "*/"');
}
out += ' ' + tag.text.replace(/@/g, '\\@');
}
return out;
}
function serializeTags(tags) {
if (tags.length === 0)
return '';
let out = '*\n';
for (const tag of tags) {
out += ' *';
// If the tagToString is multi-line, insert " * " prefixes on subsequent lines.
out += tagToString(tag).replace(/\n/g, '\n * ');
out += '\n';
}
out += ' ';
return out;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0X2FzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyL3NyYy9vdXRwdXQvb3V0cHV0X2FzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFNSCxVQUFVO0FBQ1YsTUFBTSxDQUFOLElBQVksWUFFWDtBQUZELFdBQVksWUFBWTtJQUN0QixpREFBSyxDQUFBO0FBQ1AsQ0FBQyxFQUZXLFlBQVksS0FBWixZQUFZLFFBRXZCO0FBRUQsTUFBTTtJQUNKLFlBQW1CLFlBQWlDLElBQUk7UUFBckMsY0FBUyxHQUFULFNBQVMsQ0FBNEI7UUFDdEQsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNkLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1NBQ3JCO0lBQ0gsQ0FBQztJQUdELFdBQVcsQ0FBQyxRQUFzQixJQUFhLE9BQU8sSUFBSSxDQUFDLFNBQVcsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0NBQ25HO0FBRUQsTUFBTSxDQUFOLElBQVksZUFTWDtBQVRELFdBQVksZUFBZTtJQUN6QiwyREFBTyxDQUFBO0lBQ1AscURBQUksQ0FBQTtJQUNKLHlEQUFNLENBQUE7SUFDTixtREFBRyxDQUFBO0lBQ0gseURBQU0sQ0FBQTtJQUNOLDZEQUFRLENBQUE7SUFDUiw2REFBUSxDQUFBO0lBQ1IscURBQUksQ0FBQTtBQUNOLENBQUMsRUFUVyxlQUFlLEtBQWYsZUFBZSxRQVMxQjtBQUVELE1BQU0sa0JBQW1CLFNBQVEsSUFBSTtJQUNuQyxZQUFtQixJQUFxQixFQUFFLFlBQWlDLElBQUk7UUFDN0UsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBREEsU0FBSSxHQUFKLElBQUksQ0FBaUI7SUFFeEMsQ0FBQztJQUNELFNBQVMsQ0FBQyxPQUFvQixFQUFFLE9BQVk7UUFDMUMsT0FBTyxPQUFPLENBQUMs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