AST: "CSX" -> "JSX" (#5188)
* updated grammar * restore JSXIdentifier::astType()
This commit is contained in:
parent
0c2d3673d3
commit
28a1a1d304
|
@ -162,13 +162,13 @@
|
|||
function() {
|
||||
return new IdentifierLiteral($1);
|
||||
}),
|
||||
o('CSX_TAG',
|
||||
o('JSX_TAG',
|
||||
function() {
|
||||
var ref,
|
||||
ref1,
|
||||
ref2,
|
||||
ref3;
|
||||
return new CSXTag($1.toString(),
|
||||
return new JSXTag($1.toString(),
|
||||
{
|
||||
tagNameLocationData: $1.tagNameToken[2],
|
||||
closingTagOpeningBracketLocationData: (ref = $1.closingTagOpeningBracketToken) != null ? ref[2] : void 0,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// where locationData is {first_line, first_column, last_line, last_column, last_line_exclusive, last_column_exclusive}, which is a
|
||||
// format that can be fed directly into [Jison](https://github.com/zaach/jison). These
|
||||
// are read by jison in the `parser.lexer` function defined in coffeescript.coffee.
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARABLE_LEFT_SIDE, COMPARE, COMPOUND_ASSIGN, CSX_ATTRIBUTE, CSX_FRAGMENT_IDENTIFIER, CSX_IDENTIFIER, CSX_INTERPOLATION, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INSIDE_CSX, INVERSES, JSTOKEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, REGEX_INVALID_ESCAPE, RELATION, RESERVED, Rewriter, SHIFT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_INVALID_ESCAPE, STRING_SINGLE, STRING_START, TRAILING_SPACES, UNARY, UNARY_MATH, UNFINISHED, VALID_FLAGS, WHITESPACE, addTokenData, attachCommentsToNode, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, merge, repeat, replaceUnicodeCodePointEscapes, starts, throwSyntaxError,
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARABLE_LEFT_SIDE, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INSIDE_JSX, INVERSES, JSTOKEN, JSX_ATTRIBUTE, JSX_FRAGMENT_IDENTIFIER, JSX_IDENTIFIER, JSX_INTERPOLATION, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, REGEX_INVALID_ESCAPE, RELATION, RESERVED, Rewriter, SHIFT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_INVALID_ESCAPE, STRING_SINGLE, STRING_START, TRAILING_SPACES, UNARY, UNARY_MATH, UNFINISHED, VALID_FLAGS, WHITESPACE, addTokenData, attachCommentsToNode, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, merge, repeat, replaceUnicodeCodePointEscapes, starts, throwSyntaxError,
|
||||
indexOf = [].indexOf,
|
||||
slice = [].slice;
|
||||
|
||||
|
@ -58,8 +58,8 @@
|
|||
this.seenExport = false; // Used to recognize `EXPORT FROM? AS?` tokens.
|
||||
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.jsxDepth = 0; // Used to optimize JSX checks, how deep in JSX we are.
|
||||
this.jsxObjAttribute = {}; // Used to detect if JSX 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.
|
||||
this.chunkOffset = opts.offset || 0; // The start offset for the current @chunk.
|
||||
|
@ -70,7 +70,7 @@
|
|||
// `@literalToken` is the fallback catch-all.
|
||||
i = 0;
|
||||
while (this.chunk = code.slice(i)) {
|
||||
consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.numberToken() || this.csxToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
||||
consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.numberToken() || this.jsxToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
||||
// Update position.
|
||||
[this.chunkLine, this.chunkColumn, this.chunkOffset] = this.getLineAndColumnFromChunk(consumed);
|
||||
i += consumed;
|
||||
|
@ -119,9 +119,9 @@
|
|||
// referenced as property names here, so you can still do `jQuery.is()` even
|
||||
// though `is` means `===` otherwise.
|
||||
identifierToken() {
|
||||
var alias, colon, colonOffset, colonToken, id, idLength, inCSXTag, input, match, poppedToken, prev, prevprev, ref, ref1, ref10, ref11, ref12, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, regExSuper, regex, sup, tag, tagToken, tokenData;
|
||||
inCSXTag = this.atCSXTag();
|
||||
regex = inCSXTag ? CSX_ATTRIBUTE : IDENTIFIER;
|
||||
var alias, colon, colonOffset, colonToken, id, idLength, inJSXTag, input, match, poppedToken, prev, prevprev, ref, ref1, ref10, ref11, ref12, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, regExSuper, regex, sup, tag, tagToken, tokenData;
|
||||
inJSXTag = this.atJSXTag();
|
||||
regex = inJSXTag ? JSX_ATTRIBUTE : IDENTIFIER;
|
||||
if (!(match = regex.exec(this.chunk))) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -263,16 +263,16 @@
|
|||
[tagToken[2].first_line, tagToken[2].first_column, tagToken[2].range[0]] = [poppedToken[2].first_line, poppedToken[2].first_column, poppedToken[2].range[0]];
|
||||
}
|
||||
if (colon) {
|
||||
colonOffset = input.lastIndexOf(inCSXTag ? '=' : ':');
|
||||
colonOffset = input.lastIndexOf(inJSXTag ? '=' : ':');
|
||||
colonToken = this.token(':', ':', {
|
||||
offset: colonOffset,
|
||||
length: colon.length
|
||||
});
|
||||
if (inCSXTag) { // used by rewriter
|
||||
colonToken.csxColon = true;
|
||||
if (inJSXTag) { // used by rewriter
|
||||
colonToken.jsxColon = true;
|
||||
}
|
||||
}
|
||||
if (inCSXTag && tag === 'IDENTIFIER' && prev[0] !== ':') {
|
||||
if (inJSXTag && tag === 'IDENTIFIER' && prev[0] !== ':') {
|
||||
this.token(',', ',', {
|
||||
length: 0,
|
||||
origin: tagToken
|
||||
|
@ -386,7 +386,7 @@
|
|||
delimiter: quote
|
||||
});
|
||||
});
|
||||
if (this.atCSXTag()) {
|
||||
if (this.atJSXTag()) {
|
||||
this.token(',', ',', {
|
||||
length: 0,
|
||||
origin: this.prev
|
||||
|
@ -771,16 +771,15 @@
|
|||
return this;
|
||||
}
|
||||
|
||||
// CSX is like JSX but for CoffeeScript.
|
||||
csxToken() {
|
||||
var afterTag, csxTag, end, endToken, firstChar, fullId, fullTagName, id, input, j, len, match, offset, openingTagToken, prev, prevChar, properties, property, ref, tagToken, token, tokens;
|
||||
jsxToken() {
|
||||
var afterTag, end, endToken, firstChar, fullId, fullTagName, id, input, j, jsxTag, len, match, offset, openingTagToken, prev, prevChar, properties, property, ref, tagToken, 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)) || CSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(1));
|
||||
match = JSX_IDENTIFIER.exec(this.chunk.slice(1)) || JSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(1));
|
||||
// Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
||||
if (!(match && (this.csxDepth > 0 || !(prev = this.prev()) || prev.spaced || (ref = prev[0], indexOf.call(COMPARABLE_LEFT_SIDE, ref) < 0)))) {
|
||||
if (!(match && (this.jsxDepth > 0 || !(prev = this.prev()) || prev.spaced || (ref = prev[0], indexOf.call(COMPARABLE_LEFT_SIDE, ref) < 0)))) {
|
||||
return 0;
|
||||
}
|
||||
[input, id] = match;
|
||||
|
@ -790,7 +789,7 @@
|
|||
} else {
|
||||
properties = [];
|
||||
}
|
||||
tagToken = this.token('CSX_TAG', id, {
|
||||
tagToken = this.token('JSX_TAG', id, {
|
||||
length: id.length + 1,
|
||||
data: {
|
||||
openingBracketToken: this.makeToken('<', '<'),
|
||||
|
@ -819,9 +818,9 @@
|
|||
name: id,
|
||||
properties
|
||||
});
|
||||
this.csxDepth++;
|
||||
this.jsxDepth++;
|
||||
return fullId.length + 1;
|
||||
} else if (csxTag = this.atCSXTag()) {
|
||||
} else if (jsxTag = this.atJSXTag()) {
|
||||
if (this.chunk.slice(0, 2) === '/>') { // Self-closing tag.
|
||||
this.pair('/>');
|
||||
this.token(']', ']', {
|
||||
|
@ -838,15 +837,15 @@
|
|||
})
|
||||
}
|
||||
});
|
||||
this.csxDepth--;
|
||||
this.jsxDepth--;
|
||||
return 2;
|
||||
} else if (firstChar === '{') {
|
||||
if (prevChar === ':') {
|
||||
token = this.token('(', '(');
|
||||
this.csxObjAttribute[this.csxDepth] = false;
|
||||
this.jsxObjAttribute[this.jsxDepth] = false;
|
||||
} else {
|
||||
token = this.token('{', '{');
|
||||
this.csxObjAttribute[this.csxDepth] = true;
|
||||
this.jsxObjAttribute[this.jsxDepth] = true;
|
||||
}
|
||||
this.ends.push({
|
||||
tag: '}',
|
||||
|
@ -870,7 +869,7 @@
|
|||
({
|
||||
tokens,
|
||||
index: end
|
||||
} = this.matchWithInterpolations(INSIDE_CSX, '>', '</', CSX_INTERPOLATION));
|
||||
} = this.matchWithInterpolations(INSIDE_JSX, '>', '</', JSX_INTERPOLATION));
|
||||
this.mergeInterpolationTokens(tokens, {
|
||||
endOffset: end
|
||||
}, (value) => {
|
||||
|
@ -878,10 +877,10 @@
|
|||
delimiter: '>'
|
||||
});
|
||||
});
|
||||
match = CSX_IDENTIFIER.exec(this.chunk.slice(end)) || CSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(end));
|
||||
if (!match || match[1] !== `${csxTag.name}${((function() {
|
||||
match = JSX_IDENTIFIER.exec(this.chunk.slice(end)) || JSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(end));
|
||||
if (!match || match[1] !== `${jsxTag.name}${((function() {
|
||||
var k, len1, ref1, results;
|
||||
ref1 = csxTag.properties;
|
||||
ref1 = jsxTag.properties;
|
||||
results = [];
|
||||
for (k = 0, len1 = ref1.length; k < len1; k++) {
|
||||
property = ref1[k];
|
||||
|
@ -889,7 +888,7 @@
|
|||
}
|
||||
return results;
|
||||
})()).join('')}`) {
|
||||
this.error(`expected corresponding CSX closing tag for ${csxTag.name}`, csxTag.origin.data.tagNameToken[2]);
|
||||
this.error(`expected corresponding JSX closing tag for ${jsxTag.name}`, jsxTag.origin.data.tagNameToken[2]);
|
||||
}
|
||||
[, fullTagName] = match;
|
||||
afterTag = end + fullTagName.length;
|
||||
|
@ -922,17 +921,17 @@
|
|||
});
|
||||
// make the closing tag location data more easily accessible to the grammar
|
||||
addTokenData(openingTagToken, endToken.data);
|
||||
this.csxDepth--;
|
||||
this.jsxDepth--;
|
||||
return afterTag + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if (this.atCSXTag(1)) {
|
||||
} else if (this.atJSXTag(1)) {
|
||||
if (firstChar === '}') {
|
||||
this.pair(firstChar);
|
||||
if (this.csxObjAttribute[this.csxDepth]) {
|
||||
if (this.jsxObjAttribute[this.jsxDepth]) {
|
||||
this.token('}', '}');
|
||||
this.csxObjAttribute[this.csxDepth] = false;
|
||||
this.jsxObjAttribute[this.jsxDepth] = false;
|
||||
} else {
|
||||
this.token(')', ')');
|
||||
}
|
||||
|
@ -946,9 +945,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
atCSXTag(depth = 0) {
|
||||
atJSXTag(depth = 0) {
|
||||
var i, last, ref;
|
||||
if (this.csxDepth === 0) {
|
||||
if (this.jsxDepth === 0) {
|
||||
return false;
|
||||
}
|
||||
i = this.ends.length - 1;
|
||||
|
@ -1132,9 +1131,9 @@
|
|||
// `#{` if interpolations are desired).
|
||||
// - `delimiter` is the delimiter of the token. Examples are `'`, `"`, `'''`,
|
||||
// `"""` and `///`.
|
||||
// - `closingDelimiter` is different from `delimiter` only in CSX
|
||||
// - `interpolators` matches the start of an interpolation, for CSX it's both
|
||||
// `{` and `<` (i.e. nested CSX tag)
|
||||
// - `closingDelimiter` is different from `delimiter` only in JSX
|
||||
// - `interpolators` matches the start of an interpolation, for JSX it's both
|
||||
// `{` and `<` (i.e. nested JSX tag)
|
||||
|
||||
// This method allows us to have strings within interpolations within strings,
|
||||
// ad infinitum.
|
||||
|
@ -1600,13 +1599,13 @@
|
|||
// Token matching regexes.
|
||||
IDENTIFIER = /^(?!\d)((?:(?!\s)[$\w\x7f-\uffff])+)([^\n\S]*:(?!:))?/; // Is this a property name?
|
||||
|
||||
CSX_IDENTIFIER = /^(?![\d<])((?:(?!\s)[\.\-$\w\x7f-\uffff])+)/; // Must not start with `<`.
|
||||
JSX_IDENTIFIER = /^(?![\d<])((?:(?!\s)[\.\-$\w\x7f-\uffff])+)/; // Must not start with `<`.
|
||||
// Like `IDENTIFIER`, but includes `-`s and `.`s.
|
||||
|
||||
// Fragment: <></>
|
||||
CSX_FRAGMENT_IDENTIFIER = /^()>/; // Ends immediately with `>`.
|
||||
JSX_FRAGMENT_IDENTIFIER = /^()>/; // Ends immediately with `>`.
|
||||
|
||||
CSX_ATTRIBUTE = /^(?!\d)((?:(?!\s)[\-$\w\x7f-\uffff])+)([^\S]*=(?!=))?/; // Like `IDENTIFIER`, but includes `-`s.
|
||||
JSX_ATTRIBUTE = /^(?!\d)((?:(?!\s)[\-$\w\x7f-\uffff])+)([^\S]*=(?!=))?/; // Like `IDENTIFIER`, but includes `-`s.
|
||||
// Is this an attribute with a value?
|
||||
|
||||
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; // binary
|
||||
|
@ -1645,11 +1644,11 @@
|
|||
|
||||
HEREDOC_DOUBLE = /^(?:[^\\"#]|\\[\s\S]|"(?!"")|\#(?!\{))*/;
|
||||
|
||||
INSIDE_CSX = /^(?:[^\{<])*/; // Start of CoffeeScript interpolation. // Similar to `HEREDOC_DOUBLE` but there is no escaping.
|
||||
// Maybe CSX tag (`<` not allowed even if bare).
|
||||
INSIDE_JSX = /^(?:[^\{<])*/; // Start of CoffeeScript interpolation. // Similar to `HEREDOC_DOUBLE` but there is no escaping.
|
||||
// Maybe JSX tag (`<` not allowed even if bare).
|
||||
|
||||
CSX_INTERPOLATION = /^(?:\{|<(?!\/))/; // CoffeeScript interpolation.
|
||||
// CSX opening tag.
|
||||
JSX_INTERPOLATION = /^(?:\{|<(?!\/))/; // CoffeeScript interpolation.
|
||||
// JSX opening tag.
|
||||
|
||||
HEREDOC_INDENT = /\n+([^\n\S]*)(?=\S)/g;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// nodes are created as the result of actions in the [grammar](grammar.html),
|
||||
// but some are created by other nodes as a method of code generation. To convert
|
||||
// the syntax tree into a string of JavaScript code, call `compile()` on the root.
|
||||
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXAttribute, CSXAttributes, CSXElement, CSXEmptyExpression, CSXExpressionContainer, CSXIdentifier, CSXTag, CSXText, Call, Catch, Class, Code, CodeFragment, ComputedPropertyName, DefaultLiteral, DynamicImport, DynamicImportCall, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncDirectiveReturn, FuncGlyph, HEREGEX_OMIT, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, Interpolation, JS_FORBIDDEN, LEADING_BLANK_LINE, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, MetaProperty, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, ObjectProperty, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, Root, SIMPLENUM, SIMPLE_STRING_OMIT, STRING_OMIT, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, SwitchCase, SwitchWhen, TAB, THIS, TRAILING_BLANK_LINE, TaggedTemplateCall, TemplateElement, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, greater, hasLineComments, indentInitial, isAstLocGreater, isFunction, isLiteralArguments, isLiteralThis, isLocationDataEndGreater, isLocationDataStartGreater, isNumber, isPlainObject, isUnassignable, jisonLocationDataToAstLocationData, lesser, locationDataToString, makeDelimitedLiteral, merge, mergeAstLocationData, mergeLocationData, moveComments, multident, replaceUnicodeCodePointEscapes, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility,
|
||||
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, Call, Catch, Class, Code, CodeFragment, ComputedPropertyName, DefaultLiteral, DynamicImport, DynamicImportCall, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncDirectiveReturn, FuncGlyph, HEREGEX_OMIT, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, Interpolation, JSXAttribute, JSXAttributes, JSXElement, JSXEmptyExpression, JSXExpressionContainer, JSXIdentifier, JSXTag, JSXText, JS_FORBIDDEN, LEADING_BLANK_LINE, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, MetaProperty, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, ObjectProperty, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, Root, SIMPLENUM, SIMPLE_STRING_OMIT, STRING_OMIT, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, SwitchCase, SwitchWhen, TAB, THIS, TRAILING_BLANK_LINE, TaggedTemplateCall, TemplateElement, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, greater, hasLineComments, indentInitial, isAstLocGreater, isFunction, isLiteralArguments, isLiteralThis, isLocationDataEndGreater, isLocationDataStartGreater, isNumber, isPlainObject, isUnassignable, jisonLocationDataToAstLocationData, lesser, locationDataToString, makeDelimitedLiteral, merge, mergeAstLocationData, mergeLocationData, moveComments, multident, replaceUnicodeCodePointEscapes, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility,
|
||||
indexOf = [].indexOf,
|
||||
splice = [].splice,
|
||||
slice1 = [].slice;
|
||||
|
@ -796,7 +796,7 @@
|
|||
len = this.expressions.length;
|
||||
ref1 = this.expressions, [lastExp] = slice1.call(ref1, -1);
|
||||
lastExp = (lastExp != null ? lastExp.unwrap() : void 0) || false;
|
||||
// We also need to check that we’re not returning a CSX tag if there’s an
|
||||
// We also need to check that we’re not returning a JSX tag if there’s an
|
||||
// adjacent one at the same level; JSX doesn’t allow that.
|
||||
if (lastExp && lastExp instanceof Parens && lastExp.body.expressions.length > 1) {
|
||||
({
|
||||
|
@ -805,7 +805,7 @@
|
|||
[penult, last] = slice1.call(expressions, -2);
|
||||
penult = penult.unwrap();
|
||||
last = last.unwrap();
|
||||
if (penult instanceof CSXElement && last instanceof CSXElement) {
|
||||
if (penult instanceof JSXElement && last instanceof JSXElement) {
|
||||
expressions[expressions.length - 1].error('Adjacent JSX elements must be wrapped in an enclosing tag');
|
||||
}
|
||||
}
|
||||
|
@ -1335,19 +1335,19 @@
|
|||
}
|
||||
|
||||
compileNode(o) {
|
||||
if (this.csx) {
|
||||
if (this.jsx) {
|
||||
return [this.makeCode(this.unquote(true, true))];
|
||||
}
|
||||
return super.compileNode(o);
|
||||
}
|
||||
|
||||
unquote(doubleQuote = false, csx = false) {
|
||||
unquote(doubleQuote = false, jsx = false) {
|
||||
var unquoted;
|
||||
unquoted = this.value.slice(1, -1);
|
||||
if (doubleQuote) {
|
||||
unquoted = unquoted.replace(/\\"/g, '"');
|
||||
}
|
||||
if (csx) {
|
||||
if (jsx) {
|
||||
unquoted = unquoted.replace(/\\n/g, '\n');
|
||||
}
|
||||
return unquoted;
|
||||
|
@ -1458,7 +1458,7 @@
|
|||
}
|
||||
|
||||
astType() {
|
||||
if (this.csx) {
|
||||
if (this.jsx) {
|
||||
return 'JSXIdentifier';
|
||||
} else {
|
||||
return 'Identifier';
|
||||
|
@ -1479,32 +1479,10 @@
|
|||
|
||||
}).call(this);
|
||||
|
||||
exports.CSXTag = CSXTag = class CSXTag extends IdentifierLiteral {
|
||||
constructor(value, {tagNameLocationData, closingTagOpeningBracketLocationData, closingTagSlashLocationData, closingTagNameLocationData, closingTagClosingBracketLocationData}) {
|
||||
super(value);
|
||||
this.tagNameLocationData = tagNameLocationData;
|
||||
this.closingTagOpeningBracketLocationData = closingTagOpeningBracketLocationData;
|
||||
this.closingTagSlashLocationData = closingTagSlashLocationData;
|
||||
this.closingTagNameLocationData = closingTagNameLocationData;
|
||||
this.closingTagClosingBracketLocationData = closingTagClosingBracketLocationData;
|
||||
}
|
||||
|
||||
astType() {
|
||||
return 'JSXIdentifier';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
return {
|
||||
name: this.value
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.PropertyName = PropertyName = (function() {
|
||||
class PropertyName extends Literal {
|
||||
astType() {
|
||||
if (this.csx) {
|
||||
if (this.jsx) {
|
||||
return 'JSXIdentifier';
|
||||
} else {
|
||||
return 'Identifier';
|
||||
|
@ -1883,8 +1861,8 @@
|
|||
return !this.properties.length && this.base.isStatement(o);
|
||||
}
|
||||
|
||||
isCSXTag() {
|
||||
return this.base instanceof CSXTag;
|
||||
isJSXTag() {
|
||||
return this.base instanceof JSXTag;
|
||||
}
|
||||
|
||||
assigns(name) {
|
||||
|
@ -2061,7 +2039,7 @@
|
|||
}
|
||||
|
||||
astType() {
|
||||
if (this.isCSXTag()) {
|
||||
if (this.isJSXTag()) {
|
||||
return 'JSXMemberExpression';
|
||||
} else {
|
||||
return 'MemberExpression';
|
||||
|
@ -2074,8 +2052,8 @@
|
|||
astProperties(o) {
|
||||
var computed, property, ref1, ref2;
|
||||
ref1 = this.properties, [property] = slice1.call(ref1, -1);
|
||||
if (this.isCSXTag()) {
|
||||
property.name.csx = true;
|
||||
if (this.isJSXTag()) {
|
||||
property.name.jsx = true;
|
||||
}
|
||||
computed = property instanceof Index || !(((ref2 = property.name) != null ? ref2.unwrap() : void 0) instanceof PropertyName);
|
||||
return {
|
||||
|
@ -2088,7 +2066,7 @@
|
|||
}
|
||||
|
||||
astLocationData() {
|
||||
if (!this.isCSXTag()) {
|
||||
if (!this.isJSXTag()) {
|
||||
return super.astLocationData();
|
||||
}
|
||||
// don't include leading < of JSX tag in location data
|
||||
|
@ -2223,20 +2201,38 @@
|
|||
|
||||
};
|
||||
|
||||
//### CSX
|
||||
exports.CSXIdentifier = CSXIdentifier = class CSXIdentifier extends IdentifierLiteral {
|
||||
//### JSX
|
||||
exports.JSXIdentifier = JSXIdentifier = class JSXIdentifier extends IdentifierLiteral {
|
||||
astType() {
|
||||
return 'JSXIdentifier';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.CSXExpressionContainer = CSXExpressionContainer = (function() {
|
||||
class CSXExpressionContainer extends Base {
|
||||
exports.JSXTag = JSXTag = class JSXTag extends JSXIdentifier {
|
||||
constructor(value, {tagNameLocationData, closingTagOpeningBracketLocationData, closingTagSlashLocationData, closingTagNameLocationData, closingTagClosingBracketLocationData}) {
|
||||
super(value);
|
||||
this.tagNameLocationData = tagNameLocationData;
|
||||
this.closingTagOpeningBracketLocationData = closingTagOpeningBracketLocationData;
|
||||
this.closingTagSlashLocationData = closingTagSlashLocationData;
|
||||
this.closingTagNameLocationData = closingTagNameLocationData;
|
||||
this.closingTagClosingBracketLocationData = closingTagClosingBracketLocationData;
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
return {
|
||||
name: this.value
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.JSXExpressionContainer = JSXExpressionContainer = (function() {
|
||||
class JSXExpressionContainer extends Base {
|
||||
constructor(expression1, {locationData} = {}) {
|
||||
super();
|
||||
this.expression = expression1;
|
||||
this.expression.csxAttribute = true;
|
||||
this.expression.jsxAttribute = true;
|
||||
this.locationData = locationData != null ? locationData : this.expression.locationData;
|
||||
}
|
||||
|
||||
|
@ -2244,10 +2240,6 @@
|
|||
return this.expression.compileNode(o);
|
||||
}
|
||||
|
||||
astType() {
|
||||
return 'JSXExpressionContainer';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
return {
|
||||
expression: this.expression.ast()
|
||||
|
@ -2256,30 +2248,21 @@
|
|||
|
||||
};
|
||||
|
||||
CSXExpressionContainer.prototype.children = ['expression'];
|
||||
JSXExpressionContainer.prototype.children = ['expression'];
|
||||
|
||||
return CSXExpressionContainer;
|
||||
return JSXExpressionContainer;
|
||||
|
||||
}).call(this);
|
||||
|
||||
exports.CSXEmptyExpression = CSXEmptyExpression = class CSXEmptyExpression extends Base {
|
||||
astType() {
|
||||
return 'JSXEmptyExpression';
|
||||
}
|
||||
exports.JSXEmptyExpression = JSXEmptyExpression = class JSXEmptyExpression extends Base {};
|
||||
|
||||
};
|
||||
|
||||
exports.CSXText = CSXText = class CSXText extends Base {
|
||||
exports.JSXText = JSXText = class JSXText extends Base {
|
||||
constructor(stringLiteral) {
|
||||
super();
|
||||
this.value = stringLiteral.unquote(true, true);
|
||||
this.locationData = stringLiteral.locationData;
|
||||
}
|
||||
|
||||
astType() {
|
||||
return 'JSXText';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
return {
|
||||
value: this.value,
|
||||
|
@ -2291,8 +2274,8 @@
|
|||
|
||||
};
|
||||
|
||||
exports.CSXAttribute = CSXAttribute = (function() {
|
||||
class CSXAttribute extends Base {
|
||||
exports.JSXAttribute = JSXAttribute = (function() {
|
||||
class JSXAttribute extends Base {
|
||||
constructor({
|
||||
name: name1,
|
||||
value
|
||||
|
@ -2300,7 +2283,7 @@
|
|||
var ref1;
|
||||
super();
|
||||
this.name = name1;
|
||||
this.value = value != null ? (value = value.base, value instanceof StringLiteral ? value : new CSXExpressionContainer(value)) : null;
|
||||
this.value = value != null ? (value = value.base, value instanceof StringLiteral ? value : new JSXExpressionContainer(value)) : null;
|
||||
if ((ref1 = this.value) != null) {
|
||||
ref1.comments = value.comments;
|
||||
}
|
||||
|
@ -2316,10 +2299,6 @@
|
|||
return compiledName.concat(this.makeCode('='), val);
|
||||
}
|
||||
|
||||
astType() {
|
||||
return 'JSXAttribute';
|
||||
}
|
||||
|
||||
astProperties() {
|
||||
var ref1, ref2;
|
||||
return {
|
||||
|
@ -2330,14 +2309,14 @@
|
|||
|
||||
};
|
||||
|
||||
CSXAttribute.prototype.children = ['name', 'value'];
|
||||
JSXAttribute.prototype.children = ['name', 'value'];
|
||||
|
||||
return CSXAttribute;
|
||||
return JSXAttribute;
|
||||
|
||||
}).call(this);
|
||||
|
||||
exports.CSXAttributes = CSXAttributes = (function() {
|
||||
class CSXAttributes extends Base {
|
||||
exports.JSXAttributes = JSXAttributes = (function() {
|
||||
class JSXAttributes extends Base {
|
||||
constructor(arr) {
|
||||
var attribute, base, j, k, len1, len2, object, property, ref1, ref2, value, variable;
|
||||
super();
|
||||
|
@ -2349,15 +2328,15 @@
|
|||
({base} = object);
|
||||
if (base instanceof IdentifierLiteral) {
|
||||
// attribute with no value eg disabled
|
||||
attribute = new CSXAttribute({
|
||||
name: new CSXIdentifier(base.value).withLocationDataAndCommentsFrom(base)
|
||||
attribute = new JSXAttribute({
|
||||
name: new JSXIdentifier(base.value).withLocationDataAndCommentsFrom(base)
|
||||
});
|
||||
attribute.locationData = base.locationData;
|
||||
this.attributes.push(attribute);
|
||||
} else if (!base.generated) {
|
||||
// object spread attribute eg {...props}
|
||||
attribute = base.properties[0];
|
||||
attribute.csx = true;
|
||||
attribute.jsx = true;
|
||||
attribute.locationData = base.locationData;
|
||||
this.attributes.push(attribute);
|
||||
} else {
|
||||
|
@ -2366,8 +2345,8 @@
|
|||
for (k = 0, len2 = ref2.length; k < len2; k++) {
|
||||
property = ref2[k];
|
||||
({variable, value} = property);
|
||||
attribute = new CSXAttribute({
|
||||
name: new CSXIdentifier(variable.base.value).withLocationDataAndCommentsFrom(variable.base),
|
||||
attribute = new JSXAttribute({
|
||||
name: new JSXIdentifier(variable.base.value).withLocationDataAndCommentsFrom(variable.base),
|
||||
value
|
||||
});
|
||||
attribute.locationData = property.locationData;
|
||||
|
@ -2386,7 +2365,7 @@
|
|||
} = object);
|
||||
properties = (attribute != null ? attribute.properties : void 0) || [];
|
||||
if (!(attribute instanceof Obj || attribute instanceof IdentifierLiteral) || (attribute instanceof Obj && !attribute.generated && (properties.length > 1 || !(properties[0] instanceof Splat)))) {
|
||||
return object.error("Unexpected token. Allowed CSX attributes are: id=\"val\", src={source}, {props...} or attribute.");
|
||||
return object.error("Unexpected token. Allowed JSX attributes are: id=\"val\", src={source}, {props...} or attribute.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2415,15 +2394,15 @@
|
|||
|
||||
};
|
||||
|
||||
CSXAttributes.prototype.children = ['attributes'];
|
||||
JSXAttributes.prototype.children = ['attributes'];
|
||||
|
||||
return CSXAttributes;
|
||||
return JSXAttributes;
|
||||
|
||||
}).call(this);
|
||||
|
||||
// Node for a CSX element
|
||||
exports.CSXElement = CSXElement = (function() {
|
||||
class CSXElement extends Base {
|
||||
// Node for a JSX element
|
||||
exports.JSXElement = JSXElement = (function() {
|
||||
class JSXElement extends Base {
|
||||
constructor({
|
||||
tagName: tagName1,
|
||||
attributes,
|
||||
|
@ -2438,7 +2417,7 @@
|
|||
compileNode(o) {
|
||||
var fragments, ref1, tag;
|
||||
if ((ref1 = this.content) != null) {
|
||||
ref1.base.csx = true;
|
||||
ref1.base.jsx = true;
|
||||
}
|
||||
fragments = [this.makeCode('<')];
|
||||
fragments.push(...(tag = this.tagName.compileToFragments(o, LEVEL_ACCESS)));
|
||||
|
@ -2541,7 +2520,7 @@
|
|||
children = (function() {
|
||||
var j, len1, ref1, results;
|
||||
if (content instanceof StringLiteral) {
|
||||
return [new CSXText(content)]; // StringWithInterpolations
|
||||
return [new JSXText(content)]; // StringWithInterpolations
|
||||
} else {
|
||||
ref1 = this.content.unwrapAll().extractElements(o, {
|
||||
includeInterpolationWrappers: true
|
||||
|
@ -2550,17 +2529,17 @@
|
|||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
element = ref1[j];
|
||||
if (element instanceof StringLiteral) {
|
||||
results.push(new CSXText(element)); // Interpolation
|
||||
results.push(new JSXText(element)); // Interpolation
|
||||
} else {
|
||||
({expression} = element);
|
||||
if (expression == null) {
|
||||
results.push(new CSXEmptyExpression().withLocationDataFrom(element));
|
||||
results.push(new JSXEmptyExpression().withLocationDataFrom(element));
|
||||
} else {
|
||||
unwrapped = expression.unwrapAll();
|
||||
if (unwrapped instanceof CSXElement) {
|
||||
if (unwrapped instanceof JSXElement) {
|
||||
results.push(unwrapped);
|
||||
} else {
|
||||
results.push(new CSXExpressionContainer(unwrapped, {
|
||||
results.push(new JSXExpressionContainer(unwrapped, {
|
||||
locationData: element.locationData
|
||||
}));
|
||||
}
|
||||
|
@ -2573,7 +2552,7 @@
|
|||
results = [];
|
||||
for (j = 0, len1 = children.length; j < len1; j++) {
|
||||
child = children[j];
|
||||
if (!(child instanceof CSXText && child.value.length === 0)) {
|
||||
if (!(child instanceof JSXText && child.value.length === 0)) {
|
||||
results.push(child.ast(o));
|
||||
}
|
||||
}
|
||||
|
@ -2596,9 +2575,9 @@
|
|||
|
||||
};
|
||||
|
||||
CSXElement.prototype.children = ['tagName', 'attributes', 'content'];
|
||||
JSXElement.prototype.children = ['tagName', 'attributes', 'content'];
|
||||
|
||||
return CSXElement;
|
||||
return JSXElement;
|
||||
|
||||
}).call(this);
|
||||
|
||||
|
@ -2619,10 +2598,10 @@
|
|||
if (this.variable instanceof Value && this.variable.isNotCallable()) {
|
||||
this.variable.error("literal is not a function");
|
||||
}
|
||||
if (this.variable.base instanceof CSXTag) {
|
||||
return new CSXElement({
|
||||
if (this.variable.base instanceof JSXTag) {
|
||||
return new JSXElement({
|
||||
tagName: this.variable,
|
||||
attributes: new CSXAttributes(this.args[0].base),
|
||||
attributes: new JSXAttributes(this.args[0].base),
|
||||
content: this.args[1]
|
||||
});
|
||||
}
|
||||
|
@ -5836,7 +5815,7 @@
|
|||
compileNode(o) {
|
||||
var compiledSplat;
|
||||
compiledSplat = [this.makeCode('...'), ...this.name.compileToFragments(o, LEVEL_OP)];
|
||||
if (!this.csx) {
|
||||
if (!this.jsx) {
|
||||
return compiledSplat;
|
||||
}
|
||||
return [this.makeCode('{'), ...compiledSplat, this.makeCode('}')];
|
||||
|
@ -5847,7 +5826,7 @@
|
|||
}
|
||||
|
||||
astType() {
|
||||
if (this.csx) {
|
||||
if (this.jsx) {
|
||||
return 'JSXSpreadAttribute';
|
||||
} else if (this.lhs) {
|
||||
return 'RestElement';
|
||||
|
@ -6781,13 +6760,13 @@
|
|||
shouldWrapComment = (ref1 = expr.comments) != null ? ref1.some(function(comment) {
|
||||
return comment.here && !comment.unshift && !comment.newLine;
|
||||
}) : void 0;
|
||||
if (expr instanceof Value && expr.isAtomic() && !this.csxAttribute && !shouldWrapComment) {
|
||||
if (expr instanceof Value && expr.isAtomic() && !this.jsxAttribute && !shouldWrapComment) {
|
||||
expr.front = this.front;
|
||||
return expr.compileToFragments(o);
|
||||
}
|
||||
fragments = expr.compileToFragments(o, LEVEL_PAREN);
|
||||
bare = o.level < LEVEL_OP && !shouldWrapComment && (expr instanceof Op && !expr.isInOperator() || expr.unwrap() instanceof Call || (expr instanceof For && expr.returns)) && (o.level < LEVEL_COND || fragments.length <= 3);
|
||||
if (this.csxAttribute) {
|
||||
if (this.jsxAttribute) {
|
||||
return this.wrapInBraces(fragments);
|
||||
}
|
||||
if (bare) {
|
||||
|
@ -6863,7 +6842,7 @@
|
|||
}
|
||||
attachCommentsToNode(salvagedComments, node);
|
||||
}
|
||||
if ((unwrapped = (ref1 = node.expression) != null ? ref1.unwrapAll() : void 0) instanceof PassthroughLiteral && unwrapped.generated && !this.csx) {
|
||||
if ((unwrapped = (ref1 = node.expression) != null ? ref1.unwrapAll() : void 0) instanceof PassthroughLiteral && unwrapped.generated && !this.jsx) {
|
||||
commentPlaceholder = new StringLiteral('').withLocationDataFrom(node);
|
||||
commentPlaceholder.comments = unwrapped.comments;
|
||||
if (node.comments) {
|
||||
|
@ -6902,21 +6881,21 @@
|
|||
if (this.comments == null) {
|
||||
this.comments = (ref1 = this.startQuote) != null ? ref1.comments : void 0;
|
||||
}
|
||||
if (this.csxAttribute) {
|
||||
if (this.jsxAttribute) {
|
||||
wrapped = new Parens(new StringWithInterpolations(this.body));
|
||||
wrapped.csxAttribute = true;
|
||||
wrapped.jsxAttribute = true;
|
||||
return wrapped.compileNode(o);
|
||||
}
|
||||
elements = this.extractElements(o);
|
||||
fragments = [];
|
||||
if (!this.csx) {
|
||||
if (!this.jsx) {
|
||||
fragments.push(this.makeCode('`'));
|
||||
}
|
||||
for (j = 0, len1 = elements.length; j < len1; j++) {
|
||||
element = elements[j];
|
||||
if (element instanceof StringLiteral) {
|
||||
element.value = element.unquote(true, this.csx);
|
||||
if (!this.csx) {
|
||||
element.value = element.unquote(true, this.jsx);
|
||||
if (!this.jsx) {
|
||||
// Backticks and `${` inside template literals must be escaped.
|
||||
element.value = element.value.replace(/(\\*)(`|\$\{)/g, function(match, backslashes, toBeEscaped) {
|
||||
if (backslashes.length % 2 === 0) {
|
||||
|
@ -6928,7 +6907,7 @@
|
|||
}
|
||||
fragments.push(...element.compileToFragments(o));
|
||||
} else {
|
||||
if (!this.csx) {
|
||||
if (!this.jsx) {
|
||||
fragments.push(this.makeCode('$'));
|
||||
}
|
||||
code = element.compileToFragments(o, LEVEL_PAREN);
|
||||
|
@ -6951,7 +6930,7 @@
|
|||
fragments.push(...code);
|
||||
}
|
||||
}
|
||||
if (!this.csx) {
|
||||
if (!this.jsx) {
|
||||
fragments.push(this.makeCode('`'));
|
||||
}
|
||||
return fragments;
|
||||
|
@ -6960,7 +6939,7 @@
|
|||
isNestedTag(element) {
|
||||
var call;
|
||||
call = typeof element.unwrapAll === "function" ? element.unwrapAll() : void 0;
|
||||
return this.csx && call instanceof CSXElement;
|
||||
return this.jsx && call instanceof JSXElement;
|
||||
}
|
||||
|
||||
astType() {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -89,7 +89,7 @@
|
|||
this.addImplicitBracesAndParens();
|
||||
this.rescueStowawayComments();
|
||||
this.addLocationDataToGeneratedTokens();
|
||||
this.enforceValidCSXAttributes();
|
||||
this.enforceValidJSXAttributes();
|
||||
this.fixOutdentLocationData();
|
||||
this.exposeTokenDataToGrammar();
|
||||
if (typeof process !== "undefined" && process !== null ? (ref1 = process.env) != null ? ref1.DEBUG_REWRITTEN_TOKEN_STREAM : void 0 : void 0) {
|
||||
|
@ -578,11 +578,11 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Make sure only strings and wrapped expressions are used in CSX attributes.
|
||||
enforceValidCSXAttributes() {
|
||||
// Make sure only strings and wrapped expressions are used in JSX attributes.
|
||||
enforceValidJSXAttributes() {
|
||||
return this.scanTokens(function(token, i, tokens) {
|
||||
var next, ref;
|
||||
if (token.csxColon) {
|
||||
if (token.jsxColon) {
|
||||
next = tokens[i + 1];
|
||||
if ((ref = next[0]) !== 'STRING_START' && ref !== 'STRING' && ref !== '(') {
|
||||
throwSyntaxError('expected wrapped or quoted JSX attribute', next[2]);
|
||||
|
@ -993,7 +993,7 @@
|
|||
IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||||
|
||||
// If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
||||
IMPLICIT_CALL = ['IDENTIFIER', 'CSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'DO', 'DO_IIFE', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||||
IMPLICIT_CALL = ['IDENTIFIER', 'JSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'DO', 'DO_IIFE', 'YIELD', 'AWAIT', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||||
|
||||
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ grammar =
|
|||
|
||||
Identifier: [
|
||||
o 'IDENTIFIER', -> new IdentifierLiteral $1
|
||||
o 'CSX_TAG', -> new CSXTag $1.toString(),
|
||||
o 'JSX_TAG', -> new JSXTag $1.toString(),
|
||||
tagNameLocationData: $1.tagNameToken[2]
|
||||
closingTagOpeningBracketLocationData: $1.closingTagOpeningBracketToken?[2]
|
||||
closingTagSlashLocationData: $1.closingTagSlashToken?[2]
|
||||
|
|
|
@ -49,8 +49,8 @@ exports.Lexer = class Lexer
|
|||
@seenExport = no # Used to recognize `EXPORT FROM? AS?` tokens.
|
||||
@importSpecifierList = no # Used to identify when in an `IMPORT {...} FROM? ...`.
|
||||
@exportSpecifierList = no # Used to identify when in an `EXPORT {...} FROM? ...`.
|
||||
@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...} />).
|
||||
@jsxDepth = 0 # Used to optimize JSX checks, how deep in JSX we are.
|
||||
@jsxObjAttribute = {} # Used to detect if JSX attributes is wrapped in {} (<div {props...} />).
|
||||
|
||||
@chunkLine =
|
||||
opts.line or 0 # The start line for the current @chunk.
|
||||
|
@ -72,7 +72,7 @@ exports.Lexer = class Lexer
|
|||
@lineToken() or
|
||||
@stringToken() or
|
||||
@numberToken() or
|
||||
@csxToken() or
|
||||
@jsxToken() or
|
||||
@regexToken() or
|
||||
@jsToken() or
|
||||
@literalToken()
|
||||
|
@ -111,8 +111,8 @@ exports.Lexer = class Lexer
|
|||
# referenced as property names here, so you can still do `jQuery.is()` even
|
||||
# though `is` means `===` otherwise.
|
||||
identifierToken: ->
|
||||
inCSXTag = @atCSXTag()
|
||||
regex = if inCSXTag then CSX_ATTRIBUTE else IDENTIFIER
|
||||
inJSXTag = @atJSXTag()
|
||||
regex = if inJSXTag then JSX_ATTRIBUTE else IDENTIFIER
|
||||
return 0 unless match = regex.exec @chunk
|
||||
[input, id, colon] = match
|
||||
|
||||
|
@ -233,10 +233,10 @@ exports.Lexer = class Lexer
|
|||
[tagToken[2].first_line, tagToken[2].first_column, tagToken[2].range[0]] =
|
||||
[poppedToken[2].first_line, poppedToken[2].first_column, poppedToken[2].range[0]]
|
||||
if colon
|
||||
colonOffset = input.lastIndexOf if inCSXTag then '=' else ':'
|
||||
colonOffset = input.lastIndexOf if inJSXTag then '=' else ':'
|
||||
colonToken = @token ':', ':', offset: colonOffset, length: colon.length
|
||||
colonToken.csxColon = yes if inCSXTag # used by rewriter
|
||||
if inCSXTag and tag is 'IDENTIFIER' and prev[0] isnt ':'
|
||||
colonToken.jsxColon = yes if inJSXTag # used by rewriter
|
||||
if inJSXTag and tag is 'IDENTIFIER' and prev[0] isnt ':'
|
||||
@token ',', ',', length: 0, origin: tagToken
|
||||
|
||||
input.length
|
||||
|
@ -304,7 +304,7 @@ exports.Lexer = class Lexer
|
|||
@mergeInterpolationTokens tokens, {quote, indent, endOffset: end}, (value) =>
|
||||
@validateUnicodeCodePointEscapes value, delimiter: quote
|
||||
|
||||
if @atCSXTag()
|
||||
if @atJSXTag()
|
||||
@token ',', ',', length: 0, origin: @prev
|
||||
|
||||
end
|
||||
|
@ -543,15 +543,14 @@ exports.Lexer = class Lexer
|
|||
@tokens.pop()
|
||||
this
|
||||
|
||||
# CSX is like JSX but for CoffeeScript.
|
||||
csxToken: ->
|
||||
jsxToken: ->
|
||||
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 '<'
|
||||
match = CSX_IDENTIFIER.exec(@chunk[1...]) or CSX_FRAGMENT_IDENTIFIER.exec(@chunk[1...])
|
||||
match = JSX_IDENTIFIER.exec(@chunk[1...]) or JSX_FRAGMENT_IDENTIFIER.exec(@chunk[1...])
|
||||
return 0 unless match and (
|
||||
@csxDepth > 0 or
|
||||
@jsxDepth > 0 or
|
||||
# Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
||||
not (prev = @prev()) or
|
||||
prev.spaced or
|
||||
|
@ -563,7 +562,7 @@ exports.Lexer = class Lexer
|
|||
[id, properties...] = id.split '.'
|
||||
else
|
||||
properties = []
|
||||
tagToken = @token 'CSX_TAG', id,
|
||||
tagToken = @token 'JSX_TAG', id,
|
||||
length: id.length + 1
|
||||
data:
|
||||
openingBracketToken: @makeToken '<', '<'
|
||||
|
@ -577,9 +576,9 @@ exports.Lexer = class Lexer
|
|||
@token 'CALL_START', '(', generated: yes
|
||||
@token '[', '[', generated: yes
|
||||
@ends.push {tag: '/>', origin: tagToken, name: id, properties}
|
||||
@csxDepth++
|
||||
@jsxDepth++
|
||||
return fullId.length + 1
|
||||
else if csxTag = @atCSXTag()
|
||||
else if jsxTag = @atJSXTag()
|
||||
if @chunk[...2] is '/>' # Self-closing tag.
|
||||
@pair '/>'
|
||||
@token ']', ']',
|
||||
|
@ -591,15 +590,15 @@ exports.Lexer = class Lexer
|
|||
data:
|
||||
selfClosingSlashToken: @makeToken '/', '/'
|
||||
closingBracketToken: @makeToken '>', '>', offset: 1
|
||||
@csxDepth--
|
||||
@jsxDepth--
|
||||
return 2
|
||||
else if firstChar is '{'
|
||||
if prevChar is ':'
|
||||
token = @token '(', '('
|
||||
@csxObjAttribute[@csxDepth] = no
|
||||
@jsxObjAttribute[@jsxDepth] = no
|
||||
else
|
||||
token = @token '{', '{'
|
||||
@csxObjAttribute[@csxDepth] = yes
|
||||
@jsxObjAttribute[@jsxDepth] = yes
|
||||
@ends.push {tag: '}', origin: token}
|
||||
return 1
|
||||
else if firstChar is '>' # end of opening tag
|
||||
|
@ -611,13 +610,13 @@ exports.Lexer = class Lexer
|
|||
closingBracketToken: @makeToken '>', '>'
|
||||
@token ',', 'JSX_COMMA', generated: yes
|
||||
{tokens, index: end} =
|
||||
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
|
||||
@matchWithInterpolations INSIDE_JSX, '>', '</', JSX_INTERPOLATION
|
||||
@mergeInterpolationTokens tokens, {endOffset: end}, (value) =>
|
||||
@validateUnicodeCodePointEscapes value, delimiter: '>'
|
||||
match = CSX_IDENTIFIER.exec(@chunk[end...]) or CSX_FRAGMENT_IDENTIFIER.exec(@chunk[end...])
|
||||
if not match or match[1] isnt "#{csxTag.name}#{(".#{property}" for property in csxTag.properties).join ''}"
|
||||
@error "expected corresponding CSX closing tag for #{csxTag.name}",
|
||||
csxTag.origin.data.tagNameToken[2]
|
||||
match = JSX_IDENTIFIER.exec(@chunk[end...]) or JSX_FRAGMENT_IDENTIFIER.exec(@chunk[end...])
|
||||
if not match or match[1] isnt "#{jsxTag.name}#{(".#{property}" for property in jsxTag.properties).join ''}"
|
||||
@error "expected corresponding JSX closing tag for #{jsxTag.name}",
|
||||
jsxTag.origin.data.tagNameToken[2]
|
||||
[, fullTagName] = match
|
||||
afterTag = end + fullTagName.length
|
||||
if @chunk[afterTag] isnt '>'
|
||||
|
@ -635,16 +634,16 @@ exports.Lexer = class Lexer
|
|||
closingTagClosingBracketToken: @makeToken '>', '>', offset: end + fullTagName.length
|
||||
# make the closing tag location data more easily accessible to the grammar
|
||||
addTokenData openingTagToken, endToken.data
|
||||
@csxDepth--
|
||||
@jsxDepth--
|
||||
return afterTag + 1
|
||||
else
|
||||
return 0
|
||||
else if @atCSXTag 1
|
||||
else if @atJSXTag 1
|
||||
if firstChar is '}'
|
||||
@pair firstChar
|
||||
if @csxObjAttribute[@csxDepth]
|
||||
if @jsxObjAttribute[@jsxDepth]
|
||||
@token '}', '}'
|
||||
@csxObjAttribute[@csxDepth] = no
|
||||
@jsxObjAttribute[@jsxDepth] = no
|
||||
else
|
||||
@token ')', ')'
|
||||
@token ',', ','
|
||||
|
@ -654,8 +653,8 @@ exports.Lexer = class Lexer
|
|||
else
|
||||
return 0
|
||||
|
||||
atCSXTag: (depth = 0) ->
|
||||
return no if @csxDepth is 0
|
||||
atJSXTag: (depth = 0) ->
|
||||
return no if @jsxDepth is 0
|
||||
i = @ends.length - 1
|
||||
i-- while @ends[i]?.tag is 'OUTDENT' or depth-- > 0 # Ignore indents.
|
||||
last = @ends[i]
|
||||
|
@ -782,9 +781,9 @@ exports.Lexer = class Lexer
|
|||
# `#{` if interpolations are desired).
|
||||
# - `delimiter` is the delimiter of the token. Examples are `'`, `"`, `'''`,
|
||||
# `"""` and `///`.
|
||||
# - `closingDelimiter` is different from `delimiter` only in CSX
|
||||
# - `interpolators` matches the start of an interpolation, for CSX it's both
|
||||
# `{` and `<` (i.e. nested CSX tag)
|
||||
# - `closingDelimiter` is different from `delimiter` only in JSX
|
||||
# - `interpolators` matches the start of an interpolation, for JSX it's both
|
||||
# `{` and `<` (i.e. nested JSX tag)
|
||||
#
|
||||
# This method allows us to have strings within interpolations within strings,
|
||||
# ad infinitum.
|
||||
|
@ -1163,17 +1162,17 @@ IDENTIFIER = /// ^
|
|||
( [^\n\S]* : (?!:) )? # Is this a property name?
|
||||
///
|
||||
|
||||
CSX_IDENTIFIER = /// ^
|
||||
JSX_IDENTIFIER = /// ^
|
||||
(?![\d<]) # Must not start with `<`.
|
||||
( (?: (?!\s)[\.\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s and `.`s.
|
||||
///
|
||||
|
||||
# Fragment: <></>
|
||||
CSX_FRAGMENT_IDENTIFIER = /// ^
|
||||
JSX_FRAGMENT_IDENTIFIER = /// ^
|
||||
()> # Ends immediately with `>`.
|
||||
///
|
||||
|
||||
CSX_ATTRIBUTE = /// ^
|
||||
JSX_ATTRIBUTE = /// ^
|
||||
(?!\d)
|
||||
( (?: (?!\s)[\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s.
|
||||
( [^\S]* = (?!=) )? # Is this an attribute with a value?
|
||||
|
@ -1215,15 +1214,15 @@ STRING_DOUBLE = /// ^(?: [^\\"#] | \\[\s\S] | \#(?!\{) )* ///
|
|||
HEREDOC_SINGLE = /// ^(?: [^\\'] | \\[\s\S] | '(?!'') )* ///
|
||||
HEREDOC_DOUBLE = /// ^(?: [^\\"#] | \\[\s\S] | "(?!"") | \#(?!\{) )* ///
|
||||
|
||||
INSIDE_CSX = /// ^(?:
|
||||
INSIDE_JSX = /// ^(?:
|
||||
[^
|
||||
\{ # Start of CoffeeScript interpolation.
|
||||
< # Maybe CSX tag (`<` not allowed even if bare).
|
||||
< # Maybe JSX tag (`<` not allowed even if bare).
|
||||
]
|
||||
)* /// # Similar to `HEREDOC_DOUBLE` but there is no escaping.
|
||||
CSX_INTERPOLATION = /// ^(?:
|
||||
JSX_INTERPOLATION = /// ^(?:
|
||||
\{ # CoffeeScript interpolation.
|
||||
| <(?!/) # CSX opening tag.
|
||||
| <(?!/) # JSX opening tag.
|
||||
)///
|
||||
|
||||
HEREDOC_INDENT = /\n+([^\n\S]*)(?=\S)/g
|
||||
|
|
137
src/nodes.coffee
137
src/nodes.coffee
|
@ -563,14 +563,14 @@ exports.Block = class Block extends Base
|
|||
len = @expressions.length
|
||||
[..., lastExp] = @expressions
|
||||
lastExp = lastExp?.unwrap() or no
|
||||
# We also need to check that we’re not returning a CSX tag if there’s an
|
||||
# We also need to check that we’re not returning a JSX tag if there’s an
|
||||
# adjacent one at the same level; JSX doesn’t allow that.
|
||||
if lastExp and lastExp instanceof Parens and lastExp.body.expressions.length > 1
|
||||
{body:{expressions}} = lastExp
|
||||
[..., penult, last] = expressions
|
||||
penult = penult.unwrap()
|
||||
last = last.unwrap()
|
||||
if penult instanceof CSXElement and last instanceof CSXElement
|
||||
if penult instanceof JSXElement and last instanceof JSXElement
|
||||
expressions[expressions.length - 1].error 'Adjacent JSX elements must be wrapped in an enclosing tag'
|
||||
while len--
|
||||
expr = @expressions[len]
|
||||
|
@ -940,13 +940,13 @@ exports.StringLiteral = class StringLiteral extends Literal
|
|||
}
|
||||
|
||||
compileNode: (o) ->
|
||||
return [@makeCode @unquote(yes, yes)] if @csx
|
||||
return [@makeCode @unquote(yes, yes)] if @jsx
|
||||
super o
|
||||
|
||||
unquote: (doubleQuote = no, csx = no) ->
|
||||
unquote: (doubleQuote = no, jsx = no) ->
|
||||
unquoted = @value[1...-1]
|
||||
unquoted = unquoted.replace /\\"/g, '"' if doubleQuote
|
||||
unquoted = unquoted.replace /\\n/g, '\n' if csx
|
||||
unquoted = unquoted.replace /\\n/g, '\n' if jsx
|
||||
unquoted
|
||||
|
||||
# `StringLiteral`s can represent either entire literal strings
|
||||
|
@ -1025,7 +1025,7 @@ exports.IdentifierLiteral = class IdentifierLiteral extends Literal
|
|||
iterator @
|
||||
|
||||
astType: ->
|
||||
if @csx
|
||||
if @jsx
|
||||
'JSXIdentifier'
|
||||
else
|
||||
'Identifier'
|
||||
|
@ -1034,27 +1034,11 @@ exports.IdentifierLiteral = class IdentifierLiteral extends Literal
|
|||
return
|
||||
name: @value
|
||||
|
||||
exports.CSXTag = class CSXTag extends IdentifierLiteral
|
||||
constructor: (value, {
|
||||
@tagNameLocationData
|
||||
@closingTagOpeningBracketLocationData
|
||||
@closingTagSlashLocationData
|
||||
@closingTagNameLocationData
|
||||
@closingTagClosingBracketLocationData
|
||||
}) ->
|
||||
super value
|
||||
|
||||
astType: -> 'JSXIdentifier'
|
||||
|
||||
astProperties: ->
|
||||
return
|
||||
name: @value
|
||||
|
||||
exports.PropertyName = class PropertyName extends Literal
|
||||
isAssignable: YES
|
||||
|
||||
astType: ->
|
||||
if @csx
|
||||
if @jsx
|
||||
'JSXIdentifier'
|
||||
else
|
||||
'Identifier'
|
||||
|
@ -1269,7 +1253,7 @@ exports.Value = class Value extends Base
|
|||
@isUndefined() or @isNull() or @isBoolean()
|
||||
|
||||
isStatement : (o) -> not @properties.length and @base.isStatement o
|
||||
isCSXTag : -> @base instanceof CSXTag
|
||||
isJSXTag : -> @base instanceof JSXTag
|
||||
assigns : (name) -> not @properties.length and @base.assigns name
|
||||
jumps : (o) -> not @properties.length and @base.jumps o
|
||||
|
||||
|
@ -1395,7 +1379,7 @@ exports.Value = class Value extends Base
|
|||
super o, level
|
||||
|
||||
astType: ->
|
||||
if @isCSXTag()
|
||||
if @isJSXTag()
|
||||
'JSXMemberExpression'
|
||||
else
|
||||
'MemberExpression'
|
||||
|
@ -1405,7 +1389,7 @@ exports.Value = class Value extends Base
|
|||
# a child `Value` node assigned to the `object` property.
|
||||
astProperties: (o) ->
|
||||
[..., property] = @properties
|
||||
property.name.csx = yes if @isCSXTag()
|
||||
property.name.jsx = yes if @isJSXTag()
|
||||
computed = property instanceof Index or property.name?.unwrap() not instanceof PropertyName
|
||||
return {
|
||||
object: @object().ast o, LEVEL_ACCESS
|
||||
|
@ -1416,7 +1400,7 @@ exports.Value = class Value extends Base
|
|||
}
|
||||
|
||||
astLocationData: ->
|
||||
return super() unless @isCSXTag()
|
||||
return super() unless @isJSXTag()
|
||||
# don't include leading < of JSX tag in location data
|
||||
mergeAstLocationData(
|
||||
jisonLocationDataToAstLocationData(@base.tagNameLocationData),
|
||||
|
@ -1497,15 +1481,29 @@ exports.LineComment = class LineComment extends Base
|
|||
fragment.isComment = fragment.isLineComment = yes
|
||||
fragment
|
||||
|
||||
#### CSX
|
||||
#### JSX
|
||||
|
||||
exports.CSXIdentifier = class CSXIdentifier extends IdentifierLiteral
|
||||
exports.JSXIdentifier = class JSXIdentifier extends IdentifierLiteral
|
||||
astType: -> 'JSXIdentifier'
|
||||
|
||||
exports.CSXExpressionContainer = class CSXExpressionContainer extends Base
|
||||
exports.JSXTag = class JSXTag extends JSXIdentifier
|
||||
constructor: (value, {
|
||||
@tagNameLocationData
|
||||
@closingTagOpeningBracketLocationData
|
||||
@closingTagSlashLocationData
|
||||
@closingTagNameLocationData
|
||||
@closingTagClosingBracketLocationData
|
||||
}) ->
|
||||
super value
|
||||
|
||||
astProperties: ->
|
||||
return
|
||||
name: @value
|
||||
|
||||
exports.JSXExpressionContainer = class JSXExpressionContainer extends Base
|
||||
constructor: (@expression, {locationData} = {}) ->
|
||||
super()
|
||||
@expression.csxAttribute = yes
|
||||
@expression.jsxAttribute = yes
|
||||
@locationData = locationData ? @expression.locationData
|
||||
|
||||
children: ['expression']
|
||||
|
@ -1513,23 +1511,18 @@ exports.CSXExpressionContainer = class CSXExpressionContainer extends Base
|
|||
compileNode: (o) ->
|
||||
@expression.compileNode(o)
|
||||
|
||||
astType: -> 'JSXExpressionContainer'
|
||||
|
||||
astProperties: ->
|
||||
return
|
||||
expression: @expression.ast()
|
||||
|
||||
exports.CSXEmptyExpression = class CSXEmptyExpression extends Base
|
||||
astType: -> 'JSXEmptyExpression'
|
||||
exports.JSXEmptyExpression = class JSXEmptyExpression extends Base
|
||||
|
||||
exports.CSXText = class CSXText extends Base
|
||||
exports.JSXText = class JSXText extends Base
|
||||
constructor: (stringLiteral) ->
|
||||
super()
|
||||
@value = stringLiteral.unquote yes, yes
|
||||
@locationData = stringLiteral.locationData
|
||||
|
||||
astType: -> 'JSXText'
|
||||
|
||||
astProperties: ->
|
||||
return {
|
||||
@value
|
||||
|
@ -1537,7 +1530,7 @@ exports.CSXText = class CSXText extends Base
|
|||
raw: @value
|
||||
}
|
||||
|
||||
exports.CSXAttribute = class CSXAttribute extends Base
|
||||
exports.JSXAttribute = class JSXAttribute extends Base
|
||||
constructor: ({@name, value}) ->
|
||||
super()
|
||||
@value =
|
||||
|
@ -1546,7 +1539,7 @@ exports.CSXAttribute = class CSXAttribute extends Base
|
|||
if value instanceof StringLiteral
|
||||
value
|
||||
else
|
||||
new CSXExpressionContainer value
|
||||
new JSXExpressionContainer value
|
||||
else
|
||||
null
|
||||
@value?.comments = value.comments
|
||||
|
@ -1559,14 +1552,12 @@ exports.CSXAttribute = class CSXAttribute extends Base
|
|||
val = @value.compileToFragments o, LEVEL_LIST
|
||||
compiledName.concat @makeCode('='), val
|
||||
|
||||
astType: -> 'JSXAttribute'
|
||||
|
||||
astProperties: ->
|
||||
return
|
||||
name: @name.ast()
|
||||
value: @value?.ast() ? null
|
||||
|
||||
exports.CSXAttributes = class CSXAttributes extends Base
|
||||
exports.JSXAttributes = class JSXAttributes extends Base
|
||||
constructor: (arr) ->
|
||||
super()
|
||||
@attributes = []
|
||||
|
@ -1575,21 +1566,21 @@ exports.CSXAttributes = class CSXAttributes extends Base
|
|||
{base} = object
|
||||
if base instanceof IdentifierLiteral
|
||||
# attribute with no value eg disabled
|
||||
attribute = new CSXAttribute name: new CSXIdentifier(base.value).withLocationDataAndCommentsFrom base
|
||||
attribute = new JSXAttribute name: new JSXIdentifier(base.value).withLocationDataAndCommentsFrom base
|
||||
attribute.locationData = base.locationData
|
||||
@attributes.push attribute
|
||||
else if not base.generated
|
||||
# object spread attribute eg {...props}
|
||||
attribute = base.properties[0]
|
||||
attribute.csx = yes
|
||||
attribute.jsx = yes
|
||||
attribute.locationData = base.locationData
|
||||
@attributes.push attribute
|
||||
else
|
||||
# Obj containing attributes with values eg a="b" c={d}
|
||||
for property in base.properties
|
||||
{variable, value} = property
|
||||
attribute = new CSXAttribute {
|
||||
name: new CSXIdentifier(variable.base.value).withLocationDataAndCommentsFrom variable.base
|
||||
attribute = new JSXAttribute {
|
||||
name: new JSXIdentifier(variable.base.value).withLocationDataAndCommentsFrom variable.base
|
||||
value
|
||||
}
|
||||
attribute.locationData = property.locationData
|
||||
|
@ -1604,7 +1595,7 @@ exports.CSXAttributes = class CSXAttributes extends Base
|
|||
properties = attribute?.properties or []
|
||||
if not (attribute instanceof Obj or attribute instanceof IdentifierLiteral) or (attribute instanceof Obj and not attribute.generated and (properties.length > 1 or not (properties[0] instanceof Splat)))
|
||||
object.error """
|
||||
Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
"""
|
||||
|
||||
compileNode: (o) ->
|
||||
|
@ -1617,15 +1608,15 @@ exports.CSXAttributes = class CSXAttributes extends Base
|
|||
ast: (o) ->
|
||||
attribute.ast(o) for attribute in @attributes
|
||||
|
||||
# Node for a CSX element
|
||||
exports.CSXElement = class CSXElement extends Base
|
||||
# Node for a JSX element
|
||||
exports.JSXElement = class JSXElement extends Base
|
||||
constructor: ({@tagName, @attributes, @content}) ->
|
||||
super()
|
||||
|
||||
children: ['tagName', 'attributes', 'content']
|
||||
|
||||
compileNode: (o) ->
|
||||
@content?.base.csx = yes
|
||||
@content?.base.jsx = yes
|
||||
fragments = [@makeCode('<')]
|
||||
fragments.push (tag = @tagName.compileToFragments(o, LEVEL_ACCESS))...
|
||||
fragments.push @attributes.compileToFragments(o)...
|
||||
|
@ -1719,23 +1710,23 @@ exports.CSXElement = class CSXElement extends Base
|
|||
content = @content.unwrapAll()
|
||||
children =
|
||||
if content instanceof StringLiteral
|
||||
[new CSXText content]
|
||||
[new JSXText content]
|
||||
else # StringWithInterpolations
|
||||
for element in @content.unwrapAll().extractElements o, includeInterpolationWrappers: yes
|
||||
if element instanceof StringLiteral
|
||||
new CSXText element
|
||||
new JSXText element
|
||||
else # Interpolation
|
||||
{expression} = element
|
||||
unless expression?
|
||||
new CSXEmptyExpression().withLocationDataFrom element
|
||||
new JSXEmptyExpression().withLocationDataFrom element
|
||||
else
|
||||
unwrapped = expression.unwrapAll()
|
||||
if unwrapped instanceof CSXElement
|
||||
if unwrapped instanceof JSXElement
|
||||
unwrapped
|
||||
else
|
||||
new CSXExpressionContainer unwrapped, locationData: element.locationData
|
||||
new JSXExpressionContainer unwrapped, locationData: element.locationData
|
||||
|
||||
child.ast(o) for child in children when not (child instanceof CSXText and child.value.length is 0)
|
||||
child.ast(o) for child in children when not (child instanceof JSXText and child.value.length is 0)
|
||||
|
||||
astProperties: (o) ->
|
||||
Object.assign(
|
||||
|
@ -1765,10 +1756,10 @@ exports.Call = class Call extends Base
|
|||
if @variable instanceof Value and @variable.isNotCallable()
|
||||
@variable.error "literal is not a function"
|
||||
|
||||
if @variable.base instanceof CSXTag
|
||||
return new CSXElement(
|
||||
if @variable.base instanceof JSXTag
|
||||
return new JSXElement(
|
||||
tagName: @variable
|
||||
attributes: new CSXAttributes @args[0].base
|
||||
attributes: new JSXAttributes @args[0].base
|
||||
content: @args[1]
|
||||
)
|
||||
|
||||
|
@ -3905,13 +3896,13 @@ exports.Splat = class Splat extends Base
|
|||
|
||||
compileNode: (o) ->
|
||||
compiledSplat = [@makeCode('...'), @name.compileToFragments(o, LEVEL_OP)...]
|
||||
return compiledSplat unless @csx
|
||||
return compiledSplat unless @jsx
|
||||
return [@makeCode('{'), compiledSplat..., @makeCode('}')]
|
||||
|
||||
unwrap: -> @name
|
||||
|
||||
astType: ->
|
||||
if @csx
|
||||
if @jsx
|
||||
'JSXSpreadAttribute'
|
||||
else if @lhs
|
||||
'RestElement'
|
||||
|
@ -4527,7 +4518,7 @@ exports.Parens = class Parens extends Base
|
|||
# by comment-based type annotations from JavaScript labels.
|
||||
shouldWrapComment = expr.comments?.some(
|
||||
(comment) -> comment.here and not comment.unshift and not comment.newLine)
|
||||
if expr instanceof Value and expr.isAtomic() and not @csxAttribute and not shouldWrapComment
|
||||
if expr instanceof Value and expr.isAtomic() and not @jsxAttribute and not shouldWrapComment
|
||||
expr.front = @front
|
||||
return expr.compileToFragments o
|
||||
fragments = expr.compileToFragments o, LEVEL_PAREN
|
||||
|
@ -4535,7 +4526,7 @@ exports.Parens = class Parens extends Base
|
|||
expr instanceof Op and not expr.isInOperator() or expr.unwrap() instanceof Call or
|
||||
(expr instanceof For and expr.returns)
|
||||
) and (o.level < LEVEL_COND or fragments.length <= 3)
|
||||
return @wrapInBraces fragments if @csxAttribute
|
||||
return @wrapInBraces fragments if @jsxAttribute
|
||||
if bare then fragments else @wrapInParentheses fragments
|
||||
|
||||
ast: (o) -> @body.unwrap().ast o, LEVEL_PAREN
|
||||
|
@ -4580,7 +4571,7 @@ exports.StringWithInterpolations = class StringWithInterpolations extends Base
|
|||
comment.unshift = yes
|
||||
comment.newLine = yes
|
||||
attachCommentsToNode salvagedComments, node
|
||||
if (unwrapped = node.expression?.unwrapAll()) instanceof PassthroughLiteral and unwrapped.generated and not @csx
|
||||
if (unwrapped = node.expression?.unwrapAll()) instanceof PassthroughLiteral and unwrapped.generated and not @jsx
|
||||
commentPlaceholder = new StringLiteral('').withLocationDataFrom node
|
||||
commentPlaceholder.comments = unwrapped.comments
|
||||
(commentPlaceholder.comments ?= []).push node.comments... if node.comments
|
||||
|
@ -4606,19 +4597,19 @@ exports.StringWithInterpolations = class StringWithInterpolations extends Base
|
|||
compileNode: (o) ->
|
||||
@comments ?= @startQuote?.comments
|
||||
|
||||
if @csxAttribute
|
||||
if @jsxAttribute
|
||||
wrapped = new Parens new StringWithInterpolations @body
|
||||
wrapped.csxAttribute = yes
|
||||
wrapped.jsxAttribute = yes
|
||||
return wrapped.compileNode o
|
||||
|
||||
elements = @extractElements o
|
||||
|
||||
fragments = []
|
||||
fragments.push @makeCode '`' unless @csx
|
||||
fragments.push @makeCode '`' unless @jsx
|
||||
for element in elements
|
||||
if element instanceof StringLiteral
|
||||
element.value = element.unquote yes, @csx
|
||||
unless @csx
|
||||
element.value = element.unquote yes, @jsx
|
||||
unless @jsx
|
||||
# Backticks and `${` inside template literals must be escaped.
|
||||
element.value = element.value.replace /(\\*)(`|\$\{)/g, (match, backslashes, toBeEscaped) ->
|
||||
if backslashes.length % 2 is 0
|
||||
|
@ -4627,7 +4618,7 @@ exports.StringWithInterpolations = class StringWithInterpolations extends Base
|
|||
match
|
||||
fragments.push element.compileToFragments(o)...
|
||||
else
|
||||
fragments.push @makeCode '$' unless @csx
|
||||
fragments.push @makeCode '$' unless @jsx
|
||||
code = element.compileToFragments(o, LEVEL_PAREN)
|
||||
if not @isNestedTag(element) or
|
||||
code.some((fragment) -> fragment.comments?.some((comment) -> comment.here is no))
|
||||
|
@ -4641,12 +4632,12 @@ exports.StringWithInterpolations = class StringWithInterpolations extends Base
|
|||
code[0].isStringWithInterpolations = yes
|
||||
code[code.length - 1].isStringWithInterpolations = yes
|
||||
fragments.push code...
|
||||
fragments.push @makeCode '`' unless @csx
|
||||
fragments.push @makeCode '`' unless @jsx
|
||||
fragments
|
||||
|
||||
isNestedTag: (element) ->
|
||||
call = element.unwrapAll?()
|
||||
@csx and call instanceof CSXElement
|
||||
@jsx and call instanceof JSXElement
|
||||
|
||||
astType: -> 'TemplateLiteral'
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ exports.Rewriter = class Rewriter
|
|||
@addImplicitBracesAndParens()
|
||||
@rescueStowawayComments()
|
||||
@addLocationDataToGeneratedTokens()
|
||||
@enforceValidCSXAttributes()
|
||||
@enforceValidJSXAttributes()
|
||||
@fixOutdentLocationData()
|
||||
@exposeTokenDataToGrammar()
|
||||
if process?.env?.DEBUG_REWRITTEN_TOKEN_STREAM
|
||||
|
@ -409,10 +409,10 @@ exports.Rewriter = class Rewriter
|
|||
endImplicitObject i + offset
|
||||
return forward(1)
|
||||
|
||||
# Make sure only strings and wrapped expressions are used in CSX attributes.
|
||||
enforceValidCSXAttributes: ->
|
||||
# Make sure only strings and wrapped expressions are used in JSX attributes.
|
||||
enforceValidJSXAttributes: ->
|
||||
@scanTokens (token, i, tokens) ->
|
||||
if token.csxColon
|
||||
if token.jsxColon
|
||||
next = tokens[i + 1]
|
||||
if next[0] not in ['STRING_START', 'STRING', '(']
|
||||
throwSyntaxError 'expected wrapped or quoted JSX attribute', next[2]
|
||||
|
@ -722,7 +722,7 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'IN
|
|||
|
||||
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
||||
IMPLICIT_CALL = [
|
||||
'IDENTIFIER', 'CSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN'
|
||||
'IDENTIFIER', 'JSX_TAG', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN'
|
||||
'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS'
|
||||
'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS'
|
||||
'UNDEFINED', 'NULL', 'BOOL'
|
||||
|
|
|
@ -200,7 +200,7 @@ test "AST as expected for IdentifierLiteral node", ->
|
|||
type: 'Identifier'
|
||||
name: 'id'
|
||||
|
||||
test "AST as expected for CSXTag node", ->
|
||||
test "AST as expected for JSXTag node", ->
|
||||
testExpression '<CSXY />',
|
||||
type: 'JSXElement'
|
||||
openingElement:
|
||||
|
|
|
@ -2241,7 +2241,7 @@ test "AST location data as expected for Existence node", ->
|
|||
line: 1
|
||||
column: 7
|
||||
|
||||
test "AST location data as expected for CSXTag node", ->
|
||||
test "AST location data as expected for JSXTag node", ->
|
||||
testAstLocationData '<CSXY />',
|
||||
type: 'JSXElement'
|
||||
openingElement:
|
||||
|
|
|
@ -725,7 +725,7 @@ test "Block comment in an interpolated string", ->
|
|||
eqJS '"a#{### Comment ###}b"', '`a${/* Comment */""}b`;'
|
||||
eqJS '"a#{### 1 ###}b#{### 2 ###}c"', '`a${/* 1 */""}b${/* 2 */""}c`;'
|
||||
|
||||
test "#4629: Block comment in CSX interpolation", ->
|
||||
test "#4629: Block comment in JSX interpolation", ->
|
||||
eqJS '<div>{### Comment ###}</div>', '<div>{/* Comment */}</div>;'
|
||||
eqJS '''
|
||||
<div>
|
||||
|
|
|
@ -1589,17 +1589,17 @@ test "#4248: Unicode code point escapes", ->
|
|||
\ ^\^^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "CSX error: non-matching tag names", ->
|
||||
test "JSX error: non-matching tag names", ->
|
||||
assertErrorFormat '''
|
||||
<div><span></div></span>
|
||||
''',
|
||||
'''
|
||||
[stdin]:1:7: error: expected corresponding CSX closing tag for span
|
||||
[stdin]:1:7: error: expected corresponding JSX closing tag for span
|
||||
<div><span></div></span>
|
||||
^^^^
|
||||
'''
|
||||
|
||||
test "CSX error: bare expressions not allowed", ->
|
||||
test "JSX error: bare expressions not allowed", ->
|
||||
assertErrorFormat '''
|
||||
<div x=3 />
|
||||
''',
|
||||
|
@ -1609,7 +1609,7 @@ test "CSX error: bare expressions not allowed", ->
|
|||
^
|
||||
'''
|
||||
|
||||
test "CSX error: unescaped opening tag angle bracket disallowed", ->
|
||||
test "JSX error: unescaped opening tag angle bracket disallowed", ->
|
||||
assertErrorFormat '''
|
||||
<Person><<</Person>
|
||||
''',
|
||||
|
@ -1619,7 +1619,7 @@ test "CSX error: unescaped opening tag angle bracket disallowed", ->
|
|||
^^
|
||||
'''
|
||||
|
||||
test "CSX error: ambiguous tag-like expression", ->
|
||||
test "JSX error: ambiguous tag-like expression", ->
|
||||
assertErrorFormat '''
|
||||
x = a <b > c
|
||||
''',
|
||||
|
@ -1629,51 +1629,51 @@ test "CSX error: ambiguous tag-like expression", ->
|
|||
^
|
||||
'''
|
||||
|
||||
test 'CSX error: invalid attributes', ->
|
||||
test 'JSX error: invalid attributes', ->
|
||||
assertErrorFormatAst '''
|
||||
<div a="b" {props} />
|
||||
''', '''
|
||||
[stdin]:1:12: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
[stdin]:1:12: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
<div a="b" {props} />
|
||||
^^^^^^^
|
||||
'''
|
||||
assertErrorFormatAst '''
|
||||
<div a={b} {a:{b}} />
|
||||
''', '''
|
||||
[stdin]:1:12: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
[stdin]:1:12: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
<div a={b} {a:{b}} />
|
||||
^^^^^^^
|
||||
'''
|
||||
assertErrorFormatAst '''
|
||||
<div {"#{a}"} />
|
||||
''', '''
|
||||
[stdin]:1:6: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
[stdin]:1:6: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
<div {"#{a}"} />
|
||||
^^^^^^^^
|
||||
'''
|
||||
assertErrorFormatAst '''
|
||||
<div props... />
|
||||
''', '''
|
||||
[stdin]:1:11: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
[stdin]:1:11: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
<div props... />
|
||||
^^^
|
||||
'''
|
||||
assertErrorFormatAst '''
|
||||
<div {a:"b", props..., c:d()} />
|
||||
''', '''
|
||||
[stdin]:1:6: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
[stdin]:1:6: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
<div {a:"b", props..., c:d()} />
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
'''
|
||||
assertErrorFormatAst '''
|
||||
<div {props..., a, b} />
|
||||
''', '''
|
||||
[stdin]:1:6: error: Unexpected token. Allowed CSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
[stdin]:1:6: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
|
||||
<div {props..., a, b} />
|
||||
^^^^^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test '#5034: CSX error: Adjacent JSX elements must be wrapped in an enclosing tag', ->
|
||||
test '#5034: JSX error: Adjacent JSX elements must be wrapped in an enclosing tag', ->
|
||||
assertErrorFormat '''
|
||||
render = -> (
|
||||
<Row>a</Row>
|
||||
|
|
|
@ -184,7 +184,7 @@ test 'escaped CoffeeScript attribute over multiple lines', ->
|
|||
<Person name={test() ? 'yes' : 'no'} />;
|
||||
'''
|
||||
|
||||
test 'multiple line escaped CoffeeScript with nested CSX', ->
|
||||
test 'multiple line escaped CoffeeScript with nested JSX', ->
|
||||
eqJS '''
|
||||
<Person name={
|
||||
if test()
|
||||
|
@ -222,7 +222,7 @@ test 'multiple line escaped CoffeeScript with nested CSX', ->
|
|||
</Person>;
|
||||
'''
|
||||
|
||||
test 'nested CSX within an attribute, with object attr value', ->
|
||||
test 'nested JSX within an attribute, with object attr value', ->
|
||||
eqJS '''
|
||||
<Company>
|
||||
<Person name={<NameComponent attr3={ {'a': {}, b: '{'} } />} />
|
||||
|
@ -248,7 +248,7 @@ test 'complex nesting', ->
|
|||
})} />;
|
||||
'''
|
||||
|
||||
test 'multiline tag with nested CSX within an attribute', ->
|
||||
test 'multiline tag with nested JSX within an attribute', ->
|
||||
eqJS '''
|
||||
<Person
|
||||
name={
|
||||
|
@ -299,7 +299,7 @@ test 'lots of attributes', ->
|
|||
<Person eyes={2} friends={getFriends()} popular="yes" active={isActive() ? 'active' : 'inactive'} data-attr='works' checked check={me_out} />;
|
||||
'''
|
||||
|
||||
# TODO: fix partially indented CSX
|
||||
# TODO: fix partially indented JSX
|
||||
# test 'multiline elements', ->
|
||||
# eqJS '''
|
||||
# <div something={
|
||||
|
@ -378,7 +378,7 @@ test 'heregex', ->
|
|||
<Person />;
|
||||
'''
|
||||
|
||||
test 'comment within CSX is not treated as comment', ->
|
||||
test 'comment within JSX is not treated as comment', ->
|
||||
eqJS '''
|
||||
<Person>
|
||||
# i am not a comment
|
||||
|
@ -389,7 +389,7 @@ test 'comment within CSX is not treated as comment', ->
|
|||
</Person>;
|
||||
'''
|
||||
|
||||
test 'comment at start of CSX escape', ->
|
||||
test 'comment at start of JSX escape', ->
|
||||
eqJS '''
|
||||
<Person>
|
||||
{# i am a comment
|
||||
|
@ -403,7 +403,7 @@ test 'comment at start of CSX escape', ->
|
|||
</Person>;
|
||||
'''
|
||||
|
||||
test 'comment at end of CSX escape', ->
|
||||
test 'comment at end of JSX escape', ->
|
||||
eqJS '''
|
||||
<Person>
|
||||
{"i am a string"
|
||||
|
@ -418,7 +418,7 @@ test 'comment at end of CSX escape', ->
|
|||
</Person>;
|
||||
'''
|
||||
|
||||
test 'CSX comment cannot be used inside interpolation', ->
|
||||
test 'JSX comment cannot be used inside interpolation', ->
|
||||
throws -> CoffeeScript.compile '''
|
||||
<Person>
|
||||
{# i am a comment}
|
||||
|
@ -430,21 +430,21 @@ test 'comment syntax cannot be used inline', ->
|
|||
<Person>{#comment inline}</Person>
|
||||
'''
|
||||
|
||||
test 'string within CSX is ignored', ->
|
||||
test 'string within JSX is ignored', ->
|
||||
eqJS '''
|
||||
<Person> "i am not a string" 'nor am i' </Person>
|
||||
''', '''
|
||||
<Person> "i am not a string" 'nor am i' </Person>;
|
||||
'''
|
||||
|
||||
test 'special chars within CSX are ignored', ->
|
||||
test 'special chars within JSX are ignored', ->
|
||||
eqJS """
|
||||
<Person> a,/';][' a\''@$%^&˚¬∑˜˚∆å∂¬˚*()*&^%$>> '"''"'''\'\'m' i </Person>
|
||||
""", """
|
||||
<Person> a,/';][' a''@$%^&˚¬∑˜˚∆å∂¬˚*()*&^%$>> '"''"'''''m' i </Person>;
|
||||
"""
|
||||
|
||||
test 'html entities (name, decimal, hex) within CSX', ->
|
||||
test 'html entities (name, decimal, hex) within JSX', ->
|
||||
eqJS '''
|
||||
<Person> &&&€ € €;; </Person>
|
||||
''', '''
|
||||
|
@ -619,55 +619,55 @@ test 'closing tags must be closed', ->
|
|||
<a></a
|
||||
'''
|
||||
|
||||
# Tests for allowing less than operator without spaces when ther is no CSX
|
||||
# Tests for allowing less than operator without spaces when ther is no JSX
|
||||
|
||||
test 'unspaced less than without CSX: identifier', ->
|
||||
test 'unspaced less than without JSX: identifier', ->
|
||||
a = 3
|
||||
div = 5
|
||||
ok a<div
|
||||
|
||||
test 'unspaced less than without CSX: number', ->
|
||||
test 'unspaced less than without JSX: number', ->
|
||||
div = 5
|
||||
ok 3<div
|
||||
|
||||
test 'unspaced less than without CSX: paren', ->
|
||||
test 'unspaced less than without JSX: paren', ->
|
||||
div = 5
|
||||
ok (3)<div
|
||||
|
||||
test 'unspaced less than without CSX: index', ->
|
||||
test 'unspaced less than without JSX: index', ->
|
||||
div = 5
|
||||
a = [3]
|
||||
ok a[0]<div
|
||||
|
||||
test 'tag inside CSX works following: identifier', ->
|
||||
test 'tag inside JSX works following: identifier', ->
|
||||
eqJS '''
|
||||
<span>a<div /></span>
|
||||
''', '''
|
||||
<span>a<div /></span>;
|
||||
'''
|
||||
|
||||
test 'tag inside CSX works following: number', ->
|
||||
test 'tag inside JSX works following: number', ->
|
||||
eqJS '''
|
||||
<span>3<div /></span>
|
||||
''', '''
|
||||
<span>3<div /></span>;
|
||||
'''
|
||||
|
||||
test 'tag inside CSX works following: paren', ->
|
||||
test 'tag inside JSX works following: paren', ->
|
||||
eqJS '''
|
||||
<span>(3)<div /></span>
|
||||
''', '''
|
||||
<span>(3)<div /></span>;
|
||||
'''
|
||||
|
||||
test 'tag inside CSX works following: square bracket', ->
|
||||
test 'tag inside JSX works following: square bracket', ->
|
||||
eqJS '''
|
||||
<span>]<div /></span>
|
||||
''', '''
|
||||
<span>]<div /></span>;
|
||||
'''
|
||||
|
||||
test 'unspaced less than inside CSX works but is not encouraged', ->
|
||||
test 'unspaced less than inside JSX works but is not encouraged', ->
|
||||
eqJS '''
|
||||
a = 3
|
||||
div = 5
|
||||
|
@ -682,7 +682,7 @@ test 'unspaced less than inside CSX works but is not encouraged', ->
|
|||
html = <span>{a < div}</span>;
|
||||
'''
|
||||
|
||||
test 'unspaced less than before CSX works but is not encouraged', ->
|
||||
test 'unspaced less than before JSX works but is not encouraged', ->
|
||||
eqJS '''
|
||||
div = 5
|
||||
res = 2<div
|
||||
|
@ -697,7 +697,7 @@ test 'unspaced less than before CSX works but is not encouraged', ->
|
|||
html = <span />;
|
||||
'''
|
||||
|
||||
test 'unspaced less than after CSX works but is not encouraged', ->
|
||||
test 'unspaced less than after JSX works but is not encouraged', ->
|
||||
eqJS '''
|
||||
div = 5
|
||||
html = <span />
|
||||
|
@ -712,7 +712,7 @@ test 'unspaced less than after CSX works but is not encouraged', ->
|
|||
res = 2 < div;
|
||||
'''
|
||||
|
||||
test '#4686: comments inside interpolations that also contain CSX tags', ->
|
||||
test '#4686: comments inside interpolations that also contain JSX tags', ->
|
||||
eqJS '''
|
||||
<div>
|
||||
{
|
||||
|
@ -727,7 +727,7 @@ test '#4686: comments inside interpolations that also contain CSX tags', ->
|
|||
</div>;
|
||||
'''
|
||||
|
||||
test '#4686: comments inside interpolations that also contain CSX attributes', ->
|
||||
test '#4686: comments inside interpolations that also contain JSX attributes', ->
|
||||
eqJS '''
|
||||
<div>
|
||||
<div anAttr={
|
||||
|
@ -742,7 +742,7 @@ test '#4686: comments inside interpolations that also contain CSX attributes', -
|
|||
</div>;
|
||||
'''
|
||||
|
||||
test '#5086: comments inside CSX tags but outside interpolations', ->
|
||||
test '#5086: comments inside JSX tags but outside interpolations', ->
|
||||
eqJS '''
|
||||
<div>
|
||||
<div ###comment### attribute={value} />
|
||||
|
@ -753,7 +753,7 @@ test '#5086: comments inside CSX tags but outside interpolations', ->
|
|||
</div>;
|
||||
'''
|
||||
|
||||
test '#5086: comments inside CSX attributes but outside interpolations', ->
|
||||
test '#5086: comments inside JSX attributes but outside interpolations', ->
|
||||
eqJS '''
|
||||
<div>
|
||||
<div attribute={###attr comment### value} />
|
||||
|
@ -764,7 +764,7 @@ test '#5086: comments inside CSX attributes but outside interpolations', ->
|
|||
</div>;
|
||||
'''
|
||||
|
||||
test '#5086: comments inside nested CSX tags and attributes but outside interpolations', ->
|
||||
test '#5086: comments inside nested JSX tags and attributes but outside interpolations', ->
|
||||
eqJS '''
|
||||
<div>
|
||||
<div>
|
Loading…
Reference in New Issue