[geany/geany] f08af8: Merge branch 'js-update'
Colomban Wendling
git-noreply at xxxxx
Tue Dec 2 14:03:20 UTC 2014
Branch: refs/heads/master
Author: Colomban Wendling <ban at herbesfolles.org>
Committer: Colomban Wendling <ban at herbesfolles.org>
Date: Tue, 02 Dec 2014 14:03:20 UTC
Commit: f08af8046f8cbbd7d48fc767155d1fe805c1c45d
https://github.com/geany/geany/commit/f08af8046f8cbbd7d48fc767155d1fe805c1c45d
Log Message:
-----------
Merge branch 'js-update'
Import back JavaScript parser changes from fishman/ctags.
Modified Paths:
--------------
tagmanager/ctags/js.c
tests/ctags/Makefile.am
tests/ctags/js-broken-strings.js
tests/ctags/js-broken-strings.js.tags
tests/ctags/js-string-continuation.js
tests/ctags/js-string-continuation.js.tags
Modified: tagmanager/ctags/js.c
102 lines changed, 51 insertions(+), 51 deletions(-)
===================================================================
@@ -19,7 +19,6 @@
#include "general.h" /* must always come first */
#include <ctype.h> /* to define isalpha () */
#include <string.h>
-#include <setjmp.h>
#include <mio/mio.h>
#ifdef DEBUG
#include <stdio.h>
@@ -41,8 +40,6 @@
* DATA DECLARATIONS
*/
-typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
-
/*
* Tracks class and function names already created
*/
@@ -85,6 +82,7 @@ typedef struct sKeywordDesc {
typedef enum eTokenType {
TOKEN_UNDEFINED,
+ TOKEN_EOF,
TOKEN_CHARACTER,
TOKEN_CLOSE_PAREN,
TOKEN_SEMICOLON,
@@ -126,8 +124,6 @@ static tokenType LastTokenType;
static langType Lang_js;
-static jmp_buf Exception;
-
typedef enum {
JSTAG_FUNCTION,
JSTAG_CLASS,
@@ -364,11 +360,32 @@ static void parseString (vString *const string, const int delimiter)
end = TRUE;
else if (c == '\\')
{
- c = fileGetc(); /* This maybe a ' or ". */
- vStringPut(string, c);
+ /* Eat the escape sequence (\", \', etc). We properly handle
+ * <LineContinuation> by eating a whole \<CR><LF> not to see <LF>
+ * as an unescaped character, which is invalid and handled below.
+ * Also, handle the fact that <LineContinuation> produces an empty
+ * sequence.
+ * See ECMA-262 7.8.4 */
+ c = fileGetc();
+ if (c != '\r' && c != '\n')
+ vStringPut(string, c);
+ else if (c == '\r')
+ {
+ c = fileGetc();
+ if (c != '\n')
+ fileUngetc (c);
+ }
}
else if (c == delimiter)
end = TRUE;
+ else if (c == '\r' || c == '\n')
+ {
+ /* those are invalid when not escaped */
+ end = TRUE;
+ /* we don't want to eat the newline itself to let the automatic
+ * semicolon insertion code kick in */
+ fileUngetc (c);
+ }
else
vStringPut (string, c);
}
@@ -458,7 +475,7 @@ static void readTokenFull (tokenInfo *const token, boolean include_newlines, vSt
switch (c)
{
- case EOF: longjmp (Exception, (int)ExceptionEOF); break;
+ case EOF: token->type = TOKEN_EOF; break;
case '(': token->type = TOKEN_OPEN_PAREN; break;
case ')': token->type = TOKEN_CLOSE_PAREN; break;
case ';': token->type = TOKEN_SEMICOLON; break;
@@ -669,32 +686,18 @@ static void skipArgumentList (tokenInfo *const token, boolean include_newlines,
{
int nest_level = 0;
- /*
- * Other databases can have arguments with fully declared
- * datatypes:
- * ( name varchar(30), text binary(10) )
- * So we must check for nested open and closing parantheses
- */
-
if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */
{
nest_level++;
if (repr)
vStringPut (repr, '(');
- while (! (isType (token, TOKEN_CLOSE_PAREN) && (nest_level == 0)))
+ while (nest_level > 0 && ! isType (token, TOKEN_EOF))
{
readTokenFull (token, FALSE, repr);
if (isType (token, TOKEN_OPEN_PAREN))
- {
nest_level++;
- }
- if (isType (token, TOKEN_CLOSE_PAREN))
- {
- if (nest_level > 0)
- {
- nest_level--;
- }
- }
+ else if (isType (token, TOKEN_CLOSE_PAREN))
+ nest_level--;
}
readTokenFull (token, include_newlines, NULL);
}
@@ -713,20 +716,13 @@ static void skipArrayList (tokenInfo *const token, boolean include_newlines)
if (isType (token, TOKEN_OPEN_SQUARE)) /* arguments? */
{
nest_level++;
- while (! (isType (token, TOKEN_CLOSE_SQUARE) && (nest_level == 0)))
+ while (nest_level > 0 && ! isType (token, TOKEN_EOF))
{
readToken (token);
if (isType (token, TOKEN_OPEN_SQUARE))
- {
nest_level++;
- }
- if (isType (token, TOKEN_CLOSE_SQUARE))
- {
- if (nest_level > 0)
- {
- nest_level--;
- }
- }
+ else if (isType (token, TOKEN_CLOSE_SQUARE))
+ nest_level--;
}
readTokenFull (token, include_newlines, NULL);
}
@@ -762,8 +758,9 @@ static boolean findCmdTerm (tokenInfo *const token, boolean include_newlines)
* Read until we find either a semicolon or closing brace.
* Any nested braces will be handled within.
*/
- while (! ( isType (token, TOKEN_SEMICOLON) ||
- isType (token, TOKEN_CLOSE_CURLY) ) )
+ while (! isType (token, TOKEN_SEMICOLON) &&
+ ! isType (token, TOKEN_CLOSE_CURLY) &&
+ ! isType (token, TOKEN_EOF))
{
/* Handle nested blocks */
if ( isType (token, TOKEN_OPEN_CURLY))
@@ -1132,7 +1129,8 @@ static boolean parseBlock (tokenInfo *const token, tokenInfo *const orig_parent)
* If we find a statement without a terminator consider the
* block finished, otherwise the stack will be off by one.
*/
- } while (! isType (token, TOKEN_CLOSE_CURLY) && read_next_token );
+ } while (! isType (token, TOKEN_EOF) &&
+ ! isType (token, TOKEN_CLOSE_CURLY) && read_next_token);
}
deleteToken (parent);
@@ -1209,7 +1207,8 @@ static boolean parseMethods (tokenInfo *const token, tokenInfo *const class)
/* skip whatever is the value */
while (! isType (token, TOKEN_COMMA) &&
- ! isType (token, TOKEN_CLOSE_CURLY))
+ ! isType (token, TOKEN_CLOSE_CURLY) &&
+ ! isType (token, TOKEN_EOF))
{
if (isType (token, TOKEN_OPEN_CURLY))
{
@@ -1329,7 +1328,8 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
while (! isType (token, TOKEN_CLOSE_CURLY) &&
! isType (token, TOKEN_SEMICOLON) &&
- ! isType (token, TOKEN_EQUAL_SIGN) )
+ ! isType (token, TOKEN_EQUAL_SIGN) &&
+ ! isType (token, TOKEN_EOF))
{
if (isType (token, TOKEN_OPEN_CURLY))
parseBlock (token, parent);
@@ -1403,9 +1403,10 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
readToken (method_body_token);
vStringCopy (method_body_token->scope, token->scope);
- while (! ( isType (method_body_token, TOKEN_SEMICOLON) ||
- isType (method_body_token, TOKEN_CLOSE_CURLY) ||
- isType (method_body_token, TOKEN_OPEN_CURLY)) )
+ while (! isType (method_body_token, TOKEN_SEMICOLON) &&
+ ! isType (method_body_token, TOKEN_CLOSE_CURLY) &&
+ ! isType (method_body_token, TOKEN_OPEN_CURLY) &&
+ ! isType (method_body_token, TOKEN_EOF))
{
if ( isType (method_body_token, TOKEN_OPEN_PAREN) )
skipArgumentList(method_body_token, FALSE,
@@ -1728,7 +1729,7 @@ static boolean parseStatement (tokenInfo *const token, tokenInfo *const parent,
if (parenDepth > 0)
{
- while (parenDepth > 0)
+ while (parenDepth > 0 && ! isType (token, TOKEN_EOF))
{
if (isType (token, TOKEN_OPEN_PAREN))
parenDepth++;
@@ -1795,7 +1796,8 @@ static void parseUI5 (tokenInfo *const token)
if (isType (token, TOKEN_PERIOD))
{
readToken (token);
- while (! isType (token, TOKEN_OPEN_PAREN) )
+ while (! isType (token, TOKEN_OPEN_PAREN) &&
+ ! isType (token, TOKEN_EOF))
{
readToken (token);
}
@@ -1813,7 +1815,8 @@ static void parseUI5 (tokenInfo *const token)
do
{
parseMethods (token, name);
- } while (! isType (token, TOKEN_CLOSE_CURLY) );
+ } while (! isType (token, TOKEN_CLOSE_CURLY) &&
+ ! isType (token, TOKEN_EOF));
}
deleteToken (name);
@@ -1884,7 +1887,7 @@ static void parseJsFile (tokenInfo *const token)
parseUI5 (token);
else
parseLine (token, token, FALSE);
- } while (TRUE);
+ } while (! isType (token, TOKEN_EOF));
}
static void initialize (const langType language)
@@ -1897,15 +1900,12 @@ static void initialize (const langType language)
static void findJsTags (void)
{
tokenInfo *const token = newToken ();
- exception_t exception;
ClassNames = stringListNew ();
FunctionNames = stringListNew ();
LastTokenType = TOKEN_UNDEFINED;
- exception = (exception_t) (setjmp (Exception));
- while (exception == ExceptionNone)
- parseJsFile (token);
+ parseJsFile (token);
stringListDelete (ClassNames);
stringListDelete (FunctionNames);
Modified: tests/ctags/Makefile.am
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -159,12 +159,14 @@ test_sources = \
intro.tex \
invalid_name.f90 \
java_enum.java \
+ js-broken-strings.js \
js-class-related-unterminated.js \
js-const.js \
js-implicit-semicolons.js \
js-let.js \
js-scope.js \
js-signature.js \
+ js-string-continuation.js \
js-sub-block-scope.js \
js-unknown-construct-nesting.js \
jsFunc_tutorial.js \
Modified: tests/ctags/js-broken-strings.js
10 lines changed, 10 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,10 @@
+// this file willfully uses CR-LF line endings to check their handling
+
+var s1 = "I'm invalid because not terminated
+
+var s2 = "I'm valid, I have a line continuation:\
+; function bug1(){}";
+
+var s3 = "I'm invalid because I'm not terminated either \
+var bug2 = 'this is inside the s3 string'
+var s4 = 'this is a separate, valid string'
Modified: tests/ctags/js-broken-strings.js.tags
5 lines changed, 5 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,5 @@
+# format=tagmanager
+s1�16384�0
+s2�16384�0
+s3�16384�0
+s4�16384�0
Modified: tests/ctags/js-string-continuation.js
19 lines changed, 19 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,19 @@
+
+var o = {
+ "first": function(){},
+ "sec\
+ond": function(){},
+ "\
+t\
+h\
+i\
+r\
+d\
+": function(){},
+ "fourth": function(){},
+};
+
+o.first();
+o.second();
+o.third();
+o.fourth();
Modified: tests/ctags/js-string-continuation.js.tags
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,6 @@
+# format=tagmanager
+first�128�()�o�0
+fourth�128�()�o�0
+o�16384�0
+second�128�()�o�0
+third�128�()�o�0
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list