1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

[CS2] CSX spread attributes: <div {props…} /> (#4607)

* CSX spread attributes: <div {props...} />

* whitespace cleanup

* Style

* valid CSX attributes

* added comments; cleanup

* Fixed allowed CSX properties.

* Cleanup

* Typo

* Improved RegEx

* Reworked CSX attributes

* small fix for CSX attribute validation

* cleanup

* tests

* fix nested assignement; remove unused variable

* cleanup; improve tests

* fix esoteric case; improve tracking nested splats in CSX tag
This commit is contained in:
zdenko 2017-08-03 06:00:39 +02:00 committed by Geoffrey Booth
parent a118ec7cc9
commit cbf035fca9
7 changed files with 351 additions and 420 deletions

View file

@ -52,6 +52,7 @@
this.importSpecifierList = false; // Used to identify when in an `IMPORT {...} FROM? ...`. this.importSpecifierList = false; // Used to identify when in an `IMPORT {...} FROM? ...`.
this.exportSpecifierList = false; // Used to identify when in an `EXPORT {...} FROM? ...`. this.exportSpecifierList = false; // Used to identify when in an `EXPORT {...} FROM? ...`.
this.csxDepth = 0; // Used to optimize CSX checks, how deep in CSX we are. this.csxDepth = 0; // Used to optimize CSX checks, how deep in CSX we are.
this.csxObjAttribute = {}; // Used to detect if CSX attributes is wrapped in {} (<div {props...} />).
this.chunkLine = opts.line || 0; // The start line for the current @chunk. this.chunkLine = opts.line || 0; // The start line for the current @chunk.
this.chunkColumn = opts.column || 0; // The start column of the current @chunk. this.chunkColumn = opts.column || 0; // The start column of the current @chunk.
code = this.clean(code); // The stripped, cleaned original source code. code = this.clean(code); // The stripped, cleaned original source code.
@ -730,8 +731,10 @@
// CSX is like JSX but for CoffeeScript. // CSX is like JSX but for CoffeeScript.
csxToken() { csxToken() {
var afterTag, colon, csxTag, end, firstChar, id, input, match, origin, prev, ref, token, tokens; var afterTag, colon, csxTag, end, firstChar, id, input, match, origin, prev, prevChar, ref, token, tokens;
firstChar = this.chunk[0]; firstChar = this.chunk[0];
// Check the previous token to detect if attribute is spread.
prevChar = this.tokens.length > 0 ? this.tokens[this.tokens.length - 1][0] : '';
if (firstChar === '<') { if (firstChar === '<') {
match = CSX_IDENTIFIER.exec(this.chunk.slice(1)); match = CSX_IDENTIFIER.exec(this.chunk.slice(1));
// Not the right hand side of an unspaced comparison (i.e. `a<b`). // Not the right hand side of an unspaced comparison (i.e. `a<b`).
@ -741,7 +744,7 @@
[input, id, colon] = match; [input, id, colon] = match;
origin = this.token('CSX_TAG', id, 1, id.length); origin = this.token('CSX_TAG', id, 1, id.length);
this.token('CALL_START', '('); this.token('CALL_START', '(');
this.token('{', '{'); this.token('[', '[');
this.ends.push({ this.ends.push({
tag: '/>', tag: '/>',
origin: origin, origin: origin,
@ -752,12 +755,18 @@
} else if (csxTag = this.atCSXTag()) { } else if (csxTag = this.atCSXTag()) {
if (this.chunk.slice(0, 2) === '/>') { if (this.chunk.slice(0, 2) === '/>') {
this.pair('/>'); this.pair('/>');
this.token('}', '}', 0, 2); this.token(']', ']', 0, 2);
this.token('CALL_END', ')', 0, 2); this.token('CALL_END', ')', 0, 2);
this.csxDepth--; this.csxDepth--;
return 2; return 2;
} else if (firstChar === '{') { } else if (firstChar === '{') {
token = this.token('(', '('); if (prevChar === ':') {
token = this.token('(', '(');
this.csxObjAttribute[this.csxDepth] = false;
} else {
token = this.token('{', '{');
this.csxObjAttribute[this.csxDepth] = true;
}
this.ends.push({ this.ends.push({
tag: '}', tag: '}',
origin: token origin: token
@ -766,7 +775,7 @@
} else if (firstChar === '>') { } else if (firstChar === '>') {
// Ignore terminators inside a tag. // Ignore terminators inside a tag.
this.pair('/>'); // As if the current tag was self-closing. this.pair('/>'); // As if the current tag was self-closing.
origin = this.token('}', '}'); origin = this.token(']', ']');
this.token(',', ','); this.token(',', ',');
({ ({
tokens, tokens,
@ -800,7 +809,12 @@
} else if (this.atCSXTag(1)) { } else if (this.atCSXTag(1)) {
if (firstChar === '}') { if (firstChar === '}') {
this.pair(firstChar); this.pair(firstChar);
this.token(')', ')'); if (this.csxObjAttribute[this.csxDepth]) {
this.token('}', '}');
this.csxObjAttribute[this.csxDepth] = false;
} else {
this.token(')', ')');
}
this.token(',', ','); this.token(',', ',');
return 1; return 1;
} else { } else {

View file

@ -1670,7 +1670,7 @@
} }
compileCSX(o) { compileCSX(o) {
var attributes, content, fragments, tag; var attr, attrProps, attributes, content, fragments, j, len1, obj, ref1, tag;
[attributes, content] = this.args; [attributes, content] = this.args;
attributes.base.csx = true; attributes.base.csx = true;
if (content != null) { if (content != null) {
@ -1678,7 +1678,23 @@
} }
fragments = [this.makeCode('<')]; fragments = [this.makeCode('<')];
fragments.push(...(tag = this.variable.compileToFragments(o, LEVEL_ACCESS))); fragments.push(...(tag = this.variable.compileToFragments(o, LEVEL_ACCESS)));
fragments.push(...attributes.compileToFragments(o, LEVEL_PAREN)); if (attributes.base instanceof Arr) {
ref1 = attributes.base.objects;
for (j = 0, len1 = ref1.length; j < len1; j++) {
obj = ref1[j];
attr = obj.base;
attrProps = (attr != null ? attr.properties : void 0) || [];
// Catch invalid CSX attributes: <div {a:"b", props} {props} "value" />
if (!(attr instanceof Obj || attr instanceof IdentifierLiteral) || (attr instanceof Obj && !attr.generated && (attrProps.length > 1 || !(attrProps[0] instanceof Splat)))) {
obj.error("Unexpected token. Allowed CSX attributes are: id=\"val\", src={source}, {props...} or attribute.");
}
if (obj.base instanceof Obj) {
obj.base.csx = true;
}
fragments.push(this.makeCode(' '));
fragments.push(...obj.compileToFragments(o, LEVEL_PAREN));
}
}
if (content) { if (content) {
fragments.push(this.makeCode('>')); fragments.push(this.makeCode('>'));
fragments.push(...content.compileNode(o, LEVEL_LIST)); fragments.push(...content.compileNode(o, LEVEL_LIST));
@ -2109,12 +2125,16 @@
} }
} }
} }
if (this.hasSplat()) { if (this.hasSplat() && !this.csx) {
// Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md // Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md
return this.compileSpread(o); return this.compileSpread(o);
} }
idt = o.indent += TAB; idt = o.indent += TAB;
lastNode = this.lastNode(this.properties); lastNode = this.lastNode(this.properties);
if (this.csx) {
// CSX attributes <div id="val" attr={aaa} {props...} />
return this.compileCSXAttributes(o);
}
// If this object is the left-hand side of an assignment, all its children // If this object is the left-hand side of an assignment, all its children
// are too. // are too.
if (this.lhs) { if (this.lhs) {
@ -2136,7 +2156,7 @@
ref1 = this.properties; ref1 = this.properties;
for (l = 0, len3 = ref1.length; l < len3; l++) { for (l = 0, len3 = ref1.length; l < len3; l++) {
prop = ref1[l]; prop = ref1[l];
if (prop instanceof Assign && prop.context === 'object' && !this.csx) { if (prop instanceof Assign && prop.context === 'object') {
isCompact = false; isCompact = false;
} }
} }
@ -2144,7 +2164,7 @@
answer.push(this.makeCode(isCompact ? '' : '\n')); answer.push(this.makeCode(isCompact ? '' : '\n'));
for (i = q = 0, len4 = props.length; q < len4; i = ++q) { for (i = q = 0, len4 = props.length; q < len4; i = ++q) {
prop = props[i]; prop = props[i];
join = i === props.length - 1 ? '' : isCompact && this.csx ? ' ' : isCompact ? ', ' : prop === lastNode || this.csx ? '\n' : ',\n'; join = i === props.length - 1 ? '' : isCompact ? ', ' : prop === lastNode ? '\n' : ',\n';
indent = isCompact ? '' : idt; indent = isCompact ? '' : idt;
key = prop instanceof Assign && prop.context === 'object' ? prop.variable : prop instanceof Assign ? (!this.lhs ? prop.operatorToken.error(`unexpected ${prop.operatorToken.value}`) : void 0, prop.variable) : prop; key = prop instanceof Assign && prop.context === 'object' ? prop.variable : prop instanceof Assign ? (!this.lhs ? prop.operatorToken.error(`unexpected ${prop.operatorToken.value}`) : void 0, prop.variable) : prop;
if (key instanceof Value && key.hasProperties()) { if (key instanceof Value && key.hasProperties()) {
@ -2168,21 +2188,13 @@
if (indent) { if (indent) {
answer.push(this.makeCode(indent)); answer.push(this.makeCode(indent));
} }
if (this.csx) {
prop.csx = true;
}
if (this.csx && i === 0) {
answer.push(this.makeCode(' '));
}
answer.push(...prop.compileToFragments(o, LEVEL_TOP)); answer.push(...prop.compileToFragments(o, LEVEL_TOP));
if (join) { if (join) {
answer.push(this.makeCode(join)); answer.push(this.makeCode(join));
} }
} }
answer.push(this.makeCode(isCompact ? '' : `\n${this.tab}`)); answer.push(this.makeCode(isCompact ? '' : `\n${this.tab}`));
if (!this.csx) { answer = this.wrapInBraces(answer);
answer = this.wrapInBraces(answer);
}
if (this.front) { if (this.front) {
return this.wrapInParentheses(answer); return this.wrapInParentheses(answer);
} else { } else {
@ -2256,6 +2268,27 @@
return (new Call(new Literal('Object.assign'), slices)).compileToFragments(o); return (new Call(new Literal('Object.assign'), slices)).compileToFragments(o);
} }
compileCSXAttributes(o) {
var answer, i, j, join, len1, prop, props;
props = this.properties;
answer = [];
for (i = j = 0, len1 = props.length; j < len1; i = ++j) {
prop = props[i];
prop.csx = true;
join = i === props.length - 1 ? '' : ' ';
if (prop instanceof Splat) {
prop = new Literal(`{${prop.compile(o)}}`);
}
answer.push(...prop.compileToFragments(o, LEVEL_TOP));
answer.push(this.makeCode(join));
}
if (this.front) {
return this.wrapInParentheses(answer);
} else {
return answer;
}
}
}; };
Obj.prototype.children = ['properties']; Obj.prototype.children = ['properties'];

View file

@ -105,16 +105,13 @@ case 12:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.StatementLiteral($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.StatementLiteral($$[$0]));
break; break;
case 27: case 27:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Op($$[$0], this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Op($$[$0], new yy.Value(new yy.Literal(''))));
new yy.Value(new yy.Literal(''))));
break; break;
case 28: case 271: case 272: case 275: case 28: case 271: case 272: case 275:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0]));
$$[$0]));
break; break;
case 29: case 29:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-2].concat($$[$0-1]), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-2].concat($$[$0-1]), $$[$0]));
$$[$0]));
break; break;
case 30: case 30:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Block); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Block);
@ -165,49 +162,34 @@ case 48:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.NaNLiteral($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.NaNLiteral($$[$0]));
break; break;
case 49: case 49:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0]));
$$[$0]));
break; break;
case 50: case 50:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Assign($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0]));
$$[$0]));
break; break;
case 51: case 51:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign($$[$0-4], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1]));
$$[$0-1]));
break; break;
case 52: case 108: case 112: case 113: case 115: case 116: case 117: case 118: case 120: case 244: case 245: case 52: case 108: case 112: case 113: case 115: case 116: case 117: case 118: case 120: case 244: case 245:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Value($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Value($$[$0]));
break; break;
case 54: case 54:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object', {
$$[$0],
'object',
{
operatorToken: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1])) operatorToken: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1]))
})); }));
break; break;
case 55: case 55:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-4])(new yy.Value($$[$0-4])), this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object', {
$$[$0-1],
'object',
{
operatorToken: yy.addDataToNode(yy, _$[$0-3])(new yy.Literal($$[$0-3])) operatorToken: yy.addDataToNode(yy, _$[$0-3])(new yy.Literal($$[$0-3]))
})); }));
break; break;
case 56: case 56:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), $$[$0], null, {
$$[$0],
null,
{
operatorToken: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1])) operatorToken: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1]))
})); }));
break; break;
case 57: case 57:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-4])(new yy.Value($$[$0-4])), this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], null, {
$$[$0-1],
null,
{
operatorToken: yy.addDataToNode(yy, _$[$0-3])(new yy.Literal($$[$0-3])) operatorToken: yy.addDataToNode(yy, _$[$0-3])(new yy.Literal($$[$0-3]))
})); }));
break; break;
@ -224,18 +206,13 @@ case 66: case 107:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Splat($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Splat($$[$0]));
break; break;
case 72: case 72:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.SuperCall(yy.addDataToNode(yy, _$[$0-1])(new yy.Super), this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.SuperCall(yy.addDataToNode(yy, _$[$0-1])(new yy.Super), $$[$0], false, $$[$0-1]));
$$[$0],
false,
$$[$0-1]));
break; break;
case 73: case 73:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Call(new yy.Value($$[$0-1]), this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Call(new yy.Value($$[$0-1]), $$[$0]));
$$[$0]));
break; break;
case 74: case 74:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Call($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Call($$[$0-1], $$[$0]));
$$[$0]));
break; break;
case 75: case 76: case 75: case 76:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])((new yy.Value($$[$0-1])).add($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])((new yy.Value($$[$0-1])).add($$[$0]));
@ -265,14 +242,10 @@ case 85:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.AwaitReturn); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.AwaitReturn);
break; break;
case 86: case 86:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Code($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 87: case 87:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Code([], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 88: case 89: case 88: case 89:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.FuncGlyph($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.FuncGlyph($$[$0]));
@ -296,18 +269,13 @@ case 97:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Param($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Param($$[$0]));
break; break;
case 98: case 98:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Param($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true));
null,
true));
break; break;
case 99: case 99:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Param($$[$0], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Param($$[$0], null, true));
null,
true));
break; break;
case 100: case 100:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Param($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0]));
$$[$0]));
break; break;
case 101: case 210: case 101: case 210:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Expansion); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Expansion);
@ -316,36 +284,25 @@ case 109:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].add($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].add($$[$0]));
break; break;
case 121: case 121:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Super(yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0])), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Super(yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0])), [], false, $$[$0-2]));
[],
false,
$$[$0-2]));
break; break;
case 122: case 122:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Super(yy.addDataToNode(yy, _$[$0-1])(new yy.Index($$[$0-1])), this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Super(yy.addDataToNode(yy, _$[$0-1])(new yy.Index($$[$0-1])), [], false, $$[$0-3]));
[],
false,
$$[$0-3]));
break; break;
case 124: case 124:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Access($$[$0], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Access($$[$0], 'soak'));
'soak'));
break; break;
case 125: case 125:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Access(new yy.PropertyName('prototype'))), this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Access(new yy.PropertyName('prototype'))), yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))]);
yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))]);
break; break;
case 126: case 126:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Access(new yy.PropertyName('prototype'), this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Access(new yy.PropertyName('prototype'), 'soak')), yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))]);
'soak')),
yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))]);
break; break;
case 127: case 127:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Access(new yy.PropertyName('prototype'))); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Access(new yy.PropertyName('prototype')));
break; break;
case 130: case 130:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(yy.extend($$[$0], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(yy.extend($$[$0], {
{
soak: true soak: true
})); }));
break; break;
@ -356,76 +313,52 @@ case 132:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Slice($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Slice($$[$0]));
break; break;
case 133: case 133:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Obj($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated));
$$[$0-3].generated));
break; break;
case 139: case 139:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Class); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Class);
break; break;
case 140: case 140:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Class(null, this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0]));
null,
$$[$0]));
break; break;
case 141: case 141:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Class(null, this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Class(null, $$[$0]));
$$[$0]));
break; break;
case 142: case 142:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Class(null, this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0]));
$$[$0-1],
$$[$0]));
break; break;
case 143: case 143:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Class($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Class($$[$0]));
break; break;
case 144: case 144:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Class($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0]));
null,
$$[$0]));
break; break;
case 145: case 145:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Class($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0]));
$$[$0]));
break; break;
case 146: case 146:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Class($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0]));
$$[$0-1],
$$[$0]));
break; break;
case 147: case 147:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.ImportDeclaration(null, this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.ImportDeclaration(null, $$[$0]));
$$[$0]));
break; break;
case 148: case 148:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-2], null), $$[$0]));
null),
$$[$0]));
break; break;
case 149: case 149:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, $$[$0-2]), $$[$0]));
$$[$0-2]),
$$[$0]));
break; break;
case 150: case 150:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, new yy.ImportSpecifierList([])), $$[$0]));
new yy.ImportSpecifierList([])),
$$[$0]));
break; break;
case 151: case 151:
this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, new yy.ImportSpecifierList($$[$0-4])), $$[$0]));
new yy.ImportSpecifierList($$[$0-4])),
$$[$0]));
break; break;
case 152: case 152:
this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-4], this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-4], $$[$0-2]), $$[$0]));
$$[$0-2]),
$$[$0]));
break; break;
case 153: case 153:
this.$ = yy.addDataToNode(yy, _$[$0-8], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-7], this.$ = yy.addDataToNode(yy, _$[$0-8], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-7], new yy.ImportSpecifierList($$[$0-4])), $$[$0]));
new yy.ImportSpecifierList($$[$0-4])),
$$[$0]));
break; break;
case 157: case 177: case 190: case 206: case 157: case 177: case 190: case 206:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])($$[$0-2]); this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])($$[$0-2]);
@ -434,22 +367,19 @@ case 159:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportSpecifier($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportSpecifier($$[$0]));
break; break;
case 160: case 160:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportSpecifier($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportSpecifier($$[$0-2], $$[$0]));
$$[$0]));
break; break;
case 161: case 161:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportSpecifier(new yy.Literal($$[$0]))); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportSpecifier(new yy.Literal($$[$0])));
break; break;
case 162: case 162:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportSpecifier(new yy.Literal($$[$0-2]), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportSpecifier(new yy.Literal($$[$0-2]), $$[$0]));
$$[$0]));
break; break;
case 163: case 163:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportDefaultSpecifier($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportDefaultSpecifier($$[$0]));
break; break;
case 164: case 164:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportNamespaceSpecifier(new yy.Literal($$[$0-2]), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportNamespaceSpecifier(new yy.Literal($$[$0-2]), $$[$0]));
$$[$0]));
break; break;
case 165: case 165:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList([]))); this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList([])));
@ -461,26 +391,17 @@ case 167:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.ExportNamedDeclaration($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.ExportNamedDeclaration($$[$0]));
break; break;
case 168: case 168:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-2], $$[$0], null, {
$$[$0],
null,
{
moduleDeclaration: 'export' moduleDeclaration: 'export'
}))); })));
break; break;
case 169: case 169:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-3], $$[$0], null, {
$$[$0],
null,
{
moduleDeclaration: 'export' moduleDeclaration: 'export'
}))); })));
break; break;
case 170: case 170:
this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-4], this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-4], $$[$0-1], null, {
$$[$0-1],
null,
{
moduleDeclaration: 'export' moduleDeclaration: 'export'
}))); })));
break; break;
@ -488,46 +409,34 @@ case 171:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportDefaultDeclaration($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportDefaultDeclaration($$[$0]));
break; break;
case 172: case 172:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ExportAllDeclaration(new yy.Literal($$[$0-2]), this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ExportAllDeclaration(new yy.Literal($$[$0-2]), $$[$0]));
$$[$0]));
break; break;
case 173: case 173:
this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList($$[$0-4]), this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList($$[$0-4]), $$[$0]));
$$[$0]));
break; break;
case 179: case 179:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ExportSpecifier($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ExportSpecifier($$[$0]));
break; break;
case 180: case 180:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier($$[$0-2], $$[$0]));
$$[$0]));
break; break;
case 181: case 181:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier($$[$0-2], new yy.Literal($$[$0])));
new yy.Literal($$[$0])));
break; break;
case 182: case 182:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ExportSpecifier(new yy.Literal($$[$0]))); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ExportSpecifier(new yy.Literal($$[$0])));
break; break;
case 183: case 183:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier(new yy.Literal($$[$0-2]), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier(new yy.Literal($$[$0-2]), $$[$0]));
$$[$0]));
break; break;
case 184: case 184:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.TaggedTemplateCall($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.TaggedTemplateCall($$[$0-2], $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 185: case 185:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Call($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 186: case 186:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.SuperCall(yy.addDataToNode(yy, _$[$0-2])(new yy.Super), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.SuperCall(yy.addDataToNode(yy, _$[$0-2])(new yy.Super), $$[$0], $$[$0-1], $$[$0-2]));
$$[$0],
$$[$0-1],
$$[$0-2]));
break; break;
case 187: case 187:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(false); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(false);
@ -542,9 +451,7 @@ case 191: case 192:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Value(new yy.ThisLiteral($$[$0]))); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Value(new yy.ThisLiteral($$[$0])));
break; break;
case 193: case 193:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Value(yy.addDataToNode(yy, _$[$0-1])(new yy.ThisLiteral($$[$0-1])), this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Value(yy.addDataToNode(yy, _$[$0-1])(new yy.ThisLiteral($$[$0-1])), [yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))], 'this'));
[yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))],
'this'));
break; break;
case 194: case 194:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Arr([])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Arr([]));
@ -559,65 +466,43 @@ case 197:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])('exclusive'); this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])('exclusive');
break; break;
case 198: case 198:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Range($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]));
$$[$0-1],
$$[$0-2]));
break; break;
case 199: case 199:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Range($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 200: case 200:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Range($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0]));
null,
$$[$0]));
break; break;
case 201: case 201:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Range(null, this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 202: case 202:
this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Range(null, this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Range(null, null, $$[$0]));
null,
$$[$0]));
break; break;
case 212: case 212:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([].concat($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0]));
$$[$0]));
break; break;
case 213: case 213:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Try($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Try($$[$0]));
break; break;
case 214: case 214:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Try($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]));
$$[$0][0],
$$[$0][1]));
break; break;
case 215: case 215:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Try($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0]));
null,
null,
$$[$0]));
break; break;
case 216: case 216:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Try($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]));
$$[$0-2][0],
$$[$0-2][1],
$$[$0]));
break; break;
case 217: case 217:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([$$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([$$[$0-1], $$[$0]]);
$$[$0]]);
break; break;
case 218: case 218:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Value($$[$0-1])), this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Value($$[$0-1])), $$[$0]]);
$$[$0]]);
break; break;
case 219: case 219:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([null, this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([null, $$[$0]]);
$$[$0]]);
break; break;
case 220: case 220:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Throw($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Throw($$[$0]));
@ -635,20 +520,17 @@ case 224:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While($$[$0]));
break; break;
case 225: case 225:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.While($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.While($$[$0-2], {
{
guard: $$[$0] guard: $$[$0]
})); }));
break; break;
case 226: case 226:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While($$[$0], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While($$[$0], {
{
invert: true invert: true
})); }));
break; break;
case 227: case 227:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.While($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.While($$[$0-2], {
{
invert: true, invert: true,
guard: $$[$0] guard: $$[$0]
})); }));
@ -669,12 +551,10 @@ case 233:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While(yy.addDataToNode(yy, _$[$0-1])(new yy.BooleanLiteral('true'))).addBody(yy.addDataToNode(yy, _$[$0])(yy.Block.wrap([$$[$0]])))); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While(yy.addDataToNode(yy, _$[$0-1])(new yy.BooleanLiteral('true'))).addBody(yy.addDataToNode(yy, _$[$0])(yy.Block.wrap([$$[$0]]))));
break; break;
case 234: case 235: case 234: case 235:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.For($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
$$[$0]));
break; break;
case 236: case 236:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.For($$[$0], this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1]));
$$[$0-1]));
break; break;
case 237: case 237:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({ this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({
@ -707,8 +587,7 @@ this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])((function () {
}())); }()));
break; break;
case 247: case 247:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([$$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([$$[$0-2], $$[$0]]);
$$[$0]]);
break; break;
case 248: case 248:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({ this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({
@ -768,45 +647,33 @@ this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])({
}); });
break; break;
case 257: case 257:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Switch($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1]));
$$[$0-1]));
break; break;
case 258: case 258:
this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.Switch($$[$0-5], this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]));
$$[$0-3],
$$[$0-1]));
break; break;
case 259: case 259:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Switch(null, this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1]));
$$[$0-1]));
break; break;
case 260: case 260:
this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.Switch(null, this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1]));
$$[$0-3],
$$[$0-1]));
break; break;
case 262: case 262:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].concat($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].concat($$[$0]));
break; break;
case 263: case 263:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([[$$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]);
$$[$0]]]);
break; break;
case 264: case 264:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])([[$$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]);
$$[$0-1]]]);
break; break;
case 265: case 265:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], {
$$[$0],
{
type: $$[$0-2] type: $$[$0-2]
})); }));
break; break;
case 266: case 266:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])($$[$0-4].addElse(yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])($$[$0-4].addElse(yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], {
$$[$0],
{
type: $$[$0-2] type: $$[$0-2]
})))); }))));
break; break;
@ -814,86 +681,58 @@ case 268:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])($$[$0-2].addElse($$[$0])); this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])($$[$0-2].addElse($$[$0]));
break; break;
case 269: case 270: case 269: case 270:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0], yy.addDataToNode(yy, _$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
yy.addDataToNode(yy, _$[$0-2])(yy.Block.wrap([$$[$0-2]])),
{
type: $$[$0-1], type: $$[$0-1],
statement: true statement: true
})); }));
break; break;
case 273: case 273:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('-', this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('-', $$[$0]));
$$[$0]));
break; break;
case 274: case 274:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('+', this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('+', $$[$0]));
$$[$0]));
break; break;
case 276: case 276:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('--', this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('--', $$[$0]));
$$[$0]));
break; break;
case 277: case 277:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('++', this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('++', $$[$0]));
$$[$0]));
break; break;
case 278: case 278:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('--', this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true));
$$[$0-1],
null,
true));
break; break;
case 279: case 279:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('++', this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true));
$$[$0-1],
null,
true));
break; break;
case 280: case 280:
this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Existence($$[$0-1])); this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Existence($$[$0-1]));
break; break;
case 281: case 281:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op('+', this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0]));
$$[$0-2],
$$[$0]));
break; break;
case 282: case 282:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op('-', this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0]));
$$[$0-2],
$$[$0]));
break; break;
case 283: case 284: case 285: case 286: case 287: case 288: case 289: case 290: case 291: case 292: case 283: case 284: case 285: case 286: case 287: case 288: case 289: case 290: case 291: case 292:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-1], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
$$[$0-2],
$$[$0]));
break; break;
case 293: case 293:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])((function () { this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])((function () {
if ($$[$0-1].charAt(0) === '!') { if ($$[$0-1].charAt(0) === '!') {
return new yy.Op($$[$0-1].slice(1), return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
$$[$0-2],
$$[$0]).invert();
} else { } else {
return new yy.Op($$[$0-1], return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
$$[$0-2],
$$[$0]);
} }
}())); }()));
break; break;
case 294: case 294:
this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign($$[$0-2], this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1]));
$$[$0],
$$[$0-1]));
break; break;
case 295: case 295:
this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign($$[$0-4], this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]));
$$[$0-1],
$$[$0-3]));
break; break;
case 296: case 296:
this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Assign($$[$0-3], this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0], $$[$0-2]));
$$[$0],
$$[$0-2]));
break; break;
} }
}, },

View file

@ -49,6 +49,7 @@ exports.Lexer = class Lexer
@importSpecifierList = no # Used to identify when in an `IMPORT {...} FROM? ...`. @importSpecifierList = no # Used to identify when in an `IMPORT {...} FROM? ...`.
@exportSpecifierList = no # Used to identify when in an `EXPORT {...} FROM? ...`. @exportSpecifierList = no # Used to identify when in an `EXPORT {...} FROM? ...`.
@csxDepth = 0 # Used to optimize CSX checks, how deep in CSX we are. @csxDepth = 0 # Used to optimize CSX checks, how deep in CSX we are.
@csxObjAttribute = {} # Used to detect if CSX attributes is wrapped in {} (<div {props...} />).
@chunkLine = @chunkLine =
opts.line or 0 # The start line for the current @chunk. opts.line or 0 # The start line for the current @chunk.
@ -546,6 +547,8 @@ exports.Lexer = class Lexer
# CSX is like JSX but for CoffeeScript. # CSX is like JSX but for CoffeeScript.
csxToken: -> csxToken: ->
firstChar = @chunk[0] firstChar = @chunk[0]
# Check the previous token to detect if attribute is spread.
prevChar = if @tokens.length > 0 then @tokens[@tokens.length - 1][0] else ''
if firstChar is '<' if firstChar is '<'
match = CSX_IDENTIFIER.exec @chunk[1...] match = CSX_IDENTIFIER.exec @chunk[1...]
return 0 unless match and ( return 0 unless match and (
@ -558,25 +561,30 @@ exports.Lexer = class Lexer
[input, id, colon] = match [input, id, colon] = match
origin = @token 'CSX_TAG', id, 1, id.length origin = @token 'CSX_TAG', id, 1, id.length
@token 'CALL_START', '(' @token 'CALL_START', '('
@token '{', '{' @token '[', '['
@ends.push tag: '/>', origin: origin, name: id @ends.push tag: '/>', origin: origin, name: id
@csxDepth++ @csxDepth++
return id.length + 1 return id.length + 1
else if csxTag = @atCSXTag() else if csxTag = @atCSXTag()
if @chunk[...2] is '/>' if @chunk[...2] is '/>'
@pair '/>' @pair '/>'
@token '}', '}', 0, 2 @token ']', ']', 0, 2
@token 'CALL_END', ')', 0, 2 @token 'CALL_END', ')', 0, 2
@csxDepth-- @csxDepth--
return 2 return 2
else if firstChar is '{' else if firstChar is '{'
token = @token '(', '(' if prevChar is ':'
token = @token '(', '('
@csxObjAttribute[@csxDepth] = no
else
token = @token '{', '{'
@csxObjAttribute[@csxDepth] = yes
@ends.push {tag: '}', origin: token} @ends.push {tag: '}', origin: token}
return 1 return 1
else if firstChar is '>' else if firstChar is '>'
# Ignore terminators inside a tag. # Ignore terminators inside a tag.
@pair '/>' # As if the current tag was self-closing. @pair '/>' # As if the current tag was self-closing.
origin = @token '}', '}' origin = @token ']', ']'
@token ',', ',' @token ',', ','
{tokens, index: end} = {tokens, index: end} =
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION @matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
@ -598,7 +606,11 @@ exports.Lexer = class Lexer
else if @atCSXTag 1 else if @atCSXTag 1
if firstChar is '}' if firstChar is '}'
@pair firstChar @pair firstChar
@token ')', ')' if @csxObjAttribute[@csxDepth]
@token '}', '}'
@csxObjAttribute[@csxDepth] = no
else
@token ')', ')'
@token ',', ',' @token ',', ','
return 1 return 1
else else

View file

@ -1122,7 +1122,18 @@ exports.Call = class Call extends Base
content?.base.csx = yes content?.base.csx = yes
fragments = [@makeCode('<')] fragments = [@makeCode('<')]
fragments.push (tag = @variable.compileToFragments(o, LEVEL_ACCESS))... fragments.push (tag = @variable.compileToFragments(o, LEVEL_ACCESS))...
fragments.push attributes.compileToFragments(o, LEVEL_PAREN)... if attributes.base instanceof Arr
for obj in attributes.base.objects
attr = obj.base
attrProps = attr?.properties or []
# Catch invalid CSX attributes: <div {a:"b", props} {props} "value" />
if not (attr instanceof Obj or attr instanceof IdentifierLiteral) or (attr instanceof Obj and not attr.generated and (attrProps.length > 1 or not (attrProps[0] instanceof Splat)))
obj.error """
Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
"""
obj.base.csx = yes if obj.base instanceof Obj
fragments.push @makeCode ' '
fragments.push obj.compileToFragments(o, LEVEL_PAREN)...
if content if content
fragments.push @makeCode('>') fragments.push @makeCode('>')
fragments.push content.compileNode(o, LEVEL_LIST)... fragments.push content.compileNode(o, LEVEL_LIST)...
@ -1425,11 +1436,14 @@ exports.Obj = class Obj extends Base
node.error 'cannot have an implicit value in an implicit object' node.error 'cannot have an implicit value in an implicit object'
# Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md # Object spread properties. https://github.com/tc39/proposal-object-rest-spread/blob/master/Spread.md
return @compileSpread o if @hasSplat() return @compileSpread o if @hasSplat() and not @csx
idt = o.indent += TAB idt = o.indent += TAB
lastNode = @lastNode @properties lastNode = @lastNode @properties
# CSX attributes <div id="val" attr={aaa} {props...} />
return @compileCSXAttributes o if @csx
# If this object is the left-hand side of an assignment, all its children # If this object is the left-hand side of an assignment, all its children
# are too. # are too.
if @lhs if @lhs
@ -1443,7 +1457,7 @@ exports.Obj = class Obj extends Base
isCompact = yes isCompact = yes
for prop in @properties for prop in @properties
if prop instanceof Assign and prop.context is 'object' and not @csx if prop instanceof Assign and prop.context is 'object'
isCompact = no isCompact = no
answer = [] answer = []
@ -1451,11 +1465,9 @@ exports.Obj = class Obj extends Base
for prop, i in props for prop, i in props
join = if i is props.length - 1 join = if i is props.length - 1
'' ''
else if isCompact and @csx
' '
else if isCompact else if isCompact
', ' ', '
else if prop is lastNode or @csx else if prop is lastNode
'\n' '\n'
else else
',\n' ',\n'
@ -1480,12 +1492,10 @@ exports.Obj = class Obj extends Base
else if not prop.bareLiteral?(IdentifierLiteral) else if not prop.bareLiteral?(IdentifierLiteral)
prop = new Assign prop, prop, 'object' prop = new Assign prop, prop, 'object'
if indent then answer.push @makeCode indent if indent then answer.push @makeCode indent
prop.csx = yes if @csx
answer.push @makeCode ' ' if @csx and i is 0
answer.push prop.compileToFragments(o, LEVEL_TOP)... answer.push prop.compileToFragments(o, LEVEL_TOP)...
if join then answer.push @makeCode join if join then answer.push @makeCode join
answer.push @makeCode if isCompact then '' else "\n#{@tab}" answer.push @makeCode if isCompact then '' else "\n#{@tab}"
answer = @wrapInBraces answer if not @csx answer = @wrapInBraces answer
if @front then @wrapInParentheses answer else answer if @front then @wrapInParentheses answer else answer
assigns: (name) -> assigns: (name) ->
@ -1521,6 +1531,17 @@ exports.Obj = class Obj extends Base
slices.unshift new Obj unless slices[0] instanceof Obj slices.unshift new Obj unless slices[0] instanceof Obj
(new Call new Literal('Object.assign'), slices).compileToFragments o (new Call new Literal('Object.assign'), slices).compileToFragments o
compileCSXAttributes: (o) ->
props = @properties
answer = []
for prop, i in props
prop.csx = yes
join = if i is props.length - 1 then '' else ' '
prop = new Literal "{#{prop.compile(o)}}" if prop instanceof Splat
answer.push prop.compileToFragments(o, LEVEL_TOP)...
answer.push @makeCode join
if @front then @wrapInParentheses answer else answer
#### Arr #### Arr
# An array literal. # An array literal.

View file

@ -483,147 +483,115 @@ test 'self closing tag with namespace', ->
<Something.Tag />; <Something.Tag />;
''' '''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'self closing tag with spread attribute', ->
# test 'self closing tag with spread attribute', -> eqJS '''
# eqJS ''' <Component a={b} {x...} b="c" />
# <Component a={b} {... x } b="c" /> ''', '''
# ''', ''' <Component a={b} {...x} b="c" />;
# React.createElement(Component, Object.assign({"a": (b)}, x , {"b": "c"})) '''
# '''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'complex spread attribute', ->
# test 'complex spread attribute', -> eqJS '''
# eqJS ''' <Component {x...} a={b} {x...} b="c" {$my_xtraCoolVar123...} />
# <Component {...x} a={b} {... x } b="c" {...$my_xtraCoolVar123 } /> ''', '''
# ''', ''' <Component {...x} a={b} {...x} b="c" {...$my_xtraCoolVar123} />;
# React.createElement(Component, Object.assign({}, x, {"a": (b)}, x , {"b": "c"}, $my_xtraCoolVar123 )) '''
# '''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'multiline spread attribute', ->
# test 'multiline spread attribute', -> eqJS '''
# eqJS ''' <Component {
# <Component {... x...} a={b} {x...} b="c" {z...}>
# x } a={b} {... x } b="c" {...z }> </Component>
# </Component> ''', '''
# ''', ''' <Component {...x} a={b} {...x} b="c" {...z}>
# React.createElement(Component, Object.assign({}, </Component>;
# x , {"a": (b)}, x , {"b": "c"}, z ) '''
# )
# '''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'multiline tag with spread attribute', ->
# test 'multiline tag with spread attribute', -> eqJS '''
# eqJS ''' <Component
# <Component z="1"
# z="1" {x...}
# {...x} a={b}
# a={b} b="c"
# b="c" >
# > </Component>
# </Component> ''', '''
# ''', ''' <Component z="1" {...x} a={b} b="c">
# React.createElement(Component, Object.assign({ \ </Component>;
# "z": "1" '''
# }, x, { \
# "a": (b), \
# "b": "c"
# })
# )
# '''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'multiline tag with spread attribute first', ->
# test 'multiline tag with spread attribute first', -> eqJS '''
# eqJS ''' <Component
# <Component {x...}
# {... z="1"
# x} a={b}
# z="1" b="c"
# a={b} >
# b="c" </Component>
# > ''', '''
# </Component> <Component {...x} z="1" a={b} b="c">
# ''', ''' </Component>;
# React.createElement(Component, Object.assign({}, \ '''
# x, { \ test 'complex multiline spread attribute', ->
# "z": "1", \ eqJS '''
# "a": (b), \ <Component
# "b": "c" {y...
# }) } a={b} {x...} b="c" {z...}>
# ) <div code={someFunc({a:{b:{}, C:'}'}})} />
# ''' </Component>
''', '''
<Component {...y} a={b} {...x} b="c" {...z}>
<div code={someFunc({
a: {
b: {},
C: '}'
}
})} />
</Component>;
'''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'self closing spread attribute on single line', ->
# test 'complex multiline spread attribute', -> eqJS '''
# eqJS ''' <Component a="b" c="d" {@props...} />
# <Component ''', '''
# {... <Component a="b" c="d" {...this.props} />;
# y} a={b} {... x } b="c" {...z }> '''
# <div code={someFunc({a:{b:{}, C:'}'}})} />
# </Component>
# ''', '''
# React.createElement(Component, Object.assign({}, \
# y, {"a": (b)}, x , {"b": "c"}, z ), test 'self closing spread attribute on new line', ->
# React.createElement("div", {"code": (someFunc({a:{b:{}, C:'}'}}))}) eqJS '''
# ) <Component
# ''' a="b"
c="d"
{@props...}
/>
''', '''
<Component a="b" c="d" {...this.props} />;
'''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'self closing spread attribute on same line', ->
# test 'self closing spread attribute on single line', -> eqJS '''
# eqJS ''' <Component
# <Component a="b" c="d" {...@props} /> a="b"
# ''', ''' c="d"
# React.createElement(Component, Object.assign({"a": "b", "c": "d"}, @props )) {@props...} />
# ''' ''', '''
<Component a="b" c="d" {...this.props} />;
'''
# TODO: Uncomment the following test once destructured object spreads are supported. test 'self closing spread attribute on next line', ->
# test 'self closing spread attribute on new line', -> eqJS '''
# eqJS ''' <Component
# <Component a="b"
# a="b" c="d"
# c="d" {@props...}
# {...@props}
# />
# ''', '''
# React.createElement(Component, Object.assign({ \
# "a": "b", \
# "c": "d"
# }, @props
# ))
# '''
# TODO: Uncomment the following test once destructured object spreads are supported. />
# test 'self closing spread attribute on same line', -> ''', '''
# eqJS ''' <Component a="b" c="d" {...this.props} />;
# <Component '''
# a="b"
# c="d"
# {...@props} />
# ''', '''
# React.createElement(Component, Object.assign({ \
# "a": "b", \
# "c": "d"
# }, @props ))
# '''
# TODO: Uncomment the following test once destructured object spreads are supported.
# test 'self closing spread attribute on next line', ->
# eqJS '''
# <Component
# a="b"
# c="d"
# {...@props}
# />
# ''', '''
# React.createElement(Component, Object.assign({ \
# "a": "b", \
# "c": "d"
# }, @props
# ))
# '''
test 'empty strings are not converted to true', -> test 'empty strings are not converted to true', ->
eqJS ''' eqJS '''

View file

@ -1587,6 +1587,50 @@ test "CSX error: ambiguous tag-like expression", ->
^ ^
''' '''
test 'CSX error: invalid attributes', ->
assertErrorFormat '''
<div a="b" {props} />
''', '''
[stdin]:1:12: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
<div a="b" {props} />
^^^^^^^
'''
assertErrorFormat '''
<div a={b} {a:{b}} />
''', '''
[stdin]:1:12: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
<div a={b} {a:{b}} />
^^^^^^^
'''
assertErrorFormat '''
<div {"#{a}"} />
''', '''
[stdin]:1:6: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
<div {"#{a}"} />
^^^^^^^^
'''
assertErrorFormat '''
<div props... />
''', '''
[stdin]:1:11: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
<div props... />
^^^
'''
assertErrorFormat '''
<div {a:"b", props..., c:d()} />
''', '''
[stdin]:1:6: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
<div {a:"b", props..., c:d()} />
^^^^^^^^^^^^^^^^^^^^^^^^
'''
assertErrorFormat '''
<div {props..., a, b} />
''', '''
[stdin]:1:6: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
<div {props..., a, b} />
^^^^^^^^^^^^^^^^
'''
test 'Bound method called as callback before binding throws runtime error', -> test 'Bound method called as callback before binding throws runtime error', ->
class Base class Base
constructor: -> constructor: ->