Skip to content

Commit

Permalink
javascript: Properly handle nested unknown blocks
Browse files Browse the repository at this point in the history
Properly match open curly braces when parsing a statement not to
possibly get fooled by unexpected nested blocks, e.g. after a
`switch`'s `case` or a label.

This mostly reverts c54c3ad and
replaces it with a more correct and complete solution.
  • Loading branch information
b4n committed Nov 24, 2014
1 parent f158f5d commit 5a1a22d
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 29 deletions.
40 changes: 11 additions & 29 deletions tagmanager/ctags/js.c
Expand Up @@ -169,7 +169,7 @@ static const keywordDesc JsKeywordTable [] = {

/* Recursive functions */
static void parseFunction (tokenInfo *const token);
static boolean parseBlock (tokenInfo *const token, tokenInfo *const parent);
static boolean parseBlock (tokenInfo *const token, tokenInfo *const orig_parent);
static boolean parseLine (tokenInfo *const token, boolean is_inside_class);
static void parseUI5 (tokenInfo *const token);

Expand Down Expand Up @@ -674,31 +674,6 @@ static void findCmdTerm (tokenInfo *const token)
}
}

static void findMatchingToken (tokenInfo *const token, tokenType begin_token, tokenType end_token)
{
int nest_level = 0;

if ( ! isType (token, end_token))
{
nest_level++;
while (! (isType (token, end_token) && (nest_level == 0)))
{
readToken (token);
if (isType (token, begin_token))
{
nest_level++;
}
if (isType (token, end_token))
{
if (nest_level > 0)
{
nest_level--;
}
}
}
}
}

static void parseSwitch (tokenInfo *const token)
{
/*
Expand Down Expand Up @@ -726,9 +701,8 @@ static void parseSwitch (tokenInfo *const token)

if (isType (token, TOKEN_OPEN_CURLY))
{
findMatchingToken (token, TOKEN_OPEN_CURLY, TOKEN_CLOSE_CURLY);
parseBlock (token, token);
}

}

static boolean parseLoop (tokenInfo *const token)
Expand Down Expand Up @@ -951,11 +925,15 @@ static void parseFunction (tokenInfo *const token)
deleteToken (name);
}

static boolean parseBlock (tokenInfo *const token, tokenInfo *const parent)
static boolean parseBlock (tokenInfo *const token, tokenInfo *const orig_parent)
{
boolean is_class = FALSE;
boolean read_next_token = TRUE;
vString * saveScope = vStringNew ();
tokenInfo *const parent = newToken ();

/* backup the parent token to allow calls like parseBlock(token, token) */
copyToken (parent, orig_parent);

token->nestLevel++;
/*
Expand Down Expand Up @@ -1041,6 +1019,7 @@ static boolean parseBlock (tokenInfo *const token, tokenInfo *const parent)
} while (! isType (token, TOKEN_CLOSE_CURLY) && read_next_token );
}

deleteToken (parent);
vStringDelete(saveScope);
token->nestLevel--;

Expand Down Expand Up @@ -1228,6 +1207,9 @@ static boolean parseStatement (tokenInfo *const token, boolean is_inside_class)
! isType (token, TOKEN_SEMICOLON) &&
! isType (token, TOKEN_EQUAL_SIGN) )
{
if (isType (token, TOKEN_OPEN_CURLY))
parseBlock (token, token);

/* Potentially the name of the function */
readToken (token);
if (isType (token, TOKEN_PERIOD))
Expand Down
1 change: 1 addition & 0 deletions tests/ctags/Makefile.am
Expand Up @@ -160,6 +160,7 @@ test_sources = \
invalid_name.f90 \
java_enum.java \
js-scope.js \
js-unknown-construct-nesting.js \
jsFunc_tutorial.js \
keyword_abstract.cs \
keyword_catch_try.cs \
Expand Down
23 changes: 23 additions & 0 deletions tests/ctags/js-unknown-construct-nesting.js
@@ -0,0 +1,23 @@

var o = {
aa: function () {
foo: {
return ;
}
},

bb: function (a) {
switch (a) {
case 1:
if (1) {
return 32
}
break;
case 2:
return 31;
}
return 1;
},

cc: function() {}
};
5 changes: 5 additions & 0 deletions tests/ctags/js-unknown-construct-nesting.js.tags
@@ -0,0 +1,5 @@
# format=tagmanager
aa�128�o�0
bb�128�o�0
cc�128�o�0
o�1�0

0 comments on commit 5a1a22d

Please sign in to comment.