Skip to content

Commit

Permalink
JavaScript Parser updates for bug 2777310.
Browse files Browse the repository at this point in the history
var x = 1;
var y = [];
var z = {};

Only x and y are detected - z is ignored,
despite this being perfectly valid syntax
(and quite common, when initialising
a variable for use as a hash table).

[It's equivalent to z = new Object(), in a
similar fashion to y = [] being equivalent
to y = new Array() ].

As far as I can tell, the cause seems to be that
object literals are not being considered as valid
for the right hand side of an assignment.

Now, global variables for z is generated for the release after 5.8.

git-svn-id: https://ctags.svn.sourceforge.net/svnroot/ctags/trunk@763 c5d04d22-be80-434c-894e-aa346cc9e8e8
  • Loading branch information
dfishburn authored and Reza Jelveh committed Oct 19, 2011
1 parent ec0c139 commit 5863484
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Test/bug2777310.js
@@ -0,0 +1,4 @@
var x = 1;
var z = {};
var y = [];

67 changes: 65 additions & 2 deletions jscript.c
Expand Up @@ -959,9 +959,10 @@ static boolean parseBlock (tokenInfo *const token, tokenInfo *const parent)
return is_class;
}

static void parseMethods (tokenInfo *const token, tokenInfo *const class)
static boolean parseMethods (tokenInfo *const token, tokenInfo *const class)
{
tokenInfo *const name = newToken ();
boolean has_methods = FALSE;

/*
* This deals with these formats
Expand All @@ -974,6 +975,16 @@ static void parseMethods (tokenInfo *const token, tokenInfo *const class)
do
{
readToken (token);
if (isType (token, TOKEN_CLOSE_CURLY))
{
/*
* This was most likely a variable declaration of a hash table.
* indicate there were no methods and return.
*/
has_methods = FALSE;
goto cleanUp;
}

if (isType (token, TOKEN_STRING) || isKeyword(token, KEYWORD_NONE))
{
copyToken(name, token);
Expand All @@ -992,6 +1003,7 @@ static void parseMethods (tokenInfo *const token, tokenInfo *const class)

if (isType (token, TOKEN_OPEN_CURLY))
{
has_methods = TRUE;
addToScope (name, class->string);
makeJsTag (name, JSTAG_METHOD);
parseBlock (token, name);
Expand All @@ -1005,6 +1017,7 @@ static void parseMethods (tokenInfo *const token, tokenInfo *const class)
}
else
{
has_methods = TRUE;
addToScope (name, class->string);
makeJsTag (name, JSTAG_PROPERTY);

Expand All @@ -1020,7 +1033,10 @@ static void parseMethods (tokenInfo *const token, tokenInfo *const class)

findCmdTerm (token);

cleanUp:
deleteToken (name);

return has_methods;
}

static boolean parseStatement (tokenInfo *const token, boolean is_inside_class)
Expand All @@ -1032,6 +1048,7 @@ static boolean parseStatement (tokenInfo *const token, boolean is_inside_class)
boolean is_terminated = TRUE;
boolean is_global = FALSE;
boolean is_prototype = FALSE;
boolean has_methods = FALSE;
vString * fulltag;

vStringClear(saveScope);
Expand Down Expand Up @@ -1345,8 +1362,54 @@ static boolean parseStatement (tokenInfo *const token, boolean is_inside_class)
* 'validMethodOne' : function(a,b) {},
* 'validMethodTwo' : function(a,b) {}
* }
* Or checks if this is a hash variable.
* var z = {};
*/
parseMethods(token, name);
has_methods = parseMethods(token, name);
if ( ! has_methods )
{
/*
* Only create variables for global scope
*/
if ( token->nestLevel == 0 && is_global )
{
/*
* A pointer can be created to the function.
* If we recognize the function/class name ignore the variable.
* This format looks identical to a variable definition.
* A variable defined outside of a block is considered
* a global variable:
* var g_var1 = 1;
* var g_var2;
* This is not a global variable:
* var g_var = function;
* This is a global variable:
* var g_var = different_var_name;
*/
fulltag = vStringNew ();
if (vStringLength (token->scope) > 0)
{
vStringCopy(fulltag, token->scope);
vStringCatS (fulltag, ".");
vStringCatS (fulltag, vStringValue(token->string));
}
else
{
vStringCopy(fulltag, token->string);
}
vStringTerminate(fulltag);
if ( ! stringListHas(FunctionNames, vStringValue (fulltag)) &&
! stringListHas(ClassNames, vStringValue (fulltag)) )
{
readToken (token);
if ( ! isType (token, TOKEN_SEMICOLON))
findCmdTerm (token);
if (isType (token, TOKEN_SEMICOLON))
makeJsTag (name, JSTAG_VARIABLE);
}
vStringDelete (fulltag);
}
}
if (isType (token, TOKEN_CLOSE_CURLY))
{
/*
Expand Down

0 comments on commit 5863484

Please sign in to comment.