javascript: Add support for the const keyword

`const` is not yet part of the current ECMAScript standard but is
part of the ECMAScript 6 draft and is supported by popular engines
including Mozilla and WebKit, and people already use it.

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
This commit is contained in:
Colomban Wendling 2014-11-23 19:31:09 +01:00
parent b85d754610
commit ef8c40f1e4
4 changed files with 33 additions and 6 deletions

View File

@ -58,6 +58,7 @@ typedef enum eKeywordId {
KEYWORD_capital_object, KEYWORD_capital_object,
KEYWORD_prototype, KEYWORD_prototype,
KEYWORD_var, KEYWORD_var,
KEYWORD_const,
KEYWORD_new, KEYWORD_new,
KEYWORD_this, KEYWORD_this,
KEYWORD_for, KEYWORD_for,
@ -131,6 +132,7 @@ typedef enum {
JSTAG_CLASS, JSTAG_CLASS,
JSTAG_METHOD, JSTAG_METHOD,
JSTAG_PROPERTY, JSTAG_PROPERTY,
JSTAG_CONSTANT,
JSTAG_VARIABLE, JSTAG_VARIABLE,
JSTAG_COUNT JSTAG_COUNT
} jsKind; } jsKind;
@ -140,6 +142,7 @@ static kindOption JsKinds [] = {
{ TRUE, 'c', "class", "classes" }, { TRUE, 'c', "class", "classes" },
{ TRUE, 'm', "method", "methods" }, { TRUE, 'm', "method", "methods" },
{ TRUE, 'p', "member", "properties" }, { TRUE, 'p', "member", "properties" },
{ TRUE, 'C', "macro", "constants" },
{ TRUE, 'v', "variable", "global variables" } { TRUE, 'v', "variable", "global variables" }
}; };
@ -150,6 +153,7 @@ static const keywordDesc JsKeywordTable [] = {
{ "Object", KEYWORD_capital_object }, { "Object", KEYWORD_capital_object },
{ "prototype", KEYWORD_prototype }, { "prototype", KEYWORD_prototype },
{ "var", KEYWORD_var }, { "var", KEYWORD_var },
{ "const", KEYWORD_const },
{ "new", KEYWORD_new }, { "new", KEYWORD_new },
{ "this", KEYWORD_this }, { "this", KEYWORD_this },
{ "for", KEYWORD_for }, { "for", KEYWORD_for },
@ -1079,7 +1083,8 @@ static boolean parseBlock (tokenInfo *const token, tokenInfo *const orig_parent)
vStringCopy(token->scope, saveScope); vStringCopy(token->scope, saveScope);
} }
else if (isKeyword (token, KEYWORD_var)) else if (isKeyword (token, KEYWORD_var) ||
isKeyword (token, KEYWORD_const))
{ {
/* /*
* Potentially we have found an inner function. * Potentially we have found an inner function.
@ -1253,6 +1258,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
vString * saveScope = vStringNew (); vString * saveScope = vStringNew ();
boolean is_class = FALSE; boolean is_class = FALSE;
boolean is_var = FALSE; boolean is_var = FALSE;
boolean is_const = FALSE;
boolean is_terminated = TRUE; boolean is_terminated = TRUE;
boolean is_global = FALSE; boolean is_global = FALSE;
boolean has_methods = FALSE; boolean has_methods = FALSE;
@ -1292,8 +1298,10 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
/* /*
* var can preceed an inner function * var can preceed an inner function
*/ */
if ( isKeyword(token, KEYWORD_var) ) if ( isKeyword(token, KEYWORD_var) ||
isKeyword(token, KEYWORD_const) )
{ {
is_const = isKeyword(token, KEYWORD_const);
/* /*
* Only create variables for global scope * Only create variables for global scope
*/ */
@ -1482,7 +1490,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
* var g_var2; * var g_var2;
*/ */
if (isType (token, TOKEN_SEMICOLON)) if (isType (token, TOKEN_SEMICOLON))
makeJsTag (name, JSTAG_VARIABLE, NULL); makeJsTag (name, is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL);
} }
/* /*
* Statement has ended. * Statement has ended.
@ -1617,7 +1625,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) && if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) &&
! stringListHas(ClassNames, vStringValue (fulltag)) ) ! stringListHas(ClassNames, vStringValue (fulltag)) )
{ {
makeJsTag (name, JSTAG_VARIABLE, NULL); makeJsTag (name, is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL);
} }
vStringDelete (fulltag); vStringDelete (fulltag);
} }
@ -1653,7 +1661,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
{ {
if ( is_var ) if ( is_var )
{ {
makeJsTag (name, JSTAG_VARIABLE, NULL); makeJsTag (name, is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL);
} }
else else
{ {
@ -1708,7 +1716,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) && if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) &&
! stringListHas(ClassNames, vStringValue (fulltag)) ) ! stringListHas(ClassNames, vStringValue (fulltag)) )
{ {
makeJsTag (name, JSTAG_VARIABLE, NULL); makeJsTag (name, is_const ? JSTAG_CONSTANT : JSTAG_VARIABLE, NULL);
} }
vStringDelete (fulltag); vStringDelete (fulltag);
} }

View File

@ -160,6 +160,7 @@ test_sources = \
invalid_name.f90 \ invalid_name.f90 \
java_enum.java \ java_enum.java \
js-class-related-unterminated.js \ js-class-related-unterminated.js \
js-const.js \
js-implicit-semicolons.js \ js-implicit-semicolons.js \
js-scope.js \ js-scope.js \
js-signature.js \ js-signature.js \

10
tests/ctags/js-const.js Normal file
View File

@ -0,0 +1,10 @@
const A = 1;
const B = 1;
const Group = {
X:1,
Y:2,
Z:3
};
const func = function () {}

View File

@ -0,0 +1,8 @@
# format=tagmanager
AÌ65536Ö0
BÌ65536Ö0
GroupÌ1Ö0
XÌ64ÎGroupÖ0
YÌ64ÎGroupÖ0
ZÌ64ÎGroupÖ0
funcÌ16Í()Ö0