1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00
jashkenas--coffeescript/lib/coffeescript/nodes.js
Geoffrey Booth 221a8720fe Merge branch '2' into 2.0.0-alpha1
# Conflicts:
#	Cakefile
#	README.md
#	documentation/sections/changelog.md
2017-02-18 18:36:15 -05:00

4109 lines
132 KiB
JavaScript

// Generated by CoffeeScript 2.0.0-alpha1
(function() {
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, Call, Class, Code, CodeFragment, Comment, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, JS_FORBIDDEN, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isLiteralArguments, isLiteralThis, isUnassignable, locationDataToString, merge, multident, ref1, ref2, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, utility,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
slice = [].slice;
Error.stackTraceLimit = 2e308;
Scope = require('./scope').Scope;
ref1 = require('./lexer'), isUnassignable = ref1.isUnassignable, JS_FORBIDDEN = ref1.JS_FORBIDDEN;
ref2 = require('./helpers'), compact = ref2.compact, flatten = ref2.flatten, extend = ref2.extend, merge = ref2.merge, del = ref2.del, starts = ref2.starts, ends = ref2.ends, some = ref2.some, addLocationDataFn = ref2.addLocationDataFn, locationDataToString = ref2.locationDataToString, throwSyntaxError = ref2.throwSyntaxError;
exports.extend = extend;
exports.addLocationDataFn = addLocationDataFn;
YES = function() {
return true;
};
NO = function() {
return false;
};
THIS = function() {
return this;
};
NEGATE = function() {
this.negated = !this.negated;
return this;
};
exports.CodeFragment = CodeFragment = class CodeFragment {
constructor(parent, code) {
var ref3;
this.code = `${code}`;
this.locationData = parent != null ? parent.locationData : void 0;
this.type = (parent != null ? (ref3 = parent.constructor) != null ? ref3.name : void 0 : void 0) || 'unknown';
}
toString() {
return `${this.code}${(this.locationData ? ": " + locationDataToString(this.locationData) : '')}`;
}
};
fragmentsToText = function(fragments) {
var fragment;
return ((function() {
var j, len1, results;
results = [];
for (j = 0, len1 = fragments.length; j < len1; j++) {
fragment = fragments[j];
results.push(fragment.code);
}
return results;
})()).join('');
};
exports.Base = Base = (function() {
class Base {
compile(o, lvl) {
return fragmentsToText(this.compileToFragments(o, lvl));
}
compileToFragments(o, lvl) {
var node;
o = extend({}, o);
if (lvl) {
o.level = lvl;
}
node = this.unfoldSoak(o) || this;
node.tab = o.indent;
if (o.level === LEVEL_TOP || !node.isStatement(o)) {
return node.compileNode(o);
} else {
return node.compileClosure(o);
}
}
compileClosure(o) {
var args, argumentsNode, func, jumpNode, meth, parts, ref3, ref4;
if (jumpNode = this.jumps()) {
jumpNode.error('cannot use a pure statement in an expression');
}
o.sharedScope = true;
func = new Code([], Block.wrap([this]));
args = [];
if (this.contains((function(node) {
return node instanceof SuperCall;
}))) {
func.bound = true;
} else if ((argumentsNode = this.contains(isLiteralArguments)) || this.contains(isLiteralThis)) {
args = [new ThisLiteral];
if (argumentsNode) {
meth = 'apply';
args.push(new IdentifierLiteral('arguments'));
} else {
meth = 'call';
}
func = new Value(func, [new Access(new PropertyName(meth))]);
}
parts = (new Call(func, args)).compileNode(o);
switch (false) {
case !(func.isGenerator || ((ref3 = func.base) != null ? ref3.isGenerator : void 0)):
parts.unshift(this.makeCode("(yield* "));
parts.push(this.makeCode(")"));
break;
case !(func.isAsync || ((ref4 = func.base) != null ? ref4.isAsync : void 0)):
parts.unshift(this.makeCode("(await "));
parts.push(this.makeCode(")"));
}
return parts;
}
cache(o, level, shouldCache) {
var complex, ref, sub;
complex = shouldCache != null ? shouldCache(this) : this.shouldCache();
if (complex) {
ref = new IdentifierLiteral(o.scope.freeVariable('ref'));
sub = new Assign(ref, this);
if (level) {
return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]];
} else {
return [sub, ref];
}
} else {
ref = level ? this.compileToFragments(o, level) : this;
return [ref, ref];
}
}
hoist() {
var compileNode, compileToFragments, target;
this.hoisted = true;
target = new HoistTarget(this);
compileNode = this.compileNode;
compileToFragments = this.compileToFragments;
this.compileNode = function(o) {
return target.update(compileNode, o);
};
this.compileToFragments = function(o) {
return target.update(compileToFragments, o);
};
return target;
}
cacheToCodeFragments(cacheValues) {
return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])];
}
makeReturn(res) {
var me;
me = this.unwrapAll();
if (res) {
return new Call(new Literal(`${res}.push`), [me]);
} else {
return new Return(me);
}
}
contains(pred) {
var node;
node = void 0;
this.traverseChildren(false, function(n) {
if (pred(n)) {
node = n;
return false;
}
});
return node;
}
lastNonComment(list) {
var i;
i = list.length;
while (i--) {
if (!(list[i] instanceof Comment)) {
return list[i];
}
}
return null;
}
toString(idt = '', name = this.constructor.name) {
var tree;
tree = '\n' + idt + name;
if (this.soak) {
tree += '?';
}
this.eachChild(function(node) {
return tree += node.toString(idt + TAB);
});
return tree;
}
eachChild(func) {
var attr, child, j, k, len1, len2, ref3, ref4;
if (!this.children) {
return this;
}
ref3 = this.children;
for (j = 0, len1 = ref3.length; j < len1; j++) {
attr = ref3[j];
if (this[attr]) {
ref4 = flatten([this[attr]]);
for (k = 0, len2 = ref4.length; k < len2; k++) {
child = ref4[k];
if (func(child) === false) {
return this;
}
}
}
}
return this;
}
traverseChildren(crossScope, func) {
return this.eachChild(function(child) {
var recur;
recur = func(child);
if (recur !== false) {
return child.traverseChildren(crossScope, func);
}
});
}
replaceInContext(match, replacement) {
var attr, child, children, i, j, k, len1, len2, ref3, ref4;
if (!this.children) {
return false;
}
ref3 = this.children;
for (j = 0, len1 = ref3.length; j < len1; j++) {
attr = ref3[j];
if (children = this[attr]) {
if (Array.isArray(children)) {
for (i = k = 0, len2 = children.length; k < len2; i = ++k) {
child = children[i];
if (match(child)) {
[].splice.apply(children, [i, i - i + 1].concat(ref4 = replacement(child, this))), ref4;
return true;
} else {
if (child.replaceInContext(match, replacement)) {
return true;
}
}
}
} else if (match(children)) {
this[attr] = replacement(children, this);
return true;
} else {
if (children.replaceInContext(match, replacement)) {
return true;
}
}
}
}
}
invert() {
return new Op('!', this);
}
unwrapAll() {
var node;
node = this;
while (node !== (node = node.unwrap())) {
continue;
}
return node;
}
updateLocationDataIfMissing(locationData) {
if (this.locationData) {
return this;
}
this.locationData = locationData;
return this.eachChild(function(child) {
return child.updateLocationDataIfMissing(locationData);
});
}
error(message) {
return throwSyntaxError(message, this.locationData);
}
makeCode(code) {
return new CodeFragment(this, code);
}
wrapInBraces(fragments) {
return [].concat(this.makeCode('('), fragments, this.makeCode(')'));
}
joinFragmentArrays(fragmentsList, joinStr) {
var answer, fragments, i, j, len1;
answer = [];
for (i = j = 0, len1 = fragmentsList.length; j < len1; i = ++j) {
fragments = fragmentsList[i];
if (i) {
answer.push(this.makeCode(joinStr));
}
answer = answer.concat(fragments);
}
return answer;
}
};
Base.prototype.children = [];
Base.prototype.isStatement = NO;
Base.prototype.jumps = NO;
Base.prototype.shouldCache = YES;
Base.prototype.isChainable = NO;
Base.prototype.isAssignable = NO;
Base.prototype.isNumber = NO;
Base.prototype.unwrap = THIS;
Base.prototype.unfoldSoak = NO;
Base.prototype.assigns = NO;
return Base;
})();
exports.HoistTarget = HoistTarget = class HoistTarget extends Base {
static expand(fragments) {
var fragment, i, j, ref3;
for (i = j = fragments.length - 1; j >= 0; i = j += -1) {
fragment = fragments[i];
if (fragment.fragments) {
[].splice.apply(fragments, [i, i - i + 1].concat(ref3 = this.expand(fragment.fragments))), ref3;
}
}
return fragments;
}
constructor(source1) {
super();
this.source = source1;
this.options = {};
this.targetFragments = {
fragments: []
};
}
isStatement(o) {
return this.source.isStatement(o);
}
update(compile, o) {
return this.targetFragments.fragments = compile.call(this.source, merge(o, this.options));
}
compileToFragments(o, level) {
this.options.indent = o.indent;
this.options.level = level != null ? level : o.level;
return [this.targetFragments];
}
compileNode(o) {
return this.compileToFragments(o);
}
compileClosure(o) {
return this.compileToFragments(o);
}
};
exports.Block = Block = (function() {
class Block extends Base {
constructor(nodes) {
super();
this.expressions = compact(flatten(nodes || []));
}
push(node) {
this.expressions.push(node);
return this;
}
pop() {
return this.expressions.pop();
}
unshift(node) {
this.expressions.unshift(node);
return this;
}
unwrap() {
if (this.expressions.length === 1) {
return this.expressions[0];
} else {
return this;
}
}
isEmpty() {
return !this.expressions.length;
}
isStatement(o) {
var exp, j, len1, ref3;
ref3 = this.expressions;
for (j = 0, len1 = ref3.length; j < len1; j++) {
exp = ref3[j];
if (exp.isStatement(o)) {
return true;
}
}
return false;
}
jumps(o) {
var exp, j, jumpNode, len1, ref3;
ref3 = this.expressions;
for (j = 0, len1 = ref3.length; j < len1; j++) {
exp = ref3[j];
if (jumpNode = exp.jumps(o)) {
return jumpNode;
}
}
}
makeReturn(res) {
var expr, len;
len = this.expressions.length;
while (len--) {
expr = this.expressions[len];
if (!(expr instanceof Comment)) {
this.expressions[len] = expr.makeReturn(res);
if (expr instanceof Return && !expr.expression) {
this.expressions.splice(len, 1);
}
break;
}
}
return this;
}
compileToFragments(o = {}, level) {
if (o.scope) {
return super.compileToFragments(o, level);
} else {
return this.compileRoot(o);
}
}
compileNode(o) {
var answer, compiledNodes, fragments, index, j, len1, node, ref3, top;
this.tab = o.indent;
top = o.level === LEVEL_TOP;
compiledNodes = [];
ref3 = this.expressions;
for (index = j = 0, len1 = ref3.length; j < len1; index = ++j) {
node = ref3[index];
node = node.unwrapAll();
node = node.unfoldSoak(o) || node;
if (node instanceof Block) {
compiledNodes.push(node.compileNode(o));
} else if (node.hoisted) {
node.compileToFragments(o);
} else if (top) {
node.front = true;
fragments = node.compileToFragments(o);
if (!node.isStatement(o)) {
fragments.unshift(this.makeCode(`${this.tab}`));
fragments.push(this.makeCode(";"));
}
compiledNodes.push(fragments);
} else {
compiledNodes.push(node.compileToFragments(o, LEVEL_LIST));
}
}
if (top) {
if (this.spaced) {
return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n"));
} else {
return this.joinFragmentArrays(compiledNodes, '\n');
}
}
if (compiledNodes.length) {
answer = this.joinFragmentArrays(compiledNodes, ', ');
} else {
answer = [this.makeCode("void 0")];
}
if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) {
return this.wrapInBraces(answer);
} else {
return answer;
}
}
compileRoot(o) {
var exp, fragments, i, j, len1, name, prelude, preludeExps, ref3, ref4, rest;
o.indent = o.bare ? '' : TAB;
o.level = LEVEL_TOP;
this.spaced = true;
o.scope = new Scope(null, this, null, (ref3 = o.referencedVars) != null ? ref3 : []);
ref4 = o.locals || [];
for (j = 0, len1 = ref4.length; j < len1; j++) {
name = ref4[j];
o.scope.parameter(name);
}
prelude = [];
if (!o.bare) {
preludeExps = (function() {
var k, len2, ref5, results;
ref5 = this.expressions;
results = [];
for (i = k = 0, len2 = ref5.length; k < len2; i = ++k) {
exp = ref5[i];
if (!(exp.unwrap() instanceof Comment)) {
break;
}
results.push(exp);
}
return results;
}).call(this);
rest = this.expressions.slice(preludeExps.length);
this.expressions = preludeExps;
if (preludeExps.length) {
prelude = this.compileNode(merge(o, {
indent: ''
}));
prelude.push(this.makeCode("\n"));
}
this.expressions = rest;
}
fragments = this.compileWithDeclarations(o);
HoistTarget.expand(fragments);
if (o.bare) {
return fragments;
}
return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n"));
}
compileWithDeclarations(o) {
var assigns, declars, exp, fragments, i, j, len1, post, ref3, ref4, ref5, rest, scope, spaced;
fragments = [];
post = [];
ref3 = this.expressions;
for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
exp = ref3[i];
exp = exp.unwrap();
if (!(exp instanceof Comment || exp instanceof Literal)) {
break;
}
}
o = merge(o, {
level: LEVEL_TOP
});
if (i) {
rest = this.expressions.splice(i, 9e9);
ref4 = [this.spaced, false], spaced = ref4[0], this.spaced = ref4[1];
ref5 = [this.compileNode(o), spaced], fragments = ref5[0], this.spaced = ref5[1];
this.expressions = rest;
}
post = this.compileNode(o);
scope = o.scope;
if (scope.expressions === this) {
declars = o.scope.hasDeclarations();
assigns = scope.hasAssignments;
if (declars || assigns) {
if (i) {
fragments.push(this.makeCode('\n'));
}
fragments.push(this.makeCode(`${this.tab}var `));
if (declars) {
fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
}
if (assigns) {
if (declars) {
fragments.push(this.makeCode(`,\n${this.tab + TAB}`));
}
fragments.push(this.makeCode(scope.assignedVariables().join(`,\n${this.tab + TAB}`)));
}
fragments.push(this.makeCode(`;\n${(this.spaced ? '\n' : '')}`));
} else if (fragments.length && post.length) {
fragments.push(this.makeCode("\n"));
}
}
return fragments.concat(post);
}
static wrap(nodes) {
if (nodes.length === 1 && nodes[0] instanceof Block) {
return nodes[0];
}
return new Block(nodes);
}
};
Block.prototype.children = ['expressions'];
return Block;
})();
exports.Literal = Literal = (function() {
class Literal extends Base {
constructor(value1) {
super();
this.value = value1;
}
assigns(name) {
return name === this.value;
}
compileNode(o) {
return [this.makeCode(this.value)];
}
toString() {
return ` ${(this.isStatement() ? super.toString() : this.constructor.name)}: ${this.value}`;
}
};
Literal.prototype.shouldCache = NO;
return Literal;
})();
exports.NumberLiteral = NumberLiteral = class NumberLiteral extends Literal {};
exports.InfinityLiteral = InfinityLiteral = class InfinityLiteral extends NumberLiteral {
compileNode() {
return [this.makeCode('2e308')];
}
};
exports.NaNLiteral = NaNLiteral = class NaNLiteral extends NumberLiteral {
constructor() {
super('NaN');
}
compileNode(o) {
var code;
code = [this.makeCode('0/0')];
if (o.level >= LEVEL_OP) {
return this.wrapInBraces(code);
} else {
return code;
}
}
};
exports.StringLiteral = StringLiteral = class StringLiteral extends Literal {};
exports.RegexLiteral = RegexLiteral = class RegexLiteral extends Literal {};
exports.PassthroughLiteral = PassthroughLiteral = class PassthroughLiteral extends Literal {};
exports.IdentifierLiteral = IdentifierLiteral = (function() {
class IdentifierLiteral extends Literal {};
IdentifierLiteral.prototype.isAssignable = YES;
return IdentifierLiteral;
})();
exports.PropertyName = PropertyName = (function() {
class PropertyName extends Literal {};
PropertyName.prototype.isAssignable = YES;
return PropertyName;
})();
exports.StatementLiteral = StatementLiteral = (function() {
class StatementLiteral extends Literal {
jumps(o) {
if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
return this;
}
if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
return this;
}
}
compileNode(o) {
return [this.makeCode(`${this.tab}${this.value};`)];
}
};
StatementLiteral.prototype.isStatement = YES;
StatementLiteral.prototype.makeReturn = THIS;
return StatementLiteral;
})();
exports.ThisLiteral = ThisLiteral = class ThisLiteral extends Literal {
constructor() {
super('this');
}
compileNode(o) {
var code, ref3;
code = ((ref3 = o.scope.method) != null ? ref3.bound : void 0) ? o.scope.method.context : this.value;
return [this.makeCode(code)];
}
};
exports.UndefinedLiteral = UndefinedLiteral = class UndefinedLiteral extends Literal {
constructor() {
super('undefined');
}
compileNode(o) {
return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')];
}
};
exports.NullLiteral = NullLiteral = class NullLiteral extends Literal {
constructor() {
super('null');
}
};
exports.BooleanLiteral = BooleanLiteral = class BooleanLiteral extends Literal {};
exports.Return = Return = (function() {
class Return extends Base {
constructor(expression1) {
super();
this.expression = expression1;
}
compileToFragments(o, level) {
var expr, ref3;
expr = (ref3 = this.expression) != null ? ref3.makeReturn() : void 0;
if (expr && !(expr instanceof Return)) {
return expr.compileToFragments(o, level);
} else {
return super.compileToFragments(o, level);
}
}
compileNode(o) {
var answer;
answer = [];
answer.push(this.makeCode(this.tab + `return${(this.expression ? " " : "")}`));
if (this.expression) {
answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
}
answer.push(this.makeCode(";"));
return answer;
}
};
Return.prototype.children = ['expression'];
Return.prototype.isStatement = YES;
Return.prototype.makeReturn = THIS;
Return.prototype.jumps = THIS;
return Return;
})();
exports.YieldReturn = YieldReturn = class YieldReturn extends Return {
compileNode(o) {
if (o.scope.parent == null) {
this.error('yield can only occur inside functions');
}
return super.compileNode(o);
}
};
exports.AwaitReturn = AwaitReturn = class AwaitReturn extends Return {
compileNode(o) {
if (o.scope.parent == null) {
this.error('await can only occur inside functions');
}
return super.compileNode(o);
}
};
exports.Value = Value = (function() {
class Value extends Base {
constructor(base, props, tag) {
if (!props && base instanceof Value) {
return base;
}
super();
this.base = base;
this.properties = props || [];
if (tag) {
this[tag] = true;
}
return this;
}
add(props) {
this.properties = this.properties.concat(props);
return this;
}
hasProperties() {
return !!this.properties.length;
}
bareLiteral(type) {
return !this.properties.length && this.base instanceof type;
}
isArray() {
return this.bareLiteral(Arr);
}
isRange() {
return this.bareLiteral(Range);
}
shouldCache() {
return this.hasProperties() || this.base.shouldCache();
}
isAssignable() {
return this.hasProperties() || this.base.isAssignable();
}
isNumber() {
return this.bareLiteral(NumberLiteral);
}
isString() {
return this.bareLiteral(StringLiteral);
}
isRegex() {
return this.bareLiteral(RegexLiteral);
}
isUndefined() {
return this.bareLiteral(UndefinedLiteral);
}
isNull() {
return this.bareLiteral(NullLiteral);
}
isBoolean() {
return this.bareLiteral(BooleanLiteral);
}
isAtomic() {
var j, len1, node, ref3;
ref3 = this.properties.concat(this.base);
for (j = 0, len1 = ref3.length; j < len1; j++) {
node = ref3[j];
if (node.soak || node instanceof Call) {
return false;
}
}
return true;
}
isNotCallable() {
return this.isNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject() || this.isUndefined() || this.isNull() || this.isBoolean();
}
isStatement(o) {
return !this.properties.length && this.base.isStatement(o);
}
assigns(name) {
return !this.properties.length && this.base.assigns(name);
}
jumps(o) {
return !this.properties.length && this.base.jumps(o);
}
isObject(onlyGenerated) {
if (this.properties.length) {
return false;
}
return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
}
isSplice() {
var lastProp, ref3;
ref3 = this.properties, lastProp = ref3[ref3.length - 1];
return lastProp instanceof Slice;
}
looksStatic(className) {
var ref3;
return (this["this"] || this.base instanceof ThisLiteral || this.base.value === className) && this.properties.length === 1 && ((ref3 = this.properties[0].name) != null ? ref3.value : void 0) !== 'prototype';
}
unwrap() {
if (this.properties.length) {
return this;
} else {
return this.base;
}
}
cacheReference(o) {
var base, bref, name, nref, ref3;
ref3 = this.properties, name = ref3[ref3.length - 1];
if (this.properties.length < 2 && !this.base.shouldCache() && !(name != null ? name.shouldCache() : void 0)) {
return [this, this];
}
base = new Value(this.base, this.properties.slice(0, -1));
if (base.shouldCache()) {
bref = new IdentifierLiteral(o.scope.freeVariable('base'));
base = new Value(new Parens(new Assign(bref, base)));
}
if (!name) {
return [base, bref];
}
if (name.shouldCache()) {
nref = new IdentifierLiteral(o.scope.freeVariable('name'));
name = new Index(new Assign(nref, name.index));
nref = new Index(nref);
}
return [base.add(name), new Value(bref || base.base, [nref || name])];
}
compileNode(o) {
var fragments, j, len1, prop, props;
this.base.front = this.front;
props = this.properties;
fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null));
if (props.length && SIMPLENUM.test(fragmentsToText(fragments))) {
fragments.push(this.makeCode('.'));
}
for (j = 0, len1 = props.length; j < len1; j++) {
prop = props[j];
fragments.push(...prop.compileToFragments(o));
}
return fragments;
}
unfoldSoak(o) {
return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (() => {
var fst, i, ifn, j, len1, prop, ref, ref3, snd;
if (ifn = this.base.unfoldSoak(o)) {
ifn.body.properties.push(...this.properties);
return ifn;
}
ref3 = this.properties;
for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
prop = ref3[i];
if (!prop.soak) {
continue;
}
prop.soak = false;
fst = new Value(this.base, this.properties.slice(0, i));
snd = new Value(this.base, this.properties.slice(i));
if (fst.shouldCache()) {
ref = new IdentifierLiteral(o.scope.freeVariable('ref'));
fst = new Parens(new Assign(ref, fst));
snd.base = ref;
}
return new If(new Existence(fst), snd, {
soak: true
});
}
return false;
})();
}
};
Value.prototype.children = ['base', 'properties'];
return Value;
})();
exports.Comment = Comment = (function() {
class Comment extends Base {
constructor(comment1) {
super();
this.comment = comment1;
}
compileNode(o, level) {
var code, comment;
comment = this.comment.replace(/^(\s*)#(?=\s)/gm, "$1 *");
code = `/*${multident(comment, this.tab)}${(indexOf.call(comment, '\n') >= 0 ? `\n${this.tab}` : '')} */`;
if ((level || o.level) === LEVEL_TOP) {
code = o.indent + code;
}
return [this.makeCode("\n"), this.makeCode(code)];
}
};
Comment.prototype.isStatement = YES;
Comment.prototype.makeReturn = THIS;
return Comment;
})();
exports.Call = Call = (function() {
class Call extends Base {
constructor(variable1, args1 = [], soak1) {
super();
this.variable = variable1;
this.args = args1;
this.soak = soak1;
this.isNew = false;
if (this.variable instanceof Value && this.variable.isNotCallable()) {
this.variable.error("literal is not a function");
}
}
updateLocationDataIfMissing(locationData) {
var base, ref3;
if (this.locationData && this.needsUpdatedStartLocation) {
this.locationData.first_line = locationData.first_line;
this.locationData.first_column = locationData.first_column;
base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
if (base.needsUpdatedStartLocation) {
this.variable.locationData.first_line = locationData.first_line;
this.variable.locationData.first_column = locationData.first_column;
base.updateLocationDataIfMissing(locationData);
}
delete this.needsUpdatedStartLocation;
}
return super.updateLocationDataIfMissing(locationData);
}
newInstance() {
var base, ref3;
base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
if (base instanceof Call && !base.isNew) {
base.newInstance();
} else {
this.isNew = true;
}
this.needsUpdatedStartLocation = true;
return this;
}
unfoldSoak(o) {
var call, ifn, j, left, len1, list, ref3, ref4, rite;
if (this.soak) {
if (this.variable instanceof Super) {
left = new Literal(this.variable.compile(o));
rite = new Value(left);
if (this.variable.accessor == null) {
this.variable.error("Unsupported reference to 'super'");
}
} else {
if (ifn = unfoldSoak(o, this, 'variable')) {
return ifn;
}
ref3 = new Value(this.variable).cacheReference(o), left = ref3[0], rite = ref3[1];
}
rite = new Call(rite, this.args);
rite.isNew = this.isNew;
left = new Literal(`typeof ${left.compile(o)} === \"function\"`);
return new If(left, new Value(rite), {
soak: true
});
}
call = this;
list = [];
while (true) {
if (call.variable instanceof Call) {
list.push(call);
call = call.variable;
continue;
}
if (!(call.variable instanceof Value)) {
break;
}
list.push(call);
if (!((call = call.variable.base) instanceof Call)) {
break;
}
}
ref4 = list.reverse();
for (j = 0, len1 = ref4.length; j < len1; j++) {
call = ref4[j];
if (ifn) {
if (call.variable instanceof Call) {
call.variable = ifn;
} else {
call.variable.base = ifn;
}
}
ifn = unfoldSoak(o, call, 'variable');
}
return ifn;
}
compileNode(o) {
var arg, argIndex, compiledArgs, fragments, j, len1, ref3, ref4;
if ((ref3 = this.variable) != null) {
ref3.front = this.front;
}
compiledArgs = [];
ref4 = this.args;
for (argIndex = j = 0, len1 = ref4.length; j < len1; argIndex = ++j) {
arg = ref4[argIndex];
if (argIndex) {
compiledArgs.push(this.makeCode(", "));
}
compiledArgs.push(...arg.compileToFragments(o, LEVEL_LIST));
}
fragments = [];
if (this.isNew) {
if (this.variable instanceof Super) {
this.variable.error("Unsupported reference to 'super'");
}
fragments.push(this.makeCode('new '));
}
fragments.push(...this.variable.compileToFragments(o, LEVEL_ACCESS));
fragments.push(this.makeCode('('), ...compiledArgs, this.makeCode(')'));
return fragments;
}
};
Call.prototype.children = ['variable', 'args'];
return Call;
})();
exports.SuperCall = SuperCall = (function() {
class SuperCall extends Call {
isStatement(o) {
var ref3;
return ((ref3 = this.expressions) != null ? ref3.length : void 0) && o.level === LEVEL_TOP;
}
compileNode(o) {
var ref, ref3, ref4, replacement, superCall;
if (!((ref3 = this.expressions) != null ? ref3.length : void 0)) {
return super.compileNode(o);
}
superCall = new Literal(fragmentsToText(super.compileNode(o)));
replacement = new Block(this.expressions.slice());
if (o.level > LEVEL_TOP) {
ref4 = superCall.cache(o, null, YES), superCall = ref4[0], ref = ref4[1];
replacement.push(ref);
}
replacement.unshift(superCall);
return replacement.compileToFragments(o, o.level === LEVEL_TOP ? o.level : LEVEL_LIST);
}
};
SuperCall.prototype.children = Call.prototype.children.concat(['expressions']);
return SuperCall;
})();
exports.Super = Super = (function() {
class Super extends Base {
constructor(accessor) {
super();
this.accessor = accessor;
}
compileNode(o) {
var method, name, nref, variable;
method = o.scope.namedMethod();
if (!(method != null ? method.isMethod : void 0)) {
this.error('cannot use super outside of an instance method');
}
this.inCtor = !!method.ctor;
if (!(this.inCtor || (this.accessor != null))) {
name = method.name, variable = method.variable;
if (name.shouldCache() || (name instanceof Index && name.index.isAssignable())) {
nref = new IdentifierLiteral(o.scope.parent.freeVariable('name'));
name.index = new Assign(nref, name.index);
}
this.accessor = nref != null ? new Index(nref) : name;
}
return (new Value(new Literal('super'), this.accessor ? [this.accessor] : [])).compileToFragments(o);
}
};
Super.prototype.children = ['accessor'];
return Super;
})();
exports.RegexWithInterpolations = RegexWithInterpolations = class RegexWithInterpolations extends Call {
constructor(args = []) {
super(new Value(new IdentifierLiteral('RegExp')), args, false);
}
};
exports.TaggedTemplateCall = TaggedTemplateCall = class TaggedTemplateCall extends Call {
constructor(variable, arg, soak) {
if (arg instanceof StringLiteral) {
arg = new StringWithInterpolations(Block.wrap([new Value(arg)]));
}
super(variable, [arg], soak);
}
compileNode(o) {
return this.variable.compileToFragments(o, LEVEL_ACCESS).concat(this.args[0].compileToFragments(o, LEVEL_LIST));
}
};
exports.Extends = Extends = (function() {
class Extends extends Base {
constructor(child1, parent1) {
super();
this.child = child1;
this.parent = parent1;
}
compileToFragments(o) {
return new Call(new Value(new Literal(utility('extend', o))), [this.child, this.parent]).compileToFragments(o);
}
};
Extends.prototype.children = ['child', 'parent'];
return Extends;
})();
exports.Access = Access = (function() {
class Access extends Base {
constructor(name1, tag) {
super();
this.name = name1;
this.soak = tag === 'soak';
}
compileToFragments(o) {
var name, node, ref3;
name = this.name.compileToFragments(o);
node = this.name.unwrap();
if (node instanceof PropertyName) {
if (ref3 = node.value, indexOf.call(JS_FORBIDDEN, ref3) >= 0) {
return [this.makeCode('["'), ...name, this.makeCode('"]')];
} else {
return [this.makeCode('.'), ...name];
}
} else {
return [this.makeCode('['), ...name, this.makeCode(']')];
}
}
};
Access.prototype.children = ['name'];
Access.prototype.shouldCache = NO;
return Access;
})();
exports.Index = Index = (function() {
class Index extends Base {
constructor(index1) {
super();
this.index = index1;
}
compileToFragments(o) {
return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]"));
}
shouldCache() {
return this.index.shouldCache();
}
};
Index.prototype.children = ['index'];
return Index;
})();
exports.Range = Range = (function() {
class Range extends Base {
constructor(from1, to1, tag) {
super();
this.from = from1;
this.to = to1;
this.exclusive = tag === 'exclusive';
this.equals = this.exclusive ? '' : '=';
}
compileVariables(o) {
var ref3, ref4, ref5, shouldCache, step;
o = merge(o, {
top: true
});
shouldCache = del(o, 'shouldCache');
ref3 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST, shouldCache)), this.fromC = ref3[0], this.fromVar = ref3[1];
ref4 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST, shouldCache)), this.toC = ref4[0], this.toVar = ref4[1];
if (step = del(o, 'step')) {
ref5 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST, shouldCache)), this.step = ref5[0], this.stepVar = ref5[1];
}
this.fromNum = this.from.isNumber() ? Number(this.fromVar) : null;
this.toNum = this.to.isNumber() ? Number(this.toVar) : null;
return this.stepNum = (step != null ? step.isNumber() : void 0) ? Number(this.stepVar) : null;
}
compileNode(o) {
var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, ref3, ref4, stepPart, to, varPart;
if (!this.fromVar) {
this.compileVariables(o);
}
if (!o.index) {
return this.compileArray(o);
}
known = (this.fromNum != null) && (this.toNum != null);
idx = del(o, 'index');
idxName = del(o, 'name');
namedIndex = idxName && idxName !== idx;
varPart = `${idx} = ${this.fromC}`;
if (this.toC !== this.toVar) {
varPart += `, ${this.toC}`;
}
if (this.step !== this.stepVar) {
varPart += `, ${this.step}`;
}
ref3 = [`${idx} <${this.equals}`, `${idx} >${this.equals}`], lt = ref3[0], gt = ref3[1];
condPart = this.stepNum != null ? this.stepNum > 0 ? `${lt} ${this.toVar}` : `${gt} ${this.toVar}` : known ? ((ref4 = [this.fromNum, this.toNum], from = ref4[0], to = ref4[1], ref4), from <= to ? `${lt} ${to}` : `${gt} ${to}`) : (cond = this.stepVar ? `${this.stepVar} > 0` : `${this.fromVar} <= ${this.toVar}`, `${cond} ? ${lt} ${this.toVar} : ${gt} ${this.toVar}`);
stepPart = this.stepVar ? `${idx} += ${this.stepVar}` : known ? namedIndex ? from <= to ? `++${idx}` : `--${idx}` : from <= to ? `${idx}++` : `${idx}--` : namedIndex ? `${cond} ? ++${idx} : --${idx}` : `${cond} ? ${idx}++ : ${idx}--`;
if (namedIndex) {
varPart = `${idxName} = ${varPart}`;
}
if (namedIndex) {
stepPart = `${idxName} = ${stepPart}`;
}
return [this.makeCode(`${varPart}; ${condPart}; ${stepPart}`)];
}
compileArray(o) {
var args, body, cond, hasArgs, i, idt, j, known, post, pre, range, ref3, ref4, result, results, vars;
known = (this.fromNum != null) && (this.toNum != null);
if (known && Math.abs(this.fromNum - this.toNum) <= 20) {
range = (function() {
results = [];
for (var j = ref3 = this.fromNum, ref4 = this.toNum; ref3 <= ref4 ? j <= ref4 : j >= ref4; ref3 <= ref4 ? j++ : j--){ results.push(j); }
return results;
}).apply(this);
if (this.exclusive) {
range.pop();
}
return [this.makeCode(`[${range.join(', ')}]`)];
}
idt = this.tab + TAB;
i = o.scope.freeVariable('i', {
single: true
});
result = o.scope.freeVariable('results');
pre = `\n${idt}${result} = [];`;
if (known) {
o.index = i;
body = fragmentsToText(this.compileNode(o));
} else {
vars = `${i} = ${this.fromC}` + (this.toC !== this.toVar ? `, ${this.toC}` : '');
cond = `${this.fromVar} <= ${this.toVar}`;
body = `var ${vars}; ${cond} ? ${i} <${this.equals} ${this.toVar} : ${i} >${this.equals} ${this.toVar}; ${cond} ? ${i}++ : ${i}--`;
}
post = `{ ${result}.push(${i}); }\n${idt}return ${result};\n${o.indent}`;
hasArgs = function(node) {
return node != null ? node.contains(isLiteralArguments) : void 0;
};
if (hasArgs(this.from) || hasArgs(this.to)) {
args = ', arguments';
}
return [this.makeCode(`(function() {${pre}\n${idt}for (${body})${post}}).apply(this${args != null ? args : ''})`)];
}
};
Range.prototype.children = ['from', 'to'];
return Range;
})();
exports.Slice = Slice = (function() {
class Slice extends Base {
constructor(range1) {
super();
this.range = range1;
}
compileNode(o) {
var compiled, compiledText, from, fromCompiled, ref3, to, toStr;
ref3 = this.range, to = ref3.to, from = ref3.from;
fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')];
if (to) {
compiled = to.compileToFragments(o, LEVEL_PAREN);
compiledText = fragmentsToText(compiled);
if (!(!this.range.exclusive && +compiledText === -1)) {
toStr = ', ' + (this.range.exclusive ? compiledText : to.isNumber() ? `${+compiledText + 1}` : (compiled = to.compileToFragments(o, LEVEL_ACCESS), `+${fragmentsToText(compiled)} + 1 || 9e9`));
}
}
return [this.makeCode(`.slice(${fragmentsToText(fromCompiled)}${toStr || ''})`)];
}
};
Slice.prototype.children = ['range'];
return Slice;
})();
exports.Obj = Obj = (function() {
class Obj extends Base {
constructor(props, generated = false) {
super();
this.generated = generated;
this.objects = this.properties = props || [];
}
compileNode(o) {
var answer, i, idt, indent, j, join, k, key, lastNoncom, len1, len2, node, prop, props, ref3, value;
props = this.properties;
if (this.generated) {
for (j = 0, len1 = props.length; j < len1; j++) {
node = props[j];
if (node instanceof Value) {
node.error('cannot have an implicit value in an implicit object');
}
}
}
idt = o.indent += TAB;
lastNoncom = this.lastNonComment(this.properties);
answer = [];
answer.push(this.makeCode(`{${(props.length === 0 ? '}' : '\n')}`));
for (i = k = 0, len2 = props.length; k < len2; i = ++k) {
prop = props[i];
join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
indent = prop instanceof Comment ? '' : idt;
if (prop instanceof Assign) {
if (prop.context !== 'object') {
prop.operatorToken.error(`unexpected ${prop.operatorToken.value}`);
}
if (prop.variable instanceof Value && prop.variable.hasProperties()) {
prop.variable.error('invalid object key');
}
}
if (prop instanceof Value && prop["this"]) {
prop = new Assign(prop.properties[0].name, prop, 'object');
}
if (!(prop instanceof Comment) && !(prop instanceof Assign)) {
if (prop.shouldCache()) {
ref3 = prop.base.cache(o), key = ref3[0], value = ref3[1];
if (key instanceof IdentifierLiteral) {
key = new PropertyName(key.value);
}
prop = new Assign(key, value, 'object');
} else {
prop = new Assign(prop, prop, 'object');
}
}
if (indent) {
answer.push(this.makeCode(indent));
}
answer.push(...prop.compileToFragments(o, LEVEL_TOP));
if (join) {
answer.push(this.makeCode(join));
}
}
if (props.length !== 0) {
answer.push(this.makeCode(`\n${this.tab}}`));
}
if (this.front) {
return this.wrapInBraces(answer);
} else {
return answer;
}
}
assigns(name) {
var j, len1, prop, ref3;
ref3 = this.properties;
for (j = 0, len1 = ref3.length; j < len1; j++) {
prop = ref3[j];
if (prop.assigns(name)) {
return true;
}
}
return false;
}
};
Obj.prototype.children = ['properties'];
return Obj;
})();
exports.Arr = Arr = (function() {
class Arr extends Base {
constructor(objs) {
super();
this.objects = objs || [];
}
compileNode(o) {
var answer, compiledObjs, fragments, index, j, len1, obj;
if (!this.objects.length) {
return [this.makeCode('[]')];
}
o.indent += TAB;
answer = [];
compiledObjs = (function() {
var j, len1, ref3, results;
ref3 = this.objects;
results = [];
for (j = 0, len1 = ref3.length; j < len1; j++) {
obj = ref3[j];
results.push(obj.compileToFragments(o, LEVEL_LIST));
}
return results;
}).call(this);
for (index = j = 0, len1 = compiledObjs.length; j < len1; index = ++j) {
fragments = compiledObjs[index];
if (index) {
answer.push(this.makeCode(", "));
}
answer.push(...fragments);
}
if (fragmentsToText(answer).indexOf('\n') >= 0) {
answer.unshift(this.makeCode(`[\n${o.indent}`));
answer.push(this.makeCode(`\n${this.tab}]`));
} else {
answer.unshift(this.makeCode("["));
answer.push(this.makeCode("]"));
}
return answer;
}
assigns(name) {
var j, len1, obj, ref3;
ref3 = this.objects;
for (j = 0, len1 = ref3.length; j < len1; j++) {
obj = ref3[j];
if (obj.assigns(name)) {
return true;
}
}
return false;
}
};
Arr.prototype.children = ['objects'];
return Arr;
})();
exports.Class = Class = (function() {
class Class extends Base {
constructor(variable1, parent1, body1 = new Block) {
super();
this.variable = variable1;
this.parent = parent1;
this.body = body1;
}
compileNode(o) {
var assign, executableBody, parentName, result;
this.name = this.determineName();
executableBody = this.walkBody();
if (this.parent instanceof Value && !this.parent.hasProperties()) {
parentName = this.parent.base.value;
}
this.hasNameClash = (this.name != null) && this.name === parentName;
if (executableBody || this.hasNameClash) {
this.compileNode = this.compileClassDeclaration;
result = new ExecutableClassBody(this, executableBody).compileToFragments(o);
this.compileNode = this.constructor.prototype.compileNode;
} else {
result = this.compileClassDeclaration(o);
if ((this.name == null) && o.level === LEVEL_TOP) {
result = this.wrapInBraces(result);
}
}
if (this.variable) {
assign = new Assign(this.variable, new Literal(''), null, {
moduleDeclaration: this.moduleDeclaration
});
return [...assign.compileToFragments(o), ...result];
} else {
return result;
}
}
compileClassDeclaration(o) {
var ref3, result;
if (this.externalCtor || this.boundMethods.length) {
if (this.ctor == null) {
this.ctor = this.makeDefaultConstructor();
}
}
if ((ref3 = this.ctor) != null) {
ref3.noReturn = true;
}
if (this.boundMethods.length) {
this.proxyBoundMethods(o);
}
o.indent += TAB;
result = [];
result.push(this.makeCode("class "));
if (this.name) {
result.push(this.makeCode(`${this.name} `));
}
if (this.parent) {
result.push(this.makeCode('extends '), ...this.parent.compileToFragments(o), this.makeCode(' '));
}
result.push(this.makeCode('{'));
if (!this.body.isEmpty()) {
this.body.spaced = true;
result.push(this.makeCode('\n'));
result.push(...this.body.compileToFragments(o, LEVEL_TOP));
result.push(this.makeCode(`\n${this.tab}`));
}
result.push(this.makeCode('}'));
return result;
}
determineName() {
var message, name, node, ref3, tail;
if (!this.variable) {
return null;
}
ref3 = this.variable.properties, tail = ref3[ref3.length - 1];
node = tail ? tail instanceof Access && tail.name : this.variable.base;
if (!(node instanceof IdentifierLiteral || node instanceof PropertyName)) {
return null;
}
name = node.value;
if (!tail) {
message = isUnassignable(name);
if (message) {
this.variable.error(message);
}
}
if (indexOf.call(JS_FORBIDDEN, name) >= 0) {
return `_${name}`;
} else {
return name;
}
}
walkBody() {
var assign, end, executableBody, expression, expressions, exprs, i, initializer, initializerExpression, j, k, len1, len2, method, properties, pushSlice, ref3, start;
this.ctor = null;
this.boundMethods = [];
executableBody = null;
initializer = [];
expressions = this.body.expressions;
i = 0;
ref3 = expressions.slice();
for (j = 0, len1 = ref3.length; j < len1; j++) {
expression = ref3[j];
if (expression instanceof Value && expression.isObject(true)) {
properties = expression.base.properties;
exprs = [];
end = 0;
start = 0;
pushSlice = function() {
if (end > start) {
return exprs.push(new Value(new Obj(properties.slice(start, end), true)));
}
};
while (assign = properties[end]) {
if (initializerExpression = this.addInitializerExpression(assign)) {
pushSlice();
exprs.push(initializerExpression);
initializer.push(initializerExpression);
start = end + 1;
} else if (initializer[initializer.length - 1] instanceof Comment) {
exprs.pop();
initializer.pop();
start--;
}
end++;
}
pushSlice();
[].splice.apply(expressions, [i, i - i + 1].concat(exprs)), exprs;
i += exprs.length;
} else {
if (initializerExpression = this.addInitializerExpression(expression)) {
initializer.push(initializerExpression);
expressions[i] = initializerExpression;
} else if (initializer[initializer.length - 1] instanceof Comment) {
initializer.pop();
}
i += 1;
}
}
for (k = 0, len2 = initializer.length; k < len2; k++) {
method = initializer[k];
if (method instanceof Code) {
if (method.ctor) {
if (this.ctor) {
method.error('Cannot define more than one constructor in a class');
}
this.ctor = method;
} else if (method.bound && method.isStatic) {
method.context = this.name;
} else if (method.bound) {
this.boundMethods.push(method.name);
method.bound = false;
}
}
}
if (initializer.length !== expressions.length) {
this.body.expressions = (function() {
var l, len3, results;
results = [];
for (l = 0, len3 = initializer.length; l < len3; l++) {
expression = initializer[l];
results.push(expression.hoist());
}
return results;
})();
return new Block(expressions);
}
}
addInitializerExpression(node) {
switch (false) {
case !(node instanceof Comment):
return node;
case !this.validInitializerMethod(node):
return this.addInitializerMethod(node);
default:
return null;
}
}
validInitializerMethod(node) {
if (!(node instanceof Assign && node.value instanceof Code)) {
return false;
}
if (node.context === 'object' && !node.variable.hasProperties()) {
return true;
}
return node.variable.looksStatic(this.name) && (this.name || !node.value.bound);
}
addInitializerMethod(assign) {
var method, methodName, variable;
variable = assign.variable, method = assign.value;
method.isMethod = true;
method.isStatic = variable.looksStatic(this.name);
if (method.isStatic) {
method.name = variable.properties[0];
} else {
methodName = variable.base;
method.name = new (methodName.shouldCache() ? Index : Access)(methodName);
method.name.updateLocationDataIfMissing(methodName.locationData);
if (methodName.value === 'constructor') {
method.ctor = (this.parent ? 'derived' : 'base');
}
if (method.bound && method.ctor) {
method.error('Cannot define a constructor as a bound function');
}
}
return method;
}
makeDefaultConstructor() {
var applyArgs, applyCtor, ctor;
ctor = this.addInitializerMethod(new Assign(new Value(new PropertyName('constructor')), new Code));
this.body.unshift(ctor);
if (this.parent) {
ctor.body.push(new SuperCall(new Super, [new Splat(new IdentifierLiteral('arguments'))]));
}
if (this.externalCtor) {
applyCtor = new Value(this.externalCtor, [new Access(new PropertyName('apply'))]);
applyArgs = [new ThisLiteral, new IdentifierLiteral('arguments')];
ctor.body.push(new Call(applyCtor, applyArgs));
ctor.body.makeReturn();
}
return ctor;
}
proxyBoundMethods(o) {
var name;
this.ctor.thisAssignments = (function() {
var j, ref3, results;
ref3 = this.boundMethods;
results = [];
for (j = ref3.length - 1; j >= 0; j += -1) {
name = ref3[j];
name = new Value(new ThisLiteral, [name]).compile(o);
results.push(new Literal(`${name} = ${utility('bind', o)}(${name}, this)`));
}
return results;
}).call(this);
return null;
}
};
Class.prototype.children = ['variable', 'parent', 'body'];
return Class;
})();
exports.ExecutableClassBody = ExecutableClassBody = (function() {
class ExecutableClassBody extends Base {
constructor(_class, body1 = new Block) {
super();
this["class"] = _class;
this.body = body1;
}
compileNode(o) {
var args, argumentsNode, directives, externalCtor, ident, jumpNode, klass, params, parent, ref3, wrapper;
if (jumpNode = this.body.jumps()) {
jumpNode.error('Class bodies cannot contain pure statements');
}
if (argumentsNode = this.body.contains(isLiteralArguments)) {
argumentsNode.error("Class bodies shouldn't reference arguments");
}
this.name = (ref3 = this["class"].name) != null ? ref3 : this.defaultClassVariableName;
directives = this.walkBody();
this.setContext();
ident = new IdentifierLiteral(this.name);
params = [];
args = [];
wrapper = new Code(params, this.body);
klass = new Parens(new Call(wrapper, args));
this.body.spaced = true;
o.classScope = wrapper.makeScope(o.scope);
if (this["class"].hasNameClash) {
parent = new IdentifierLiteral(o.classScope.freeVariable('superClass'));
wrapper.params.push(new Param(parent));
args.push(this["class"].parent);
this["class"].parent = parent;
}
if (this.externalCtor) {
externalCtor = new IdentifierLiteral(o.classScope.freeVariable('ctor', {
reserve: false
}));
this["class"].externalCtor = externalCtor;
this.externalCtor.variable.base = externalCtor;
}
if (this.name !== this["class"].name) {
this.body.expressions.unshift(new Assign(new IdentifierLiteral(this.name), this["class"]));
} else {
this.body.expressions.unshift(this["class"]);
}
this.body.expressions.unshift(...directives);
this.body.push(ident);
return klass.compileToFragments(o);
}
walkBody() {
var directives, expr, index;
directives = [];
index = 0;
while (expr = this.body.expressions[index]) {
if (!(expr instanceof Comment || expr instanceof Value && expr.isString())) {
break;
}
if (expr.hoisted) {
index++;
} else {
directives.push(...this.body.expressions.splice(index, 1));
}
}
this.traverseChildren(false, (child) => {
var cont, i, j, len1, node, ref3;
if (child instanceof Class || child instanceof HoistTarget) {
return false;
}
cont = true;
if (child instanceof Block) {
ref3 = child.expressions;
for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
node = ref3[i];
if (node instanceof Value && node.isObject(true)) {
cont = false;
child.expressions[i] = this.addProperties(node.base.properties);
} else if (node instanceof Assign && node.variable.looksStatic(this.name)) {
node.value.isStatic = true;
}
}
child.expressions = flatten(child.expressions);
}
return cont;
});
return directives;
}
setContext() {
return this.body.traverseChildren(false, (node) => {
if (node instanceof ThisLiteral) {
return node.value = this.name;
} else if (node instanceof Code && node.bound) {
return node.context = this.name;
}
});
}
addProperties(assigns) {
var assign, base, name, prototype, result, value, variable;
result = (function() {
var j, len1, results;
results = [];
for (j = 0, len1 = assigns.length; j < len1; j++) {
assign = assigns[j];
variable = assign.variable;
base = variable != null ? variable.base : void 0;
value = assign.value;
delete assign.context;
if (assign instanceof Comment) {
} else if (base.value === 'constructor') {
if (value instanceof Code) {
base.error('constructors must be defined at the top level of a class body');
}
assign = this.externalCtor = new Assign(new Value, value);
} else if (!assign.variable["this"]) {
name = new (base.shouldCache() ? Index : Access)(base);
prototype = new Access(new PropertyName('prototype'));
variable = new Value(new ThisLiteral(), [prototype, name]);
assign.variable = variable;
} else if (assign.value instanceof Code) {
assign.value.isStatic = true;
}
results.push(assign);
}
return results;
}).call(this);
return compact(result);
}
};
ExecutableClassBody.prototype.children = ['class', 'body'];
ExecutableClassBody.prototype.defaultClassVariableName = '_Class';
return ExecutableClassBody;
})();
exports.ModuleDeclaration = ModuleDeclaration = (function() {
class ModuleDeclaration extends Base {
constructor(clause, source1) {
super();
this.clause = clause;
this.source = source1;
this.checkSource();
}
checkSource() {
if ((this.source != null) && this.source instanceof StringWithInterpolations) {
return this.source.error('the name of the module to be imported from must be an uninterpolated string');
}
}
checkScope(o, moduleDeclarationType) {
if (o.indent.length !== 0) {
return this.error(`${moduleDeclarationType} statements must be at top-level scope`);
}
}
};
ModuleDeclaration.prototype.children = ['clause', 'source'];
ModuleDeclaration.prototype.isStatement = YES;
ModuleDeclaration.prototype.jumps = THIS;
ModuleDeclaration.prototype.makeReturn = THIS;
return ModuleDeclaration;
})();
exports.ImportDeclaration = ImportDeclaration = class ImportDeclaration extends ModuleDeclaration {
compileNode(o) {
var code, ref3;
this.checkScope(o, 'import');
o.importedSymbols = [];
code = [];
code.push(this.makeCode(`${this.tab}import `));
if (this.clause != null) {
code.push(...this.clause.compileNode(o));
}
if (((ref3 = this.source) != null ? ref3.value : void 0) != null) {
if (this.clause !== null) {
code.push(this.makeCode(' from '));
}
code.push(this.makeCode(this.source.value));
}
code.push(this.makeCode(';'));
return code;
}
};
exports.ImportClause = ImportClause = (function() {
class ImportClause extends Base {
constructor(defaultBinding, namedImports) {
super();
this.defaultBinding = defaultBinding;
this.namedImports = namedImports;
}
compileNode(o) {
var code;
code = [];
if (this.defaultBinding != null) {
code.push(...this.defaultBinding.compileNode(o));
if (this.namedImports != null) {
code.push(this.makeCode(', '));
}
}
if (this.namedImports != null) {
code.push(...this.namedImports.compileNode(o));
}
return code;
}
};
ImportClause.prototype.children = ['defaultBinding', 'namedImports'];
return ImportClause;
})();
exports.ExportDeclaration = ExportDeclaration = class ExportDeclaration extends ModuleDeclaration {
compileNode(o) {
var code, ref3;
this.checkScope(o, 'export');
code = [];
code.push(this.makeCode(`${this.tab}export `));
if (this instanceof ExportDefaultDeclaration) {
code.push(this.makeCode('default '));
}
if (!(this instanceof ExportDefaultDeclaration) && (this.clause instanceof Assign || this.clause instanceof Class)) {
if (this.clause instanceof Class && !this.clause.variable) {
this.clause.error('anonymous classes cannot be exported');
}
code.push(this.makeCode('var '));
this.clause.moduleDeclaration = 'export';
}
if ((this.clause.body != null) && this.clause.body instanceof Block) {
code = code.concat(this.clause.compileToFragments(o, LEVEL_TOP));
} else {
code = code.concat(this.clause.compileNode(o));
}
if (((ref3 = this.source) != null ? ref3.value : void 0) != null) {
code.push(this.makeCode(` from ${this.source.value}`));
}
code.push(this.makeCode(';'));
return code;
}
};
exports.ExportNamedDeclaration = ExportNamedDeclaration = class ExportNamedDeclaration extends ExportDeclaration {};
exports.ExportDefaultDeclaration = ExportDefaultDeclaration = class ExportDefaultDeclaration extends ExportDeclaration {};
exports.ExportAllDeclaration = ExportAllDeclaration = class ExportAllDeclaration extends ExportDeclaration {};
exports.ModuleSpecifierList = ModuleSpecifierList = (function() {
class ModuleSpecifierList extends Base {
constructor(specifiers) {
super();
this.specifiers = specifiers;
}
compileNode(o) {
var code, compiledList, fragments, index, j, len1, specifier;
code = [];
o.indent += TAB;
compiledList = (function() {
var j, len1, ref3, results;
ref3 = this.specifiers;
results = [];
for (j = 0, len1 = ref3.length; j < len1; j++) {
specifier = ref3[j];
results.push(specifier.compileToFragments(o, LEVEL_LIST));
}
return results;
}).call(this);
if (this.specifiers.length !== 0) {
code.push(this.makeCode(`{\n${o.indent}`));
for (index = j = 0, len1 = compiledList.length; j < len1; index = ++j) {
fragments = compiledList[index];
if (index) {
code.push(this.makeCode(`,\n${o.indent}`));
}
code.push(...fragments);
}
code.push(this.makeCode("\n}"));
} else {
code.push(this.makeCode('{}'));
}
return code;
}
};
ModuleSpecifierList.prototype.children = ['specifiers'];
return ModuleSpecifierList;
})();
exports.ImportSpecifierList = ImportSpecifierList = class ImportSpecifierList extends ModuleSpecifierList {};
exports.ExportSpecifierList = ExportSpecifierList = class ExportSpecifierList extends ModuleSpecifierList {};
exports.ModuleSpecifier = ModuleSpecifier = (function() {
class ModuleSpecifier extends Base {
constructor(original, alias, moduleDeclarationType1) {
super();
this.original = original;
this.alias = alias;
this.moduleDeclarationType = moduleDeclarationType1;
this.identifier = this.alias != null ? this.alias.value : this.original.value;
}
compileNode(o) {
var code;
o.scope.find(this.identifier, this.moduleDeclarationType);
code = [];
code.push(this.makeCode(this.original.value));
if (this.alias != null) {
code.push(this.makeCode(` as ${this.alias.value}`));
}
return code;
}
};
ModuleSpecifier.prototype.children = ['original', 'alias'];
return ModuleSpecifier;
})();
exports.ImportSpecifier = ImportSpecifier = class ImportSpecifier extends ModuleSpecifier {
constructor(imported, local) {
super(imported, local, 'import');
}
compileNode(o) {
var ref3;
if ((ref3 = this.identifier, indexOf.call(o.importedSymbols, ref3) >= 0) || o.scope.check(this.identifier)) {
this.error(`'${this.identifier}' has already been declared`);
} else {
o.importedSymbols.push(this.identifier);
}
return super.compileNode(o);
}
};
exports.ImportDefaultSpecifier = ImportDefaultSpecifier = class ImportDefaultSpecifier extends ImportSpecifier {};
exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier = class ImportNamespaceSpecifier extends ImportSpecifier {};
exports.ExportSpecifier = ExportSpecifier = class ExportSpecifier extends ModuleSpecifier {
constructor(local, exported) {
super(local, exported, 'export');
}
};
exports.Assign = Assign = (function() {
class Assign extends Base {
constructor(variable1, value1, context1, options = {}) {
super();
this.variable = variable1;
this.value = value1;
this.context = context1;
this.param = options.param, this.subpattern = options.subpattern, this.operatorToken = options.operatorToken, this.moduleDeclaration = options.moduleDeclaration;
}
isStatement(o) {
return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && (this.moduleDeclaration || indexOf.call(this.context, "?") >= 0);
}
checkAssignability(o, varBase) {
if (Object.prototype.hasOwnProperty.call(o.scope.positions, varBase.value) && o.scope.variables[o.scope.positions[varBase.value]].type === 'import') {
return varBase.error(`'${varBase.value}' is read-only`);
}
}
assigns(name) {
return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
}
unfoldSoak(o) {
return unfoldSoak(o, this, 'variable');
}
compileNode(o) {
var answer, compiledName, isValue, j, name, properties, prototype, ref3, ref4, ref5, ref6, ref7, ref8, val, varBase;
if (isValue = this.variable instanceof Value) {
if (this.variable.isArray() || this.variable.isObject()) {
return this.compilePatternMatch(o);
}
if (this.variable.isSplice()) {
return this.compileSplice(o);
}
if ((ref3 = this.context) === '||=' || ref3 === '&&=' || ref3 === '?=') {
return this.compileConditional(o);
}
if ((ref4 = this.context) === '**=' || ref4 === '//=' || ref4 === '%%=') {
return this.compileSpecialMath(o);
}
}
if (this.value instanceof Code) {
if (this.value.isStatic) {
this.value.name = this.variable.properties[0];
} else if (((ref5 = this.variable.properties) != null ? ref5.length : void 0) >= 2) {
ref6 = this.variable.properties, properties = 3 <= ref6.length ? slice.call(ref6, 0, j = ref6.length - 2) : (j = 0, []), prototype = ref6[j++], name = ref6[j++];
if (((ref7 = prototype.name) != null ? ref7.value : void 0) === 'prototype') {
this.value.name = name;
}
}
}
if (!this.context) {
varBase = this.variable.unwrapAll();
if (!varBase.isAssignable()) {
this.variable.error(`'${this.variable.compile(o)}' can't be assigned`);
}
if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
if (this.moduleDeclaration) {
this.checkAssignability(o, varBase);
o.scope.add(varBase.value, this.moduleDeclaration);
} else if (this.param) {
o.scope.add(varBase.value, 'var');
} else {
this.checkAssignability(o, varBase);
o.scope.find(varBase.value);
}
}
}
val = this.value.compileToFragments(o, LEVEL_LIST);
if (isValue && this.variable.base instanceof Obj) {
this.variable.front = true;
}
compiledName = this.variable.compileToFragments(o, LEVEL_LIST);
if (this.context === 'object') {
if (this.variable.shouldCache()) {
compiledName.unshift(this.makeCode('['));
compiledName.push(this.makeCode(']'));
} else if (ref8 = fragmentsToText(compiledName), indexOf.call(JS_FORBIDDEN, ref8) >= 0) {
compiledName.unshift(this.makeCode('"'));
compiledName.push(this.makeCode('"'));
}
return compiledName.concat(this.makeCode(": "), val);
}
answer = compiledName.concat(this.makeCode(` ${this.context || '='} `), val);
if (o.level <= LEVEL_LIST) {
return answer;
} else {
return this.wrapInBraces(answer);
}
}
compilePatternMatch(o) {
var acc, assigns, code, defaultValue, expandedIdx, fragments, i, idx, isObject, ivar, j, len1, message, name, obj, objects, olen, ref, ref3, ref4, ref5, ref6, rest, top, val, value, vvar, vvarText;
top = o.level === LEVEL_TOP;
value = this.value;
objects = this.variable.base.objects;
if (!(olen = objects.length)) {
code = value.compileToFragments(o);
if (o.level >= LEVEL_OP) {
return this.wrapInBraces(code);
} else {
return code;
}
}
obj = objects[0];
if (olen === 1 && obj instanceof Expansion) {
obj.error('Destructuring assignment has no target');
}
isObject = this.variable.isObject();
if (top && olen === 1 && !(obj instanceof Splat)) {
defaultValue = null;
if (obj instanceof Assign && obj.context === 'object') {
ref3 = obj, (ref4 = ref3.variable, idx = ref4.base), obj = ref3.value;
if (obj instanceof Assign) {
defaultValue = obj.value;
obj = obj.variable;
}
} else {
if (obj instanceof Assign) {
defaultValue = obj.value;
obj = obj.variable;
}
idx = isObject ? obj["this"] ? obj.properties[0].name : new PropertyName(obj.unwrap().value) : new NumberLiteral(0);
}
acc = idx.unwrap() instanceof PropertyName;
value = new Value(value);
value.properties.push(new (acc ? Access : Index)(idx));
message = isUnassignable(obj.unwrap().value);
if (message) {
obj.error(message);
}
if (defaultValue) {
value = new Op('?', value, defaultValue);
}
return new Assign(obj, value, null, {
param: this.param
}).compileToFragments(o, LEVEL_TOP);
}
vvar = value.compileToFragments(o, LEVEL_LIST);
vvarText = fragmentsToText(vvar);
assigns = [];
expandedIdx = false;
if (!(value.unwrap() instanceof IdentifierLiteral) || this.variable.assigns(vvarText)) {
assigns.push([this.makeCode(`${(ref = o.scope.freeVariable('ref'))} = `), ...vvar]);
vvar = [this.makeCode(ref)];
vvarText = ref;
}
for (i = j = 0, len1 = objects.length; j < len1; i = ++j) {
obj = objects[i];
idx = i;
if (!expandedIdx && obj instanceof Splat) {
name = obj.name.unwrap().value;
obj = obj.unwrap();
val = `${olen} <= ${vvarText}.length ? ${utility('slice', o)}.call(${vvarText}, ${i}`;
if (rest = olen - i - 1) {
ivar = o.scope.freeVariable('i', {
single: true
});
val += `, ${ivar} = ${vvarText}.length - ${rest}) : (${ivar} = ${i}, [])`;
} else {
val += ") : []";
}
val = new Literal(val);
expandedIdx = `${ivar}++`;
} else if (!expandedIdx && obj instanceof Expansion) {
if (rest = olen - i - 1) {
if (rest === 1) {
expandedIdx = `${vvarText}.length - 1`;
} else {
ivar = o.scope.freeVariable('i', {
single: true
});
val = new Literal(`${ivar} = ${vvarText}.length - ${rest}`);
expandedIdx = `${ivar}++`;
assigns.push(val.compileToFragments(o, LEVEL_LIST));
}
}
continue;
} else {
if (obj instanceof Splat || obj instanceof Expansion) {
obj.error("multiple splats/expansions are disallowed in an assignment");
}
defaultValue = null;
if (obj instanceof Assign && obj.context === 'object') {
ref5 = obj, (ref6 = ref5.variable, idx = ref6.base), obj = ref5.value;
if (obj instanceof Assign) {
defaultValue = obj.value;
obj = obj.variable;
}
} else {
if (obj instanceof Assign) {
defaultValue = obj.value;
obj = obj.variable;
}
idx = isObject ? obj["this"] ? obj.properties[0].name : new PropertyName(obj.unwrap().value) : new Literal(expandedIdx || idx);
}
name = obj.unwrap().value;
acc = idx.unwrap() instanceof PropertyName;
val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]);
if (defaultValue) {
val = new Op('?', val, defaultValue);
}
}
if (name != null) {
message = isUnassignable(name);
if (message) {
obj.error(message);
}
}
assigns.push(new Assign(obj, val, null, {
param: this.param,
subpattern: true
}).compileToFragments(o, LEVEL_LIST));
}
if (!(top || this.subpattern)) {
assigns.push(vvar);
}
fragments = this.joinFragmentArrays(assigns, ', ');
if (o.level < LEVEL_LIST) {
return fragments;
} else {
return this.wrapInBraces(fragments);
}
}
compileConditional(o) {
var fragments, left, ref3, right;
ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1];
if (!left.properties.length && left.base instanceof Literal && !(left.base instanceof ThisLiteral) && !o.scope.check(left.base.value)) {
this.variable.error(`the variable \"${left.base.value}\" can't be assigned with ${this.context} because it has not been declared before`);
}
if (indexOf.call(this.context, "?") >= 0) {
o.isExistentialEquals = true;
return new If(new Existence(left), right, {
type: 'if'
}).addElse(new Assign(right, this.value, '=')).compileToFragments(o);
} else {
fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o);
if (o.level <= LEVEL_LIST) {
return fragments;
} else {
return this.wrapInBraces(fragments);
}
}
}
compileSpecialMath(o) {
var left, ref3, right;
ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1];
return new Assign(left, new Op(this.context.slice(0, -1), right, this.value)).compileToFragments(o);
}
compileSplice(o) {
var answer, exclusive, from, fromDecl, fromRef, name, ref3, ref4, ref5, to, valDef, valRef;
ref3 = this.variable.properties.pop().range, from = ref3.from, to = ref3.to, exclusive = ref3.exclusive;
name = this.variable.compile(o);
if (from) {
ref4 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = ref4[0], fromRef = ref4[1];
} else {
fromDecl = fromRef = '0';
}
if (to) {
if ((from != null ? from.isNumber() : void 0) && to.isNumber()) {
to = to.compile(o) - fromRef;
if (!exclusive) {
to += 1;
}
} else {
to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
if (!exclusive) {
to += ' + 1';
}
}
} else {
to = "9e9";
}
ref5 = this.value.cache(o, LEVEL_LIST), valDef = ref5[0], valRef = ref5[1];
answer = [].concat(this.makeCode(`[].splice.apply(${name}, [${fromDecl}, ${to}].concat(`), valDef, this.makeCode(")), "), valRef);
if (o.level > LEVEL_TOP) {
return this.wrapInBraces(answer);
} else {
return answer;
}
}
};
Assign.prototype.children = ['variable', 'value'];
return Assign;
})();
exports.Code = Code = (function() {
class Code extends Base {
constructor(params, body, tag) {
super();
this.params = params || [];
this.body = body || new Block;
this.bound = tag === 'boundfunc';
this.isGenerator = false;
this.isAsync = false;
this.isMethod = false;
this.body.traverseChildren(false, (node) => {
if ((node instanceof Op && node.isYield()) || node instanceof YieldReturn) {
this.isGenerator = true;
}
if ((node instanceof Op && node.isAwait()) || node instanceof AwaitReturn) {
this.isAsync = true;
}
if (this.isGenerator && this.isAsync) {
return node.error("function can't contain both yield and await");
}
});
}
isStatement() {
return this.isMethod;
}
makeScope(parentScope) {
return new Scope(parentScope, this.body, this);
}
compileNode(o) {
var answer, body, condition, exprs, haveBodyParam, haveSplatParam, i, ifTrue, j, k, len1, len2, m, methodScope, modifiers, name, param, paramNames, params, paramsAfterSplat, ref, ref3, ref4, ref5, ref6, ref7, ref8, signature, splatParamName, thisAssignments, wasEmpty;
if (this.ctor) {
if (this.isAsync) {
this.name.error('Class constructor may not be async');
}
if (this.isGenerator) {
this.name.error('Class constructor may not be a generator');
}
}
if (this.bound) {
if ((ref3 = o.scope.method) != null ? ref3.bound : void 0) {
this.context = o.scope.method.context;
}
if (!this.context) {
this.context = 'this';
}
}
o.scope = del(o, 'classScope') || this.makeScope(o.scope);
o.scope.shared = del(o, 'sharedScope');
o.indent += TAB;
delete o.bare;
delete o.isExistentialEquals;
params = [];
exprs = [];
thisAssignments = (ref4 = (ref5 = this.thisAssignments) != null ? ref5.slice() : void 0) != null ? ref4 : [];
paramsAfterSplat = [];
haveSplatParam = false;
haveBodyParam = false;
paramNames = [];
this.eachParamName(function(name, node, param) {
var target;
if (indexOf.call(paramNames, name) >= 0) {
node.error(`multiple parameters named '${name}'`);
}
paramNames.push(name);
if (node["this"]) {
name = node.properties[0].name.value;
if (indexOf.call(JS_FORBIDDEN, name) >= 0) {
name = `_${name}`;
}
target = new IdentifierLiteral(o.scope.freeVariable(name));
param.renameParam(node, target);
return thisAssignments.push(new Assign(node, target));
}
});
ref6 = this.params;
for (i = j = 0, len1 = ref6.length; j < len1; i = ++j) {
param = ref6[i];
if (param.splat || param instanceof Expansion) {
if (haveSplatParam) {
param.error('only one splat or expansion parameter is allowed per function definition');
} else if (param instanceof Expansion && this.params.length === 1) {
param.error('an expansion parameter cannot be the only parameter in a function definition');
}
haveSplatParam = true;
if (param.splat) {
params.push(ref = param.asReference(o));
splatParamName = fragmentsToText(ref.compileNode(o));
if (param.shouldCache()) {
exprs.push(new Assign(new Value(param.name), ref, '=', {
param: true
}));
}
} else {
splatParamName = o.scope.freeVariable('args');
params.push(new Value(new IdentifierLiteral(splatParamName)));
}
o.scope.parameter(splatParamName);
} else {
if (param.shouldCache() || haveBodyParam) {
param.assignedInBody = true;
haveBodyParam = true;
if (param.value != null) {
condition = new Op('==', param, new UndefinedLiteral);
ifTrue = new Assign(new Value(param.name), param.value, '=', {
param: true
});
exprs.push(new If(condition, ifTrue));
} else {
exprs.push(new Assign(new Value(param.name), param.asReference(o), '=', {
param: true
}));
}
}
if (!haveSplatParam) {
if (param.shouldCache()) {
ref = param.asReference(o);
} else {
if ((param.value != null) && !param.assignedInBody) {
ref = new Assign(new Value(param.name), param.value, '=');
} else {
ref = param;
}
}
o.scope.parameter(fragmentsToText((param.value != null ? param : ref).compileToFragments(o)));
params.push(ref);
} else {
paramsAfterSplat.push(param);
if ((param.value != null) && !param.shouldCache()) {
condition = new Op('==', param, new UndefinedLiteral);
ifTrue = new Assign(new Value(param.name), param.value, '=');
exprs.push(new If(condition, ifTrue));
}
if (((ref7 = param.name) != null ? ref7.value : void 0) != null) {
o.scope.add(param.name.value, 'var', true);
}
}
}
}
if (paramsAfterSplat.length !== 0) {
exprs.unshift(new Assign(new Value(new Arr([
new Splat(new IdentifierLiteral(splatParamName)), ...(function() {
var k, len2, results;
results = [];
for (k = 0, len2 = paramsAfterSplat.length; k < len2; k++) {
param = paramsAfterSplat[k];
results.push(param.asReference(o));
}
return results;
})()
])), new Value(new IdentifierLiteral(splatParamName))));
}
wasEmpty = this.body.isEmpty();
if (!this.expandCtorSuper(thisAssignments)) {
this.body.expressions.unshift(...thisAssignments);
}
this.body.expressions.unshift(...exprs);
if (!(wasEmpty || this.noReturn)) {
this.body.makeReturn();
}
modifiers = [];
if (this.isMethod && this.isStatic) {
modifiers.push('static');
}
if (this.isAsync) {
modifiers.push('async');
}
if (!(this.isMethod || this.bound)) {
modifiers.push(`function${(this.isGenerator ? '*' : '')}`);
} else if (this.isGenerator) {
modifiers.push('*');
}
signature = [this.makeCode('(')];
for (i = k = 0, len2 = params.length; k < len2; i = ++k) {
param = params[i];
if (i) {
signature.push(this.makeCode(', '));
}
if (haveSplatParam && i === params.length - 1) {
signature.push(this.makeCode('...'));
}
signature.push(...param.compileToFragments(o));
}
signature.push(this.makeCode(')'));
if (!this.body.isEmpty()) {
body = this.body.compileWithDeclarations(o);
}
if (this.isMethod) {
ref8 = [o.scope, o.scope.parent], methodScope = ref8[0], o.scope = ref8[1];
name = this.name.compileToFragments(o);
if (name[0].code === '.') {
name.shift();
}
o.scope = methodScope;
}
answer = this.joinFragmentArrays((function() {
var l, len3, results;
results = [];
for (l = 0, len3 = modifiers.length; l < len3; l++) {
m = modifiers[l];
results.push(this.makeCode(m));
}
return results;
}).call(this), ' ');
if (modifiers.length && name) {
answer.push(this.makeCode(' '));
}
if (name) {
answer.push(...name);
}
answer.push(...signature);
if (this.bound && !this.isMethod) {
answer.push(this.makeCode(' =>'));
}
answer.push(this.makeCode(' {'));
if (body != null ? body.length : void 0) {
answer.push(this.makeCode('\n'), ...body, this.makeCode(`\n${this.tab}`));
}
answer.push(this.makeCode('}'));
if (this.isMethod) {
return [this.makeCode(this.tab), ...answer];
}
if (this.front || (o.level >= LEVEL_ACCESS)) {
return this.wrapInBraces(answer);
} else {
return answer;
}
}
eachParamName(iterator) {
var j, len1, param, ref3, results;
ref3 = this.params;
results = [];
for (j = 0, len1 = ref3.length; j < len1; j++) {
param = ref3[j];
results.push(param.eachName(iterator));
}
return results;
}
traverseChildren(crossScope, func) {
if (crossScope) {
return super.traverseChildren(crossScope, func);
}
}
replaceInContext(child, replacement) {
if (this.bound) {
return super.replaceInContext(child, replacement);
} else {
return false;
}
}
expandCtorSuper(thisAssignments) {
var haveThisParam, param, ref3, seenSuper;
if (!this.ctor) {
return false;
}
this.eachSuperCall(Block.wrap(this.params), function(superCall) {
return superCall.error("'super' is not allowed in constructor parameter defaults");
});
seenSuper = this.eachSuperCall(this.body, (superCall) => {
if (this.ctor === 'base') {
superCall.error("'super' is only allowed in derived class constructors");
}
return superCall.expressions = thisAssignments;
});
haveThisParam = thisAssignments.length && thisAssignments.length !== ((ref3 = this.thisAssignments) != null ? ref3.length : void 0);
if (this.ctor === 'derived' && !seenSuper && haveThisParam) {
param = thisAssignments[0].variable;
param.error("Can't use @params in derived class constructors without calling super");
}
return seenSuper;
}
eachSuperCall(context, iterator) {
var seenSuper;
seenSuper = false;
context.traverseChildren(true, (child) => {
if (child instanceof SuperCall) {
seenSuper = true;
iterator(child);
} else if (child instanceof ThisLiteral && this.ctor === 'derived' && !seenSuper) {
child.error("Can't reference 'this' before calling super in derived class constructors");
}
return !(child instanceof SuperCall) && (!(child instanceof Code) || child.bound);
});
return seenSuper;
}
};
Code.prototype.children = ['params', 'body'];
Code.prototype.jumps = NO;
return Code;
})();
exports.Param = Param = (function() {
class Param extends Base {
constructor(name1, value1, splat) {
var message, token;
super();
this.name = name1;
this.value = value1;
this.splat = splat;
message = isUnassignable(this.name.unwrapAll().value);
if (message) {
this.name.error(message);
}
if (this.name instanceof Obj && this.name.generated) {
token = this.name.objects[0].operatorToken;
token.error(`unexpected ${token.value}`);
}
}
compileToFragments(o) {
return this.name.compileToFragments(o, LEVEL_LIST);
}
asReference(o) {
var name, node;
if (this.reference) {
return this.reference;
}
node = this.name;
if (node["this"]) {
name = node.properties[0].name.value;
if (indexOf.call(JS_FORBIDDEN, name) >= 0) {
name = `_${name}`;
}
node = new IdentifierLiteral(o.scope.freeVariable(name));
} else if (node.shouldCache()) {
node = new IdentifierLiteral(o.scope.freeVariable('arg'));
}
node = new Value(node);
node.updateLocationDataIfMissing(this.locationData);
return this.reference = node;
}
shouldCache() {
return this.name.shouldCache();
}
eachName(iterator, name = this.name) {
var atParam, j, len1, node, obj, ref3, ref4;
atParam = (obj) => {
return iterator(`@${obj.properties[0].name.value}`, obj, this);
};
if (name instanceof Literal) {
return iterator(name.value, name, this);
}
if (name instanceof Value) {
return atParam(name);
}
ref4 = (ref3 = name.objects) != null ? ref3 : [];
for (j = 0, len1 = ref4.length; j < len1; j++) {
obj = ref4[j];
if (obj instanceof Assign && (obj.context == null)) {
obj = obj.variable;
}
if (obj instanceof Assign) {
if (obj.value instanceof Assign) {
obj = obj.value;
}
this.eachName(iterator, obj.value.unwrap());
} else if (obj instanceof Splat) {
node = obj.name.unwrap();
iterator(node.value, node, this);
} else if (obj instanceof Value) {
if (obj.isArray() || obj.isObject()) {
this.eachName(iterator, obj.base);
} else if (obj["this"]) {
atParam(obj);
} else {
iterator(obj.base.value, obj.base, this);
}
} else if (!(obj instanceof Expansion)) {
obj.error(`illegal parameter ${obj.compile()}`);
}
}
}
renameParam(node, newNode) {
var isNode, replacement;
isNode = function(candidate) {
return candidate === node;
};
replacement = (node, parent) => {
var key;
if (parent instanceof Obj) {
key = node;
if (node["this"]) {
key = node.properties[0].name;
}
return new Assign(new Value(key), newNode, 'object');
} else {
return newNode;
}
};
return this.replaceInContext(isNode, replacement);
}
};
Param.prototype.children = ['name', 'value'];
return Param;
})();
exports.Splat = Splat = (function() {
class Splat extends Base {
constructor(name) {
super();
this.name = name.compile ? name : new Literal(name);
}
assigns(name) {
return this.name.assigns(name);
}
compileToFragments(o) {
return [this.makeCode('...'), ...this.name.compileToFragments(o)];
}
unwrap() {
return this.name;
}
};
Splat.prototype.children = ['name'];
Splat.prototype.isAssignable = YES;
return Splat;
})();
exports.Expansion = Expansion = (function() {
class Expansion extends Base {
compileNode(o) {
return this.error('Expansion must be used inside a destructuring assignment or parameter list');
}
asReference(o) {
return this;
}
eachName(iterator) {}
};
Expansion.prototype.shouldCache = NO;
return Expansion;
})();
exports.While = While = (function() {
class While extends Base {
constructor(condition, options) {
super();
this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
this.guard = options != null ? options.guard : void 0;
}
makeReturn(res) {
if (res) {
return super.makeReturn(res);
} else {
this.returns = !this.jumps({
loop: true
});
return this;
}
}
addBody(body1) {
this.body = body1;
return this;
}
jumps() {
var expressions, j, jumpNode, len1, node;
expressions = this.body.expressions;
if (!expressions.length) {
return false;
}
for (j = 0, len1 = expressions.length; j < len1; j++) {
node = expressions[j];
if (jumpNode = node.jumps({
loop: true
})) {
return jumpNode;
}
}
return false;
}
compileNode(o) {
var answer, body, rvar, set;
o.indent += TAB;
set = '';
body = this.body;
if (body.isEmpty()) {
body = this.makeCode('');
} else {
if (this.returns) {
body.makeReturn(rvar = o.scope.freeVariable('results'));
set = `${this.tab}${rvar} = [];\n`;
}
if (this.guard) {
if (body.expressions.length > 1) {
body.expressions.unshift(new If((new Parens(this.guard)).invert(), new StatementLiteral("continue")));
} else {
if (this.guard) {
body = Block.wrap([new If(this.guard, body)]);
}
}
}
body = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode(`\n${this.tab}`));
}
answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}"));
if (this.returns) {
answer.push(this.makeCode(`\n${this.tab}return ${rvar};`));
}
return answer;
}
};
While.prototype.children = ['condition', 'guard', 'body'];
While.prototype.isStatement = YES;
return While;
})();
exports.Op = Op = (function() {
var CONVERSIONS, INVERSIONS;
class Op extends Base {
constructor(op, first, second, flip) {
if (op === 'in') {
return new In(first, second);
}
if (op === 'do') {
return Op.prototype.generateDo(first);
}
if (op === 'new') {
if (first instanceof Call && !first["do"] && !first.isNew) {
return first.newInstance();
}
if (first instanceof Code && first.bound || first["do"]) {
first = new Parens(first);
}
}
super();
this.operator = CONVERSIONS[op] || op;
this.first = first;
this.second = second;
this.flip = !!flip;
return this;
}
isNumber() {
var ref3;
return this.isUnary() && ((ref3 = this.operator) === '+' || ref3 === '-') && this.first instanceof Value && this.first.isNumber();
}
isAwait() {
return this.operator === 'await';
}
isYield() {
var ref3;
return (ref3 = this.operator) === 'yield' || ref3 === 'yield*';
}
isUnary() {
return !this.second;
}
shouldCache() {
return !this.isNumber();
}
isChainable() {
var ref3;
return (ref3 = this.operator) === '<' || ref3 === '>' || ref3 === '>=' || ref3 === '<=' || ref3 === '===' || ref3 === '!==';
}
invert() {
var allInvertable, curr, fst, op, ref3;
if (this.isChainable() && this.first.isChainable()) {
allInvertable = true;
curr = this;
while (curr && curr.operator) {
allInvertable && (allInvertable = curr.operator in INVERSIONS);
curr = curr.first;
}
if (!allInvertable) {
return new Parens(this).invert();
}
curr = this;
while (curr && curr.operator) {
curr.invert = !curr.invert;
curr.operator = INVERSIONS[curr.operator];
curr = curr.first;
}
return this;
} else if (op = INVERSIONS[this.operator]) {
this.operator = op;
if (this.first.unwrap() instanceof Op) {
this.first.invert();
}
return this;
} else if (this.second) {
return new Parens(this).invert();
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((ref3 = fst.operator) === '!' || ref3 === 'in' || ref3 === 'instanceof')) {
return fst;
} else {
return new Op('!', this);
}
}
unfoldSoak(o) {
var ref3;
return ((ref3 = this.operator) === '++' || ref3 === '--' || ref3 === 'delete') && unfoldSoak(o, this, 'first');
}
generateDo(exp) {
var call, func, j, len1, param, passedParams, ref, ref3;
passedParams = [];
func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
ref3 = func.params || [];
for (j = 0, len1 = ref3.length; j < len1; j++) {
param = ref3[j];
if (param.value) {
passedParams.push(param.value);
delete param.value;
} else {
passedParams.push(param);
}
}
call = new Call(exp, passedParams);
call["do"] = true;
return call;
}
compileNode(o) {
var answer, isChain, lhs, message, ref3, rhs;
isChain = this.isChainable() && this.first.isChainable();
if (!isChain) {
this.first.front = this.front;
}
if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
this.error('delete operand may not be argument or var');
}
if ((ref3 = this.operator) === '--' || ref3 === '++') {
message = isUnassignable(this.first.unwrapAll().value);
if (message) {
this.first.error(message);
}
}
if (this.isYield() || this.isAwait()) {
return this.compileContinuation(o);
}
if (this.isUnary()) {
return this.compileUnary(o);
}
if (isChain) {
return this.compileChain(o);
}
switch (this.operator) {
case '?':
return this.compileExistence(o);
case '**':
return this.compilePower(o);
case '//':
return this.compileFloorDivision(o);
case '%%':
return this.compileModulo(o);
default:
lhs = this.first.compileToFragments(o, LEVEL_OP);
rhs = this.second.compileToFragments(o, LEVEL_OP);
answer = [].concat(lhs, this.makeCode(` ${this.operator} `), rhs);
if (o.level <= LEVEL_OP) {
return answer;
} else {
return this.wrapInBraces(answer);
}
}
}
compileChain(o) {
var fragments, fst, ref3, shared;
ref3 = this.first.second.cache(o), this.first.second = ref3[0], shared = ref3[1];
fst = this.first.compileToFragments(o, LEVEL_OP);
fragments = fst.concat(this.makeCode(` ${(this.invert ? '&&' : '||')} `), shared.compileToFragments(o), this.makeCode(` ${this.operator} `), this.second.compileToFragments(o, LEVEL_OP));
return this.wrapInBraces(fragments);
}
compileExistence(o) {
var fst, ref;
if (this.first.shouldCache()) {
ref = new IdentifierLiteral(o.scope.freeVariable('ref'));
fst = new Parens(new Assign(ref, this.first));
} else {
fst = this.first;
ref = fst;
}
return new If(new Existence(fst), ref, {
type: 'if'
}).addElse(this.second).compileToFragments(o);
}
compileUnary(o) {
var op, parts, plusMinus;
parts = [];
op = this.operator;
parts.push([this.makeCode(op)]);
if (op === '!' && this.first instanceof Existence) {
this.first.negated = !this.first.negated;
return this.first.compileToFragments(o);
}
if (o.level >= LEVEL_ACCESS) {
return (new Parens(this)).compileToFragments(o);
}
plusMinus = op === '+' || op === '-';
if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
parts.push([this.makeCode(' ')]);
}
if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
this.first = new Parens(this.first);
}
parts.push(this.first.compileToFragments(o, LEVEL_OP));
if (this.flip) {
parts.reverse();
}
return this.joinFragmentArrays(parts, '');
}
compileContinuation(o) {
var op, parts, ref3, ref4;
parts = [];
op = this.operator;
if (o.scope.parent == null) {
this.error(`${this.operator} can only occur inside functions`);
}
if (((ref3 = o.scope.method) != null ? ref3.bound : void 0) && o.scope.method.isGenerator) {
this.error('yield cannot occur inside bound (fat arrow) functions');
}
if (indexOf.call(Object.keys(this.first), 'expression') >= 0 && !(this.first instanceof Throw)) {
if (this.first.expression != null) {
parts.push(this.first.expression.compileToFragments(o, LEVEL_OP));
}
} else {
if (o.level >= LEVEL_PAREN) {
parts.push([this.makeCode("(")]);
}
parts.push([this.makeCode(op)]);
if (((ref4 = this.first.base) != null ? ref4.value : void 0) !== '') {
parts.push([this.makeCode(" ")]);
}
parts.push(this.first.compileToFragments(o, LEVEL_OP));
if (o.level >= LEVEL_PAREN) {
parts.push([this.makeCode(")")]);
}
}
return this.joinFragmentArrays(parts, '');
}
compilePower(o) {
var pow;
pow = new Value(new IdentifierLiteral('Math'), [new Access(new PropertyName('pow'))]);
return new Call(pow, [this.first, this.second]).compileToFragments(o);
}
compileFloorDivision(o) {
var div, floor, second;
floor = new Value(new IdentifierLiteral('Math'), [new Access(new PropertyName('floor'))]);
second = this.second.shouldCache() ? new Parens(this.second) : this.second;
div = new Op('/', this.first, second);
return new Call(floor, [div]).compileToFragments(o);
}
compileModulo(o) {
var mod;
mod = new Value(new Literal(utility('modulo', o)));
return new Call(mod, [this.first, this.second]).compileToFragments(o);
}
toString(idt) {
return super.toString(idt, this.constructor.name + ' ' + this.operator);
}
};
CONVERSIONS = {
'==': '===',
'!=': '!==',
'of': 'in',
'yieldfrom': 'yield*'
};
INVERSIONS = {
'!==': '===',
'===': '!=='
};
Op.prototype.children = ['first', 'second'];
return Op;
})();
exports.In = In = (function() {
class In extends Base {
constructor(object, array) {
super();
this.object = object;
this.array = array;
}
compileNode(o) {
var hasSplat, j, len1, obj, ref3;
if (this.array instanceof Value && this.array.isArray() && this.array.base.objects.length) {
ref3 = this.array.base.objects;
for (j = 0, len1 = ref3.length; j < len1; j++) {
obj = ref3[j];
if (!(obj instanceof Splat)) {
continue;
}
hasSplat = true;
break;
}
if (!hasSplat) {
return this.compileOrTest(o);
}
}
return this.compileLoopTest(o);
}
compileOrTest(o) {
var cmp, cnj, i, item, j, len1, ref, ref3, ref4, ref5, sub, tests;
ref3 = this.object.cache(o, LEVEL_OP), sub = ref3[0], ref = ref3[1];
ref4 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = ref4[0], cnj = ref4[1];
tests = [];
ref5 = this.array.base.objects;
for (i = j = 0, len1 = ref5.length; j < len1; i = ++j) {
item = ref5[i];
if (i) {
tests.push(this.makeCode(cnj));
}
tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS));
}
if (o.level < LEVEL_OP) {
return tests;
} else {
return this.wrapInBraces(tests);
}
}
compileLoopTest(o) {
var fragments, ref, ref3, sub;
ref3 = this.object.cache(o, LEVEL_LIST), sub = ref3[0], ref = ref3[1];
fragments = [].concat(this.makeCode(utility('indexOf', o) + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
if (fragmentsToText(sub) === fragmentsToText(ref)) {
return fragments;
}
fragments = sub.concat(this.makeCode(', '), fragments);
if (o.level < LEVEL_LIST) {
return fragments;
} else {
return this.wrapInBraces(fragments);
}
}
toString(idt) {
return super.toString(idt, this.constructor.name + (this.negated ? '!' : ''));
}
};
In.prototype.children = ['object', 'array'];
In.prototype.invert = NEGATE;
return In;
})();
exports.Try = Try = (function() {
class Try extends Base {
constructor(attempt, errorVariable, recovery, ensure) {
super();
this.attempt = attempt;
this.errorVariable = errorVariable;
this.recovery = recovery;
this.ensure = ensure;
}
jumps(o) {
var ref3;
return this.attempt.jumps(o) || ((ref3 = this.recovery) != null ? ref3.jumps(o) : void 0);
}
makeReturn(res) {
if (this.attempt) {
this.attempt = this.attempt.makeReturn(res);
}
if (this.recovery) {
this.recovery = this.recovery.makeReturn(res);
}
return this;
}
compileNode(o) {
var catchPart, ensurePart, generatedErrorVariableName, message, placeholder, tryPart;
o.indent += TAB;
tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
catchPart = this.recovery ? (generatedErrorVariableName = o.scope.freeVariable('error', {
reserve: false
}), placeholder = new IdentifierLiteral(generatedErrorVariableName), this.errorVariable ? (message = isUnassignable(this.errorVariable.unwrapAll().value), message ? this.errorVariable.error(message) : void 0, this.recovery.unshift(new Assign(this.errorVariable, placeholder))) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode(`\n${this.tab}}`))) : !(this.ensure || this.recovery) ? (generatedErrorVariableName = o.scope.freeVariable('error', {
reserve: false
}), [this.makeCode(` catch (${generatedErrorVariableName}) {}`)]) : [];
ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode(`\n${this.tab}}`)) : [];
return [].concat(this.makeCode(`${this.tab}try {\n`), tryPart, this.makeCode(`\n${this.tab}}`), catchPart, ensurePart);
}
};
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
Try.prototype.isStatement = YES;
return Try;
})();
exports.Throw = Throw = (function() {
class Throw extends Base {
constructor(expression1) {
super();
this.expression = expression1;
}
compileNode(o) {
return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";"));
}
};
Throw.prototype.children = ['expression'];
Throw.prototype.isStatement = YES;
Throw.prototype.jumps = NO;
Throw.prototype.makeReturn = THIS;
return Throw;
})();
exports.Existence = Existence = (function() {
class Existence extends Base {
constructor(expression1) {
super();
this.expression = expression1;
}
compileNode(o) {
var cmp, cnj, code, ref3;
this.expression.front = this.front;
code = this.expression.compile(o, LEVEL_OP);
if (this.expression.unwrap() instanceof IdentifierLiteral && !o.scope.check(code)) {
ref3 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = ref3[0], cnj = ref3[1];
code = `typeof ${code} ${cmp} \"undefined\" ${cnj} ${code} ${cmp} null`;
} else {
code = `${code} ${(this.negated ? '==' : '!=')} null`;
}
return [this.makeCode(o.level <= LEVEL_COND ? code : `(${code})`)];
}
};
Existence.prototype.children = ['expression'];
Existence.prototype.invert = NEGATE;
return Existence;
})();
exports.Parens = Parens = (function() {
class Parens extends Base {
constructor(body1) {
super();
this.body = body1;
}
unwrap() {
return this.body;
}
shouldCache() {
return this.body.shouldCache();
}
compileNode(o) {
var bare, expr, fragments;
expr = this.body.unwrap();
if (expr instanceof Value && expr.isAtomic()) {
expr.front = this.front;
return expr.compileToFragments(o);
}
fragments = expr.compileToFragments(o, LEVEL_PAREN);
bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
if (bare) {
return fragments;
} else {
return this.wrapInBraces(fragments);
}
}
};
Parens.prototype.children = ['body'];
return Parens;
})();
exports.StringWithInterpolations = StringWithInterpolations = (function() {
class StringWithInterpolations extends Base {
constructor(body1) {
super();
this.body = body1;
}
unwrap() {
return this;
}
shouldCache() {
return this.body.shouldCache();
}
compileNode(o) {
var element, elements, expr, fragments, j, len1, value;
expr = this.body.unwrap();
elements = [];
expr.traverseChildren(false, function(node) {
if (node instanceof StringLiteral) {
elements.push(node);
return true;
} else if (node instanceof Parens) {
elements.push(node);
return false;
}
return true;
});
fragments = [];
fragments.push(this.makeCode('`'));
for (j = 0, len1 = elements.length; j < len1; j++) {
element = elements[j];
if (element instanceof StringLiteral) {
value = element.value.slice(1, -1);
value = value.replace(/(\\*)(`|\$\{)/g, function(match, backslashes, toBeEscaped) {
if (backslashes.length % 2 === 0) {
return `${backslashes}\\${toBeEscaped}`;
} else {
return match;
}
});
fragments.push(this.makeCode(value));
} else {
fragments.push(this.makeCode('${'));
fragments.push(...element.compileToFragments(o, LEVEL_PAREN));
fragments.push(this.makeCode('}'));
}
}
fragments.push(this.makeCode('`'));
return fragments;
}
};
StringWithInterpolations.prototype.children = ['body'];
return StringWithInterpolations;
})();
exports.For = For = (function() {
class For extends While {
constructor(body, source) {
var ref3;
super();
this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
this.body = Block.wrap([body]);
this.own = !!source.own;
this.object = !!source.object;
this.from = !!source.from;
if (this.from && this.index) {
this.index.error('cannot use index with for-from');
}
if (this.own && !this.object) {
source.ownTag.error(`cannot use own with for-${(this.from ? 'from' : 'in')}`);
}
if (this.object) {
ref3 = [this.index, this.name], this.name = ref3[0], this.index = ref3[1];
}
if (this.index instanceof Value && !this.index.isAssignable()) {
this.index.error('index cannot be a pattern matching expression');
}
this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length && !this.from;
this.pattern = this.name instanceof Value;
if (this.range && this.index) {
this.index.error('indexes do not apply to range loops');
}
if (this.range && this.pattern) {
this.name.error('cannot pattern match over range loops');
}
this.returns = false;
}
compileNode(o) {
var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, last, lvar, name, namePart, ref, ref3, ref4, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart;
body = Block.wrap([this.body]);
ref3 = body.expressions, last = ref3[ref3.length - 1];
if ((last != null ? last.jumps() : void 0) instanceof Return) {
this.returns = false;
}
source = this.range ? this.source.base : this.source;
scope = o.scope;
if (!this.pattern) {
name = this.name && (this.name.compile(o, LEVEL_LIST));
}
index = this.index && (this.index.compile(o, LEVEL_LIST));
if (name && !this.pattern) {
scope.find(name);
}
if (index && !(this.index instanceof Value)) {
scope.find(index);
}
if (this.returns) {
rvar = scope.freeVariable('results');
}
if (this.from) {
if (this.pattern) {
ivar = scope.freeVariable('x', {
single: true
});
}
} else {
ivar = (this.object && index) || scope.freeVariable('i', {
single: true
});
}
kvar = ((this.range || this.from) && name) || index || ivar;
kvarAssign = kvar !== ivar ? `${kvar} = ` : "";
if (this.step && !this.range) {
ref4 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST, shouldCacheOrIsAssignable)), step = ref4[0], stepVar = ref4[1];
if (this.step.isNumber()) {
stepNum = Number(stepVar);
}
}
if (this.pattern) {
name = ivar;
}
varPart = '';
guardPart = '';
defPart = '';
idt1 = this.tab + TAB;
if (this.range) {
forPartFragments = source.compileToFragments(merge(o, {
index: ivar,
name: name,
step: this.step,
shouldCache: shouldCacheOrIsAssignable
}));
} else {
svar = this.source.compile(o, LEVEL_LIST);
if ((name || this.own) && !(this.source.unwrap() instanceof IdentifierLiteral)) {
defPart += `${this.tab}${(ref = scope.freeVariable('ref'))} = ${svar};\n`;
svar = ref;
}
if (name && !this.pattern && !this.from) {
namePart = `${name} = ${svar}[${kvar}]`;
}
if (!this.object && !this.from) {
if (step !== stepVar) {
defPart += `${this.tab}${step};\n`;
}
down = stepNum < 0;
if (!(this.step && (stepNum != null) && down)) {
lvar = scope.freeVariable('len');
}
declare = `${kvarAssign}${ivar} = 0, ${lvar} = ${svar}.length`;
declareDown = `${kvarAssign}${ivar} = ${svar}.length - 1`;
compare = `${ivar} < ${lvar}`;
compareDown = `${ivar} >= 0`;
if (this.step) {
if (stepNum != null) {
if (down) {
compare = compareDown;
declare = declareDown;
}
} else {
compare = `${stepVar} > 0 ? ${compare} : ${compareDown}`;
declare = `(${stepVar} > 0 ? (${declare}) : ${declareDown})`;
}
increment = `${ivar} += ${stepVar}`;
} else {
increment = `${(kvar !== ivar ? `++${ivar}` : `${ivar}++`)}`;
}
forPartFragments = [this.makeCode(`${declare}; ${compare}; ${kvarAssign}${increment}`)];
}
}
if (this.returns) {
resultPart = `${this.tab}${rvar} = [];\n`;
returnResult = `\n${this.tab}return ${rvar};`;
body.makeReturn(rvar);
}
if (this.guard) {
if (body.expressions.length > 1) {
body.expressions.unshift(new If((new Parens(this.guard)).invert(), new StatementLiteral("continue")));
} else {
if (this.guard) {
body = Block.wrap([new If(this.guard, body)]);
}
}
}
if (this.pattern) {
body.expressions.unshift(new Assign(this.name, this.from ? new IdentifierLiteral(kvar) : new Literal(`${svar}[${kvar}]`)));
}
defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
if (namePart) {
varPart = `\n${idt1}${namePart};`;
}
if (this.object) {
forPartFragments = [this.makeCode(`${kvar} in ${svar}`)];
if (this.own) {
guardPart = `\n${idt1}if (!${utility('hasProp', o)}.call(${svar}, ${kvar})) continue;`;
}
} else if (this.from) {
forPartFragments = [this.makeCode(`${kvar} of ${svar}`)];
}
bodyFragments = body.compileToFragments(merge(o, {
indent: idt1
}), LEVEL_TOP);
if (bodyFragments && bodyFragments.length > 0) {
bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
}
return [].concat(defPartFragments, this.makeCode(`${resultPart || ''}${this.tab}for (`), forPartFragments, this.makeCode(`) {${guardPart}${varPart}`), bodyFragments, this.makeCode(`${this.tab}}${returnResult || ''}`));
}
pluckDirectCall(o, body) {
var base, defs, expr, fn, idx, j, len1, ref, ref3, ref4, ref5, ref6, ref7, ref8, ref9, val;
defs = [];
ref3 = body.expressions;
for (idx = j = 0, len1 = ref3.length; j < len1; idx = ++j) {
expr = ref3[idx];
expr = expr.unwrapAll();
if (!(expr instanceof Call)) {
continue;
}
val = (ref4 = expr.variable) != null ? ref4.unwrapAll() : void 0;
if (!((val instanceof Code) || (val instanceof Value && ((ref5 = val.base) != null ? ref5.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((ref6 = (ref7 = val.properties[0].name) != null ? ref7.value : void 0) === 'call' || ref6 === 'apply')))) {
continue;
}
fn = ((ref8 = val.base) != null ? ref8.unwrapAll() : void 0) || val;
ref = new IdentifierLiteral(o.scope.freeVariable('fn'));
base = new Value(ref);
if (val.base) {
ref9 = [base, val], val.base = ref9[0], base = ref9[1];
}
body.expressions[idx] = new Call(base, expr.args);
defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n'));
}
return defs;
}
};
For.prototype.children = ['body', 'source', 'guard', 'step'];
return For;
})();
exports.Switch = Switch = (function() {
class Switch extends Base {
constructor(subject, cases, otherwise) {
super();
this.subject = subject;
this.cases = cases;
this.otherwise = otherwise;
}
jumps(o = {
block: true
}) {
var block, conds, j, jumpNode, len1, ref3, ref4, ref5;
ref3 = this.cases;
for (j = 0, len1 = ref3.length; j < len1; j++) {
ref4 = ref3[j], conds = ref4[0], block = ref4[1];
if (jumpNode = block.jumps(o)) {
return jumpNode;
}
}
return (ref5 = this.otherwise) != null ? ref5.jumps(o) : void 0;
}
makeReturn(res) {
var j, len1, pair, ref3, ref4;
ref3 = this.cases;
for (j = 0, len1 = ref3.length; j < len1; j++) {
pair = ref3[j];
pair[1].makeReturn(res);
}
if (res) {
this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
}
if ((ref4 = this.otherwise) != null) {
ref4.makeReturn(res);
}
return this;
}
compileNode(o) {
var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref3, ref4, ref5;
idt1 = o.indent + TAB;
idt2 = o.indent = idt1 + TAB;
fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n"));
ref3 = this.cases;
for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
ref4 = ref3[i], conditions = ref4[0], block = ref4[1];
ref5 = flatten([conditions]);
for (k = 0, len2 = ref5.length; k < len2; k++) {
cond = ref5[k];
if (!this.subject) {
cond = cond.invert();
}
fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n"));
}
if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) {
fragments = fragments.concat(body, this.makeCode('\n'));
}
if (i === this.cases.length - 1 && !this.otherwise) {
break;
}
expr = this.lastNonComment(block.expressions);
if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
continue;
}
fragments.push(cond.makeCode(idt2 + 'break;\n'));
}
if (this.otherwise && this.otherwise.expressions.length) {
fragments.push(this.makeCode(idt1 + "default:\n"), ...this.otherwise.compileToFragments(o, LEVEL_TOP), this.makeCode("\n"));
}
fragments.push(this.makeCode(this.tab + '}'));
return fragments;
}
};
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
Switch.prototype.isStatement = YES;
return Switch;
})();
exports.If = If = (function() {
class If extends Base {
constructor(condition, body1, options = {}) {
super();
this.body = body1;
this.condition = options.type === 'unless' ? condition.invert() : condition;
this.elseBody = null;
this.isChain = false;
this.soak = options.soak;
}
bodyNode() {
var ref3;
return (ref3 = this.body) != null ? ref3.unwrap() : void 0;
}
elseBodyNode() {
var ref3;
return (ref3 = this.elseBody) != null ? ref3.unwrap() : void 0;
}
addElse(elseBody) {
if (this.isChain) {
this.elseBodyNode().addElse(elseBody);
} else {
this.isChain = elseBody instanceof If;
this.elseBody = this.ensureBlock(elseBody);
this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
}
return this;
}
isStatement(o) {
var ref3;
return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((ref3 = this.elseBodyNode()) != null ? ref3.isStatement(o) : void 0);
}
jumps(o) {
var ref3;
return this.body.jumps(o) || ((ref3 = this.elseBody) != null ? ref3.jumps(o) : void 0);
}
compileNode(o) {
if (this.isStatement(o)) {
return this.compileStatement(o);
} else {
return this.compileExpression(o);
}
}
makeReturn(res) {
if (res) {
this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
}
this.body && (this.body = new Block([this.body.makeReturn(res)]));
this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
return this;
}
ensureBlock(node) {
if (node instanceof Block) {
return node;
} else {
return new Block([node]);
}
}
compileStatement(o) {
var answer, body, child, cond, exeq, ifPart, indent;
child = del(o, 'chainChild');
exeq = del(o, 'isExistentialEquals');
if (exeq) {
return new If(this.condition.invert(), this.elseBodyNode(), {
type: 'if'
}).compileToFragments(o);
}
indent = o.indent + TAB;
cond = this.condition.compileToFragments(o, LEVEL_PAREN);
body = this.ensureBlock(this.body).compileToFragments(merge(o, {
indent: indent
}));
ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode(`\n${this.tab}}`));
if (!child) {
ifPart.unshift(this.makeCode(this.tab));
}
if (!this.elseBody) {
return ifPart;
}
answer = ifPart.concat(this.makeCode(' else '));
if (this.isChain) {
o.chainChild = true;
answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP));
} else {
answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {
indent: indent
}), LEVEL_TOP), this.makeCode(`\n${this.tab}}`));
}
return answer;
}
compileExpression(o) {
var alt, body, cond, fragments;
cond = this.condition.compileToFragments(o, LEVEL_COND);
body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
if (o.level >= LEVEL_COND) {
return this.wrapInBraces(fragments);
} else {
return fragments;
}
}
unfoldSoak() {
return this.soak && this;
}
};
If.prototype.children = ['condition', 'body', 'elseBody'];
return If;
})();
UTILITIES = {
extend: function(o) {
return `function(child, parent) { for (var key in parent) { if (${utility('hasProp', o)}.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); return child; }`;
},
bind: function() {
return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
},
indexOf: function() {
return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }";
},
modulo: function() {
return "function(a, b) { return (+a % (b = +b) + b) % b; }";
},
hasProp: function() {
return '{}.hasOwnProperty';
},
slice: function() {
return '[].slice';
}
};
LEVEL_TOP = 1;
LEVEL_PAREN = 2;
LEVEL_LIST = 3;
LEVEL_COND = 4;
LEVEL_OP = 5;
LEVEL_ACCESS = 6;
TAB = ' ';
SIMPLENUM = /^[+-]?\d+$/;
utility = function(name, o) {
var ref, root;
root = o.scope.root;
if (name in root.utilities) {
return root.utilities[name];
} else {
ref = root.freeVariable(name);
root.assign(ref, UTILITIES[name](o));
return root.utilities[name] = ref;
}
};
multident = function(code, tab) {
code = code.replace(/\n/g, '$&' + tab);
return code.replace(/\s+$/, '');
};
isLiteralArguments = function(node) {
return node instanceof IdentifierLiteral && node.value === 'arguments';
};
isLiteralThis = function(node) {
return node instanceof ThisLiteral || (node instanceof Code && node.bound);
};
shouldCacheOrIsAssignable = function(node) {
return node.shouldCache() || (typeof node.isAssignable === "function" ? node.isAssignable() : void 0);
};
unfoldSoak = function(o, parent, name) {
var ifn;
if (!(ifn = parent[name].unfoldSoak(o))) {
return;
}
parent[name] = ifn.body;
ifn.body = new Value(parent);
return ifn;
};
}).call(this);