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.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.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.chunkColumn = opts.column || 0; // The start column of the current @chunk.
code = this.clean(code); // The stripped, cleaned original source code.
@ -730,8 +731,10 @@
// CSX is like JSX but for CoffeeScript.
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];
// Check the previous token to detect if attribute is spread.
prevChar = this.tokens.length > 0 ? this.tokens[this.tokens.length - 1][0] : '';
if (firstChar === '<') {
match = CSX_IDENTIFIER.exec(this.chunk.slice(1));
// Not the right hand side of an unspaced comparison (i.e. `a<b`).
@ -741,7 +744,7 @@
[input, id, colon] = match;
origin = this.token('CSX_TAG', id, 1, id.length);
this.token('CALL_START', '(');
this.token('{', '{');
this.token('[', '[');
this.ends.push({
tag: '/>',
origin: origin,
@ -752,12 +755,18 @@
} else if (csxTag = this.atCSXTag()) {
if (this.chunk.slice(0, 2) === '/>') {
this.pair('/>');
this.token('}', '}', 0, 2);
this.token(']', ']', 0, 2);
this.token('CALL_END', ')', 0, 2);
this.csxDepth--;
return 2;
} 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({
tag: '}',
origin: token
@ -766,7 +775,7 @@
} else if (firstChar === '>') {
// Ignore terminators inside a tag.
this.pair('/>'); // As if the current tag was self-closing.
origin = this.token('}', '}');
origin = this.token(']', ']');
this.token(',', ',');
({
tokens,
@ -800,7 +809,12 @@
} else if (this.atCSXTag(1)) {
if (firstChar === '}') {
this.pair(firstChar);
this.token(')', ')');
if (this.csxObjAttribute[this.csxDepth]) {
this.token('}', '}');
this.csxObjAttribute[this.csxDepth] = false;
} else {
this.token(')', ')');
}
this.token(',', ',');
return 1;
} else {