mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
[CS2] Destructuring (#4478)
* Output simple array destructuring assignments to ES2015 * Output simple object destructured assignments to ES2015 * Compile shorthand object properties to ES2015 shorthand properties This dramatically improves the appearance of destructured imports. * Compile default values in destructured assignment to ES2015 * Rename `wrapInBraces` to `wrapInParentheses`, and `compilePatternMatch` to `compileDestructuring`, for clarity; style improvements (no `==` or `!=`, etc.) * Don’t confuse the syntax highlighter * Comment Assign::compilePatternMatch a bit * Assignment expressions in conditionals are a bad practice * Optional check for existence that only checks `!== undefined`, not `!= null`, to follow ES convention that default values only apply when a variable is undefined, not falsy * Add comments; remove unnecessary array splats in function tests * The fallback destructuring code should apply default values only if `undefined`, not falsy, to follow ES spec * Support destructuring in function parameters (first pass); catch destructured reserved words * Destructured variables in function parameter lists shouldn’t be added to the function body with `var` declarations; treat splat array function parameters the legacy way to avoid rethinking #4005 * Remove redundancy in undefined-only check for existence; fix passing option to check * Fix undefined redundancy * Simplify getting the variable name * Reimplement “check for existence if not undefined” without creating a new operator * `Obj::isAssignable` should not mutate; pass `lhs` property in from `Assign` or `Code` to child arrays and objects so that those child nodes are set as allowable for destructuring * Revert changes to tests * Restore revised test for empty destructuring assignment
This commit is contained in:
parent
5e1d978946
commit
b192e215a5
17 changed files with 953 additions and 646 deletions
|
@ -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) {
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
scanTokens(block) {
|
||||
var i, token, tokens;
|
||||
tokens = this.tokens;
|
||||
({tokens} = this);
|
||||
i = 0;
|
||||
while (token = tokens[i]) {
|
||||
i += block.call(this, token, i, tokens);
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
detectEnd(i, condition, action) {
|
||||
var levels, ref, ref1, token, tokens;
|
||||
tokens = this.tokens;
|
||||
({tokens} = this);
|
||||
levels = 0;
|
||||
while (token = tokens[i]) {
|
||||
if (levels === 0 && condition.call(this, token, i)) {
|
||||
|
@ -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, 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);
|
||||
[stackTag, stackIdx, {sameLine, startsLine}] = stackTop();
|
||||
if (inImplicitCall() && prevTag !== ',') {
|
||||
endImplicitCall();
|
||||
} else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':') {
|
||||
|
@ -351,9 +351,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;
|
||||
}
|
||||
|
@ -395,8 +401,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 +424,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 +444,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 +498,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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue