Skip to content

Commit

Permalink
Merge pull request #2159 from masatake/js-ignore-bable-decorators
Browse files Browse the repository at this point in the history
JavaScript: skip "TC39 Standards Track Decorators in Babel"
  • Loading branch information
masatake committed Jul 30, 2019
2 parents 1a94658 + f2e65b3 commit 920e791
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
1 change: 1 addition & 0 deletions Units/parser-javascript.r/babel-decorators.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--sort=no
6 changes: 6 additions & 0 deletions Units/parser-javascript.r/babel-decorators.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Example input.js /^class Example {$/;" c
doSomething input.js /^ doSomething() {$/;" m class:Example
MyClass input.js /^class MyClass {$/;" c
my_method input.js /^ my_method() {}$/;" m class:MyClass
YourClass input.js /^class YourClass {$/;" c
your_method input.js /^ @decorator @dec(arg1, arg2) @namespace.decorator @(complex ? dec1 : dec2) your_method() {}$/;" m class:YourClass
22 changes: 22 additions & 0 deletions Units/parser-javascript.r/babel-decorators.d/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Taken from https://www.sitepoint.com/javascript-decorators-what-they-are/
@log()
@immutable()
class Example {
@time('demo')
doSomething() {
//
}
}

// Taken from https://babeljs.io/blog/2018/09/17/decorators
class MyClass {
@decorator
@dec(arg1, arg2)
@namespace.decorator
@(complex ? dec1 : dec2)
my_method() {}
}

class YourClass {
@decorator @dec(arg1, arg2) @namespace.decorator @(complex ? dec1 : dec2) your_method() {}
}
69 changes: 68 additions & 1 deletion parsers/jscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ typedef enum eTokenType {
TOKEN_REGEXP,
TOKEN_POSTFIX_OPERATOR,
TOKEN_STAR,
/* To handle Babel's decorators.
* Used only in readTokenFull or lower functions. */
TOKEN_ATMARK,
TOKEN_BINARY_OPERATOR
} tokenType;

Expand Down Expand Up @@ -218,6 +221,7 @@ static const keywordTable JsKeywordTable [] = {

/* Recursive functions */
static void readTokenFull (tokenInfo *const token, bool include_newlines, vString *const repr);
static void skipArgumentList (tokenInfo *const token, bool include_newlines, vString *const repr);
static void parseFunction (tokenInfo *const token);
static bool parseBlock (tokenInfo *const token, const vString *const parentScope);
static bool parseLine (tokenInfo *const token, bool is_inside_class);
Expand Down Expand Up @@ -800,7 +804,7 @@ static void parseTemplateString (vString *const string)
while (c != EOF);
}

static void readTokenFull (tokenInfo *const token, bool include_newlines, vString *const repr)
static void readTokenFullRaw (tokenInfo *const token, bool include_newlines, vString *const repr)
{
int c;
int i;
Expand Down Expand Up @@ -971,6 +975,10 @@ static void readTokenFull (tokenInfo *const token, bool include_newlines, vStrin
}
break;

case '@':
token->type = TOKEN_ATMARK;
break;

case '\\':
c = readUnicodeEscapeSequence (c);
/* fallthrough */
Expand Down Expand Up @@ -1047,6 +1055,65 @@ static void readTokenFull (tokenInfo *const token, bool include_newlines, vStrin
LastTokenType = token->type;
}

/* See https://babeljs.io/blog/2018/09/17/decorators */
static void skipBabelDecorator (tokenInfo *token, bool include_newlines, vString *const repr)
{
readTokenFullRaw (token, include_newlines, repr);
if (isType (token, TOKEN_OPEN_PAREN))
{
/* @(complex ? dec1 : dec2) */
skipArgumentList (token, include_newlines, repr);
TRACE_PRINT ("found @(...) style decorator");
}
else if (isType (token, TOKEN_IDENTIFIER))
{
/* @namespace.foo (...) */
bool found_period = false;
while (1)
{
readTokenFullRaw (token, include_newlines, repr);
if (isType (token, TOKEN_IDENTIFIER))
{
if (!found_period)
{
TRACE_PRINT("found @namespace.bar style decorator");
break;
}
found_period = false;
}
else if (isType (token, TOKEN_PERIOD))
found_period = true;
else if (isType (token, TOKEN_OPEN_PAREN))
{
skipArgumentList (token, include_newlines, repr);
TRACE_PRINT("found @foo(...) style decorator");
break;
}
else
{
TRACE_PRINT("found @foo style decorator");
break;
}
}
}
else
/* Unexpected token after @ */
TRACE_PRINT("found unexpected token during skipping a decorator");
}

static void readTokenFull (tokenInfo *const token, bool include_newlines, vString *const repr)
{
readTokenFullRaw (token, include_newlines, repr);

while (1)
{
if (!isType (token, TOKEN_ATMARK))
break;
skipBabelDecorator (token, include_newlines, repr);
/* @decorator0 @decorator1 ... There can be more than one decorator. */
}
}

#ifdef JSCRIPT_DO_DEBUGGING
/* trace readTokenFull() */
static void readTokenFullDebug (tokenInfo *const token, bool include_newlines, vString *const repr)
Expand Down

0 comments on commit 920e791

Please sign in to comment.