From 59959a6269287a8b4d94576b5e1f60b0d4c9861d Mon Sep 17 00:00:00 2001 From: Chris Connelly Date: Thu, 30 Mar 2017 21:19:06 +0100 Subject: [PATCH 1/3] Output simple array destructuring assignments to ES2015 --- lib/coffeescript/cake.js | 3 +- lib/coffeescript/coffeescript.js | 4 +- lib/coffeescript/command.js | 2 +- lib/coffeescript/lexer.js | 46 +++---- lib/coffeescript/nodes.js | 215 +++++++++++++++++++------------ lib/coffeescript/repl.js | 6 +- lib/coffeescript/rewriter.js | 28 ++-- lib/coffeescript/sourcemap.js | 8 +- src/nodes.coffee | 72 ++++++++--- 9 files changed, 236 insertions(+), 148 deletions(-) diff --git a/lib/coffeescript/cake.js b/lib/coffeescript/cake.js index b5334b7d6c..710c5437d9 100644 --- a/lib/coffeescript/cake.js +++ b/lib/coffeescript/cake.js @@ -24,9 +24,8 @@ helpers.extend(global, { task: function(name, description, action) { - var ref; if (!action) { - ref = [description, action], action = ref[0], description = ref[1]; + [action, description] = [description, action]; } return tasks[name] = { name: name, diff --git a/lib/coffeescript/coffeescript.js b/lib/coffeescript/coffeescript.js index 66556ffd77..767efd35e9 100644 --- a/lib/coffeescript/coffeescript.js +++ b/lib/coffeescript/coffeescript.js @@ -274,7 +274,7 @@ var tag, token; token = parser.tokens[this.pos++]; if (token) { - tag = token[0], this.yytext = token[1], this.yylloc = token[2]; + [tag, this.yytext, this.yylloc] = token; parser.errorToken = token.origin || token; this.yylineno = this.yylloc.first_line; } else { @@ -297,7 +297,7 @@ var errorLoc, errorTag, errorText, errorToken, token, tokens; token = arg.token; errorToken = parser.errorToken, tokens = parser.tokens; - errorTag = errorToken[0], errorText = errorToken[1], errorLoc = errorToken[2]; + [errorTag, errorText, errorLoc] = errorToken; errorText = (function() { switch (false) { case errorToken !== tokens[tokens.length - 1]: diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 3bd6487dde..314197f59e 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -104,7 +104,7 @@ return requires.map(function(module) { var _, match, name; if (match = module.match(/^(.*)=(.*)$/)) { - _ = match[0], name = match[1], module = match[2]; + [_, name, module] = match; } name || (name = helpers.baseFileName(module, true, useWinPathSep)); return `${name} = require('${module}')`; diff --git a/lib/coffeescript/lexer.js b/lib/coffeescript/lexer.js index cd97d9f9bf..bfb64a0792 100644 --- a/lib/coffeescript/lexer.js +++ b/lib/coffeescript/lexer.js @@ -9,7 +9,7 @@ exports.Lexer = Lexer = class Lexer { tokenize(code, opts = {}) { - var consumed, end, i, ref2; + var consumed, end, i; this.literate = opts.literate; this.indent = 0; this.baseIndent = 0; @@ -29,7 +29,7 @@ i = 0; while (this.chunk = code.slice(i)) { consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken(); - ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = ref2[0], this.chunkColumn = ref2[1]; + [this.chunkLine, this.chunkColumn] = this.getLineAndColumnFromChunk(consumed); i += consumed; if (opts.untilBalanced && this.ends.length === 0) { return { @@ -64,11 +64,11 @@ } identifierToken() { - var alias, colon, colonOffset, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, ref6, ref7, tag, tagToken; + var alias, colon, colonOffset, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, ref6, tag, tagToken; if (!(match = IDENTIFIER.exec(this.chunk))) { return 0; } - input = match[0], id = match[1], colon = match[2]; + [input, id, colon] = match; idLength = id.length; poppedToken = void 0; if (id === 'own' && this.tag() === 'FOR') { @@ -167,7 +167,7 @@ tagToken.origin = [tag, alias, tagToken[2]]; } if (poppedToken) { - ref7 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = ref7[0], tagToken[2].first_column = ref7[1]; + [tagToken[2].first_line, tagToken[2].first_column] = [poppedToken[2].first_line, poppedToken[2].first_column]; } if (colon) { colonOffset = input.lastIndexOf(':'); @@ -224,7 +224,7 @@ stringToken() { var $, attempt, delimiter, doc, end, heredoc, i, indent, indentRegex, match, quote, ref2, ref3, regex, token, tokens; - quote = (STRING_START.exec(this.chunk) || [])[0]; + [quote] = STRING_START.exec(this.chunk) || []; if (!quote) { return 0; } @@ -307,7 +307,7 @@ if (!(match = this.chunk.match(COMMENT))) { return 0; } - comment = match[0], here = match[1]; + [comment, here] = match; if (here) { if (match = HERECOMMENT_ILLEGAL.exec(comment)) { this.error(`block comments cannot contain ${match[0]}`, { @@ -347,7 +347,7 @@ tokens = match.tokens, index = match.index; break; case !(match = REGEX.exec(this.chunk)): - regex = match[0], body = match[1], closed = match[2]; + [regex, body, closed] = match; this.validateEscapes(body, { isRegex: true, offsetInChunk: 1 @@ -370,7 +370,7 @@ default: return 0; } - flags = REGEX_FLAGS.exec(this.chunk.slice(index))[0]; + [flags] = REGEX_FLAGS.exec(this.chunk.slice(index)); end = index + flags.length; origin = this.makeToken('REGEX', null, 0, end); switch (false) { @@ -543,7 +543,7 @@ literalToken() { var match, message, origin, prev, ref2, ref3, ref4, ref5, ref6, skipToken, tag, token, value; if (match = OPERATOR.exec(this.chunk)) { - value = match[0]; + [value] = match; if (CODE.test(value)) { this.tagParameters(); } @@ -662,7 +662,7 @@ } matchWithInterpolations(regex, delimiter) { - var close, column, firstToken, index, lastToken, line, nested, offsetInChunk, open, ref2, ref3, ref4, str, strPart, tokens; + var close, column, firstToken, index, lastToken, line, nested, offsetInChunk, open, ref2, ref3, str, strPart, tokens; tokens = []; offsetInChunk = delimiter.length; if (this.chunk.slice(0, offsetInChunk) !== delimiter) { @@ -670,7 +670,7 @@ } str = this.chunk.slice(offsetInChunk); while (true) { - strPart = regex.exec(str)[0]; + [strPart] = regex.exec(str); this.validateEscapes(strPart, { isRegex: delimiter.charAt(0) === '/', offsetInChunk: offsetInChunk @@ -681,18 +681,18 @@ if (str.slice(0, 2) !== '#{') { break; } - ref2 = this.getLineAndColumnFromChunk(offsetInChunk + 1), line = ref2[0], column = ref2[1]; - ref3 = new Lexer().tokenize(str.slice(1), { + [line, column] = this.getLineAndColumnFromChunk(offsetInChunk + 1); + ref2 = new Lexer().tokenize(str.slice(1), { line: line, column: column, untilBalanced: true - }), nested = ref3.tokens, index = ref3.index; + }), nested = ref2.tokens, index = ref2.index; index += 1; open = nested[0], close = nested[nested.length - 1]; open[0] = open[1] = '('; close[0] = close[1] = ')'; close.origin = ['', 'end of interpolation', close[2]]; - if (((ref4 = nested[1]) != null ? ref4[0] : void 0) === 'TERMINATOR') { + if (((ref3 = nested[1]) != null ? ref3[0] : void 0) === 'TERMINATOR') { nested.splice(1, 1); } tokens.push(['TOKENS', nested]); @@ -729,7 +729,7 @@ firstIndex = this.tokens.length; for (i = j = 0, len = tokens.length; j < len; i = ++j) { token = tokens[i]; - tag = token[0], value = token[1]; + [tag, value] = token; switch (tag) { case 'TOKENS': if (value.length === 2) { @@ -822,11 +822,11 @@ } makeToken(tag, value, offsetInChunk = 0, length = value.length) { - var lastCharacter, locationData, ref2, ref3, token; + var lastCharacter, locationData, token; locationData = {}; - ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = ref2[0], locationData.first_column = ref2[1]; + [locationData.first_line, locationData.first_column] = this.getLineAndColumnFromChunk(offsetInChunk); lastCharacter = length > 0 ? length - 1 : 0; - ref3 = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter), locationData.last_line = ref3[0], locationData.last_column = ref3[1]; + [locationData.last_line, locationData.last_column] = this.getLineAndColumnFromChunk(offsetInChunk + lastCharacter); token = [tag, value, locationData]; return token; } @@ -922,11 +922,11 @@ } error(message, options = {}) { - var first_column, first_line, location, ref2, ref3, ref4; - location = 'first_line' in options ? options : ((ref3 = this.getLineAndColumnFromChunk((ref2 = options.offset) != null ? ref2 : 0), first_line = ref3[0], first_column = ref3[1], ref3), { + var first_column, first_line, location, ref2, ref3; + location = 'first_line' in options ? options : ([first_line, first_column] = this.getLineAndColumnFromChunk((ref2 = options.offset) != null ? ref2 : 0), { first_line: first_line, first_column: first_column, - last_column: first_column + ((ref4 = options.length) != null ? ref4 : 1) - 1 + last_column: first_column + ((ref3 = options.length) != null ? ref3 : 1) - 1 }); return throwSyntaxError(message, location); } diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 9162cb7958..8fddf304f3 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -550,7 +550,7 @@ } compileWithDeclarations(o) { - var assigns, declars, exp, fragments, i, j, len1, post, ref3, ref4, ref5, rest, scope, spaced; + var assigns, declars, exp, fragments, i, j, len1, post, ref3, rest, scope, spaced; fragments = []; post = []; ref3 = this.expressions; @@ -566,8 +566,8 @@ }); 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]; + [spaced, this.spaced] = [this.spaced, false]; + [fragments, this.spaced] = [this.compileNode(o), spaced]; this.expressions = rest; } post = this.compileNode(o); @@ -672,7 +672,12 @@ exports.PassthroughLiteral = PassthroughLiteral = class PassthroughLiteral extends Literal {}; exports.IdentifierLiteral = IdentifierLiteral = (function() { - class IdentifierLiteral extends Literal {}; + class IdentifierLiteral extends Literal { + eachName(iterator) { + return iterator(this); + } + + }; IdentifierLiteral.prototype.isAssignable = YES; @@ -997,6 +1002,16 @@ })(); } + eachName(iterator) { + if (this.hasProperties()) { + return iterator(this); + } else if (this.base.isAssignable()) { + return this.base.eachName(iterator); + } else { + return this.error('tried to assign to unassignable value'); + } + } + }; Value.prototype.children = ['base', 'properties']; @@ -1074,7 +1089,7 @@ } unfoldSoak(o) { - var call, ifn, j, left, len1, list, ref3, ref4, rite; + var call, ifn, j, left, len1, list, ref3, rite; if (this.soak) { if (this.variable instanceof Super) { left = new Literal(this.variable.compile(o)); @@ -1086,7 +1101,7 @@ if (ifn = unfoldSoak(o, this, 'variable')) { return ifn; } - ref3 = new Value(this.variable).cacheReference(o), left = ref3[0], rite = ref3[1]; + [left, rite] = new Value(this.variable).cacheReference(o); } rite = new Call(rite, this.args); rite.isNew = this.isNew; @@ -1111,9 +1126,9 @@ break; } } - ref4 = list.reverse(); - for (j = 0, len1 = ref4.length; j < len1; j++) { - call = ref4[j]; + ref3 = list.reverse(); + for (j = 0, len1 = ref3.length; j < len1; j++) { + call = ref3[j]; if (ifn) { if (call.variable instanceof Call) { call.variable = ifn; @@ -1168,14 +1183,14 @@ } compileNode(o) { - var ref, ref3, ref4, replacement, superCall; + var ref, ref3, 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]; + [superCall, ref] = superCall.cache(o, null, YES); replacement.push(ref); } replacement.unshift(superCall); @@ -1331,15 +1346,15 @@ } compileVariables(o) { - var ref3, ref4, ref5, shouldCache, step; + var 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]; + [this.fromC, this.fromVar] = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST, shouldCache)); + [this.toC, this.toVar] = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST, shouldCache)); if (step = del(o, 'step')) { - ref5 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST, shouldCache)), this.step = ref5[0], this.stepVar = ref5[1]; + [this.step, this.stepVar] = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST, shouldCache)); } this.fromNum = this.from.isNumber() ? Number(this.fromVar) : null; this.toNum = this.to.isNumber() ? Number(this.toVar) : null; @@ -1347,7 +1362,7 @@ } compileNode(o) { - var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, ref3, ref4, stepPart, to, varPart; + var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart; if (!this.fromVar) { this.compileVariables(o); } @@ -1365,8 +1380,8 @@ 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}`); + [lt, gt] = [`${idx} <${this.equals}`, `${idx} >${this.equals}`]; + condPart = this.stepNum != null ? this.stepNum > 0 ? `${lt} ${this.toVar}` : `${gt} ${this.toVar}` : known ? ([from, to] = [this.fromNum, this.toNum], 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}`; @@ -1461,7 +1476,7 @@ } compileNode(o) { - var answer, i, idt, indent, j, join, k, key, lastNoncom, len1, len2, node, prop, props, ref3, value; + var answer, i, idt, indent, j, join, k, key, lastNoncom, len1, len2, node, prop, props, value; props = this.properties; if (this.generated) { for (j = 0, len1 = props.length; j < len1; j++) { @@ -1492,7 +1507,7 @@ } if (!(prop instanceof Comment) && !(prop instanceof Assign)) { if (prop.shouldCache()) { - ref3 = prop.base.cache(o), key = ref3[0], value = ref3[1]; + [key, value] = prop.base.cache(o); if (key instanceof IdentifierLiteral) { key = new PropertyName(key.value); } @@ -1546,6 +1561,24 @@ this.objects = objs || []; } + isAssignable() { + var i, j, len1, obj, ref3; + if (!this.objects.length) { + return false; + } + ref3 = this.objects; + for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { + obj = ref3[i]; + if (obj instanceof Splat && i + 1 !== this.objects.length) { + return false; + } + if (!(obj.isAssignable() && (!obj.isAtomic || obj.isAtomic()))) { + return false; + } + } + return true; + } + compileNode(o) { var answer, compiledObjs, fragments, index, j, len1, obj; if (!this.objects.length) { @@ -1592,6 +1625,18 @@ return false; } + eachName(iterator) { + var j, len1, obj, ref3, results; + ref3 = this.objects; + results = []; + for (j = 0, len1 = ref3.length; j < len1; j++) { + obj = ref3[j]; + obj = obj.unwrapAll(); + results.push(obj.eachName(iterator)); + } + return results; + } + }; Arr.prototype.children = ['objects']; @@ -2255,7 +2300,9 @@ 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.isAssignable()) { + return this.compilePatternMatch(o); + } } if (this.variable.isSplice()) { return this.compileSplice(o); @@ -2267,30 +2314,37 @@ 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)) { + varBase.eachName((name) => { + var message; + if (typeof name.hasProperties === "function" ? name.hasProperties() : void 0) { + return; + } + if (message = isUnassignable(name.value)) { + name.error(message); + } if (this.moduleDeclaration) { - this.checkAssignability(o, varBase); - o.scope.add(varBase.value, this.moduleDeclaration); + this.checkAssignability(o, name); + return o.scope.add(name.value, this.moduleDeclaration); } else if (this.param) { - o.scope.add(varBase.value, 'var'); + return o.scope.add(name.value, 'var'); } else { - this.checkAssignability(o, varBase); - o.scope.find(varBase.value); + this.checkAssignability(o, name); + return o.scope.find(name.value); + } + }); + } + 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; } } } @@ -2330,7 +2384,7 @@ return code; } } - obj = objects[0]; + [obj] = objects; if (olen === 1 && obj instanceof Expansion) { obj.error('Destructuring assignment has no target'); } @@ -2452,8 +2506,8 @@ } compileConditional(o) { - var fragments, left, ref3, right; - ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1]; + var fragments, left, right; + [left, right] = this.variable.cacheReference(o); 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`); } @@ -2473,17 +2527,17 @@ } compileSpecialMath(o) { - var left, ref3, right; - ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1]; + var left, right; + [left, right] = this.variable.cacheReference(o); 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; + var answer, exclusive, from, fromDecl, fromRef, name, ref3, 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]; + [fromDecl, fromRef] = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)); } else { fromDecl = fromRef = '0'; } @@ -2502,7 +2556,7 @@ } else { to = "9e9"; } - ref5 = this.value.cache(o, LEVEL_LIST), valDef = ref5[0], valRef = ref5[1]; + [valDef, valRef] = this.value.cache(o, LEVEL_LIST); answer = [].concat(this.makeCode(`[].splice.apply(${name}, [${fromDecl}, ${to}].concat(`), valDef, this.makeCode(")), "), valRef); if (o.level > LEVEL_TOP) { return this.wrapInBraces(answer); @@ -2551,7 +2605,7 @@ } 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; + 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, signature, splatParamName, thisAssignments, wasEmpty; if (this.ctor) { if (this.isAsync) { this.name.error('Class constructor may not be async'); @@ -2610,7 +2664,7 @@ params.push(ref = param.asReference(o)); splatParamName = fragmentsToText(ref.compileNode(o)); if (param.shouldCache()) { - exprs.push(new Assign(new Value(param.name), ref, '=', { + exprs.push(new Assign(new Value(param.name), ref, null, { param: true })); } @@ -2625,12 +2679,12 @@ haveBodyParam = true; if (param.value != null) { condition = new Op('==', param, new UndefinedLiteral); - ifTrue = new Assign(new Value(param.name), param.value, '=', { + ifTrue = new Assign(new Value(param.name), param.value, null, { param: true }); exprs.push(new If(condition, ifTrue)); } else { - exprs.push(new Assign(new Value(param.name), param.asReference(o), '=', { + exprs.push(new Assign(new Value(param.name), param.asReference(o), null, { param: true })); } @@ -2640,7 +2694,7 @@ ref = param.asReference(o); } else { if ((param.value != null) && !param.assignedInBody) { - ref = new Assign(new Value(param.name), param.value, '='); + ref = new Assign(new Value(param.name), param.value); } else { ref = param; } @@ -2651,7 +2705,7 @@ paramsAfterSplat.push(param); if ((param.value != null) && !param.shouldCache()) { condition = new Op('==', param, new UndefinedLiteral); - ifTrue = new Assign(new Value(param.name), param.value, '='); + 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) { @@ -2709,7 +2763,7 @@ body = this.body.compileWithDeclarations(o); } if (this.isMethod) { - ref8 = [o.scope, o.scope.parent], methodScope = ref8[0], o.scope = ref8[1]; + [methodScope, o.scope] = [o.scope, o.scope.parent]; name = this.name.compileToFragments(o); if (name[0].code === '.') { name.shift(); @@ -2937,6 +2991,10 @@ exports.Splat = Splat = (function() { class Splat extends Base { + isAssignable() { + return this.name.isAssignable() && (!this.name.isAtomic || this.name.isAtomic()); + } + constructor(name) { super(); this.name = name.compile ? name : new Literal(name); @@ -2958,8 +3016,6 @@ Splat.prototype.children = ['name']; - Splat.prototype.isAssignable = YES; - return Splat; })(); @@ -3223,8 +3279,8 @@ } compileChain(o) { - var fragments, fst, ref3, shared; - ref3 = this.first.second.cache(o), this.first.second = ref3[0], shared = ref3[1]; + var fragments, fst, shared; + [this.first.second, shared] = this.first.second.cache(o); 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); @@ -3372,13 +3428,13 @@ } 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]; + var cmp, cnj, i, item, j, len1, ref, ref3, sub, tests; + [sub, ref] = this.object.cache(o, LEVEL_OP); + [cmp, cnj] = this.negated ? [' !== ', ' && '] : [' === ', ' || ']; tests = []; - ref5 = this.array.base.objects; - for (i = j = 0, len1 = ref5.length; j < len1; i = ++j) { - item = ref5[i]; + ref3 = this.array.base.objects; + for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { + item = ref3[i]; if (i) { tests.push(this.makeCode(cnj)); } @@ -3392,8 +3448,8 @@ } compileLoopTest(o) { - var fragments, ref, ref3, sub; - ref3 = this.object.cache(o, LEVEL_LIST), sub = ref3[0], ref = ref3[1]; + var fragments, ref, sub; + [sub, ref] = this.object.cache(o, LEVEL_LIST); 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; @@ -3501,11 +3557,11 @@ } compileNode(o) { - var cmp, cnj, code, ref3; + var cmp, cnj, code; 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]; + [cmp, cnj] = this.negated ? ['===', '||'] : ['!==', '&&']; code = `typeof ${code} ${cmp} \"undefined\" ${cnj} ${code} ${cmp} null`; } else { code = `${code} ${(this.negated ? '==' : '!=')} null`; @@ -3626,7 +3682,6 @@ 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]); @@ -3640,7 +3695,7 @@ 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]; + [this.name, this.index] = [this.index, this.name]; } if (this.index instanceof Value && !this.index.isAssignable()) { this.index.error('index cannot be a pattern matching expression'); @@ -3657,7 +3712,7 @@ } 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; + var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, last, lvar, name, namePart, ref, ref3, 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) { @@ -3692,7 +3747,7 @@ 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]; + [step, stepVar] = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST, shouldCacheOrIsAssignable)); if (this.step.isNumber()) { stepNum = Number(stepVar); } @@ -3788,7 +3843,7 @@ } pluckDirectCall(o, body) { - var base, defs, expr, fn, idx, j, len1, ref, ref3, ref4, ref5, ref6, ref7, ref8, ref9, val; + var base, defs, expr, fn, idx, j, len1, ref, ref3, ref4, ref5, ref6, ref7, ref8, val; defs = []; ref3 = body.expressions; for (idx = j = 0, len1 = ref3.length; j < len1; idx = ++j) { @@ -3805,7 +3860,7 @@ ref = new IdentifierLiteral(o.scope.freeVariable('fn')); base = new Value(ref); if (val.base) { - ref9 = [base, val], val.base = ref9[0], base = ref9[1]; + [val.base, base] = [base, val]; } 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')); @@ -3833,15 +3888,15 @@ jumps(o = { block: true }) { - var block, conds, j, jumpNode, len1, ref3, ref4, ref5; + var block, conds, j, jumpNode, len1, ref3, ref4; ref3 = this.cases; for (j = 0, len1 = ref3.length; j < len1; j++) { - ref4 = ref3[j], conds = ref4[0], block = ref4[1]; + [conds, block] = ref3[j]; if (jumpNode = block.jumps(o)) { return jumpNode; } } - return (ref5 = this.otherwise) != null ? ref5.jumps(o) : void 0; + return (ref4 = this.otherwise) != null ? ref4.jumps(o) : void 0; } makeReturn(res) { @@ -3861,16 +3916,16 @@ } compileNode(o) { - var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref3, ref4, ref5; + var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref3, ref4; 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]; + [conditions, block] = ref3[i]; + ref4 = flatten([conditions]); + for (k = 0, len2 = ref4.length; k < len2; k++) { + cond = ref4[k]; if (!this.subject) { cond = cond.invert(); } diff --git a/lib/coffeescript/repl.js b/lib/coffeescript/repl.js index a277a44101..84c47c7c9c 100644 --- a/lib/coffeescript/repl.js +++ b/lib/coffeescript/repl.js @@ -168,10 +168,10 @@ module.exports = { start: function(opts = {}) { - var build, major, minor, ref1, repl; - ref1 = process.versions.node.split('.').map(function(n) { + var build, major, minor, repl; + [major, minor, build] = process.versions.node.split('.').map(function(n) { return parseInt(n); - }), major = ref1[0], minor = ref1[1], build = ref1[2]; + }); if (major < 6) { console.warn("Node 6+ required for CoffeeScript REPL"); process.exit(1); diff --git a/lib/coffeescript/rewriter.js b/lib/coffeescript/rewriter.js index c3d7384d41..c8ef515ec4 100644 --- a/lib/coffeescript/rewriter.js +++ b/lib/coffeescript/rewriter.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 2.0.0-alpha1 (function() { - var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, k, left, len, ref, rite, + var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, k, left, len, rite, 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; }; generate = function(tag, value, origin) { @@ -63,7 +63,7 @@ var i, k, len, ref, tag; ref = this.tokens; for (i = k = 0, len = ref.length; k < len; i = ++k) { - tag = ref[i][0]; + [tag] = ref[i]; if (tag !== 'TERMINATOR') { break; } @@ -168,10 +168,10 @@ stack = []; start = null; return this.scanTokens(function(token, i, tokens) { - var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, ref, ref1, ref2, ref3, ref4, ref5, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag; - tag = token[0]; - prevTag = (prevToken = i > 0 ? tokens[i - 1] : [])[0]; - nextTag = (i < tokens.length - 1 ? tokens[i + 1] : [])[0]; + var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, ref, ref1, ref2, ref3, ref4, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag; + [tag] = token; + [prevTag] = prevToken = i > 0 ? tokens[i - 1] : []; + [nextTag] = i < tokens.length - 1 ? tokens[i + 1] : []; stackTop = function() { return stack[stack.length - 1]; }; @@ -302,7 +302,7 @@ this.insideForDeclaration = nextTag === 'FOR'; startsLine = s === 0 || (ref2 = this.tag(s - 1), indexOf.call(LINEBREAKS, ref2) >= 0) || tokens[s - 1].newLine; if (stackTop()) { - ref3 = stackTop(), stackTag = ref3[0], stackIdx = ref3[1]; + [stackTag, stackIdx] = stackTop(); if ((stackTag === '{' || stackTag === 'INDENT' && this.tag(stackIdx - 1) === '{') && (startsLine || this.tag(s - 1) === ',' || this.tag(s - 1) === '{')) { return forward(1); } @@ -316,7 +316,7 @@ newLine = prevTag === 'OUTDENT' || prevToken.newLine; if (indexOf.call(IMPLICIT_END, tag) >= 0 || indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) { while (inImplicit()) { - ref4 = stackTop(), stackTag = ref4[0], stackIdx = ref4[1], (ref5 = ref4[2], sameLine = ref5.sameLine, startsLine = ref5.startsLine); + ref3 = stackTop(), stackTag = ref3[0], stackIdx = ref3[1], (ref4 = ref3[2], sameLine = ref4.sameLine, startsLine = ref4.startsLine); if (inImplicitCall() && prevTag !== ',') { endImplicitCall(); } else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':') { @@ -395,8 +395,8 @@ return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent); }; return this.scanTokens(function(token, i, tokens) { - var j, k, ref, ref1, ref2, tag; - tag = token[0]; + var j, k, ref, ref1, tag; + [tag] = token; if (tag === 'TERMINATOR') { if (this.tag(i + 1) === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { tokens.splice(i, 1, ...this.indentation()); @@ -418,7 +418,7 @@ } if (indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) { starter = tag; - ref2 = this.indentation(tokens[i]), indent = ref2[0], outdent = ref2[1]; + [indent, outdent] = this.indentation(tokens[i]); if (starter === 'THEN') { indent.fromThen = true; } @@ -438,8 +438,8 @@ original = null; condition = function(token, i) { var prevTag, tag; - tag = token[0]; - prevTag = this.tokens[i - 1][0]; + [tag] = token; + [prevTag] = this.tokens[i - 1]; return tag === 'TERMINATOR' || (tag === 'INDENT' && indexOf.call(SINGLE_LINERS, prevTag) < 0); }; action = function(token, i) { @@ -492,7 +492,7 @@ EXPRESSION_END = []; for (k = 0, len = BALANCED_PAIRS.length; k < len; k++) { - ref = BALANCED_PAIRS[k], left = ref[0], rite = ref[1]; + [left, rite] = BALANCED_PAIRS[k]; EXPRESSION_START.push(INVERSES[rite] = left); EXPRESSION_END.push(INVERSES[left] = rite); } diff --git a/lib/coffeescript/sourcemap.js b/lib/coffeescript/sourcemap.js index 60d5fe2c68..98c898d56f 100644 --- a/lib/coffeescript/sourcemap.js +++ b/lib/coffeescript/sourcemap.js @@ -9,8 +9,8 @@ } add(column, arg, options) { - var sourceColumn, sourceLine; - sourceLine = arg[0], sourceColumn = arg[1]; + var options, sourceColumn, sourceLine; + [sourceLine, sourceColumn] = arg; if (options === void 0) { options = {}; } @@ -45,14 +45,14 @@ add(sourceLocation, generatedLocation, options = {}) { var base, column, line, lineMap; - line = generatedLocation[0], column = generatedLocation[1]; + [line, column] = generatedLocation; lineMap = ((base = this.lines)[line] || (base[line] = new LineMap(line))); return lineMap.add(column, sourceLocation, options); } sourceLocation(arg) { var column, line, lineMap; - line = arg[0], column = arg[1]; + [line, column] = arg; while (!((lineMap = this.lines[line]) || (line <= 0))) { line--; } diff --git a/src/nodes.coffee b/src/nodes.coffee index cc2a6dabc7..bec76f24d6 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -543,6 +543,9 @@ exports.PassthroughLiteral = class PassthroughLiteral extends Literal exports.IdentifierLiteral = class IdentifierLiteral extends Literal isAssignable: YES + eachName: (iterator) -> + iterator @ + exports.PropertyName = class PropertyName extends Literal isAssignable: YES @@ -740,6 +743,14 @@ exports.Value = class Value extends Base return new If new Existence(fst), snd, soak: on no + eachName: (iterator) -> + if @hasProperties() + iterator @ + else if @base.isAssignable() + @base.eachName iterator + else + @error 'tried to assign to unassignable value' + #### Comment # CoffeeScript passes through block comments as JavaScript block comments @@ -1156,6 +1167,14 @@ exports.Arr = class Arr extends Base children: ['objects'] + isAssignable: -> + return false unless @objects.length + + for obj, i in @objects + return false if obj instanceof Splat and i + 1 != @objects.length + return false unless obj.isAssignable() and (not obj.isAtomic or obj.isAtomic()) + true + compileNode: (o) -> return [@makeCode '[]'] unless @objects.length o.indent += TAB @@ -1178,6 +1197,11 @@ exports.Arr = class Arr extends Base for obj in @objects when obj.assigns name then return yes no + eachName: (iterator) -> + for obj in @objects + obj = obj.unwrapAll() + obj.eachName iterator + #### Class # The CoffeeScript class definition. @@ -1660,30 +1684,39 @@ exports.Assign = class Assign extends Base # has not been seen yet within the current scope, declare it. compileNode: (o) -> if isValue = @variable instanceof Value - return @compilePatternMatch o if @variable.isArray() or @variable.isObject() + if @variable.isArray() or @variable.isObject() + return @compilePatternMatch o unless @variable.isAssignable() + return @compileSplice o if @variable.isSplice() return @compileConditional o if @context in ['||=', '&&=', '?='] return @compileSpecialMath o if @context in ['**=', '//=', '%%='] - if @value instanceof Code - if @value.isStatic - @value.name = @variable.properties[0] - else if @variable.properties?.length >= 2 - [properties..., prototype, name] = @variable.properties - @value.name = name if prototype.name?.value is 'prototype' + unless @context varBase = @variable.unwrapAll() unless varBase.isAssignable() @variable.error "'#{@variable.compile o}' can't be assigned" - unless varBase.hasProperties?() + + varBase.eachName (name) => + return if name.hasProperties?() + + name.error message if message = isUnassignable name.value + # `moduleDeclaration` can be `'import'` or `'export'` if @moduleDeclaration - @checkAssignability o, varBase - o.scope.add varBase.value, @moduleDeclaration + @checkAssignability o, name + o.scope.add name.value, @moduleDeclaration else if @param - o.scope.add varBase.value, 'var' + o.scope.add name.value, 'var' else - @checkAssignability o, varBase - o.scope.find varBase.value + @checkAssignability o, name + o.scope.find name.value + + if @value instanceof Code + if @value.isStatic + @value.name = @variable.properties[0] + else if @variable.properties?.length >= 2 + [properties..., prototype, name] = @variable.properties + @value.name = name if prototype.name?.value is 'prototype' val = @value.compileToFragments o, LEVEL_LIST @variable.front = true if isValue and @variable.base instanceof Obj @@ -1950,7 +1983,7 @@ exports.Code = class Code extends Base params.push ref = param.asReference o splatParamName = fragmentsToText ref.compileNode o if param.shouldCache() - exprs.push new Assign new Value(param.name), ref, '=', param: yes + exprs.push new Assign new Value(param.name), ref, null, param: yes # TODO: output destructured parameters as is, and fix destructuring # of objects with default values to work in this context (see # Obj.compileNode `if prop.context isnt 'object'`). @@ -1973,10 +2006,10 @@ exports.Code = class Code extends Base # `(arg) => { var a = arg.a; }`, with a default value if it has one. if param.value? condition = new Op '==', param, new UndefinedLiteral - ifTrue = new Assign new Value(param.name), param.value, '=', param: yes + ifTrue = new Assign new Value(param.name), param.value, null, param: yes exprs.push new If condition, ifTrue else - exprs.push new Assign new Value(param.name), param.asReference(o), '=', param: yes + exprs.push new Assign new Value(param.name), param.asReference(o), null, param: yes # If this parameter comes before the splat or expansion, it will go # in the function definition parameter list. @@ -1989,7 +2022,7 @@ exports.Code = class Code extends Base ref = param.asReference o else if param.value? and not param.assignedInBody - ref = new Assign new Value(param.name), param.value, '=' + ref = new Assign new Value(param.name), param.value else ref = param # Add this parameter’s reference to the function scope @@ -2002,7 +2035,7 @@ exports.Code = class Code extends Base # (if necessary) as an expression in the body. if param.value? and not param.shouldCache() condition = new Op '==', param, new UndefinedLiteral - ifTrue = new Assign new Value(param.name), param.value, '=' + ifTrue = new Assign new Value(param.name), param.value exprs.push new If condition, ifTrue # Add this parameter to the scope, since it wouldn’t have been added yet since it was skipped earlier. o.scope.add param.name.value, 'var', yes if param.name?.value? @@ -2205,7 +2238,8 @@ exports.Splat = class Splat extends Base children: ['name'] - isAssignable: YES + isAssignable: -> + @name.isAssignable() and (not @name.isAtomic or @name.isAtomic()) constructor: (name) -> super() From b9f8f5d88aa00530253bf1244a10cae7e3bcaa08 Mon Sep 17 00:00:00 2001 From: Chris Connelly Date: Thu, 30 Mar 2017 21:52:01 +0100 Subject: [PATCH 2/3] Output simple object destructured assignments to ES2015 --- lib/coffeescript/coffeescript.js | 22 +- lib/coffeescript/command.js | 31 +- lib/coffeescript/grammar.js | 4 +- lib/coffeescript/helpers.js | 13 +- lib/coffeescript/lexer.js | 124 ++++--- lib/coffeescript/nodes.js | 607 ++++++++++++++++++------------- lib/coffeescript/optparse.js | 4 +- lib/coffeescript/register.js | 4 +- lib/coffeescript/repl.js | 26 +- lib/coffeescript/rewriter.js | 27 +- src/nodes.coffee | 17 +- test/assignment.coffee | 3 - 12 files changed, 533 insertions(+), 349 deletions(-) diff --git a/lib/coffeescript/coffeescript.js b/lib/coffeescript/coffeescript.js index 767efd35e9..9d5be3fcc8 100644 --- a/lib/coffeescript/coffeescript.js +++ b/lib/coffeescript/coffeescript.js @@ -9,9 +9,13 @@ path = require('path'); - Lexer = require('./lexer').Lexer; + ({ + Lexer: Lexer + } = require('./lexer')); - parser = require('./parser').parser; + ({ + parser: parser + } = require('./parser')); helpers = require('./helpers'); @@ -59,7 +63,10 @@ exports.compile = compile = withPrettyErrors(function(code, options) { var currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, v3SourceMap; - merge = helpers.merge, extend = helpers.extend; + ({ + merge: merge, + extend: extend + } = helpers); options = extend({}, options); generateSourceMap = options.sourceMap || options.inlineMap || (options.filename == null); filename = options.filename || ''; @@ -295,8 +302,13 @@ parser.yy.parseError = function(message, arg) { var errorLoc, errorTag, errorText, errorToken, token, tokens; - token = arg.token; - errorToken = parser.errorToken, tokens = parser.tokens; + ({ + token: token + } = arg); + ({ + errorToken: errorToken, + tokens: tokens + } = parser); [errorTag, errorText, errorLoc] = errorToken; errorText = (function() { switch (false) { diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 314197f59e..95558397dc 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 2.0.0-alpha1 (function() { - var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, makePrelude, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, ref, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs, + var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, makePrelude, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs, 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; }; fs = require('fs'); @@ -13,9 +13,14 @@ CoffeeScript = require('./coffeescript'); - ref = require('child_process'), spawn = ref.spawn, exec = ref.exec; + ({ + spawn: spawn, + exec: exec + } = require('child_process')); - EventEmitter = require('events').EventEmitter; + ({ + EventEmitter: EventEmitter + } = require('events')); useWinPathSep = path.sep === '\\'; @@ -50,7 +55,7 @@ optionParser = null; exports.run = function() { - var i, len, literals, ref1, replCliOpts, results, source; + var i, len, literals, ref, replCliOpts, results, source; parseOptions(); replCliOpts = { useGlobal: true @@ -90,10 +95,10 @@ opts.join = path.resolve(opts.join); console.error('\nThe --join option is deprecated and will be removed in a future version.\n\nIf for some reason it\'s necessary to share local variables between files,\nreplace...\n\n $ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee\n\nwith...\n\n $ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js\n'); } - ref1 = opts["arguments"]; + ref = opts["arguments"]; results = []; - for (i = 0, len = ref1.length; i < len; i++) { - source = ref1[i]; + for (i = 0, len = ref.length; i < len; i++) { + source = ref[i]; source = path.resolve(source); results.push(compilePath(source, true, source)); } @@ -178,10 +183,10 @@ }; findDirectoryIndex = function(source) { - var err, ext, i, index, len, ref1; - ref1 = CoffeeScript.FILE_EXTENSIONS; - for (i = 0, len = ref1.length; i < len; i++) { - ext = ref1[i]; + var err, ext, i, index, len, ref; + ref = CoffeeScript.FILE_EXTENSIONS; + for (i = 0, len = ref.length; i < len; i++) { + ext = ref[i]; index = path.join(source, `index${ext}`); try { if ((fs.statSync(index)).isFile()) { @@ -425,12 +430,12 @@ }; silentUnlink = function(path) { - var err, ref1; + var err, ref; try { return fs.unlinkSync(path); } catch (error) { err = error; - if ((ref1 = err.code) !== 'ENOENT' && ref1 !== 'EPERM') { + if ((ref = err.code) !== 'ENOENT' && ref !== 'EPERM') { throw err; } } diff --git a/lib/coffeescript/grammar.js b/lib/coffeescript/grammar.js index c47943faac..8e7eee0d8e 100644 --- a/lib/coffeescript/grammar.js +++ b/lib/coffeescript/grammar.js @@ -2,7 +2,9 @@ (function() { var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; - Parser = require('jison').Parser; + ({ + Parser: Parser + } = require('jison')); unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/; diff --git a/lib/coffeescript/helpers.js b/lib/coffeescript/helpers.js index 7027a43f99..39c2da690e 100644 --- a/lib/coffeescript/helpers.js +++ b/lib/coffeescript/helpers.js @@ -197,11 +197,16 @@ }; syntaxErrorToString = function() { - var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, ref1, ref2, ref3, ref4, start; + var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, ref1, ref2, ref3, start; if (!(this.code && this.location)) { return Error.prototype.toString.call(this); } - ref1 = this.location, first_line = ref1.first_line, first_column = ref1.first_column, last_line = ref1.last_line, last_column = ref1.last_column; + ({ + first_line: first_line, + first_column: first_column, + last_line: last_line, + last_column: last_column + } = this.location); if (last_line == null) { last_line = first_line; } @@ -214,9 +219,9 @@ end = first_line === last_line ? last_column + 1 : codeLine.length; marker = codeLine.slice(0, start).replace(/[^\s]/g, ' ') + repeat('^', end - start); if (typeof process !== "undefined" && process !== null) { - colorsEnabled = ((ref2 = process.stdout) != null ? ref2.isTTY : void 0) && !((ref3 = process.env) != null ? ref3.NODE_DISABLE_COLORS : void 0); + colorsEnabled = ((ref1 = process.stdout) != null ? ref1.isTTY : void 0) && !((ref2 = process.env) != null ? ref2.NODE_DISABLE_COLORS : void 0); } - if ((ref4 = this.colorful) != null ? ref4 : colorsEnabled) { + if ((ref3 = this.colorful) != null ? ref3 : colorsEnabled) { colorize = function(str) { return `\x1B[1;31m${str}\x1B[0m`; }; diff --git a/lib/coffeescript/lexer.js b/lib/coffeescript/lexer.js index bfb64a0792..99f2d2a696 100644 --- a/lib/coffeescript/lexer.js +++ b/lib/coffeescript/lexer.js @@ -1,11 +1,22 @@ // Generated by CoffeeScript 2.0.0-alpha1 (function() { - var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVALID_ESCAPE, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, ref, ref1, repeat, starts, throwSyntaxError, + var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVALID_ESCAPE, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, repeat, starts, throwSyntaxError, 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; }; - ref = require('./rewriter'), Rewriter = ref.Rewriter, INVERSES = ref.INVERSES; - - ref1 = require('./helpers'), count = ref1.count, starts = ref1.starts, compact = ref1.compact, repeat = ref1.repeat, invertLiterate = ref1.invertLiterate, locationDataToString = ref1.locationDataToString, throwSyntaxError = ref1.throwSyntaxError; + ({ + Rewriter: Rewriter, + INVERSES: INVERSES + } = require('./rewriter')); + + ({ + count: count, + starts: starts, + compact: compact, + repeat: repeat, + invertLiterate: invertLiterate, + locationDataToString: locationDataToString, + throwSyntaxError: throwSyntaxError + } = require('./helpers')); exports.Lexer = Lexer = class Lexer { tokenize(code, opts = {}) { @@ -64,7 +75,7 @@ } identifierToken() { - var alias, colon, colonOffset, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, ref6, tag, tagToken; + var alias, colon, colonOffset, id, idLength, input, match, poppedToken, prev, ref, ref1, ref2, ref3, ref4, tag, tagToken; if (!(match = IDENTIFIER.exec(this.chunk))) { return 0; } @@ -82,10 +93,10 @@ if (id === 'as' && this.seenImport) { if (this.value() === '*') { this.tokens[this.tokens.length - 1][0] = 'IMPORT_ALL'; - } else if (ref2 = this.value(), indexOf.call(COFFEE_KEYWORDS, ref2) >= 0) { + } else if (ref = this.value(), indexOf.call(COFFEE_KEYWORDS, ref) >= 0) { this.tokens[this.tokens.length - 1][0] = 'IDENTIFIER'; } - if ((ref3 = this.tag()) === 'DEFAULT' || ref3 === 'IMPORT_ALL' || ref3 === 'IDENTIFIER') { + if ((ref1 = this.tag()) === 'DEFAULT' || ref1 === 'IMPORT_ALL' || ref1 === 'IDENTIFIER') { this.token('AS', id); return id.length; } @@ -98,11 +109,11 @@ this.token('DEFAULT', id); return id.length; } - ref4 = this.tokens, prev = ref4[ref4.length - 1]; - tag = colon || (prev != null) && (((ref5 = prev[0]) === '.' || ref5 === '?.' || ref5 === '::' || ref5 === '?::') || !prev.spaced && prev[0] === '@') ? 'PROPERTY' : 'IDENTIFIER'; + ref2 = this.tokens, prev = ref2[ref2.length - 1]; + tag = colon || (prev != null) && (((ref3 = prev[0]) === '.' || ref3 === '?.' || ref3 === '::' || ref3 === '?::') || !prev.spaced && prev[0] === '@') ? 'PROPERTY' : 'IDENTIFIER'; if (tag === 'IDENTIFIER' && (indexOf.call(JS_KEYWORDS, id) >= 0 || indexOf.call(COFFEE_KEYWORDS, id) >= 0) && !(this.exportSpecifierList && indexOf.call(COFFEE_KEYWORDS, id) >= 0)) { tag = id.toUpperCase(); - if (tag === 'WHEN' && (ref6 = this.tag(), indexOf.call(LINE_BREAK, ref6) >= 0)) { + if (tag === 'WHEN' && (ref4 = this.tag(), indexOf.call(LINE_BREAK, ref4) >= 0)) { tag = 'LEADING_WHEN'; } else if (tag === 'FOR') { this.seenFor = true; @@ -223,7 +234,7 @@ } stringToken() { - var $, attempt, delimiter, doc, end, heredoc, i, indent, indentRegex, match, quote, ref2, ref3, regex, token, tokens; + var $, attempt, delimiter, doc, end, heredoc, i, indent, indentRegex, match, quote, ref, regex, token, tokens; [quote] = STRING_START.exec(this.chunk) || []; if (!quote) { return 0; @@ -244,7 +255,10 @@ } })(); heredoc = quote.length === 3; - ref2 = this.matchWithInterpolations(regex, quote), tokens = ref2.tokens, end = ref2.index; + ({ + tokens: tokens, + index: end + } = this.matchWithInterpolations(regex, quote)); $ = tokens.length - 1; delimiter = quote.charAt(0); if (heredoc) { @@ -262,7 +276,7 @@ })()).join('#{}'); while (match = HEREDOC_INDENT.exec(doc)) { attempt = match[1]; - if (indent === null || (0 < (ref3 = attempt.length) && ref3 < indent.length)) { + if (indent === null || (0 < (ref = attempt.length) && ref < indent.length)) { indent = attempt; } } @@ -336,7 +350,7 @@ } regexToken() { - var body, closed, end, flags, index, match, origin, prev, ref2, ref3, ref4, regex, tokens; + var body, closed, end, flags, index, match, origin, prev, ref, ref1, ref2, regex, tokens; switch (false) { case !(match = REGEX_ILLEGAL.exec(this.chunk)): this.error(`regular expressions cannot begin with ${match[2]}`, { @@ -344,7 +358,10 @@ }); break; case !(match = this.matchWithInterpolations(HEREGEX, '///')): - tokens = match.tokens, index = match.index; + ({ + tokens: tokens, + index: index + } = match); break; case !(match = REGEX.exec(this.chunk)): [regex, body, closed] = match; @@ -353,13 +370,13 @@ offsetInChunk: 1 }); index = regex.length; - ref2 = this.tokens, prev = ref2[ref2.length - 1]; + ref = this.tokens, prev = ref[ref.length - 1]; if (prev) { - if (prev.spaced && (ref3 = prev[0], indexOf.call(CALLABLE, ref3) >= 0)) { + if (prev.spaced && (ref1 = prev[0], indexOf.call(CALLABLE, ref1) >= 0)) { if (!closed || POSSIBLY_DIVISION.test(regex)) { return 0; } - } else if (ref4 = prev[0], indexOf.call(NOT_REGEX, ref4) >= 0) { + } else if (ref2 = prev[0], indexOf.call(NOT_REGEX, ref2) >= 0) { return 0; } } @@ -469,7 +486,7 @@ } outdentToken(moveOut, noNewlines, outdentLength) { - var decreasedIndent, dent, lastIndent, ref2; + var decreasedIndent, dent, lastIndent, ref; decreasedIndent = this.indent - moveOut; while (moveOut > 0) { lastIndent = this.indents[this.indents.length - 1]; @@ -483,7 +500,7 @@ moveOut -= lastIndent; } else { dent = this.indents.pop() + this.outdebt; - if (outdentLength && (ref2 = this.chunk[outdentLength], indexOf.call(INDENTABLE_CLOSERS, ref2) >= 0)) { + if (outdentLength && (ref = this.chunk[outdentLength], indexOf.call(INDENTABLE_CLOSERS, ref) >= 0)) { decreasedIndent -= dent - moveOut; moveOut = dent; } @@ -508,11 +525,11 @@ } whitespaceToken() { - var match, nline, prev, ref2; + var match, nline, prev, ref; if (!((match = WHITESPACE.exec(this.chunk)) || (nline = this.chunk.charAt(0) === '\n'))) { return 0; } - ref2 = this.tokens, prev = ref2[ref2.length - 1]; + ref = this.tokens, prev = ref[ref.length - 1]; if (prev) { prev[match ? 'spaced' : 'newLine'] = true; } @@ -541,7 +558,7 @@ } literalToken() { - var match, message, origin, prev, ref2, ref3, ref4, ref5, ref6, skipToken, tag, token, value; + var match, message, origin, prev, ref, ref1, ref2, ref3, ref4, skipToken, tag, token, value; if (match = OPERATOR.exec(this.chunk)) { [value] = match; if (CODE.test(value)) { @@ -551,17 +568,17 @@ value = this.chunk.charAt(0); } tag = value; - ref2 = this.tokens, prev = ref2[ref2.length - 1]; + ref = this.tokens, prev = ref[ref.length - 1]; if (prev && indexOf.call(['=', ...COMPOUND_ASSIGN], value) >= 0) { skipToken = false; - if (value === '=' && ((ref3 = prev[1]) === '||' || ref3 === '&&') && !prev.spaced) { + if (value === '=' && ((ref1 = prev[1]) === '||' || ref1 === '&&') && !prev.spaced) { prev[0] = 'COMPOUND_ASSIGN'; prev[1] += '='; prev = this.tokens[this.tokens.length - 2]; skipToken = true; } if (prev && prev[0] !== 'PROPERTY') { - origin = (ref4 = prev.origin) != null ? ref4 : prev; + origin = (ref2 = prev.origin) != null ? ref2 : prev; message = isUnassignable(prev[1], origin[1]); if (message) { this.error(message, origin[2]); @@ -596,12 +613,12 @@ } else if (value === '?' && (prev != null ? prev.spaced : void 0)) { tag = 'BIN?'; } else if (prev && !prev.spaced) { - if (value === '(' && (ref5 = prev[0], indexOf.call(CALLABLE, ref5) >= 0)) { + if (value === '(' && (ref3 = prev[0], indexOf.call(CALLABLE, ref3) >= 0)) { if (prev[0] === '?') { prev[0] = 'FUNC_EXIST'; } tag = 'CALL_START'; - } else if (value === '[' && (ref6 = prev[0], indexOf.call(INDEXABLE, ref6) >= 0)) { + } else if (value === '[' && (ref4 = prev[0], indexOf.call(INDEXABLE, ref4) >= 0)) { tag = 'INDEX_START'; switch (prev[0]) { case '?': @@ -634,7 +651,9 @@ return this; } stack = []; - tokens = this.tokens; + ({ + tokens: tokens + } = this); i = tokens.length; tokens[--i][0] = 'PARAM_END'; while (tok = tokens[--i]) { @@ -662,7 +681,7 @@ } matchWithInterpolations(regex, delimiter) { - var close, column, firstToken, index, lastToken, line, nested, offsetInChunk, open, ref2, ref3, str, strPart, tokens; + var close, column, firstToken, index, lastToken, line, nested, offsetInChunk, open, ref, str, strPart, tokens; tokens = []; offsetInChunk = delimiter.length; if (this.chunk.slice(0, offsetInChunk) !== delimiter) { @@ -682,17 +701,20 @@ break; } [line, column] = this.getLineAndColumnFromChunk(offsetInChunk + 1); - ref2 = new Lexer().tokenize(str.slice(1), { + ({ + tokens: nested, + index: index + } = new Lexer().tokenize(str.slice(1), { line: line, column: column, untilBalanced: true - }), nested = ref2.tokens, index = ref2.index; + })); index += 1; open = nested[0], close = nested[nested.length - 1]; open[0] = open[1] = '('; close[0] = close[1] = ')'; close.origin = ['', 'end of interpolation', close[2]]; - if (((ref3 = nested[1]) != null ? ref3[0] : void 0) === 'TERMINATOR') { + if (((ref = nested[1]) != null ? ref[0] : void 0) === 'TERMINATOR') { nested.splice(1, 1); } tokens.push(['TOKENS', nested]); @@ -787,13 +809,13 @@ } pair(tag) { - var lastIndent, prev, ref2, ref3, wanted; - ref2 = this.ends, prev = ref2[ref2.length - 1]; + var lastIndent, prev, ref, ref1, wanted; + ref = this.ends, prev = ref[ref.length - 1]; if (tag !== (wanted = prev != null ? prev.tag : void 0)) { if ('OUTDENT' !== wanted) { this.error(`unmatched ${tag}`); } - ref3 = this.indents, lastIndent = ref3[ref3.length - 1]; + ref1 = this.indents, lastIndent = ref1[ref1.length - 1]; this.outdentToken(lastIndent, true); return this.pair(tag); } @@ -801,7 +823,7 @@ } getLineAndColumnFromChunk(offset) { - var column, lastLine, lineCount, ref2, string; + var column, lastLine, lineCount, ref, string; if (offset === 0) { return [this.chunkLine, this.chunkColumn]; } @@ -813,7 +835,7 @@ lineCount = count(string, '\n'); column = this.chunkColumn; if (lineCount > 0) { - ref2 = string.split('\n'), lastLine = ref2[ref2.length - 1]; + ref = string.split('\n'), lastLine = ref[ref.length - 1]; column = lastLine.length; } else { column += string.length; @@ -842,20 +864,20 @@ } tag() { - var ref2, token; - ref2 = this.tokens, token = ref2[ref2.length - 1]; + var ref, token; + ref = this.tokens, token = ref[ref.length - 1]; return token != null ? token[0] : void 0; } value() { - var ref2, token; - ref2 = this.tokens, token = ref2[ref2.length - 1]; + var ref, token; + ref = this.tokens, token = ref[ref.length - 1]; return token != null ? token[1] : void 0; } unfinished() { - var ref2; - return LINE_CONTINUER.test(this.chunk) || ((ref2 = this.tag()) === '\\' || ref2 === '.' || ref2 === '?.' || ref2 === '?::' || ref2 === 'UNARY' || ref2 === 'MATH' || ref2 === 'UNARY_MATH' || ref2 === '+' || ref2 === '-' || ref2 === '**' || ref2 === 'SHIFT' || ref2 === 'RELATION' || ref2 === 'COMPARE' || ref2 === '&' || ref2 === '^' || ref2 === '|' || ref2 === '&&' || ref2 === '||' || ref2 === 'BIN?' || ref2 === 'THROW' || ref2 === 'EXTENDS'); + var ref; + return LINE_CONTINUER.test(this.chunk) || ((ref = this.tag()) === '\\' || ref === '.' || ref === '?.' || ref === '?::' || ref === 'UNARY' || ref === 'MATH' || ref === 'UNARY_MATH' || ref === '+' || ref === '-' || ref === '**' || ref === 'SHIFT' || ref === 'RELATION' || ref === 'COMPARE' || ref === '&' || ref === '^' || ref === '|' || ref === '&&' || ref === '||' || ref === 'BIN?' || ref === 'THROW' || ref === 'EXTENDS'); } formatString(str) { @@ -867,7 +889,7 @@ } validateEscapes(str, options = {}) { - var before, hex, invalidEscape, match, message, octal, ref2, unicode; + var before, hex, invalidEscape, match, message, octal, ref, unicode; match = INVALID_ESCAPE.exec(str); if (!match) { return; @@ -879,7 +901,7 @@ message = octal ? "octal escape sequences are not allowed" : "invalid escape sequence"; invalidEscape = `\\${octal || hex || unicode}`; return this.error(`${message} ${invalidEscape}`, { - offset: ((ref2 = options.offsetInChunk) != null ? ref2 : 0) + match.index + before.length, + offset: ((ref = options.offsetInChunk) != null ? ref : 0) + match.index + before.length, length: invalidEscape.length }); } @@ -922,11 +944,11 @@ } error(message, options = {}) { - var first_column, first_line, location, ref2, ref3; - location = 'first_line' in options ? options : ([first_line, first_column] = this.getLineAndColumnFromChunk((ref2 = options.offset) != null ? ref2 : 0), { + var first_column, first_line, location, ref, ref1; + location = 'first_line' in options ? options : ([first_line, first_column] = this.getLineAndColumnFromChunk((ref = options.offset) != null ? ref : 0), { first_line: first_line, first_column: first_column, - last_column: first_column + ((ref3 = options.length) != null ? ref3 : 1) - 1 + last_column: first_column + ((ref1 = options.length) != null ? ref1 : 1) - 1 }); return throwSyntaxError(message, location); } @@ -949,7 +971,7 @@ exports.isUnassignable = isUnassignable; isForFrom = function(prev) { - var ref2; + var ref; if (prev[0] === 'IDENTIFIER') { if (prev[1] === 'from') { prev[1][0] = 'IDENTIFIER'; @@ -958,7 +980,7 @@ return true; } else if (prev[0] === 'FOR') { return false; - } else if ((ref2 = prev[1]) === '{' || ref2 === '[' || ref2 === ',' || ref2 === ':') { + } else if ((ref = prev[1]) === '{' || ref === '[' || ref === ',' || ref === ':') { return false; } else { return true; diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 8fddf304f3..05f3efc4cd 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -1,16 +1,33 @@ // 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, + 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, 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; + ({ + Scope: Scope + } = require('./scope')); + + ({ + isUnassignable: isUnassignable, + JS_FORBIDDEN: JS_FORBIDDEN + } = require('./lexer')); + + ({ + compact: compact, + flatten: flatten, + extend: extend, + merge: merge, + del: del, + starts: starts, + ends: ends, + some: some, + addLocationDataFn: addLocationDataFn, + locationDataToString: locationDataToString, + throwSyntaxError: throwSyntaxError + } = require('./helpers')); exports.extend = extend; @@ -35,10 +52,10 @@ exports.CodeFragment = CodeFragment = class CodeFragment { constructor(parent, code) { - var ref3; + var ref1; 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'; + this.type = (parent != null ? (ref1 = parent.constructor) != null ? ref1.name : void 0 : void 0) || 'unknown'; } toString() { @@ -82,7 +99,7 @@ } compileClosure(o) { - var args, argumentsNode, func, jumpNode, meth, parts, ref3, ref4; + var args, argumentsNode, func, jumpNode, meth, parts, ref1, ref2; if (jumpNode = this.jumps()) { jumpNode.error('cannot use a pure statement in an expression'); } @@ -105,11 +122,11 @@ } parts = (new Call(func, args)).compileNode(o); switch (false) { - case !(func.isGenerator || ((ref3 = func.base) != null ? ref3.isGenerator : void 0)): + case !(func.isGenerator || ((ref1 = func.base) != null ? ref1.isGenerator : void 0)): parts.unshift(this.makeCode("(yield* ")); parts.push(this.makeCode(")")); break; - case !(func.isAsync || ((ref4 = func.base) != null ? ref4.isAsync : void 0)): + case !(func.isAsync || ((ref2 = func.base) != null ? ref2.isAsync : void 0)): parts.unshift(this.makeCode("(await ")); parts.push(this.makeCode(")")); } @@ -198,17 +215,17 @@ } eachChild(func) { - var attr, child, j, k, len1, len2, ref3, ref4; + var attr, child, j, k, len1, len2, ref1, ref2; if (!this.children) { return this; } - ref3 = this.children; - for (j = 0, len1 = ref3.length; j < len1; j++) { - attr = ref3[j]; + ref1 = this.children; + for (j = 0, len1 = ref1.length; j < len1; j++) { + attr = ref1[j]; if (this[attr]) { - ref4 = flatten([this[attr]]); - for (k = 0, len2 = ref4.length; k < len2; k++) { - child = ref4[k]; + ref2 = flatten([this[attr]]); + for (k = 0, len2 = ref2.length; k < len2; k++) { + child = ref2[k]; if (func(child) === false) { return this; } @@ -229,19 +246,19 @@ } replaceInContext(match, replacement) { - var attr, child, children, i, j, k, len1, len2, ref3, ref4; + var attr, child, children, i, j, k, len1, len2, ref1, ref2; if (!this.children) { return false; } - ref3 = this.children; - for (j = 0, len1 = ref3.length; j < len1; j++) { - attr = ref3[j]; + ref1 = this.children; + for (j = 0, len1 = ref1.length; j < len1; j++) { + attr = ref1[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; + [].splice.apply(children, [i, i - i + 1].concat(ref2 = replacement(child, this))), ref2; return true; } else { if (child.replaceInContext(match, replacement)) { @@ -337,11 +354,11 @@ exports.HoistTarget = HoistTarget = class HoistTarget extends Base { static expand(fragments) { - var fragment, i, j, ref3; + var fragment, i, j, ref1; 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; + [].splice.apply(fragments, [i, i - i + 1].concat(ref1 = this.expand(fragment.fragments))), ref1; } } return fragments; @@ -414,10 +431,10 @@ } isStatement(o) { - var exp, j, len1, ref3; - ref3 = this.expressions; - for (j = 0, len1 = ref3.length; j < len1; j++) { - exp = ref3[j]; + var exp, j, len1, ref1; + ref1 = this.expressions; + for (j = 0, len1 = ref1.length; j < len1; j++) { + exp = ref1[j]; if (exp.isStatement(o)) { return true; } @@ -426,10 +443,10 @@ } jumps(o) { - var exp, j, jumpNode, len1, ref3; - ref3 = this.expressions; - for (j = 0, len1 = ref3.length; j < len1; j++) { - exp = ref3[j]; + var exp, j, jumpNode, len1, ref1; + ref1 = this.expressions; + for (j = 0, len1 = ref1.length; j < len1; j++) { + exp = ref1[j]; if (jumpNode = exp.jumps(o)) { return jumpNode; } @@ -461,13 +478,13 @@ } compileNode(o) { - var answer, compiledNodes, fragments, index, j, len1, node, ref3, top; + var answer, compiledNodes, fragments, index, j, len1, node, ref1, 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]; + ref1 = this.expressions; + for (index = j = 0, len1 = ref1.length; j < len1; index = ++j) { + node = ref1[index]; node = node.unwrapAll(); node = node.unfoldSoak(o) || node; if (node instanceof Block) { @@ -506,24 +523,24 @@ } compileRoot(o) { - var exp, fragments, i, j, len1, name, prelude, preludeExps, ref3, ref4, rest; + var exp, fragments, i, j, len1, name, prelude, preludeExps, ref1, ref2, 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 = new Scope(null, this, null, (ref1 = o.referencedVars) != null ? ref1 : []); + ref2 = o.locals || []; + for (j = 0, len1 = ref2.length; j < len1; j++) { + name = ref2[j]; o.scope.parameter(name); } prelude = []; if (!o.bare) { preludeExps = (function() { - var k, len2, ref5, results; - ref5 = this.expressions; + var k, len2, ref3, results; + ref3 = this.expressions; results = []; - for (i = k = 0, len2 = ref5.length; k < len2; i = ++k) { - exp = ref5[i]; + for (i = k = 0, len2 = ref3.length; k < len2; i = ++k) { + exp = ref3[i]; if (!(exp.unwrap() instanceof Comment)) { break; } @@ -550,12 +567,12 @@ } compileWithDeclarations(o) { - var assigns, declars, exp, fragments, i, j, len1, post, ref3, rest, scope, spaced; + var assigns, declars, exp, fragments, i, j, len1, post, ref1, rest, scope, spaced; fragments = []; post = []; - ref3 = this.expressions; - for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { - exp = ref3[i]; + ref1 = this.expressions; + for (i = j = 0, len1 = ref1.length; j < len1; i = ++j) { + exp = ref1[i]; exp = exp.unwrap(); if (!(exp instanceof Comment || exp instanceof Literal)) { break; @@ -571,7 +588,9 @@ this.expressions = rest; } post = this.compileNode(o); - scope = o.scope; + ({ + scope: scope + } = o); if (scope.expressions === this) { declars = o.scope.hasDeclarations(); assigns = scope.hasAssignments; @@ -725,8 +744,8 @@ } compileNode(o) { - var code, ref3; - code = ((ref3 = o.scope.method) != null ? ref3.bound : void 0) ? o.scope.method.context : this.value; + var code, ref1; + code = ((ref1 = o.scope.method) != null ? ref1.bound : void 0) ? o.scope.method.context : this.value; return [this.makeCode(code)]; } @@ -760,8 +779,8 @@ } compileToFragments(o, level) { - var expr, ref3; - expr = (ref3 = this.expression) != null ? ref3.makeReturn() : void 0; + var expr, ref1; + expr = (ref1 = this.expression) != null ? ref1.makeReturn() : void 0; if (expr && !(expr instanceof Return)) { return expr.compileToFragments(o, level); } else { @@ -883,10 +902,10 @@ } isAtomic() { - var j, len1, node, ref3; - ref3 = this.properties.concat(this.base); - for (j = 0, len1 = ref3.length; j < len1; j++) { - node = ref3[j]; + var j, len1, node, ref1; + ref1 = this.properties.concat(this.base); + for (j = 0, len1 = ref1.length; j < len1; j++) { + node = ref1[j]; if (node.soak || node instanceof Call) { return false; } @@ -918,14 +937,14 @@ } isSplice() { - var lastProp, ref3; - ref3 = this.properties, lastProp = ref3[ref3.length - 1]; + var lastProp, ref1; + ref1 = this.properties, lastProp = ref1[ref1.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'; + var ref1; + return (this["this"] || this.base instanceof ThisLiteral || this.base.value === className) && this.properties.length === 1 && ((ref1 = this.properties[0].name) != null ? ref1.value : void 0) !== 'prototype'; } unwrap() { @@ -937,8 +956,8 @@ } cacheReference(o) { - var base, bref, name, nref, ref3; - ref3 = this.properties, name = ref3[ref3.length - 1]; + var base, bref, name, nref, ref1; + ref1 = this.properties, name = ref1[ref1.length - 1]; if (this.properties.length < 2 && !this.base.shouldCache() && !(name != null ? name.shouldCache() : void 0)) { return [this, this]; } @@ -975,14 +994,14 @@ unfoldSoak(o) { return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (() => { - var fst, i, ifn, j, len1, prop, ref, ref3, snd; + var fst, i, ifn, j, len1, prop, ref, ref1, 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]; + ref1 = this.properties; + for (i = j = 0, len1 = ref1.length; j < len1; i = ++j) { + prop = ref1[i]; if (!prop.soak) { continue; } @@ -1061,11 +1080,11 @@ } updateLocationDataIfMissing(locationData) { - var base, ref3; + var base, ref1; 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; + base = ((ref1 = this.variable) != null ? ref1.base : void 0) || this.variable; if (base.needsUpdatedStartLocation) { this.variable.locationData.first_line = locationData.first_line; this.variable.locationData.first_column = locationData.first_column; @@ -1077,8 +1096,8 @@ } newInstance() { - var base, ref3; - base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable; + var base, ref1; + base = ((ref1 = this.variable) != null ? ref1.base : void 0) || this.variable; if (base instanceof Call && !base.isNew) { base.newInstance(); } else { @@ -1089,7 +1108,7 @@ } unfoldSoak(o) { - var call, ifn, j, left, len1, list, ref3, rite; + var call, ifn, j, left, len1, list, ref1, rite; if (this.soak) { if (this.variable instanceof Super) { left = new Literal(this.variable.compile(o)); @@ -1126,9 +1145,9 @@ break; } } - ref3 = list.reverse(); - for (j = 0, len1 = ref3.length; j < len1; j++) { - call = ref3[j]; + ref1 = list.reverse(); + for (j = 0, len1 = ref1.length; j < len1; j++) { + call = ref1[j]; if (ifn) { if (call.variable instanceof Call) { call.variable = ifn; @@ -1142,14 +1161,14 @@ } compileNode(o) { - var arg, argIndex, compiledArgs, fragments, j, len1, ref3, ref4; - if ((ref3 = this.variable) != null) { - ref3.front = this.front; + var arg, argIndex, compiledArgs, fragments, j, len1, ref1, ref2; + if ((ref1 = this.variable) != null) { + ref1.front = this.front; } compiledArgs = []; - ref4 = this.args; - for (argIndex = j = 0, len1 = ref4.length; j < len1; argIndex = ++j) { - arg = ref4[argIndex]; + ref2 = this.args; + for (argIndex = j = 0, len1 = ref2.length; j < len1; argIndex = ++j) { + arg = ref2[argIndex]; if (argIndex) { compiledArgs.push(this.makeCode(", ")); } @@ -1178,13 +1197,13 @@ 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; + var ref1; + return ((ref1 = this.expressions) != null ? ref1.length : void 0) && o.level === LEVEL_TOP; } compileNode(o) { - var ref, ref3, replacement, superCall; - if (!((ref3 = this.expressions) != null ? ref3.length : void 0)) { + var ref, ref1, replacement, superCall; + if (!((ref1 = this.expressions) != null ? ref1.length : void 0)) { return super.compileNode(o); } superCall = new Literal(fragmentsToText(super.compileNode(o))); @@ -1220,7 +1239,10 @@ } this.inCtor = !!method.ctor; if (!(this.inCtor || (this.accessor != null))) { - name = method.name, variable = method.variable; + ({ + name: name, + variable: variable + } = method); if (name.shouldCache() || (name instanceof Index && name.index.isAssignable())) { nref = new IdentifierLiteral(o.scope.parent.freeVariable('name')); name.index = new Assign(nref, name.index); @@ -1288,11 +1310,11 @@ } compileToFragments(o) { - var name, node, ref3; + var name, node, ref1; name = this.name.compileToFragments(o); node = this.name.unwrap(); if (node instanceof PropertyName) { - if (ref3 = node.value, indexOf.call(JS_FORBIDDEN, ref3) >= 0) { + if (ref1 = node.value, indexOf.call(JS_FORBIDDEN, ref1) >= 0) { return [this.makeCode('["'), ...name, this.makeCode('"]')]; } else { return [this.makeCode('.'), ...name]; @@ -1393,12 +1415,12 @@ } compileArray(o) { - var args, body, cond, hasArgs, i, idt, j, known, post, pre, range, ref3, ref4, result, results, vars; + var args, body, cond, hasArgs, i, idt, j, known, post, pre, range, ref1, ref2, 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); } + for (var j = ref1 = this.fromNum, ref2 = this.toNum; ref1 <= ref2 ? j <= ref2 : j >= ref2; ref1 <= ref2 ? j++ : j--){ results.push(j); } return results; }).apply(this); if (this.exclusive) { @@ -1446,8 +1468,11 @@ } compileNode(o) { - var compiled, compiledText, from, fromCompiled, ref3, to, toStr; - ref3 = this.range, to = ref3.to, from = ref3.from; + var compiled, compiledText, from, fromCompiled, to, toStr; + ({ + to: to, + from: from + } = this.range); fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')]; if (to) { compiled = to.compileToFragments(o, LEVEL_PAREN); @@ -1475,6 +1500,21 @@ this.objects = this.properties = props || []; } + isAssignable() { + var j, len1, prop, ref1; + ref1 = this.properties; + for (j = 0, len1 = ref1.length; j < len1; j++) { + prop = ref1[j]; + if (prop instanceof Assign) { + prop = prop.value; + } + if (!prop.isAssignable()) { + return false; + } + } + return true; + } + compileNode(o) { var answer, i, idt, indent, j, join, k, key, lastNoncom, len1, len2, node, prop, props, value; props = this.properties; @@ -1535,10 +1575,10 @@ } assigns(name) { - var j, len1, prop, ref3; - ref3 = this.properties; - for (j = 0, len1 = ref3.length; j < len1; j++) { - prop = ref3[j]; + var j, len1, prop, ref1; + ref1 = this.properties; + for (j = 0, len1 = ref1.length; j < len1; j++) { + prop = ref1[j]; if (prop.assigns(name)) { return true; } @@ -1546,6 +1586,21 @@ return false; } + eachName(iterator) { + var j, len1, prop, ref1, results; + ref1 = this.properties; + results = []; + for (j = 0, len1 = ref1.length; j < len1; j++) { + prop = ref1[j]; + if (prop instanceof Assign) { + prop = prop.value; + } + prop = prop.unwrapAll(); + results.push(prop.eachName(iterator)); + } + return results; + } + }; Obj.prototype.children = ['properties']; @@ -1562,13 +1617,13 @@ } isAssignable() { - var i, j, len1, obj, ref3; + var i, j, len1, obj, ref1; if (!this.objects.length) { return false; } - ref3 = this.objects; - for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { - obj = ref3[i]; + ref1 = this.objects; + for (i = j = 0, len1 = ref1.length; j < len1; i = ++j) { + obj = ref1[i]; if (obj instanceof Splat && i + 1 !== this.objects.length) { return false; } @@ -1587,11 +1642,11 @@ o.indent += TAB; answer = []; compiledObjs = (function() { - var j, len1, ref3, results; - ref3 = this.objects; + var j, len1, ref1, results; + ref1 = this.objects; results = []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - obj = ref3[j]; + for (j = 0, len1 = ref1.length; j < len1; j++) { + obj = ref1[j]; results.push(obj.compileToFragments(o, LEVEL_LIST)); } return results; @@ -1614,10 +1669,10 @@ } assigns(name) { - var j, len1, obj, ref3; - ref3 = this.objects; - for (j = 0, len1 = ref3.length; j < len1; j++) { - obj = ref3[j]; + var j, len1, obj, ref1; + ref1 = this.objects; + for (j = 0, len1 = ref1.length; j < len1; j++) { + obj = ref1[j]; if (obj.assigns(name)) { return true; } @@ -1626,11 +1681,11 @@ } eachName(iterator) { - var j, len1, obj, ref3, results; - ref3 = this.objects; + var j, len1, obj, ref1, results; + ref1 = this.objects; results = []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - obj = ref3[j]; + for (j = 0, len1 = ref1.length; j < len1; j++) { + obj = ref1[j]; obj = obj.unwrapAll(); results.push(obj.eachName(iterator)); } @@ -1683,14 +1738,14 @@ } compileClassDeclaration(o) { - var ref3, result; + var ref1, result; if (this.externalCtor || this.boundMethods.length) { if (this.ctor == null) { this.ctor = this.makeDefaultConstructor(); } } - if ((ref3 = this.ctor) != null) { - ref3.noReturn = true; + if ((ref1 = this.ctor) != null) { + ref1.noReturn = true; } if (this.boundMethods.length) { this.proxyBoundMethods(o); @@ -1716,11 +1771,11 @@ } determineName() { - var message, name, node, ref3, tail; + var message, name, node, ref1, tail; if (!this.variable) { return null; } - ref3 = this.variable.properties, tail = ref3[ref3.length - 1]; + ref1 = this.variable.properties, tail = ref1[ref1.length - 1]; node = tail ? tail instanceof Access && tail.name : this.variable.base; if (!(node instanceof IdentifierLiteral || node instanceof PropertyName)) { return null; @@ -1740,18 +1795,22 @@ } walkBody() { - var assign, end, executableBody, expression, expressions, exprs, i, initializer, initializerExpression, j, k, len1, len2, method, properties, pushSlice, ref3, start; + var assign, end, executableBody, expression, expressions, exprs, i, initializer, initializerExpression, j, k, len1, len2, method, properties, pushSlice, ref1, start; this.ctor = null; this.boundMethods = []; executableBody = null; initializer = []; - expressions = this.body.expressions; + ({ + expressions: expressions + } = this.body); i = 0; - ref3 = expressions.slice(); - for (j = 0, len1 = ref3.length; j < len1; j++) { - expression = ref3[j]; + ref1 = expressions.slice(); + for (j = 0, len1 = ref1.length; j < len1; j++) { + expression = ref1[j]; if (expression instanceof Value && expression.isObject(true)) { - properties = expression.base.properties; + ({ + properties: properties + } = expression.base); exprs = []; end = 0; start = 0; @@ -1839,7 +1898,10 @@ addInitializerMethod(assign) { var method, methodName, variable; - variable = assign.variable, method = assign.value; + ({ + variable: variable, + value: method + } = assign); method.isMethod = true; method.isStatic = variable.looksStatic(this.name); if (method.isStatic) { @@ -1877,11 +1939,11 @@ proxyBoundMethods(o) { var name; this.ctor.thisAssignments = (function() { - var j, ref3, results; - ref3 = this.boundMethods; + var j, ref1, results; + ref1 = this.boundMethods; results = []; - for (j = ref3.length - 1; j >= 0; j += -1) { - name = ref3[j]; + for (j = ref1.length - 1; j >= 0; j += -1) { + name = ref1[j]; name = new Value(new ThisLiteral, [name]).compile(o); results.push(new Literal(`${name} = ${utility('bind', o)}(${name}, this)`)); } @@ -1907,14 +1969,14 @@ } compileNode(o) { - var args, argumentsNode, directives, externalCtor, ident, jumpNode, klass, params, parent, ref3, wrapper; + var args, argumentsNode, directives, externalCtor, ident, jumpNode, klass, params, parent, ref1, 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; + this.name = (ref1 = this["class"].name) != null ? ref1 : this.defaultClassVariableName; directives = this.walkBody(); this.setContext(); ident = new IdentifierLiteral(this.name); @@ -1962,15 +2024,15 @@ } } this.traverseChildren(false, (child) => { - var cont, i, j, len1, node, ref3; + var cont, i, j, len1, node, ref1; 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]; + ref1 = child.expressions; + for (i = j = 0, len1 = ref1.length; j < len1; i = ++j) { + node = ref1[i]; if (node instanceof Value && node.isObject(true)) { cont = false; child.expressions[i] = this.addProperties(node.base.properties); @@ -2075,7 +2137,7 @@ exports.ImportDeclaration = ImportDeclaration = class ImportDeclaration extends ModuleDeclaration { compileNode(o) { - var code, ref3; + var code, ref1; this.checkScope(o, 'import'); o.importedSymbols = []; code = []; @@ -2083,7 +2145,7 @@ if (this.clause != null) { code.push(...this.clause.compileNode(o)); } - if (((ref3 = this.source) != null ? ref3.value : void 0) != null) { + if (((ref1 = this.source) != null ? ref1.value : void 0) != null) { if (this.clause !== null) { code.push(this.makeCode(' from ')); } @@ -2128,7 +2190,7 @@ exports.ExportDeclaration = ExportDeclaration = class ExportDeclaration extends ModuleDeclaration { compileNode(o) { - var code, ref3; + var code, ref1; this.checkScope(o, 'export'); code = []; code.push(this.makeCode(`${this.tab}export `)); @@ -2147,7 +2209,7 @@ } else { code = code.concat(this.clause.compileNode(o)); } - if (((ref3 = this.source) != null ? ref3.value : void 0) != null) { + if (((ref1 = this.source) != null ? ref1.value : void 0) != null) { code.push(this.makeCode(` from ${this.source.value}`)); } code.push(this.makeCode(';')); @@ -2174,11 +2236,11 @@ code = []; o.indent += TAB; compiledList = (function() { - var j, len1, ref3, results; - ref3 = this.specifiers; + var j, len1, ref1, results; + ref1 = this.specifiers; results = []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - specifier = ref3[j]; + for (j = 0, len1 = ref1.length; j < len1; j++) { + specifier = ref1[j]; results.push(specifier.compileToFragments(o, LEVEL_LIST)); } return results; @@ -2246,8 +2308,8 @@ } compileNode(o) { - var ref3; - if ((ref3 = this.identifier, indexOf.call(o.importedSymbols, ref3) >= 0) || o.scope.check(this.identifier)) { + var ref1; + if ((ref1 = this.identifier, indexOf.call(o.importedSymbols, ref1) >= 0) || o.scope.check(this.identifier)) { this.error(`'${this.identifier}' has already been declared`); } else { o.importedSymbols.push(this.identifier); @@ -2275,7 +2337,12 @@ 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; + ({ + param: this.param, + subpattern: this.subpattern, + operatorToken: this.operatorToken, + moduleDeclaration: this.moduleDeclaration + } = options); } isStatement(o) { @@ -2297,7 +2364,7 @@ } compileNode(o) { - var answer, compiledName, isValue, j, name, properties, prototype, ref3, ref4, ref5, ref6, ref7, ref8, val, varBase; + var answer, compiledName, isValue, j, name, properties, prototype, ref1, ref2, ref3, ref4, ref5, ref6, val, varBase; if (isValue = this.variable instanceof Value) { if (this.variable.isArray() || this.variable.isObject()) { if (!this.variable.isAssignable()) { @@ -2307,10 +2374,10 @@ if (this.variable.isSplice()) { return this.compileSplice(o); } - if ((ref3 = this.context) === '||=' || ref3 === '&&=' || ref3 === '?=') { + if ((ref1 = this.context) === '||=' || ref1 === '&&=' || ref1 === '?=') { return this.compileConditional(o); } - if ((ref4 = this.context) === '**=' || ref4 === '//=' || ref4 === '%%=') { + if ((ref2 = this.context) === '**=' || ref2 === '//=' || ref2 === '%%=') { return this.compileSpecialMath(o); } } @@ -2341,41 +2408,42 @@ 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') { + } else if (((ref3 = this.variable.properties) != null ? ref3.length : void 0) >= 2) { + ref4 = this.variable.properties, properties = 3 <= ref4.length ? slice.call(ref4, 0, j = ref4.length - 2) : (j = 0, []), prototype = ref4[j++], name = ref4[j++]; + if (((ref5 = prototype.name) != null ? ref5.value : void 0) === 'prototype') { this.value.name = name; } } } 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) { + } else if (ref6 = fragmentsToText(compiledName), indexOf.call(JS_FORBIDDEN, ref6) >= 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 { + if (o.level > LEVEL_LIST || (isValue && this.variable.base instanceof Obj)) { return this.wrapInBraces(answer); + } else { + return 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; + var acc, assigns, code, defaultValue, expandedIdx, fragments, i, idx, isObject, ivar, j, len1, message, name, obj, objects, olen, ref, rest, top, val, value, vvar, vvarText; top = o.level === LEVEL_TOP; - value = this.value; - objects = this.variable.base.objects; + ({ + value: value + } = this); + ({ + objects: objects + } = this.variable.base); if (!(olen = objects.length)) { code = value.compileToFragments(o); if (o.level >= LEVEL_OP) { @@ -2392,7 +2460,12 @@ 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; + ({ + variable: { + base: idx + }, + value: obj + } = obj); if (obj instanceof Assign) { defaultValue = obj.value; obj = obj.variable; @@ -2464,7 +2537,12 @@ } defaultValue = null; if (obj instanceof Assign && obj.context === 'object') { - ref5 = obj, (ref6 = ref5.variable, idx = ref6.base), obj = ref5.value; + ({ + variable: { + base: idx + }, + value: obj + } = obj); if (obj instanceof Assign) { defaultValue = obj.value; obj = obj.variable; @@ -2533,8 +2611,14 @@ } compileSplice(o) { - var answer, exclusive, from, fromDecl, fromRef, name, ref3, to, valDef, valRef; - ref3 = this.variable.properties.pop().range, from = ref3.from, to = ref3.to, exclusive = ref3.exclusive; + var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef; + ({ + range: { + from: from, + to: to, + exclusive: exclusive + } + } = this.variable.properties.pop()); name = this.variable.compile(o); if (from) { [fromDecl, fromRef] = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)); @@ -2605,7 +2689,7 @@ } 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, signature, splatParamName, thisAssignments, wasEmpty; + var answer, body, condition, exprs, haveBodyParam, haveSplatParam, i, ifTrue, j, k, len1, len2, m, methodScope, modifiers, name, param, paramNames, params, paramsAfterSplat, ref, ref1, ref2, ref3, ref4, ref5, signature, splatParamName, thisAssignments, wasEmpty; if (this.ctor) { if (this.isAsync) { this.name.error('Class constructor may not be async'); @@ -2615,7 +2699,7 @@ } } if (this.bound) { - if ((ref3 = o.scope.method) != null ? ref3.bound : void 0) { + if ((ref1 = o.scope.method) != null ? ref1.bound : void 0) { this.context = o.scope.method.context; } if (!this.context) { @@ -2629,7 +2713,7 @@ delete o.isExistentialEquals; params = []; exprs = []; - thisAssignments = (ref4 = (ref5 = this.thisAssignments) != null ? ref5.slice() : void 0) != null ? ref4 : []; + thisAssignments = (ref2 = (ref3 = this.thisAssignments) != null ? ref3.slice() : void 0) != null ? ref2 : []; paramsAfterSplat = []; haveSplatParam = false; haveBodyParam = false; @@ -2650,9 +2734,9 @@ return thisAssignments.push(new Assign(node, target)); } }); - ref6 = this.params; - for (i = j = 0, len1 = ref6.length; j < len1; i = ++j) { - param = ref6[i]; + ref4 = this.params; + for (i = j = 0, len1 = ref4.length; j < len1; i = ++j) { + param = ref4[i]; if (param.splat || param instanceof Expansion) { if (haveSplatParam) { param.error('only one splat or expansion parameter is allowed per function definition'); @@ -2708,7 +2792,7 @@ 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) { + if (((ref5 = param.name) != null ? ref5.value : void 0) != null) { o.scope.add(param.name.value, 'var', true); } } @@ -2805,11 +2889,11 @@ } eachParamName(iterator) { - var j, len1, param, ref3, results; - ref3 = this.params; + var j, len1, param, ref1, results; + ref1 = this.params; results = []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - param = ref3[j]; + for (j = 0, len1 = ref1.length; j < len1; j++) { + param = ref1[j]; results.push(param.eachName(iterator)); } return results; @@ -2830,7 +2914,7 @@ } expandCtorSuper(thisAssignments) { - var haveThisParam, param, ref3, seenSuper; + var haveThisParam, param, ref1, seenSuper; if (!this.ctor) { return false; } @@ -2843,7 +2927,7 @@ } return superCall.expressions = thisAssignments; }); - haveThisParam = thisAssignments.length && thisAssignments.length !== ((ref3 = this.thisAssignments) != null ? ref3.length : void 0); + haveThisParam = thisAssignments.length && thisAssignments.length !== ((ref1 = this.thisAssignments) != null ? ref1.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"); @@ -2923,7 +3007,7 @@ } eachName(iterator, name = this.name) { - var atParam, j, len1, node, obj, ref3, ref4; + var atParam, j, len1, node, obj, ref1, ref2; atParam = (obj) => { return iterator(`@${obj.properties[0].name.value}`, obj, this); }; @@ -2933,9 +3017,9 @@ 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]; + ref2 = (ref1 = name.objects) != null ? ref1 : []; + for (j = 0, len1 = ref2.length; j < len1; j++) { + obj = ref2[j]; if (obj instanceof Assign && (obj.context == null)) { obj = obj.variable; } @@ -3066,7 +3150,9 @@ jumps() { var expressions, j, jumpNode, len1, node; - expressions = this.body.expressions; + ({ + expressions: expressions + } = this.body); if (!expressions.length) { return false; } @@ -3085,7 +3171,9 @@ var answer, body, rvar, set; o.indent += TAB; set = ''; - body = this.body; + ({ + body: body + } = this); if (body.isEmpty()) { body = this.makeCode(''); } else { @@ -3149,8 +3237,8 @@ } isNumber() { - var ref3; - return this.isUnary() && ((ref3 = this.operator) === '+' || ref3 === '-') && this.first instanceof Value && this.first.isNumber(); + var ref1; + return this.isUnary() && ((ref1 = this.operator) === '+' || ref1 === '-') && this.first instanceof Value && this.first.isNumber(); } isAwait() { @@ -3158,8 +3246,8 @@ } isYield() { - var ref3; - return (ref3 = this.operator) === 'yield' || ref3 === 'yield*'; + var ref1; + return (ref1 = this.operator) === 'yield' || ref1 === 'yield*'; } isUnary() { @@ -3171,12 +3259,12 @@ } isChainable() { - var ref3; - return (ref3 = this.operator) === '<' || ref3 === '>' || ref3 === '>=' || ref3 === '<=' || ref3 === '===' || ref3 === '!=='; + var ref1; + return (ref1 = this.operator) === '<' || ref1 === '>' || ref1 === '>=' || ref1 === '<=' || ref1 === '===' || ref1 === '!=='; } invert() { - var allInvertable, curr, fst, op, ref3; + var allInvertable, curr, fst, op, ref1; if (this.isChainable() && this.first.isChainable()) { allInvertable = true; curr = this; @@ -3202,7 +3290,7 @@ 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')) { + } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((ref1 = fst.operator) === '!' || ref1 === 'in' || ref1 === 'instanceof')) { return fst; } else { return new Op('!', this); @@ -3210,17 +3298,17 @@ } unfoldSoak(o) { - var ref3; - return ((ref3 = this.operator) === '++' || ref3 === '--' || ref3 === 'delete') && unfoldSoak(o, this, 'first'); + var ref1; + return ((ref1 = this.operator) === '++' || ref1 === '--' || ref1 === 'delete') && unfoldSoak(o, this, 'first'); } generateDo(exp) { - var call, func, j, len1, param, passedParams, ref, ref3; + var call, func, j, len1, param, passedParams, ref, ref1; 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]; + ref1 = func.params || []; + for (j = 0, len1 = ref1.length; j < len1; j++) { + param = ref1[j]; if (param.value) { passedParams.push(param.value); delete param.value; @@ -3234,7 +3322,7 @@ } compileNode(o) { - var answer, isChain, lhs, message, ref3, rhs; + var answer, isChain, lhs, message, ref1, rhs; isChain = this.isChainable() && this.first.isChainable(); if (!isChain) { this.first.front = this.front; @@ -3242,7 +3330,7 @@ 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 === '++') { + if ((ref1 = this.operator) === '--' || ref1 === '++') { message = isUnassignable(this.first.unwrapAll().value); if (message) { this.first.error(message); @@ -3327,13 +3415,13 @@ } compileContinuation(o) { - var op, parts, ref3, ref4; + var op, parts, ref1, ref2; 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) { + if (((ref1 = o.scope.method) != null ? ref1.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)) { @@ -3345,7 +3433,7 @@ parts.push([this.makeCode("(")]); } parts.push([this.makeCode(op)]); - if (((ref4 = this.first.base) != null ? ref4.value : void 0) !== '') { + if (((ref2 = this.first.base) != null ? ref2.value : void 0) !== '') { parts.push([this.makeCode(" ")]); } parts.push(this.first.compileToFragments(o, LEVEL_OP)); @@ -3409,11 +3497,11 @@ } compileNode(o) { - var hasSplat, j, len1, obj, ref3; + var hasSplat, j, len1, obj, ref1; 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]; + ref1 = this.array.base.objects; + for (j = 0, len1 = ref1.length; j < len1; j++) { + obj = ref1[j]; if (!(obj instanceof Splat)) { continue; } @@ -3428,13 +3516,13 @@ } compileOrTest(o) { - var cmp, cnj, i, item, j, len1, ref, ref3, sub, tests; + var cmp, cnj, i, item, j, len1, ref, ref1, sub, tests; [sub, ref] = this.object.cache(o, LEVEL_OP); [cmp, cnj] = this.negated ? [' !== ', ' && '] : [' === ', ' || ']; tests = []; - ref3 = this.array.base.objects; - for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) { - item = ref3[i]; + ref1 = this.array.base.objects; + for (i = j = 0, len1 = ref1.length; j < len1; i = ++j) { + item = ref1[i]; if (i) { tests.push(this.makeCode(cnj)); } @@ -3487,8 +3575,8 @@ } jumps(o) { - var ref3; - return this.attempt.jumps(o) || ((ref3 = this.recovery) != null ? ref3.jumps(o) : void 0); + var ref1; + return this.attempt.jumps(o) || ((ref1 = this.recovery) != null ? ref1.jumps(o) : void 0); } makeReturn(res) { @@ -3682,8 +3770,15 @@ exports.For = For = (function() { class For extends While { constructor(body, source) { + var ref1, ref2; super(); - this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index; + ({ + source: this.source, + guard: this.guard, + step: this.step, + name: this.name, + index: this.index + } = source); this.body = Block.wrap([body]); this.own = !!source.own; this.object = !!source.object; @@ -3697,7 +3792,7 @@ if (this.object) { [this.name, this.index] = [this.index, this.name]; } - if (this.index instanceof Value && !this.index.isAssignable()) { + if (((ref1 = this.index) != null ? typeof ref1.isArray === "function" ? ref1.isArray() : void 0 : void 0) || ((ref2 = this.index) != null ? typeof ref2.isObject === "function" ? ref2.isObject() : void 0 : void 0)) { 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; @@ -3712,9 +3807,9 @@ } 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, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart; + var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, last, lvar, name, namePart, ref, ref1, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart; body = Block.wrap([this.body]); - ref3 = body.expressions, last = ref3[ref3.length - 1]; + ref1 = body.expressions, last = ref1[ref1.length - 1]; if ((last != null ? last.jumps() : void 0) instanceof Return) { this.returns = false; } @@ -3843,20 +3938,20 @@ } pluckDirectCall(o, body) { - var base, defs, expr, fn, idx, j, len1, ref, ref3, ref4, ref5, ref6, ref7, ref8, val; + var base, defs, expr, fn, idx, j, len1, ref, ref1, ref2, ref3, ref4, ref5, ref6, val; defs = []; - ref3 = body.expressions; - for (idx = j = 0, len1 = ref3.length; j < len1; idx = ++j) { - expr = ref3[idx]; + ref1 = body.expressions; + for (idx = j = 0, len1 = ref1.length; j < len1; idx = ++j) { + expr = ref1[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')))) { + val = (ref2 = expr.variable) != null ? ref2.unwrapAll() : void 0; + if (!((val instanceof Code) || (val instanceof Value && ((ref3 = val.base) != null ? ref3.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((ref4 = (ref5 = val.properties[0].name) != null ? ref5.value : void 0) === 'call' || ref4 === 'apply')))) { continue; } - fn = ((ref8 = val.base) != null ? ref8.unwrapAll() : void 0) || val; + fn = ((ref6 = val.base) != null ? ref6.unwrapAll() : void 0) || val; ref = new IdentifierLiteral(o.scope.freeVariable('fn')); base = new Value(ref); if (val.base) { @@ -3888,44 +3983,44 @@ jumps(o = { block: true }) { - var block, conds, j, jumpNode, len1, ref3, ref4; - ref3 = this.cases; - for (j = 0, len1 = ref3.length; j < len1; j++) { - [conds, block] = ref3[j]; + var block, conds, j, jumpNode, len1, ref1, ref2; + ref1 = this.cases; + for (j = 0, len1 = ref1.length; j < len1; j++) { + [conds, block] = ref1[j]; if (jumpNode = block.jumps(o)) { return jumpNode; } } - return (ref4 = this.otherwise) != null ? ref4.jumps(o) : void 0; + return (ref2 = this.otherwise) != null ? ref2.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]; + var j, len1, pair, ref1, ref2; + ref1 = this.cases; + for (j = 0, len1 = ref1.length; j < len1; j++) { + pair = ref1[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); + if ((ref2 = this.otherwise) != null) { + ref2.makeReturn(res); } return this; } compileNode(o) { - var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref3, ref4; + var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref1, ref2; 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) { - [conditions, block] = ref3[i]; - ref4 = flatten([conditions]); - for (k = 0, len2 = ref4.length; k < len2; k++) { - cond = ref4[k]; + ref1 = this.cases; + for (i = j = 0, len1 = ref1.length; j < len1; i = ++j) { + [conditions, block] = ref1[i]; + ref2 = flatten([conditions]); + for (k = 0, len2 = ref2.length; k < len2; k++) { + cond = ref2[k]; if (!this.subject) { cond = cond.invert(); } @@ -3968,17 +4063,19 @@ this.condition = options.type === 'unless' ? condition.invert() : condition; this.elseBody = null; this.isChain = false; - this.soak = options.soak; + ({ + soak: this.soak + } = options); } bodyNode() { - var ref3; - return (ref3 = this.body) != null ? ref3.unwrap() : void 0; + var ref1; + return (ref1 = this.body) != null ? ref1.unwrap() : void 0; } elseBodyNode() { - var ref3; - return (ref3 = this.elseBody) != null ? ref3.unwrap() : void 0; + var ref1; + return (ref1 = this.elseBody) != null ? ref1.unwrap() : void 0; } addElse(elseBody) { @@ -3993,13 +4090,13 @@ } 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); + var ref1; + return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((ref1 = this.elseBodyNode()) != null ? ref1.isStatement(o) : void 0); } jumps(o) { - var ref3; - return this.body.jumps(o) || ((ref3 = this.elseBody) != null ? ref3.jumps(o) : void 0); + var ref1; + return this.body.jumps(o) || ((ref1 = this.elseBody) != null ? ref1.jumps(o) : void 0); } compileNode(o) { @@ -4124,7 +4221,9 @@ utility = function(name, o) { var ref, root; - root = o.scope.root; + ({ + root: root + } = o.scope); if (name in root.utilities) { return root.utilities[name]; } else { diff --git a/lib/coffeescript/optparse.js b/lib/coffeescript/optparse.js index 79cb367ddf..fb4998c4a6 100644 --- a/lib/coffeescript/optparse.js +++ b/lib/coffeescript/optparse.js @@ -2,7 +2,9 @@ (function() { var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat; - repeat = require('./helpers').repeat; + ({ + repeat: repeat + } = require('./helpers')); exports.OptionParser = OptionParser = class OptionParser { constructor(rules, banner) { diff --git a/lib/coffeescript/register.js b/lib/coffeescript/register.js index 4338790fe2..7b0a2f9930 100644 --- a/lib/coffeescript/register.js +++ b/lib/coffeescript/register.js @@ -48,7 +48,9 @@ } if (child_process) { - fork = child_process.fork; + ({ + fork: fork + } = child_process); binary = require.resolve('../../bin/coffee'); child_process.fork = function(path, args, options) { if (helpers.isCoffee(path)) { diff --git a/lib/coffeescript/repl.js b/lib/coffeescript/repl.js index 84c47c7c9c..dfbbdaeff9 100644 --- a/lib/coffeescript/repl.js +++ b/lib/coffeescript/repl.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 2.0.0-alpha1 (function() { - var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, ref, replDefaults, runInContext, updateSyntaxError, vm; + var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, updateSyntaxError, vm; fs = require('fs'); @@ -12,18 +12,26 @@ CoffeeScript = require('./coffeescript'); - ref = require('./helpers'), merge = ref.merge, updateSyntaxError = ref.updateSyntaxError; + ({ + merge: merge, + updateSyntaxError: updateSyntaxError + } = require('./helpers')); replDefaults = { prompt: 'coffee> ', historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0, historyMaxInputSize: 10240, "eval": function(input, context, filename, cb) { - var Assign, Block, Literal, Value, ast, err, js, ref1, referencedVars, token, tokens; + var Assign, Block, Literal, Value, ast, err, js, referencedVars, token, tokens; input = input.replace(/\uFF00/g, '\n'); input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1'); input = input.replace(/^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1'); - ref1 = require('./nodes'), Block = ref1.Block, Assign = ref1.Assign, Value = ref1.Value, Literal = ref1.Literal; + ({ + Block: Block, + Assign: Assign, + Value: Value, + Literal: Literal + } = require('./nodes')); try { tokens = CoffeeScript.tokens(input); referencedVars = (function() { @@ -62,9 +70,13 @@ }; addMultilineHandler = function(repl) { - var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref1, rli; - rli = repl.rli, inputStream = repl.inputStream, outputStream = repl.outputStream; - origPrompt = (ref1 = repl._prompt) != null ? ref1 : repl.prompt; + var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref, rli; + ({ + rli: rli, + inputStream: inputStream, + outputStream: outputStream + } = repl); + origPrompt = (ref = repl._prompt) != null ? ref : repl.prompt; multiline = { enabled: false, initialPrompt: origPrompt.replace(/^[^> ]*/, function(x) { diff --git a/lib/coffeescript/rewriter.js b/lib/coffeescript/rewriter.js index c8ef515ec4..f629ece855 100644 --- a/lib/coffeescript/rewriter.js +++ b/lib/coffeescript/rewriter.js @@ -30,7 +30,9 @@ scanTokens(block) { var i, token, tokens; - tokens = this.tokens; + ({ + tokens: tokens + } = this); i = 0; while (token = tokens[i]) { i += block.call(this, token, i, tokens); @@ -40,7 +42,9 @@ detectEnd(i, condition, action) { var levels, ref, ref1, token, tokens; - tokens = this.tokens; + ({ + tokens: tokens + } = this); levels = 0; while (token = tokens[i]) { if (levels === 0 && condition.call(this, token, i)) { @@ -168,7 +172,7 @@ stack = []; start = null; return this.scanTokens(function(token, i, tokens) { - var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, ref, ref1, ref2, ref3, ref4, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag; + var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, ref, ref1, ref2, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag; [tag] = token; [prevTag] = prevToken = i > 0 ? tokens[i - 1] : []; [nextTag] = i < tokens.length - 1 ? tokens[i + 1] : []; @@ -316,7 +320,12 @@ newLine = prevTag === 'OUTDENT' || prevToken.newLine; if (indexOf.call(IMPLICIT_END, tag) >= 0 || indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) { while (inImplicit()) { - ref3 = stackTop(), stackTag = ref3[0], stackIdx = ref3[1], (ref4 = ref3[2], sameLine = ref4.sameLine, startsLine = ref4.startsLine); + [ + stackTag, stackIdx, { + sameLine: sameLine, + startsLine: startsLine + } + ] = stackTop(); if (inImplicitCall() && prevTag !== ',') { endImplicitCall(); } else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':') { @@ -351,9 +360,15 @@ return 1; } if (token[0] === '{' && (nextLocation = (ref = tokens[i + 1]) != null ? ref[2] : void 0)) { - line = nextLocation.first_line, column = nextLocation.first_column; + ({ + first_line: line, + first_column: column + } = nextLocation); } else if (prevLocation = (ref1 = tokens[i - 1]) != null ? ref1[2] : void 0) { - line = prevLocation.last_line, column = prevLocation.last_column; + ({ + last_line: line, + last_column: column + } = prevLocation); } else { line = column = 0; } diff --git a/src/nodes.coffee b/src/nodes.coffee index bec76f24d6..4c5ab47584 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1115,6 +1115,12 @@ exports.Obj = class Obj extends Base children: ['properties'] + isAssignable: -> + for prop in @properties + prop = prop.value if prop instanceof Assign + return false unless prop.isAssignable() + true + compileNode: (o) -> props = @properties if @generated @@ -1156,6 +1162,12 @@ exports.Obj = class Obj extends Base for prop in @properties when prop.assigns name then return yes no + eachName: (iterator) -> + for prop in @properties + prop = prop.value if prop instanceof Assign + prop = prop.unwrapAll() + prop.eachName iterator + #### Arr # An array literal. @@ -1719,7 +1731,6 @@ exports.Assign = class Assign extends Base @value.name = name if prototype.name?.value is 'prototype' val = @value.compileToFragments o, LEVEL_LIST - @variable.front = true if isValue and @variable.base instanceof Obj compiledName = @variable.compileToFragments o, LEVEL_LIST if @context is 'object' @@ -1732,7 +1743,7 @@ exports.Assign = class Assign extends Base return compiledName.concat @makeCode(": "), val answer = compiledName.concat @makeCode(" #{ @context or '=' } "), val - if o.level <= LEVEL_LIST then answer else @wrapInBraces answer + if o.level > LEVEL_LIST or (isValue and @variable.base instanceof Obj) then @wrapInBraces answer else answer # Brief implementation of recursive pattern matching, when assigning array or # object literals to a value. Peeks at their properties to assign inner names. @@ -2753,7 +2764,7 @@ exports.For = class For extends While @index.error 'cannot use index with for-from' if @from and @index source.ownTag.error "cannot use own with for-#{if @from then 'from' else 'in'}" if @own and not @object [@name, @index] = [@index, @name] if @object - @index.error 'index cannot be a pattern matching expression' if @index instanceof Value and not @index.isAssignable() + @index.error 'index cannot be a pattern matching expression' if @index?.isArray?() or @index?.isObject?() @range = @source instanceof Value and @source.base instanceof Range and not @source.properties.length and not @from @pattern = @name instanceof Value @index.error 'indexes do not apply to range loops' if @range and @index diff --git a/test/assignment.coffee b/test/assignment.coffee index aff5371a1d..20c940d700 100644 --- a/test/assignment.coffee +++ b/test/assignment.coffee @@ -141,9 +141,6 @@ test "#1192: assignment starting with object literals", -> # Destructuring Assignment -test "empty destructuring assignment", -> - {} = [] = undefined - test "chained destructuring assignments", -> [a] = {0: b} = {'0': c} = [nonce={}] eq nonce, a From 066071f06080b3a4c23c116004e56dd6deb3439f Mon Sep 17 00:00:00 2001 From: Chris Connelly Date: Thu, 30 Mar 2017 22:18:13 +0100 Subject: [PATCH 3/3] Compile shorthand object properties to ES2015 shorthand properties This dramatically improves the appearance of destructured imports. --- lib/coffeescript/cake.js | 6 +- lib/coffeescript/coffeescript.js | 30 +++---- lib/coffeescript/command.js | 19 ++--- lib/coffeescript/grammar.js | 4 +- lib/coffeescript/helpers.js | 7 +- lib/coffeescript/lexer.js | 46 +++-------- lib/coffeescript/nodes.js | 134 +++++++++---------------------- lib/coffeescript/optparse.js | 4 +- lib/coffeescript/register.js | 4 +- lib/coffeescript/repl.js | 20 +---- lib/coffeescript/rewriter.js | 15 +--- lib/coffeescript/scope.js | 7 +- lib/coffeescript/sourcemap.js | 6 +- src/nodes.coffee | 14 +++- 14 files changed, 93 insertions(+), 223 deletions(-) diff --git a/lib/coffeescript/cake.js b/lib/coffeescript/cake.js index 710c5437d9..13fb0e7e06 100644 --- a/lib/coffeescript/cake.js +++ b/lib/coffeescript/cake.js @@ -27,11 +27,7 @@ if (!action) { [action, description] = [description, action]; } - return tasks[name] = { - name: name, - description: description, - action: action - }; + return tasks[name] = {name, description, action}; }, option: function(letter, flag, description) { return switches.push([letter, flag, description]); diff --git a/lib/coffeescript/coffeescript.js b/lib/coffeescript/coffeescript.js index 9d5be3fcc8..35f38ac13c 100644 --- a/lib/coffeescript/coffeescript.js +++ b/lib/coffeescript/coffeescript.js @@ -9,13 +9,9 @@ path = require('path'); - ({ - Lexer: Lexer - } = require('./lexer')); + ({Lexer} = require('./lexer')); - ({ - parser: parser - } = require('./parser')); + ({parser} = require('./parser')); helpers = require('./helpers'); @@ -63,10 +59,7 @@ exports.compile = compile = withPrettyErrors(function(code, options) { var currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, v3SourceMap; - ({ - merge: merge, - extend: extend - } = helpers); + ({merge, extend} = helpers); options = extend({}, options); generateSourceMap = options.sourceMap || options.inlineMap || (options.filename == null); filename = options.filename || ''; @@ -139,7 +132,7 @@ } if (options.sourceMap) { return { - js: js, + js, sourceMap: map, v3SourceMap: JSON.stringify(v3SourceMap, null, 2) }; @@ -261,9 +254,9 @@ stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw; try { answer = compile(stripped, { - filename: filename, - sourceMap: sourceMap, - inlineMap: inlineMap, + filename, + sourceMap, + inlineMap, sourceFiles: [filename], literate: helpers.isLiterate(filename) }); @@ -302,13 +295,8 @@ parser.yy.parseError = function(message, arg) { var errorLoc, errorTag, errorText, errorToken, token, tokens; - ({ - token: token - } = arg); - ({ - errorToken: errorToken, - tokens: tokens - } = parser); + ({token} = arg); + ({errorToken, tokens} = parser); [errorTag, errorText, errorLoc] = errorToken; errorText = (function() { switch (false) { diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 95558397dc..13478f4d86 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -13,14 +13,9 @@ CoffeeScript = require('./coffeescript'); - ({ - spawn: spawn, - exec: exec - } = require('child_process')); + ({spawn, exec} = require('child_process')); - ({ - EventEmitter: EventEmitter - } = require('events')); + ({EventEmitter} = require('events')); useWinPathSep = path.sep === '\\'; @@ -208,11 +203,7 @@ o = opts; options = compileOptions(file, base); try { - t = task = { - file: file, - input: input, - options: options - }; + t = task = {file, input, options}; CoffeeScript.emit('compile', task); if (o.tokens) { return printTokens(CoffeeScript.tokens(t.input, t.options)); @@ -551,7 +542,7 @@ compileOptions = function(filename, base) { var answer, cwd, jsDir, jsPath; answer = { - filename: filename, + filename, literate: opts.literate || helpers.isLiterate(filename), bare: opts.bare, header: opts.compile && !opts['no-header'], @@ -564,7 +555,7 @@ jsPath = outputPath(filename, base); jsDir = path.dirname(jsPath); answer = helpers.merge(answer, { - jsPath: jsPath, + jsPath, sourceRoot: path.relative(jsDir, cwd), sourceFiles: [path.relative(cwd, filename)], generatedFile: helpers.baseFileName(jsPath, false, useWinPathSep) diff --git a/lib/coffeescript/grammar.js b/lib/coffeescript/grammar.js index 8e7eee0d8e..f778dbb5b3 100644 --- a/lib/coffeescript/grammar.js +++ b/lib/coffeescript/grammar.js @@ -2,9 +2,7 @@ (function() { var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; - ({ - Parser: Parser - } = require('jison')); + ({Parser} = require('jison')); unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/; diff --git a/lib/coffeescript/helpers.js b/lib/coffeescript/helpers.js index 39c2da690e..134a74dbcb 100644 --- a/lib/coffeescript/helpers.js +++ b/lib/coffeescript/helpers.js @@ -201,12 +201,7 @@ if (!(this.code && this.location)) { return Error.prototype.toString.call(this); } - ({ - first_line: first_line, - first_column: first_column, - last_line: last_line, - last_column: last_column - } = this.location); + ({first_line, first_column, last_line, last_column} = this.location); if (last_line == null) { last_line = first_line; } diff --git a/lib/coffeescript/lexer.js b/lib/coffeescript/lexer.js index 99f2d2a696..b91efc1c1b 100644 --- a/lib/coffeescript/lexer.js +++ b/lib/coffeescript/lexer.js @@ -3,20 +3,9 @@ var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVALID_ESCAPE, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, repeat, starts, throwSyntaxError, 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; }; - ({ - Rewriter: Rewriter, - INVERSES: INVERSES - } = require('./rewriter')); - - ({ - count: count, - starts: starts, - compact: compact, - repeat: repeat, - invertLiterate: invertLiterate, - locationDataToString: locationDataToString, - throwSyntaxError: throwSyntaxError - } = require('./helpers')); + ({Rewriter, INVERSES} = require('./rewriter')); + + ({count, starts, compact, repeat, invertLiterate, locationDataToString, throwSyntaxError} = require('./helpers')); exports.Lexer = Lexer = class Lexer { tokenize(code, opts = {}) { @@ -256,7 +245,7 @@ })(); heredoc = quote.length === 3; ({ - tokens: tokens, + tokens, index: end } = this.matchWithInterpolations(regex, quote)); $ = tokens.length - 1; @@ -283,9 +272,7 @@ if (indent) { indentRegex = RegExp(`\\n${indent}`, "g"); } - this.mergeInterpolationTokens(tokens, { - delimiter: delimiter - }, (value, i) => { + this.mergeInterpolationTokens(tokens, {delimiter}, (value, i) => { value = this.formatString(value); if (indentRegex) { value = value.replace(indentRegex, '\n'); @@ -299,9 +286,7 @@ return value; }); } else { - this.mergeInterpolationTokens(tokens, { - delimiter: delimiter - }, (value, i) => { + this.mergeInterpolationTokens(tokens, {delimiter}, (value, i) => { value = this.formatString(value); value = value.replace(SIMPLE_STRING_OMIT, function(match, offset) { if ((i === 0 && offset === 0) || (i === $ && offset + match.length === value.length)) { @@ -358,10 +343,7 @@ }); break; case !(match = this.matchWithInterpolations(HEREGEX, '///')): - ({ - tokens: tokens, - index: index - } = match); + ({tokens, index} = match); break; case !(match = REGEX.exec(this.chunk)): [regex, body, closed] = match; @@ -651,9 +633,7 @@ return this; } stack = []; - ({ - tokens: tokens - } = this); + ({tokens} = this); i = tokens.length; tokens[--i][0] = 'PARAM_END'; while (tok = tokens[--i]) { @@ -692,7 +672,7 @@ [strPart] = regex.exec(str); this.validateEscapes(strPart, { isRegex: delimiter.charAt(0) === '/', - offsetInChunk: offsetInChunk + offsetInChunk }); tokens.push(this.makeToken('NEOSTRING', strPart, offsetInChunk)); str = str.slice(strPart.length); @@ -703,7 +683,7 @@ [line, column] = this.getLineAndColumnFromChunk(offsetInChunk + 1); ({ tokens: nested, - index: index + index } = new Lexer().tokenize(str.slice(1), { line: line, column: column, @@ -738,7 +718,7 @@ lastToken[2].last_column -= 1; } return { - tokens: tokens, + tokens, index: offsetInChunk + delimiter.length }; } @@ -946,8 +926,8 @@ error(message, options = {}) { var first_column, first_line, location, ref, ref1; location = 'first_line' in options ? options : ([first_line, first_column] = this.getLineAndColumnFromChunk((ref = options.offset) != null ? ref : 0), { - first_line: first_line, - first_column: first_column, + first_line, + first_column, last_column: first_column + ((ref1 = options.length) != null ? ref1 : 1) - 1 }); return throwSyntaxError(message, location); diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 05f3efc4cd..c076004cb2 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -6,28 +6,11 @@ Error.stackTraceLimit = 2e308; - ({ - Scope: Scope - } = require('./scope')); - - ({ - isUnassignable: isUnassignable, - JS_FORBIDDEN: JS_FORBIDDEN - } = require('./lexer')); - - ({ - compact: compact, - flatten: flatten, - extend: extend, - merge: merge, - del: del, - starts: starts, - ends: ends, - some: some, - addLocationDataFn: addLocationDataFn, - locationDataToString: locationDataToString, - throwSyntaxError: throwSyntaxError - } = require('./helpers')); + ({Scope} = require('./scope')); + + ({isUnassignable, JS_FORBIDDEN} = require('./lexer')); + + ({compact, flatten, extend, merge, del, starts, ends, some, addLocationDataFn, locationDataToString, throwSyntaxError} = require('./helpers')); exports.extend = extend; @@ -588,9 +571,7 @@ this.expressions = rest; } post = this.compileNode(o); - ({ - scope: scope - } = o); + ({scope} = o); if (scope.expressions === this) { declars = o.scope.hasDeclarations(); assigns = scope.hasAssignments; @@ -1239,10 +1220,7 @@ } this.inCtor = !!method.ctor; if (!(this.inCtor || (this.accessor != null))) { - ({ - name: name, - variable: variable - } = method); + ({name, variable} = method); if (name.shouldCache() || (name instanceof Index && name.index.isAssignable())) { nref = new IdentifierLiteral(o.scope.parent.freeVariable('name')); name.index = new Assign(nref, name.index); @@ -1469,10 +1447,7 @@ compileNode(o) { var compiled, compiledText, from, fromCompiled, to, toStr; - ({ - to: to, - from: from - } = this.range); + ({to, from} = this.range); fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')]; if (to) { compiled = to.compileToFragments(o, LEVEL_PAREN); @@ -1516,7 +1491,7 @@ } compileNode(o) { - var answer, i, idt, indent, j, join, k, key, lastNoncom, len1, len2, node, prop, props, value; + var answer, i, idt, indent, isCompact, j, join, k, key, l, lastNoncom, len1, len2, len3, node, prop, props, ref1, value; props = this.properties; if (this.generated) { for (j = 0, len1 = props.length; j < len1; j++) { @@ -1528,12 +1503,20 @@ } idt = o.indent += TAB; lastNoncom = this.lastNonComment(this.properties); + isCompact = true; + ref1 = this.properties; + for (k = 0, len2 = ref1.length; k < len2; k++) { + prop = ref1[k]; + if (prop instanceof Assign || prop instanceof Comment) { + isCompact = false; + } + } answer = []; - answer.push(this.makeCode(`{${(props.length === 0 ? '}' : '\n')}`)); - for (i = k = 0, len2 = props.length; k < len2; i = ++k) { + answer.push(this.makeCode(`{${(isCompact ? '' : '\n')}`)); + for (i = l = 0, len3 = props.length; l < len3; i = ++l) { prop = props[i]; - join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; - indent = prop instanceof Comment ? '' : idt; + join = i === props.length - 1 ? '' : isCompact ? ', ' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; + indent = isCompact || prop instanceof Comment ? '' : idt; if (prop instanceof Assign) { if (prop.context !== 'object') { prop.operatorToken.error(`unexpected ${prop.operatorToken.value}`); @@ -1552,7 +1535,7 @@ key = new PropertyName(key.value); } prop = new Assign(key, value, 'object'); - } else { + } else if (!(typeof prop.bareLiteral === "function" ? prop.bareLiteral(IdentifierLiteral) : void 0)) { prop = new Assign(prop, prop, 'object'); } } @@ -1564,9 +1547,7 @@ answer.push(this.makeCode(join)); } } - if (props.length !== 0) { - answer.push(this.makeCode(`\n${this.tab}}`)); - } + answer.push(this.makeCode(`${(isCompact ? '' : `\n${this.tab}`)}}`)); if (this.front) { return this.wrapInBraces(answer); } else { @@ -1728,9 +1709,7 @@ } } if (this.variable) { - assign = new Assign(this.variable, new Literal(''), null, { - moduleDeclaration: this.moduleDeclaration - }); + assign = new Assign(this.variable, new Literal(''), null, {moduleDeclaration: this.moduleDeclaration}); return [...assign.compileToFragments(o), ...result]; } else { return result; @@ -1800,17 +1779,13 @@ this.boundMethods = []; executableBody = null; initializer = []; - ({ - expressions: expressions - } = this.body); + ({expressions} = this.body); i = 0; ref1 = expressions.slice(); for (j = 0, len1 = ref1.length; j < len1; j++) { expression = ref1[j]; if (expression instanceof Value && expression.isObject(true)) { - ({ - properties: properties - } = expression.base); + ({properties} = expression.base); exprs = []; end = 0; start = 0; @@ -1899,7 +1874,7 @@ addInitializerMethod(assign) { var method, methodName, variable; ({ - variable: variable, + variable, value: method } = assign); method.isMethod = true; @@ -2337,12 +2312,7 @@ this.variable = variable1; this.value = value1; this.context = context1; - ({ - param: this.param, - subpattern: this.subpattern, - operatorToken: this.operatorToken, - moduleDeclaration: this.moduleDeclaration - } = options); + ({param: this.param, subpattern: this.subpattern, operatorToken: this.operatorToken, moduleDeclaration: this.moduleDeclaration} = options); } isStatement(o) { @@ -2438,12 +2408,8 @@ compilePatternMatch(o) { var acc, assigns, code, defaultValue, expandedIdx, fragments, i, idx, isObject, ivar, j, len1, message, name, obj, objects, olen, ref, rest, top, val, value, vvar, vvarText; top = o.level === LEVEL_TOP; - ({ - value: value - } = this); - ({ - objects: objects - } = this.variable.base); + ({value} = this); + ({objects} = this.variable.base); if (!(olen = objects.length)) { code = value.compileToFragments(o); if (o.level >= LEVEL_OP) { @@ -2613,11 +2579,7 @@ compileSplice(o) { var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef; ({ - range: { - from: from, - to: to, - exclusive: exclusive - } + range: {from, to, exclusive} } = this.variable.properties.pop()); name = this.variable.compile(o); if (from) { @@ -3150,9 +3112,7 @@ jumps() { var expressions, j, jumpNode, len1, node; - ({ - expressions: expressions - } = this.body); + ({expressions} = this.body); if (!expressions.length) { return false; } @@ -3171,9 +3131,7 @@ var answer, body, rvar, set; o.indent += TAB; set = ''; - ({ - body: body - } = this); + ({body} = this); if (body.isEmpty()) { body = this.makeCode(''); } else { @@ -3772,13 +3730,7 @@ constructor(body, source) { var ref1, ref2; super(); - ({ - source: this.source, - guard: this.guard, - step: this.step, - name: this.name, - index: this.index - } = source); + ({source: this.source, guard: this.guard, step: this.step, name: this.name, index: this.index} = source); this.body = Block.wrap([body]); this.own = !!source.own; this.object = !!source.object; @@ -3857,7 +3809,7 @@ if (this.range) { forPartFragments = source.compileToFragments(merge(o, { index: ivar, - name: name, + name, step: this.step, shouldCache: shouldCacheOrIsAssignable })); @@ -4063,9 +4015,7 @@ this.condition = options.type === 'unless' ? condition.invert() : condition; this.elseBody = null; this.isChain = false; - ({ - soak: this.soak - } = options); + ({soak: this.soak} = options); } bodyNode() { @@ -4135,9 +4085,7 @@ } indent = o.indent + TAB; cond = this.condition.compileToFragments(o, LEVEL_PAREN); - body = this.ensureBlock(this.body).compileToFragments(merge(o, { - indent: indent - })); + body = this.ensureBlock(this.body).compileToFragments(merge(o, {indent})); ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode(`\n${this.tab}}`)); if (!child) { ifPart.unshift(this.makeCode(this.tab)); @@ -4150,9 +4098,7 @@ 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}}`)); + answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {indent}), LEVEL_TOP), this.makeCode(`\n${this.tab}}`)); } return answer; } @@ -4221,9 +4167,7 @@ utility = function(name, o) { var ref, root; - ({ - root: root - } = o.scope); + ({root} = o.scope); if (name in root.utilities) { return root.utilities[name]; } else { diff --git a/lib/coffeescript/optparse.js b/lib/coffeescript/optparse.js index fb4998c4a6..dbd707953f 100644 --- a/lib/coffeescript/optparse.js +++ b/lib/coffeescript/optparse.js @@ -2,9 +2,7 @@ (function() { var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat; - ({ - repeat: repeat - } = require('./helpers')); + ({repeat} = require('./helpers')); exports.OptionParser = OptionParser = class OptionParser { constructor(rules, banner) { diff --git a/lib/coffeescript/register.js b/lib/coffeescript/register.js index 7b0a2f9930..bc759db22a 100644 --- a/lib/coffeescript/register.js +++ b/lib/coffeescript/register.js @@ -48,9 +48,7 @@ } if (child_process) { - ({ - fork: fork - } = child_process); + ({fork} = child_process); binary = require.resolve('../../bin/coffee'); child_process.fork = function(path, args, options) { if (helpers.isCoffee(path)) { diff --git a/lib/coffeescript/repl.js b/lib/coffeescript/repl.js index dfbbdaeff9..0c299bedf0 100644 --- a/lib/coffeescript/repl.js +++ b/lib/coffeescript/repl.js @@ -12,10 +12,7 @@ CoffeeScript = require('./coffeescript'); - ({ - merge: merge, - updateSyntaxError: updateSyntaxError - } = require('./helpers')); + ({merge, updateSyntaxError} = require('./helpers')); replDefaults = { prompt: 'coffee> ', @@ -26,12 +23,7 @@ input = input.replace(/\uFF00/g, '\n'); input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1'); input = input.replace(/^\s*try\s*{([\s\S]*)}\s*catch.*$/m, '$1'); - ({ - Block: Block, - Assign: Assign, - Value: Value, - Literal: Literal - } = require('./nodes')); + ({Block, Assign, Value, Literal} = require('./nodes')); try { tokens = CoffeeScript.tokens(input); referencedVars = (function() { @@ -50,7 +42,7 @@ js = ast.compile({ bare: true, locals: Object.keys(context), - referencedVars: referencedVars + referencedVars }); return cb(null, runInContext(js, context, filename)); } catch (error) { @@ -71,11 +63,7 @@ addMultilineHandler = function(repl) { var inputStream, multiline, nodeLineListener, origPrompt, outputStream, ref, rli; - ({ - rli: rli, - inputStream: inputStream, - outputStream: outputStream - } = repl); + ({rli, inputStream, outputStream} = repl); origPrompt = (ref = repl._prompt) != null ? ref : repl.prompt; multiline = { enabled: false, diff --git a/lib/coffeescript/rewriter.js b/lib/coffeescript/rewriter.js index f629ece855..938da10920 100644 --- a/lib/coffeescript/rewriter.js +++ b/lib/coffeescript/rewriter.js @@ -30,9 +30,7 @@ scanTokens(block) { var i, token, tokens; - ({ - tokens: tokens - } = this); + ({tokens} = this); i = 0; while (token = tokens[i]) { i += block.call(this, token, i, tokens); @@ -42,9 +40,7 @@ detectEnd(i, condition, action) { var levels, ref, ref1, token, tokens; - ({ - tokens: tokens - } = this); + ({tokens} = this); levels = 0; while (token = tokens[i]) { if (levels === 0 && condition.call(this, token, i)) { @@ -320,12 +316,7 @@ newLine = prevTag === 'OUTDENT' || prevToken.newLine; if (indexOf.call(IMPLICIT_END, tag) >= 0 || indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) { while (inImplicit()) { - [ - stackTag, stackIdx, { - sameLine: sameLine, - startsLine: startsLine - } - ] = stackTop(); + [stackTag, stackIdx, {sameLine, startsLine}] = stackTop(); if (inImplicitCall() && prevTag !== ',') { endImplicitCall(); } else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':') { diff --git a/lib/coffeescript/scope.js b/lib/coffeescript/scope.js index c8e823ca31..87a4938443 100644 --- a/lib/coffeescript/scope.js +++ b/lib/coffeescript/scope.js @@ -30,10 +30,7 @@ if (Object.prototype.hasOwnProperty.call(this.positions, name)) { return this.variables[this.positions[name]].type = type; } else { - return this.positions[name] = this.variables.push({ - name: name, - type: type - }) - 1; + return this.positions[name] = this.variables.push({name, type}) - 1; } } @@ -110,7 +107,7 @@ assign(name, value) { this.add(name, { - value: value, + value, assigned: true }, true); return this.hasAssignments = true; diff --git a/lib/coffeescript/sourcemap.js b/lib/coffeescript/sourcemap.js index 98c898d56f..659fb5cd20 100644 --- a/lib/coffeescript/sourcemap.js +++ b/lib/coffeescript/sourcemap.js @@ -19,9 +19,9 @@ } return this.columns[column] = { line: this.line, - column: column, - sourceLine: sourceLine, - sourceColumn: sourceColumn + column, + sourceLine, + sourceColumn }; } diff --git a/src/nodes.coffee b/src/nodes.coffee index 4c5ab47584..5f55de8d69 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1128,16 +1128,22 @@ exports.Obj = class Obj extends Base node.error 'cannot have an implicit value in an implicit object' idt = o.indent += TAB lastNoncom = @lastNonComment @properties + + isCompact = true + isCompact = false for prop in @properties when prop instanceof Assign or prop instanceof Comment + answer = [] - answer.push @makeCode "{#{if props.length is 0 then '}' else '\n'}" + answer.push @makeCode "{#{if isCompact then '' else '\n'}" for prop, i in props join = if i is props.length - 1 '' + else if isCompact + ', ' else if prop is lastNoncom or prop instanceof Comment '\n' else ',\n' - indent = if prop instanceof Comment then '' else idt + indent = if isCompact or prop instanceof Comment then '' else idt if prop instanceof Assign if prop.context isnt 'object' prop.operatorToken.error "unexpected #{prop.operatorToken.value}" @@ -1150,12 +1156,12 @@ exports.Obj = class Obj extends Base [key, value] = prop.base.cache o key = new PropertyName key.value if key instanceof IdentifierLiteral prop = new Assign key, value, 'object' - else + else if not prop.bareLiteral?(IdentifierLiteral) prop = new Assign prop, prop, 'object' if indent then answer.push @makeCode indent answer.push prop.compileToFragments(o, LEVEL_TOP)... if join then answer.push @makeCode join - answer.push @makeCode "\n#{@tab}}" unless props.length is 0 + answer.push @makeCode "#{if isCompact then '' else "\n#{@tab}"}}" if @front then @wrapInBraces answer else answer assigns: (name) ->