mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
* CSX fragments * regex improvement; tests * regex improvement * regex improvement * bug fix; regex * Fix style * Split fragment tests
This commit is contained in:
parent
5bc85b8f6d
commit
7f5ab7eb0d
4 changed files with 60 additions and 10 deletions
|
@ -17,12 +17,10 @@
|
|||
// from our rules and saves it into `lib/parser.js`.
|
||||
|
||||
// The only dependency is on the **Jison.Parser**.
|
||||
var Parser, alt, alternatives, grammar, log, name, o, operators, token, tokens, unwrap;
|
||||
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
|
||||
|
||||
({Parser} = require('jison'));
|
||||
|
||||
log = console.log;
|
||||
|
||||
// Jison DSL
|
||||
// ---------
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// where locationData is {first_line, first_column, last_line, last_column}, 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_IDENTIFIER, CSX_INTERPOLATION, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INSIDE_CSX, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, REGEX_INVALID_ESCAPE, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_INVALID_ESCAPE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, UNFINISHED, UNICODE_CODE_POINT_ESCAPE, VALID_FLAGS, WHITESPACE, attachCommentsToNode, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, merge, repeat, starts, throwSyntaxError,
|
||||
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, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INSIDE_CSX, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, REGEX_INVALID_ESCAPE, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_INVALID_ESCAPE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, UNFINISHED, UNICODE_CODE_POINT_ESCAPE, VALID_FLAGS, WHITESPACE, attachCommentsToNode, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, merge, repeat, starts, throwSyntaxError,
|
||||
indexOf = [].indexOf;
|
||||
|
||||
({Rewriter, INVERSES} = require('./rewriter'));
|
||||
|
@ -741,7 +741,7 @@
|
|||
// 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));
|
||||
match = CSX_IDENTIFIER.exec(this.chunk.slice(1)) || CSX_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)))) {
|
||||
return 0;
|
||||
|
@ -793,8 +793,8 @@
|
|||
delimiter: '>'
|
||||
});
|
||||
});
|
||||
match = CSX_IDENTIFIER.exec(this.chunk.slice(end));
|
||||
if (!match || match[0] !== csxTag.name) {
|
||||
match = CSX_IDENTIFIER.exec(this.chunk.slice(end)) || CSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(end));
|
||||
if (!match || match[1] !== csxTag.name) {
|
||||
this.error(`expected corresponding CSX closing tag for ${csxTag.name}`, csxTag.origin[2]);
|
||||
}
|
||||
afterTag = end + csxTag.name.length;
|
||||
|
@ -1541,6 +1541,9 @@
|
|||
CSX_IDENTIFIER = /^(?![\d<])((?:(?!\s)[\.\-$\w\x7f-\uffff])+)/; // Must not start with `<`.
|
||||
// Like `IDENTIFIER`, but includes `-`s and `.`s.
|
||||
|
||||
// Fragment: <></>
|
||||
CSX_FRAGMENT_IDENTIFIER = /^()>/; // Ends immediately with `>`.
|
||||
|
||||
CSX_ATTRIBUTE = /^(?!\d)((?:(?!\s)[\-$\w\x7f-\uffff])+)([^\S]*=(?!=))?/; // Like `IDENTIFIER`, but includes `-`s.
|
||||
// Is this an attribute with a value?
|
||||
|
||||
|
|
|
@ -556,7 +556,7 @@ exports.Lexer = class Lexer
|
|||
# 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...]
|
||||
match = CSX_IDENTIFIER.exec(@chunk[1...]) or CSX_FRAGMENT_IDENTIFIER.exec(@chunk[1...])
|
||||
return 0 unless match and (
|
||||
@csxDepth > 0 or
|
||||
# Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
||||
|
@ -596,8 +596,8 @@ exports.Lexer = class Lexer
|
|||
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
|
||||
@mergeInterpolationTokens tokens, {delimiter: '"'}, (value, i) =>
|
||||
@formatString value, delimiter: '>'
|
||||
match = CSX_IDENTIFIER.exec @chunk[end...]
|
||||
if not match or match[0] isnt csxTag.name
|
||||
match = CSX_IDENTIFIER.exec(@chunk[end...]) or CSX_FRAGMENT_IDENTIFIER.exec(@chunk[end...])
|
||||
if not match or match[1] isnt csxTag.name
|
||||
@error "expected corresponding CSX closing tag for #{csxTag.name}",
|
||||
csxTag.origin[2]
|
||||
afterTag = end + csxTag.name.length
|
||||
|
@ -1178,6 +1178,11 @@ CSX_IDENTIFIER = /// ^
|
|||
( (?: (?!\s)[\.\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s and `.`s.
|
||||
///
|
||||
|
||||
# Fragment: <></>
|
||||
CSX_FRAGMENT_IDENTIFIER = /// ^
|
||||
()> # Ends immediately with `>`.
|
||||
///
|
||||
|
||||
CSX_ATTRIBUTE = /// ^
|
||||
(?!\d)
|
||||
( (?: (?!\s)[\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s.
|
||||
|
|
|
@ -742,3 +742,47 @@ test '#4686: comments inside interpolations that also contain CSX attributes', -
|
|||
</div>;
|
||||
'''
|
||||
|
||||
# https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
|
||||
test 'JSX fragments: empty fragment', ->
|
||||
eqJS '''
|
||||
<></>
|
||||
''', '''
|
||||
<></>;
|
||||
'''
|
||||
|
||||
test 'JSX fragments: fragment with text nodes', ->
|
||||
eqJS '''
|
||||
<>
|
||||
Some text.
|
||||
<h2>A heading</h2>
|
||||
More text.
|
||||
<h2>Another heading</h2>
|
||||
Even more text.
|
||||
</>
|
||||
''', '''
|
||||
<>
|
||||
Some text.
|
||||
<h2>A heading</h2>
|
||||
More text.
|
||||
<h2>Another heading</h2>
|
||||
Even more text.
|
||||
</>;
|
||||
'''
|
||||
|
||||
test 'JSX fragments: fragment with component nodes', ->
|
||||
eqJS '''
|
||||
Component = (props) =>
|
||||
<Fragment>
|
||||
<OtherComponent />
|
||||
<OtherComponent />
|
||||
</Fragment>
|
||||
''', '''
|
||||
var Component;
|
||||
|
||||
Component = (props) => {
|
||||
return <Fragment>
|
||||
<OtherComponent />
|
||||
<OtherComponent />
|
||||
</Fragment>;
|
||||
};
|
||||
'''
|
||||
|
|
Loading…
Reference in a new issue