Created
March 21, 2012 22:29
-
-
Save codebrainz/2153795 to your computer and use it in GitHub Desktop.
CTAGS - Add D, GLSL, Ferite and Vala support (untested)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: parsers.h | |
=================================================================== | |
--- parsers.h (revision 781) | |
+++ parsers.h (working copy) | |
@@ -26,11 +26,14 @@ | |
CppParser, \ | |
CsharpParser, \ | |
CobolParser, \ | |
+ DParser, \ | |
DosBatchParser, \ | |
EiffelParser, \ | |
ErlangParser, \ | |
+ FeriteParser, \ | |
FlexParser, \ | |
FortranParser, \ | |
+ GLSLParser, \ | |
HtmlParser, \ | |
JavaParser, \ | |
JavaScriptParser, \ | |
@@ -53,6 +56,7 @@ | |
SqlParser, \ | |
TclParser, \ | |
TexParser, \ | |
+ ValaParser, \ | |
VeraParser, \ | |
VerilogParser, \ | |
VhdlParser, \ | |
Index: c.c | |
=================================================================== | |
--- c.c (revision 781) | |
+++ c.c (working copy) | |
@@ -2,11 +2,12 @@ | |
* $Id$ | |
* | |
* Copyright (c) 1996-2003, Darren Hiebert | |
+* Copyright (c) 2012, Matthew Brush | |
* | |
* This source code is released for free distribution under the terms of the | |
* GNU General Public License. | |
* | |
-* This module contains functions for parsing and scanning C, C++ and Java | |
+* This module contains functions for parsing and scanning C, C++, D, Java and Vala | |
* source files. | |
*/ | |
@@ -48,7 +49,7 @@ | |
* DATA DECLARATIONS | |
*/ | |
-enum { NumTokens = 3 }; | |
+enum { NumTokens = 12 }; | |
typedef enum eException { | |
ExceptionNone, ExceptionEOF, ExceptionFormattingError, | |
@@ -59,31 +60,31 @@ | |
*/ | |
typedef enum eKeywordId { | |
KEYWORD_NONE = -1, | |
- KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT, | |
+ KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT, KEYWORD_ALIAS, | |
KEYWORD_BOOLEAN, KEYWORD_BYTE, KEYWORD_BAD_STATE, KEYWORD_BAD_TRANS, | |
- KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT, | |
+ KEYWORD_BIND, KEYWORD_BIND_VAR, KEYWORD_BIT, KEYWORD_BODY, | |
KEYWORD_CASE, KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST, | |
KEYWORD_CONSTRAINT, KEYWORD_COVERAGE_BLOCK, KEYWORD_COVERAGE_DEF, | |
KEYWORD_DEFAULT, KEYWORD_DELEGATE, KEYWORD_DELETE, KEYWORD_DO, | |
KEYWORD_DOUBLE, | |
KEYWORD_ELSE, KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN, | |
KEYWORD_EXTENDS, KEYWORD_EVENT, | |
- KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FOREACH, | |
+ KEYWORD_FINAL, KEYWORD_FINALLY, KEYWORD_FLOAT, KEYWORD_FOR, KEYWORD_FOREACH, | |
KEYWORD_FRIEND, KEYWORD_FUNCTION, | |
- KEYWORD_GOTO, | |
- KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT, | |
+ KEYWORD_GET, KEYWORD_GOTO, | |
+ KEYWORD_IF, KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_IN, KEYWORD_INLINE, KEYWORD_INT, | |
KEYWORD_INOUT, KEYWORD_INPUT, KEYWORD_INTEGER, KEYWORD_INTERFACE, | |
KEYWORD_INTERNAL, | |
KEYWORD_LOCAL, KEYWORD_LONG, | |
KEYWORD_M_BAD_STATE, KEYWORD_M_BAD_TRANS, KEYWORD_M_STATE, KEYWORD_M_TRANS, | |
- KEYWORD_MUTABLE, | |
+ KEYWORD_MODULE, KEYWORD_MUTABLE, | |
KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NEWCOV, KEYWORD_NATIVE, | |
- KEYWORD_OPERATOR, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE, | |
+ KEYWORD_OPERATOR, KEYWORD_OUT, KEYWORD_OUTPUT, KEYWORD_OVERLOAD, KEYWORD_OVERRIDE, | |
KEYWORD_PACKED, KEYWORD_PORT, KEYWORD_PACKAGE, KEYWORD_PRIVATE, | |
KEYWORD_PROGRAM, KEYWORD_PROTECTED, KEYWORD_PUBLIC, | |
- KEYWORD_REGISTER, KEYWORD_RETURN, | |
+ KEYWORD_REF, KEYWORD_REGISTER, KEYWORD_RETURN, | |
KEYWORD_SHADOW, KEYWORD_STATE, | |
- KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRING, | |
+ KEYWORD_SET, KEYWORD_SHORT, KEYWORD_SIGNAL, KEYWORD_SIGNED, KEYWORD_SIZE_T, KEYWORD_STATIC, KEYWORD_STRING, | |
KEYWORD_STRUCT, KEYWORD_SWITCH, KEYWORD_SYNCHRONIZED, | |
KEYWORD_TASK, KEYWORD_TEMPLATE, KEYWORD_THIS, KEYWORD_THROW, | |
KEYWORD_THROWS, KEYWORD_TRANSIENT, KEYWORD_TRANS, KEYWORD_TRANSITION, | |
@@ -91,7 +92,7 @@ | |
KEYWORD_UINT, KEYWORD_ULONG, KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USHORT, | |
KEYWORD_USING, | |
KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE, | |
- KEYWORD_WCHAR_T, KEYWORD_WHILE | |
+ KEYWORD_WCHAR_T, KEYWORD_WEAK, KEYWORD_WHILE | |
} keywordId; | |
/* Used to determine whether keyword is valid for the current language and | |
@@ -100,7 +101,7 @@ | |
typedef struct sKeywordDesc { | |
const char *name; | |
keywordId id; | |
- short isValid [5]; /* indicates languages for which kw is valid */ | |
+ short isValid [7]; /* indicates languages for which kw is valid */ | |
} keywordDesc; | |
/* Used for reporting the type of object parsed by nextToken (). | |
@@ -114,11 +115,13 @@ | |
TOKEN_COMMA, /* the comma character */ | |
TOKEN_DOUBLE_COLON, /* double colon indicates nested-name-specifier */ | |
TOKEN_KEYWORD, | |
- TOKEN_NAME, /* an unknown name */ | |
- TOKEN_PACKAGE, /* a Java package name */ | |
- TOKEN_PAREN_NAME, /* a single name in parentheses */ | |
- TOKEN_SEMICOLON, /* the semicolon character */ | |
- TOKEN_SPEC, /* a storage class specifier, qualifier, type, etc. */ | |
+ TOKEN_NAME, /* an unknown name */ | |
+ TOKEN_PACKAGE, /* a Java package name */ | |
+ TOKEN_PAREN_NAME, /* a single name in parentheses */ | |
+ TOKEN_SEMICOLON, /* the semicolon character */ | |
+ TOKEN_SPEC, /* a storage class specifier, qualifier, type, etc. */ | |
+ TOKEN_STAR, /* pointer detection */ | |
+ TOKEN_ARRAY, /* array detection */ | |
TOKEN_COUNT | |
} tokenType; | |
@@ -139,9 +142,12 @@ | |
DECL_CLASS, | |
DECL_ENUM, | |
DECL_EVENT, | |
+ DECL_SIGNAL, | |
DECL_FUNCTION, | |
- DECL_IGNORE, /* non-taggable "declaration" */ | |
+ DECL_FUNCTION_TEMPLATE, | |
+ DECL_IGNORE, /* non-taggable "declaration" */ | |
DECL_INTERFACE, | |
+ DECL_MODULE, | |
DECL_NAMESPACE, | |
DECL_NOMANGLE, /* C++ name demangling block */ | |
DECL_PACKAGE, | |
@@ -206,6 +212,8 @@ | |
memberInfo member; /* information regarding parent class/struct */ | |
vString* parentClasses; /* parent classes */ | |
struct sStatementInfo *parent; /* statement we are nested within */ | |
+ long argEndPosition; /* Position where argument list ended */ | |
+ tokenInfo* firstToken; /* First token in the statement */ | |
} statementInfo; | |
/* Describes the type of tag being generated. | |
@@ -220,6 +228,7 @@ | |
TAG_FUNCTION, /* function definition */ | |
TAG_INTERFACE, /* interface declaration */ | |
TAG_LOCAL, /* local variable definition */ | |
+ TAG_MACRO, /* #define s */ | |
TAG_MEMBER, /* structure, class or interface member */ | |
TAG_METHOD, /* method declaration */ | |
TAG_NAMESPACE, /* namespace name */ | |
@@ -227,6 +236,7 @@ | |
TAG_PROGRAM, /* program name */ | |
TAG_PROPERTY, /* property name */ | |
TAG_PROTOTYPE, /* function prototype or declaration */ | |
+ TAG_SIGNAL, /* signal */ | |
TAG_STRUCT, /* structure name */ | |
TAG_TASK, /* task name */ | |
TAG_TYPEDEF, /* typedef name */ | |
@@ -255,7 +265,11 @@ | |
static langType Lang_c; | |
static langType Lang_cpp; | |
static langType Lang_csharp; | |
+static langType Lang_d; | |
+static langType Lang_ferite; | |
+static langType Lang_glsl; | |
static langType Lang_java; | |
+static langType Lang_vala; | |
static langType Lang_vera; | |
static vString *Signature; | |
static boolean CollectingSignature; | |
@@ -312,6 +326,32 @@ | |
{ TRUE, 't', "typedef", "typedefs"}, | |
}; | |
+/* Used to index into the DKinds table. */ | |
+typedef enum | |
+{ | |
+ DK_UNDEFINED = -1, | |
+ DK_CLASS, DK_ENUMERATOR, DK_FUNCTION, | |
+ DK_ENUMERATION, DK_INTERFACE, DK_MEMBER, DK_NAMESPACE, DK_PROTOTYPE, | |
+ DK_STRUCT, DK_TYPEDEF, DK_UNION, DK_VARIABLE, | |
+ DK_EXTERN_VARIABLE | |
+} dKind; | |
+ | |
+static kindOption DKinds [] = { | |
+ { TRUE, 'c', "class", "classes"}, | |
+ { TRUE, 'e', "enumerator", "enumerators (values inside an enumeration)"}, | |
+ { TRUE, 'f', "function", "function definitions"}, | |
+ { TRUE, 'g', "enum", "enumeration names"}, | |
+ { TRUE, 'i', "interface", "interfaces"}, | |
+ { TRUE, 'm', "member", "class, struct, and union members"}, | |
+ { TRUE, 'n', "namespace", "namespaces"}, | |
+ { FALSE, 'p', "prototype", "function prototypes"}, | |
+ { TRUE, 's', "struct", "structure names"}, | |
+ { TRUE, 't', "typedef", "typedefs"}, | |
+ { TRUE, 'u', "union", "union names"}, | |
+ { TRUE, 'v', "variable", "variable definitions"}, | |
+ { FALSE, 'x', "externvar", "external variable declarations"}, | |
+}; | |
+ | |
/* Used to index into the JavaKinds table. */ | |
typedef enum { | |
JK_UNDEFINED = -1, | |
@@ -330,6 +370,28 @@ | |
{ TRUE, 'p', "package", "packages"}, | |
}; | |
+typedef enum { | |
+ VAK_UNDEFINED = -1, | |
+ VAK_CLASS, VAK_DEFINE, VAK_ENUMERATOR, VAK_FIELD, | |
+ VAK_ENUMERATION, VAK_INTERFACE, VAK_LOCAL, VAK_METHOD, | |
+ VAK_NAMESPACE, VAK_PROPERTY, VAK_SIGNAL, VAK_STRUCT | |
+} valaKind; | |
+ | |
+static kindOption ValaKinds [] = { | |
+ { TRUE, 'c', "class", "classes"}, | |
+ { TRUE, 'd', "macro", "macro definitions"}, | |
+ { TRUE, 'e', "enumerator", "enumerators (values inside an enumeration)"}, | |
+ { TRUE, 'f', "field", "fields"}, | |
+ { TRUE, 'g', "enum", "enumeration names"}, | |
+ { TRUE, 'i', "interface", "interfaces"}, | |
+ { FALSE, 'l', "local", "local variables"}, | |
+ { TRUE, 'm', "method", "methods"}, | |
+ { TRUE, 'n', "namespace", "namespaces"}, | |
+ { TRUE, 'p', "property", "properties"}, | |
+ { TRUE, 'S', "signal", "signals"}, | |
+ { TRUE, 's', "struct", "structure names"}, | |
+}; | |
+ | |
/* Used to index into the VeraKinds table. */ | |
typedef enum { | |
VK_UNDEFINED = -1, | |
@@ -356,116 +418,139 @@ | |
}; | |
static const keywordDesc KeywordTable [] = { | |
- /* C++ */ | |
- /* ANSI C | C# Java */ | |
- /* | | | | Vera */ | |
- /* keyword keyword ID | | | | | */ | |
- { "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 1, 0, 0 } }, | |
- { "abstract", KEYWORD_ABSTRACT, { 0, 0, 1, 1, 0 } }, | |
- { "bad_state", KEYWORD_BAD_STATE, { 0, 0, 0, 0, 1 } }, | |
- { "bad_trans", KEYWORD_BAD_TRANS, { 0, 0, 0, 0, 1 } }, | |
- { "bind", KEYWORD_BIND, { 0, 0, 0, 0, 1 } }, | |
- { "bind_var", KEYWORD_BIND_VAR, { 0, 0, 0, 0, 1 } }, | |
- { "bit", KEYWORD_BIT, { 0, 0, 0, 0, 1 } }, | |
- { "boolean", KEYWORD_BOOLEAN, { 0, 0, 0, 1, 0 } }, | |
- { "byte", KEYWORD_BYTE, { 0, 0, 0, 1, 0 } }, | |
- { "case", KEYWORD_CASE, { 1, 1, 1, 1, 0 } }, | |
- { "catch", KEYWORD_CATCH, { 0, 1, 1, 0, 0 } }, | |
- { "char", KEYWORD_CHAR, { 1, 1, 1, 1, 0 } }, | |
- { "class", KEYWORD_CLASS, { 0, 1, 1, 1, 1 } }, | |
- { "const", KEYWORD_CONST, { 1, 1, 1, 1, 0 } }, | |
- { "constraint", KEYWORD_CONSTRAINT, { 0, 0, 0, 0, 1 } }, | |
- { "coverage_block", KEYWORD_COVERAGE_BLOCK, { 0, 0, 0, 0, 1 } }, | |
- { "coverage_def", KEYWORD_COVERAGE_DEF, { 0, 0, 0, 0, 1 } }, | |
- { "do", KEYWORD_DO, { 1, 1, 1, 1, 0 } }, | |
- { "default", KEYWORD_DEFAULT, { 1, 1, 1, 1, 0 } }, | |
- { "delegate", KEYWORD_DELEGATE, { 0, 0, 1, 0, 0 } }, | |
- { "delete", KEYWORD_DELETE, { 0, 1, 0, 0, 0 } }, | |
- { "double", KEYWORD_DOUBLE, { 1, 1, 1, 1, 0 } }, | |
- { "else", KEYWORD_ELSE, { 1, 1, 1, 1, 0 } }, | |
- { "enum", KEYWORD_ENUM, { 1, 1, 1, 1, 1 } }, | |
- { "event", KEYWORD_EVENT, { 0, 0, 1, 0, 1 } }, | |
- { "explicit", KEYWORD_EXPLICIT, { 0, 1, 1, 0, 0 } }, | |
- { "extends", KEYWORD_EXTENDS, { 0, 0, 0, 1, 1 } }, | |
- { "extern", KEYWORD_EXTERN, { 1, 1, 1, 0, 1 } }, | |
- { "final", KEYWORD_FINAL, { 0, 0, 0, 1, 0 } }, | |
- { "float", KEYWORD_FLOAT, { 1, 1, 1, 1, 0 } }, | |
- { "for", KEYWORD_FOR, { 1, 1, 1, 1, 0 } }, | |
- { "foreach", KEYWORD_FOREACH, { 0, 0, 1, 0, 0 } }, | |
- { "friend", KEYWORD_FRIEND, { 0, 1, 0, 0, 0 } }, | |
- { "function", KEYWORD_FUNCTION, { 0, 0, 0, 0, 1 } }, | |
- { "goto", KEYWORD_GOTO, { 1, 1, 1, 1, 0 } }, | |
- { "if", KEYWORD_IF, { 1, 1, 1, 1, 0 } }, | |
- { "implements", KEYWORD_IMPLEMENTS, { 0, 0, 0, 1, 0 } }, | |
- { "import", KEYWORD_IMPORT, { 0, 0, 0, 1, 0 } }, | |
- { "inline", KEYWORD_INLINE, { 0, 1, 0, 0, 0 } }, | |
- { "inout", KEYWORD_INOUT, { 0, 0, 0, 0, 1 } }, | |
- { "input", KEYWORD_INPUT, { 0, 0, 0, 0, 1 } }, | |
- { "int", KEYWORD_INT, { 1, 1, 1, 1, 0 } }, | |
- { "integer", KEYWORD_INTEGER, { 0, 0, 0, 0, 1 } }, | |
- { "interface", KEYWORD_INTERFACE, { 0, 0, 1, 1, 1 } }, | |
- { "internal", KEYWORD_INTERNAL, { 0, 0, 1, 0, 0 } }, | |
- { "local", KEYWORD_LOCAL, { 0, 0, 0, 0, 1 } }, | |
- { "long", KEYWORD_LONG, { 1, 1, 1, 1, 0 } }, | |
- { "m_bad_state", KEYWORD_M_BAD_STATE, { 0, 0, 0, 0, 1 } }, | |
- { "m_bad_trans", KEYWORD_M_BAD_TRANS, { 0, 0, 0, 0, 1 } }, | |
- { "m_state", KEYWORD_M_STATE, { 0, 0, 0, 0, 1 } }, | |
- { "m_trans", KEYWORD_M_TRANS, { 0, 0, 0, 0, 1 } }, | |
- { "mutable", KEYWORD_MUTABLE, { 0, 1, 0, 0, 0 } }, | |
- { "namespace", KEYWORD_NAMESPACE, { 0, 1, 1, 0, 0 } }, | |
- { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0 } }, | |
- { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0 } }, | |
- { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1 } }, | |
- { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0 } }, | |
- { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1 } }, | |
- { "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0 } }, | |
- { "override", KEYWORD_OVERRIDE, { 0, 0, 1, 0, 0 } }, | |
- { "package", KEYWORD_PACKAGE, { 0, 0, 0, 1, 0 } }, | |
- { "packed", KEYWORD_PACKED, { 0, 0, 0, 0, 1 } }, | |
- { "port", KEYWORD_PORT, { 0, 0, 0, 0, 1 } }, | |
- { "private", KEYWORD_PRIVATE, { 0, 1, 1, 1, 0 } }, | |
- { "program", KEYWORD_PROGRAM, { 0, 0, 0, 0, 1 } }, | |
- { "protected", KEYWORD_PROTECTED, { 0, 1, 1, 1, 1 } }, | |
- { "public", KEYWORD_PUBLIC, { 0, 1, 1, 1, 1 } }, | |
- { "register", KEYWORD_REGISTER, { 1, 1, 0, 0, 0 } }, | |
- { "return", KEYWORD_RETURN, { 1, 1, 1, 1, 0 } }, | |
- { "shadow", KEYWORD_SHADOW, { 0, 0, 0, 0, 1 } }, | |
- { "short", KEYWORD_SHORT, { 1, 1, 1, 1, 0 } }, | |
- { "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0 } }, | |
- { "state", KEYWORD_STATE, { 0, 0, 0, 0, 1 } }, | |
- { "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1 } }, | |
- { "string", KEYWORD_STRING, { 0, 0, 1, 0, 1 } }, | |
- { "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0 } }, | |
- { "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0 } }, | |
- { "synchronized", KEYWORD_SYNCHRONIZED, { 0, 0, 0, 1, 0 } }, | |
- { "task", KEYWORD_TASK, { 0, 0, 0, 0, 1 } }, | |
- { "template", KEYWORD_TEMPLATE, { 0, 1, 0, 0, 0 } }, | |
- { "this", KEYWORD_THIS, { 0, 1, 1, 1, 0 } }, | |
- { "throw", KEYWORD_THROW, { 0, 1, 1, 1, 0 } }, | |
- { "throws", KEYWORD_THROWS, { 0, 0, 0, 1, 0 } }, | |
- { "trans", KEYWORD_TRANS, { 0, 0, 0, 0, 1 } }, | |
- { "transition", KEYWORD_TRANSITION, { 0, 0, 0, 0, 1 } }, | |
- { "transient", KEYWORD_TRANSIENT, { 0, 0, 0, 1, 0 } }, | |
- { "try", KEYWORD_TRY, { 0, 1, 1, 0, 0 } }, | |
- { "typedef", KEYWORD_TYPEDEF, { 1, 1, 1, 0, 1 } }, | |
- { "typename", KEYWORD_TYPENAME, { 0, 1, 0, 0, 0 } }, | |
- { "uint", KEYWORD_UINT, { 0, 0, 1, 0, 0 } }, | |
- { "ulong", KEYWORD_ULONG, { 0, 0, 1, 0, 0 } }, | |
- { "union", KEYWORD_UNION, { 1, 1, 0, 0, 0 } }, | |
- { "unsigned", KEYWORD_UNSIGNED, { 1, 1, 1, 0, 0 } }, | |
- { "ushort", KEYWORD_USHORT, { 0, 0, 1, 0, 0 } }, | |
- { "using", KEYWORD_USING, { 0, 1, 1, 0, 0 } }, | |
- { "virtual", KEYWORD_VIRTUAL, { 0, 1, 1, 0, 1 } }, | |
- { "void", KEYWORD_VOID, { 1, 1, 1, 1, 1 } }, | |
- { "volatile", KEYWORD_VOLATILE, { 1, 1, 1, 1, 0 } }, | |
- { "wchar_t", KEYWORD_WCHAR_T, { 1, 1, 1, 0, 0 } }, | |
- { "while", KEYWORD_WHILE, { 1, 1, 1, 1, 0 } } | |
+ /* C++ */ | |
+ /* ANSI C | C# Java */ | |
+ /* | | | | Vera */ | |
+ /* | | | | | Vala */ | |
+ /* | | | | | | D */ | |
+ /* keyword keyword ID | | | | | | | */ | |
+ { "__attribute__", KEYWORD_ATTRIBUTE, { 1, 1, 1, 0, 0, 0, 1 } }, | |
+ { "abstract", KEYWORD_ABSTRACT, { 0, 0, 1, 1, 0, 1, 1 } }, | |
+ { "alias", KEYWORD_TYPEDEF, { 0, 0, 0, 0, 0, 0, 1 } }, /* handle like typedef */ | |
+ { "bad_state", KEYWORD_BAD_STATE, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "bad_trans", KEYWORD_BAD_TRANS, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "bind", KEYWORD_BIND, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "bind_var", KEYWORD_BIND_VAR, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "bit", KEYWORD_BIT, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "body", KEYWORD_BODY, { 0, 0, 0, 0, 0, 0, 1 } }, | |
+ { "boolean", KEYWORD_BOOLEAN, { 0, 0, 0, 1, 0, 0, 0 } }, | |
+ { "byte", KEYWORD_BYTE, { 0, 0, 0, 1, 0, 0, 1 } }, | |
+ { "case", KEYWORD_CASE, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "catch", KEYWORD_CATCH, { 0, 1, 1, 0, 0, 1, 1 } }, | |
+ { "char", KEYWORD_CHAR, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "class", KEYWORD_CLASS, { 0, 1, 1, 1, 1, 1, 1 } }, | |
+ { "const", KEYWORD_CONST, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "constraint", KEYWORD_CONSTRAINT, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "coverage_block", KEYWORD_COVERAGE_BLOCK, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "coverage_def", KEYWORD_COVERAGE_DEF, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "do", KEYWORD_DO, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "default", KEYWORD_DEFAULT, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "delegate", KEYWORD_DELEGATE, { 0, 0, 1, 0, 0, 1, 1 } }, | |
+ { "delete", KEYWORD_DELETE, { 0, 1, 0, 0, 0, 1, 1 } }, | |
+ { "double", KEYWORD_DOUBLE, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "else", KEYWORD_ELSE, { 1, 1, 0, 1, 0, 1, 1 } }, | |
+ { "ensures", KEYWORD_ATTRIBUTE, { 0, 0, 0, 0, 0, 1, 0 } }, /* ignore */ | |
+ { "enum", KEYWORD_ENUM, { 1, 1, 1, 1, 1, 1, 1 } }, | |
+ { "errordomain", KEYWORD_ENUM, { 0, 0, 0, 0, 0, 1, 0 } }, /* errordomain behaves like enum */ | |
+ { "event", KEYWORD_EVENT, { 0, 0, 1, 0, 1, 0, 0 } }, | |
+ { "explicit", KEYWORD_EXPLICIT, { 0, 1, 1, 0, 0, 0, 1 } }, | |
+ { "extends", KEYWORD_EXTENDS, { 0, 0, 0, 1, 1, 0, 0 } }, | |
+ { "extern", KEYWORD_EXTERN, { 1, 1, 1, 0, 1, 1, 0 } }, | |
+ { "extern", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */ | |
+ { "final", KEYWORD_FINAL, { 0, 0, 0, 1, 0, 0, 1 } }, | |
+ { "finally", KEYWORD_FINALLY, { 0, 0, 0, 0, 0, 1, 1 } }, | |
+ { "float", KEYWORD_FLOAT, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "for", KEYWORD_FOR, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "foreach", KEYWORD_FOREACH, { 0, 0, 1, 0, 0, 1, 1 } }, | |
+ { "friend", KEYWORD_FRIEND, { 0, 1, 0, 0, 0, 0, 0 } }, | |
+ { "function", KEYWORD_FUNCTION, { 0, 0, 0, 0, 1, 0, 1 } }, | |
+ { "get", KEYWORD_GET, { 0, 0, 0, 0, 0, 1, 0 } }, | |
+ { "goto", KEYWORD_GOTO, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "if", KEYWORD_IF, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "implements", KEYWORD_IMPLEMENTS, { 0, 0, 0, 1, 0, 0, 0 } }, | |
+ { "import", KEYWORD_IMPORT, { 0, 0, 0, 1, 0, 0, 1 } }, | |
+ { "inline", KEYWORD_INLINE, { 0, 1, 0, 0, 0, 1, 0 } }, | |
+ { "in", KEYWORD_IN, { 0, 0, 0, 0, 0, 0, 1 } }, | |
+ { "inout", KEYWORD_INOUT, { 0, 0, 0, 0, 1, 0, 1 } }, | |
+ { "input", KEYWORD_INPUT, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "int", KEYWORD_INT, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "integer", KEYWORD_INTEGER, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "interface", KEYWORD_INTERFACE, { 0, 0, 1, 1, 1, 1, 1 } }, | |
+ { "internal", KEYWORD_INTERNAL, { 0, 0, 1, 0, 0, 0, 0 } }, | |
+ { "local", KEYWORD_LOCAL, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "long", KEYWORD_LONG, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "m_bad_state", KEYWORD_M_BAD_STATE, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "m_bad_trans", KEYWORD_M_BAD_TRANS, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "m_state", KEYWORD_M_STATE, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "m_trans", KEYWORD_M_TRANS, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "mutable", KEYWORD_MUTABLE, { 0, 1, 0, 0, 0, 0, 0 } }, | |
+ { "module", KEYWORD_MODULE, { 0, 0, 0, 0, 0, 0, 1 } }, | |
+ { "namespace", KEYWORD_NAMESPACE, { 0, 1, 1, 0, 0, 1, 0 } }, | |
+ { "native", KEYWORD_NATIVE, { 0, 0, 0, 1, 0, 0, 0 } }, | |
+ { "new", KEYWORD_NEW, { 0, 1, 1, 1, 0, 1, 1 } }, | |
+ { "newcov", KEYWORD_NEWCOV, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "operator", KEYWORD_OPERATOR, { 0, 1, 1, 0, 0, 0, 0 } }, | |
+ { "out", KEYWORD_OUT, { 0, 0, 0, 0, 0, 1, 1 } }, | |
+ { "output", KEYWORD_OUTPUT, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "overload", KEYWORD_OVERLOAD, { 0, 1, 0, 0, 0, 0, 0 } }, | |
+ { "override", KEYWORD_OVERRIDE, { 0, 0, 1, 0, 0, 1, 1 } }, | |
+ { "package", KEYWORD_PACKAGE, { 0, 0, 0, 1, 0, 0, 1 } }, | |
+ { "packed", KEYWORD_PACKED, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "port", KEYWORD_PORT, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "private", KEYWORD_PRIVATE, { 0, 1, 1, 1, 0, 1, 1 } }, | |
+ { "program", KEYWORD_PROGRAM, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "protected", KEYWORD_PROTECTED, { 0, 1, 1, 1, 1, 1, 1 } }, | |
+ { "public", KEYWORD_PUBLIC, { 0, 1, 1, 1, 1, 1, 1 } }, | |
+ { "ref", KEYWORD_REF, { 0, 0, 0, 0, 0, 1, 1 } }, | |
+ { "register", KEYWORD_REGISTER, { 1, 1, 0, 0, 0, 0, 0 } }, | |
+ { "requires", KEYWORD_ATTRIBUTE, { 0, 0, 0, 0, 0, 1, 0 } }, /* ignore */ | |
+ { "return", KEYWORD_RETURN, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "set", KEYWORD_SET, { 0, 0, 0, 0, 0, 1, 0 } }, | |
+ { "shadow", KEYWORD_SHADOW, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "short", KEYWORD_SHORT, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "signal", KEYWORD_SIGNAL, { 0, 0, 0, 0, 0, 1, 0 } }, | |
+ { "signed", KEYWORD_SIGNED, { 1, 1, 0, 0, 0, 0, 0 } }, | |
+ { "size_t", KEYWORD_SIZE_T, { 1, 1, 0, 0, 0, 1, 1 } }, | |
+ { "state", KEYWORD_STATE, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "static", KEYWORD_STATIC, { 1, 1, 1, 1, 1, 1, 1 } }, | |
+ { "string", KEYWORD_STRING, { 0, 0, 1, 0, 1, 1, 0 } }, | |
+ { "struct", KEYWORD_STRUCT, { 1, 1, 1, 0, 0, 1, 1 } }, | |
+ { "switch", KEYWORD_SWITCH, { 1, 1, 1, 1, 0, 1, 1 } }, | |
+ { "synchronized", KEYWORD_SYNCHRONIZED, { 0, 0, 0, 1, 0, 0, 1 } }, | |
+ { "task", KEYWORD_TASK, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "template", KEYWORD_TEMPLATE, { 0, 1, 0, 0, 0, 0, 0 } }, | |
+ { "template", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */ | |
+ { "this", KEYWORD_THIS, { 0, 0, 1, 1, 0, 1, 0 } }, /* 0 to allow D ctor tags */ | |
+ { "throw", KEYWORD_THROW, { 0, 1, 1, 1, 0, 1, 1 } }, | |
+ { "throws", KEYWORD_THROWS, { 0, 0, 0, 1, 0, 1, 0 } }, | |
+ { "trans", KEYWORD_TRANS, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "transition", KEYWORD_TRANSITION, { 0, 0, 0, 0, 1, 0, 0 } }, | |
+ { "transient", KEYWORD_TRANSIENT, { 0, 0, 0, 1, 0, 0, 0 } }, | |
+ { "try", KEYWORD_TRY, { 0, 1, 1, 0, 0, 1, 1 } }, | |
+ { "typedef", KEYWORD_TYPEDEF, { 1, 1, 1, 0, 1, 0, 1 } }, | |
+ { "typename", KEYWORD_TYPENAME, { 0, 1, 0, 0, 0, 0, 0 } }, | |
+ { "uint", KEYWORD_UINT, { 0, 0, 1, 0, 0, 1, 1 } }, | |
+ { "ulong", KEYWORD_ULONG, { 0, 0, 1, 0, 0, 1, 1 } }, | |
+ { "union", KEYWORD_UNION, { 1, 1, 0, 0, 0, 0, 1 } }, | |
+ { "unittest", KEYWORD_BODY, { 0, 0, 0, 0, 0, 0, 1 } }, /* ignore */ | |
+ { "unsigned", KEYWORD_UNSIGNED, { 1, 1, 1, 0, 0, 0, 1 } }, | |
+ { "ushort", KEYWORD_USHORT, { 0, 0, 1, 0, 0, 1, 1 } }, | |
+ { "using", KEYWORD_USING, { 0, 1, 1, 0, 0, 1, 0 } }, | |
+ { "version", KEYWORD_NAMESPACE, { 0, 0, 0, 0, 0, 0, 1 } }, /* parse block */ | |
+ { "virtual", KEYWORD_VIRTUAL, { 0, 1, 1, 0, 1, 1, 0 } }, | |
+ { "void", KEYWORD_VOID, { 1, 1, 1, 1, 1, 1, 1 } }, | |
+ { "volatile", KEYWORD_VOLATILE, { 1, 1, 1, 1, 0, 0, 1 } }, | |
+ { "wchar_t", KEYWORD_WCHAR_T, { 1, 1, 1, 0, 0, 0, 1 } }, | |
+ { "weak", KEYWORD_WEAK, { 0, 0, 0, 0, 0, 1, 0 } }, | |
+ { "while", KEYWORD_WHILE, { 1, 1, 1, 1, 0, 1, 1 } } | |
}; | |
/* | |
* FUNCTION PROTOTYPES | |
*/ | |
static void createTags (const unsigned int nestLevel, statementInfo *const parent); | |
+static void copyToken (tokenInfo *const dest, const tokenInfo *const src); | |
+static const char *getVarType (const statementInfo *const st); | |
/* | |
* FUNCTION DEFINITIONS | |
@@ -473,7 +558,15 @@ | |
extern boolean includingDefineTags (void) | |
{ | |
- return CKinds [CK_DEFINE].enabled; | |
+ if (isLanguage(Lang_c) || | |
+ isLanguage(Lang_cpp) || | |
+ isLanguage(Lang_csharp) || | |
+ isLanguage(Lang_ferite) || | |
+ isLanguage(Lang_glsl) || | |
+ isLanguage(Lang_vala)) | |
+ return CKinds [CK_DEFINE].enabled; | |
+ | |
+ return FALSE; | |
} | |
/* | |
@@ -573,7 +666,7 @@ | |
{ | |
static const char *const names [] = { | |
"none", "args", "}", "{", "colon", "comma", "double colon", "keyword", | |
- "name", "package", "paren-name", "semicolon", "specifier" | |
+ "name", "package", "paren-name", "semicolon", "specifier", "*", "[]" | |
}; | |
Assert (sizeof (names) / sizeof (names [0]) == TOKEN_COUNT); | |
Assert ((int) type < TOKEN_COUNT); | |
@@ -593,9 +686,9 @@ | |
static const char *declString (const declType declaration) | |
{ | |
static const char *const names [] = { | |
- "?", "base", "class", "enum", "event", "function", "ignore", | |
- "interface", "namespace", "no mangle", "package", "program", | |
- "struct", "task", "union", | |
+ "?", "base", "class", "enum", "event", "function", "function template", | |
+ "ignore", "interface", "module", "namespace", "no mangle", "package", | |
+ "program", "signal", "struct", "task", "union", | |
}; | |
Assert (sizeof (names) / sizeof (names [0]) == DECL_COUNT); | |
Assert ((int) declaration < DECL_COUNT); | |
@@ -660,6 +753,27 @@ | |
* Statement management | |
*/ | |
+static boolean isDataTypeKeyword (const tokenInfo *const token) | |
+{ | |
+ switch (token->keyword) | |
+ { | |
+ case KEYWORD_BOOLEAN: | |
+ case KEYWORD_BYTE: | |
+ case KEYWORD_CHAR: | |
+ case KEYWORD_DOUBLE: | |
+ case KEYWORD_FLOAT: | |
+ case KEYWORD_INT: | |
+ case KEYWORD_LONG: | |
+ case KEYWORD_SHORT: | |
+ case KEYWORD_VOID: | |
+ case KEYWORD_WCHAR_T: | |
+ case KEYWORD_SIZE_T: | |
+ return TRUE; | |
+ default: | |
+ return FALSE; | |
+ } | |
+} | |
+ | |
static boolean isContextualKeyword (const tokenInfo *const token) | |
{ | |
boolean result; | |
@@ -682,18 +796,30 @@ | |
static boolean isContextualStatement (const statementInfo *const st) | |
{ | |
boolean result = FALSE; | |
- if (st != NULL) switch (st->declaration) | |
+ | |
+ if (st != NULL) | |
{ | |
- case DECL_CLASS: | |
- case DECL_ENUM: | |
- case DECL_INTERFACE: | |
- case DECL_NAMESPACE: | |
- case DECL_STRUCT: | |
- case DECL_UNION: | |
+ if (isLanguage (Lang_vala)) | |
+ { | |
+ /* All can be a contextual statment as properties can be of any type */ | |
result = TRUE; | |
- break; | |
+ } | |
+ else | |
+ { | |
+ switch (st->declaration) | |
+ { | |
+ case DECL_CLASS: | |
+ case DECL_ENUM: | |
+ case DECL_INTERFACE: | |
+ case DECL_NAMESPACE: | |
+ case DECL_STRUCT: | |
+ case DECL_UNION: | |
+ result = TRUE; | |
+ break; | |
- default: result = FALSE; break; | |
+ default: result = FALSE; break; | |
+ } | |
+ } | |
} | |
return result; | |
} | |
@@ -762,6 +888,7 @@ | |
st->gotArgs = FALSE; | |
st->gotName = FALSE; | |
st->haveQualifyingName = FALSE; | |
+ st->argEndPosition = 0; | |
st->tokenIndex = 0; | |
if (st->parent != NULL) | |
@@ -784,13 +911,37 @@ | |
*/ | |
if (! partial) | |
st->member.access = st->member.accessDefault; | |
+ | |
+ /* Init first token */ | |
+ if (!partial) | |
+ initToken(st->firstToken); | |
} | |
+static void reinitStatementWithToken (statementInfo *const st, | |
+ tokenInfo *token, const boolean partial) | |
+{ | |
+ tokenInfo *const save = newToken (); | |
+ /* given token can be part of reinit statementInfo */ | |
+ copyToken (save, token); | |
+ reinitStatement (st, partial); | |
+ token = activeToken (st); | |
+ copyToken (token, save); | |
+ deleteToken (save); | |
+ ++st->tokenIndex; /* this is quite save becouse current tokenIndex = 0 */ | |
+} | |
+ | |
static void initStatement (statementInfo *const st, statementInfo *const parent) | |
{ | |
st->parent = parent; | |
initMemberInfo (st); | |
reinitStatement (st, FALSE); | |
+ if (parent) | |
+ { | |
+ const tokenInfo *const src = activeToken (parent); | |
+ tokenInfo *const dst = activeToken (st); | |
+ copyToken (dst, src); | |
+ st->tokenIndex++; | |
+ } | |
} | |
/* | |
@@ -843,6 +994,30 @@ | |
return result; | |
} | |
+static dKind dTagKind (const tagType type) | |
+{ | |
+ dKind result = DK_UNDEFINED; | |
+ switch (type) | |
+ { | |
+ case TAG_CLASS: result = DK_CLASS; break; | |
+ case TAG_ENUM: result = DK_ENUMERATION; break; | |
+ case TAG_ENUMERATOR: result = DK_ENUMERATOR; break; | |
+ case TAG_FUNCTION: result = DK_FUNCTION; break; | |
+ case TAG_INTERFACE: result = DK_INTERFACE; break; | |
+ case TAG_MEMBER: result = DK_MEMBER; break; | |
+ case TAG_NAMESPACE: result = DK_NAMESPACE; break; | |
+ case TAG_PROTOTYPE: result = DK_PROTOTYPE; break; | |
+ case TAG_STRUCT: result = DK_STRUCT; break; | |
+ case TAG_TYPEDEF: result = DK_TYPEDEF; break; | |
+ case TAG_UNION: result = DK_UNION; break; | |
+ case TAG_VARIABLE: result = DK_VARIABLE; break; | |
+ case TAG_EXTERN_VAR: result = DK_EXTERN_VARIABLE; break; | |
+ | |
+ default: Assert ("Bad D tag type" == NULL); break; | |
+ } | |
+ return result; | |
+} | |
+ | |
static javaKind javaTagKind (const tagType type) | |
{ | |
javaKind result = JK_UNDEFINED; | |
@@ -862,6 +1037,30 @@ | |
return result; | |
} | |
+static valaKind valaTagKind (const tagType type) | |
+{ | |
+ valaKind result = VK_UNDEFINED; | |
+ switch (type) | |
+ { | |
+ case TAG_CLASS: result = VAK_CLASS; break; | |
+ case TAG_ENUM: result = VAK_ENUMERATION; break; | |
+ case TAG_ENUMERATOR: result = VAK_ENUMERATOR; break; | |
+ case TAG_SIGNAL: result = VAK_SIGNAL; break; | |
+ case TAG_FIELD: result = VAK_FIELD ; break; | |
+ case TAG_INTERFACE: result = VAK_INTERFACE; break; | |
+ case TAG_LOCAL: result = VAK_LOCAL; break; | |
+ case TAG_METHOD: result = VAK_METHOD; break; | |
+ case TAG_NAMESPACE: result = VAK_NAMESPACE; break; | |
+ case TAG_PROPERTY: result = VAK_PROPERTY; break; | |
+ case TAG_STRUCT: result = VAK_STRUCT; break; | |
+ | |
+ default: Assert ("Bad Vala tag type" == NULL); break; | |
+ } | |
+ return result; | |
+} | |
+ | |
+ | |
+ | |
static veraKind veraTagKind (const tagType type) { | |
veraKind result = VK_UNDEFINED; | |
switch (type) | |
@@ -889,8 +1088,12 @@ | |
const char* result; | |
if (isLanguage (Lang_csharp)) | |
result = CsharpKinds [csharpTagKind (type)].name; | |
- else if (isLanguage (Lang_java)) | |
+ else if (isLanguage (Lang_d)) | |
+ result = DKinds [dTagKind (type)].name; | |
+ if (isLanguage (Lang_java)) | |
result = JavaKinds [javaTagKind (type)].name; | |
+ else if (isLanguage (Lang_vala)) | |
+ result = ValaKinds [valaTagKind (type)].name; | |
else if (isLanguage (Lang_vera)) | |
result = VeraKinds [veraTagKind (type)].name; | |
else | |
@@ -903,8 +1106,12 @@ | |
int result; | |
if (isLanguage (Lang_csharp)) | |
result = CsharpKinds [csharpTagKind (type)].letter; | |
+ else if (isLanguage (Lang_d)) | |
+ result = DKinds [dTagKind (type)].letter; | |
else if (isLanguage (Lang_java)) | |
result = JavaKinds [javaTagKind (type)].letter; | |
+ else if (isLanguage (Lang_vala)) | |
+ result = ValaKinds [valaTagKind (type)].letter; | |
else if (isLanguage (Lang_vera)) | |
result = VeraKinds [veraTagKind (type)].letter; | |
else | |
@@ -938,6 +1145,7 @@ | |
case DECL_ENUM: type = TAG_ENUM; break; | |
case DECL_EVENT: type = TAG_EVENT; break; | |
case DECL_FUNCTION: type = TAG_FUNCTION; break; | |
+ case DECL_FUNCTION_TEMPLATE: type = TAG_FUNCTION; break; | |
case DECL_INTERFACE: type = TAG_INTERFACE; break; | |
case DECL_NAMESPACE: type = TAG_NAMESPACE; break; | |
case DECL_PROGRAM: type = TAG_PROGRAM; break; | |
@@ -953,7 +1161,9 @@ | |
static const char* accessField (const statementInfo *const st) | |
{ | |
const char* result = NULL; | |
- if (isLanguage (Lang_cpp) && st->scope == SCOPE_FRIEND) | |
+ | |
+ if ((isLanguage (Lang_cpp) || isLanguage (Lang_d) || isLanguage (Lang_ferite)) && | |
+ st->scope == SCOPE_FRIEND) | |
result = "friend"; | |
else if (st->member.access != ACCESS_UNDEFINED) | |
result = accessString (st->member.access); | |
@@ -964,7 +1174,8 @@ | |
{ | |
if (isLanguage (Lang_c) || isLanguage (Lang_cpp)) | |
vStringCatS (scope, "::"); | |
- else if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) | |
+ else if (isLanguage (Lang_java) || isLanguage (Lang_d) || isLanguage (Lang_ferite) || | |
+ isLanguage (Lang_csharp) || isLanguage (Lang_vala)) | |
vStringCatS (scope, "."); | |
} | |
@@ -1015,8 +1226,8 @@ | |
vStringValue (st->parentClasses); | |
} | |
if (st->implementation != IMP_DEFAULT && | |
- (isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || | |
- isLanguage (Lang_java))) | |
+ (isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || isLanguage (Lang_vala) || | |
+ isLanguage (Lang_java) || isLanguage (Lang_d) || isLanguage (Lang_ferite))) | |
{ | |
tag->extensionFields.implementation = | |
implementationString (st->implementation); | |
@@ -1146,6 +1357,13 @@ | |
vString *typeRef = vStringNew (); | |
tagEntryInfo e; | |
+ /* take only functions which are introduced by "function ..." */ | |
+ if (type == TAG_FUNCTION && isLanguage (Lang_ferite) && | |
+ strncmp("function", st->firstToken->name->buffer, 8) != 0) | |
+ { | |
+ return; | |
+ } | |
+ | |
initTagEntry (&e, vStringValue (token->name)); | |
e.lineNumber = token->lineNumber; | |
@@ -1201,7 +1419,7 @@ | |
const boolean isFileScope = | |
(boolean) (st->member.access == ACCESS_PRIVATE || | |
(!isMember (st) && st->scope == SCOPE_STATIC)); | |
- if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) | |
+ if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) | |
type = TAG_METHOD; | |
else if (isLanguage (Lang_vera) && st->declaration == DECL_TASK) | |
type = TAG_TASK; | |
@@ -1216,11 +1434,12 @@ | |
{ | |
if (! isType (nameToken, TOKEN_NAME)) | |
; | |
- else if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) | |
+ else if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) | |
qualifyFunctionTag (st, nameToken); | |
else if (st->scope == SCOPE_TYPEDEF) | |
makeTag (nameToken, st, TRUE, TAG_TYPEDEF); | |
- else if (isValidTypeSpecifier (st->declaration) && ! isLanguage (Lang_csharp)) | |
+ else if (isValidTypeSpecifier (st->declaration) && | |
+ ! (isLanguage (Lang_csharp) || isLanguage (Lang_vala))) | |
makeTag (nameToken, st, TRUE, TAG_PROTOTYPE); | |
} | |
@@ -1233,6 +1452,7 @@ | |
const boolean fileScoped = (boolean) | |
(!(isLanguage (Lang_java) || | |
isLanguage (Lang_csharp) || | |
+ isLanguage (Lang_vala) || | |
isLanguage (Lang_vera))); | |
if (type != TAG_UNDEFINED) | |
@@ -1267,6 +1487,8 @@ | |
*/ | |
if (! isType (nameToken, TOKEN_NAME)) | |
; | |
+ else if (st->declaration == DECL_IGNORE) | |
+ ; | |
else if (st->scope == SCOPE_TYPEDEF) | |
makeTag (nameToken, st, TRUE, TAG_TYPEDEF); | |
else if (st->declaration == DECL_EVENT) | |
@@ -1274,18 +1496,22 @@ | |
TAG_EVENT); | |
else if (st->declaration == DECL_PACKAGE) | |
makeTag (nameToken, st, FALSE, TAG_PACKAGE); | |
+ else if (st->declaration == DECL_MODULE) /* handle modules in D as namespaces */ | |
+ makeTag (nameToken, st, FALSE, TAG_NAMESPACE); | |
else if (isValidTypeSpecifier (st->declaration)) | |
{ | |
if (st->notVariable) | |
; | |
else if (isMember (st)) | |
{ | |
- if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) | |
+ if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) | |
makeTag (nameToken, st, | |
(boolean) (st->member.access == ACCESS_PRIVATE), TAG_FIELD); | |
else if (st->scope == SCOPE_GLOBAL || st->scope == SCOPE_STATIC) | |
makeTag (nameToken, st, TRUE, TAG_MEMBER); | |
} | |
+ else if (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) | |
+ ; | |
else | |
{ | |
if (st->scope == SCOPE_EXTERN || ! st->haveQualifyingName) | |
@@ -1491,7 +1717,7 @@ | |
first = FALSE; | |
} | |
c = cppGetc (); | |
- } while (isident (c) || ((isLanguage (Lang_java) || isLanguage (Lang_csharp)) && (isHighChar (c) || c == '.'))); | |
+ } while (isident (c) || ((isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) && (isHighChar (c) || c == '.'))); | |
vStringTerminate (name); | |
cppUngetc (c); /* unget non-identifier character */ | |
@@ -1517,8 +1743,8 @@ | |
static void readPackageOrNamespace (statementInfo *const st, const declType declaration) | |
{ | |
st->declaration = declaration; | |
- | |
- if (declaration == DECL_NAMESPACE && !isLanguage (Lang_csharp)) | |
+ | |
+ if (declaration == DECL_NAMESPACE && !(isLanguage (Lang_csharp) || isLanguage (Lang_vala))) | |
{ | |
/* In C++ a namespace is specified one level at a time. */ | |
return; | |
@@ -1535,6 +1761,20 @@ | |
} | |
} | |
+static void readPackage (statementInfo *const st) | |
+{ | |
+ tokenInfo *const token = activeToken (st); | |
+ Assert (isType (token, TOKEN_KEYWORD)); | |
+ readPackageName (token, skipToNonWhite ()); | |
+ token->type = TOKEN_NAME; | |
+ if (isLanguage (Lang_d)) | |
+ st->declaration = DECL_MODULE; | |
+ else | |
+ st->declaration = DECL_PACKAGE; | |
+ st->gotName = TRUE; | |
+ st->haveQualifyingName = TRUE; | |
+} | |
+ | |
static void processName (statementInfo *const st) | |
{ | |
Assert (isType (activeToken (st), TOKEN_NAME)); | |
@@ -1628,12 +1868,12 @@ | |
{ | |
if (isMember (st)) | |
{ | |
- if (isLanguage (Lang_cpp)) | |
+ if (isLanguage (Lang_cpp) || isLanguage (Lang_d) || isLanguage (Lang_ferite)) | |
{ | |
int c = skipToNonWhite (); | |
if (c == ':') | |
- reinitStatement (st, FALSE); | |
+ reinitStatementWithToken (st, prevToken (st, 1), FALSE); | |
else | |
cppUngetc (c); | |
@@ -1740,10 +1980,13 @@ | |
case KEYWORD_IMPORT: skipStatement (st); break; | |
case KEYWORD_INT: st->declaration = DECL_BASE; break; | |
case KEYWORD_INTEGER: st->declaration = DECL_BASE; break; | |
+ case KEYWORD_BOOLEAN: st->declaration = DECL_BASE; break; | |
+ case KEYWORD_SIZE_T: st->declaration = DECL_BASE; break; | |
case KEYWORD_INTERFACE: processInterface (st); break; | |
case KEYWORD_LOCAL: setAccess (st, ACCESS_LOCAL); break; | |
case KEYWORD_LONG: st->declaration = DECL_BASE; break; | |
case KEYWORD_OPERATOR: readOperator (st); break; | |
+ case KEYWORD_MODULE: readPackage (st); break; | |
case KEYWORD_PRIVATE: setAccess (st, ACCESS_PRIVATE); break; | |
case KEYWORD_PROGRAM: st->declaration = DECL_PROGRAM; break; | |
case KEYWORD_PROTECTED: setAccess (st, ACCESS_PROTECTED); break; | |
@@ -1762,10 +2005,10 @@ | |
case KEYWORD_VOLATILE: st->declaration = DECL_BASE; break; | |
case KEYWORD_VIRTUAL: st->implementation = IMP_VIRTUAL; break; | |
case KEYWORD_WCHAR_T: st->declaration = DECL_BASE; break; | |
- | |
+ | |
case KEYWORD_NAMESPACE: readPackageOrNamespace (st, DECL_NAMESPACE); break; | |
case KEYWORD_PACKAGE: readPackageOrNamespace (st, DECL_PACKAGE); break; | |
- | |
+ | |
case KEYWORD_EVENT: | |
if (isLanguage (Lang_csharp)) | |
st->declaration = DECL_EVENT; | |
@@ -1776,6 +2019,11 @@ | |
st->scope = SCOPE_TYPEDEF; | |
break; | |
+ case KEYWORD_SIGNAL: | |
+ if (isLanguage (Lang_vala)) | |
+ st->declaration = DECL_SIGNAL; | |
+ break; | |
+ | |
case KEYWORD_EXTERN: | |
if (! isLanguage (Lang_csharp) || !st->gotName) | |
{ | |
@@ -1786,7 +2034,7 @@ | |
break; | |
case KEYWORD_STATIC: | |
- if (! (isLanguage (Lang_java) || isLanguage (Lang_csharp))) | |
+ if (! (isLanguage (Lang_java) || isLanguage (Lang_csharp) || isLanguage (Lang_vala))) | |
{ | |
reinitStatement (st, FALSE); | |
st->scope = SCOPE_STATIC; | |
@@ -1927,6 +2175,21 @@ | |
if (isident1 (c)) | |
{ | |
readIdentifier (token, c); | |
+ if (isLanguage(Lang_d)) | |
+ { | |
+ switch (token->keyword) | |
+ { | |
+ /* template constraint */ | |
+ case KEYWORD_IF: | |
+ /* contracts */ | |
+ case KEYWORD_IN: | |
+ case KEYWORD_OUT: | |
+ case KEYWORD_BODY: | |
+ token->keyword = KEYWORD_CONST; | |
+ default: | |
+ break; | |
+ } | |
+ } | |
switch (token->keyword) | |
{ | |
case KEYWORD_ATTRIBUTE: skipParens (); break; | |
@@ -2029,6 +2292,39 @@ | |
setToken (st, TOKEN_NONE); | |
} | |
+static void skipValaPostParens (statementInfo *const st) | |
+{ | |
+ tokenInfo *const token = activeToken (st); | |
+ int c = skipToNonWhite (); | |
+ | |
+ while (isident1 (c)) | |
+ { | |
+ readIdentifier (token, c); | |
+ if (token->keyword == KEYWORD_ATTRIBUTE) | |
+ { | |
+ /* parse contracts */ | |
+ skipParens (); | |
+ c = skipToNonWhite (); | |
+ } | |
+ else if (token->keyword == KEYWORD_THROWS) | |
+ { | |
+ do | |
+ { | |
+ c = skipToNonWhite (); | |
+ if (isident1 (c)) | |
+ { | |
+ readIdentifier (token, c); | |
+ c = skipToNonWhite (); | |
+ } | |
+ } while (c == '.' || c == ','); | |
+ } | |
+ else | |
+ break; | |
+ } | |
+ cppUngetc (c); | |
+ setToken (st, TOKEN_NONE); | |
+} | |
+ | |
static void analyzePostParens (statementInfo *const st, parenInfo *const info) | |
{ | |
const unsigned long inputLineNumber = getInputLineNumber (); | |
@@ -2039,6 +2335,8 @@ | |
; | |
else if (isLanguage (Lang_java)) | |
skipJavaThrows (st); | |
+ else if (isLanguage (Lang_vala)) | |
+ skipValaPostParens(st); | |
else | |
{ | |
if (! skipPostArgumentStuff (st, info)) | |
@@ -2087,7 +2385,7 @@ | |
* But watch out for "@interface"! | |
*/ | |
tokenInfo *const token = activeToken (st); | |
- | |
+ | |
int c = skipToNonWhite (); | |
readIdentifier (token, c); | |
if (token->keyword == KEYWORD_INTERFACE) | |
@@ -2320,6 +2618,11 @@ | |
st->gotParenName = TRUE; | |
if (! (c == '(' && info.nestedArgs)) | |
st->isPointer = info.isPointer; | |
+ if (isLanguage(Lang_d) && c == '(' && isType (prev, TOKEN_NAME)) | |
+ { | |
+ st->declaration = DECL_FUNCTION_TEMPLATE; | |
+ copyToken (st->blockName, prev); | |
+ } | |
} | |
else if (! st->gotArgs && info.isParamList) | |
{ | |
@@ -2346,7 +2649,9 @@ | |
{ | |
if (isLanguage (Lang_c) || isLanguage (Lang_cpp)) | |
vStringCatS (st->context->name, "::"); | |
- else if (isLanguage (Lang_java) || isLanguage (Lang_csharp)) | |
+ else if (isLanguage (Lang_java) || | |
+ isLanguage (Lang_d) || isLanguage (Lang_ferite) || | |
+ isLanguage (Lang_csharp) || isLanguage (Lang_vala)) | |
vStringCatS (st->context->name, "."); | |
} | |
vStringCat (st->context->name, token->name); | |
@@ -2380,8 +2685,8 @@ | |
else | |
{ | |
cppUngetc (c); | |
- if ((isLanguage (Lang_cpp) || isLanguage (Lang_csharp)) && | |
- inheritingDeclaration (st->declaration)) | |
+ if (((isLanguage (Lang_cpp) || isLanguage (Lang_csharp) || isLanguage (Lang_vala)) && | |
+ inheritingDeclaration (st->declaration)) || isLanguage (Lang_d)) | |
{ | |
readParents (st, ':'); | |
} | |
@@ -2489,7 +2794,7 @@ | |
static void parseGeneralToken (statementInfo *const st, const int c) | |
{ | |
const tokenInfo *const prev = prevToken (st, 1); | |
- | |
+ | |
if (isident1 (c) || (isLanguage (Lang_java) && isHighChar (c))) | |
{ | |
parseIdentifier (st, c); | |
@@ -2553,12 +2858,19 @@ | |
} | |
token = activeToken (st); | |
} while (isType (token, TOKEN_NONE)); | |
+ | |
+ /* We want to know about non-keyword variable types */ | |
+ if (TOKEN_NONE == st->firstToken->type) | |
+ { | |
+ if ((TOKEN_NAME == token->type) || isDataTypeKeyword(token)) | |
+ copyToken(st->firstToken, token); | |
+ } | |
} | |
/* | |
* Scanning support functions | |
*/ | |
- | |
+static unsigned int contextual_fake_count = 0; | |
static statementInfo *CurrentStatement = NULL; | |
static statementInfo *newStatement (statementInfo *const parent) | |
@@ -2569,9 +2881,9 @@ | |
for (i = 0 ; i < (unsigned int) NumTokens ; ++i) | |
st->token [i] = newToken (); | |
- st->context = newToken (); | |
- st->blockName = newToken (); | |
- st->parentClasses = vStringNew (); | |
+ st->context = newToken (); | |
+ st->blockName = newToken (); | |
+ st->parentClasses = vStringNew (); | |
initStatement (st, parent); | |
CurrentStatement = st; | |
@@ -2610,11 +2922,12 @@ | |
if (isType (token, TOKEN_SEMICOLON)) | |
isEnd = TRUE; | |
else if (isType (token, TOKEN_BRACE_CLOSE)) | |
- /* Java and C# do not require semicolons to end a block. Neither do C++ | |
- * namespaces. All other blocks require a semicolon to terminate them. | |
+ /* Java, D, C#, Vala do not require semicolons to end a block. Neither do | |
+ * C++ namespaces. All other blocks require a semicolon to terminate them. | |
*/ | |
- isEnd = (boolean) (isLanguage (Lang_java) || isLanguage (Lang_csharp) || | |
- ! isContextualStatement (st)); | |
+ isEnd = (boolean) (isLanguage (Lang_java) || isLanguage (Lang_d) || | |
+ isLanguage (Lang_csharp) || isLanguage (Lang_vala) || | |
+ ! isContextualStatement (st)); | |
else | |
isEnd = FALSE; | |
@@ -2690,38 +3003,95 @@ | |
case TOKEN_BRACE_OPEN: | |
if (isType (prev, TOKEN_ARGS)) | |
{ | |
- if (st->haveQualifyingName) | |
+ if (st->declaration == DECL_FUNCTION_TEMPLATE) | |
+ qualifyFunctionTag (st, st->blockName); | |
+ else if (st->haveQualifyingName) | |
{ | |
if (! isLanguage (Lang_vera)) | |
st->declaration = DECL_FUNCTION; | |
if (isType (prev2, TOKEN_NAME)) | |
copyToken (st->blockName, prev2); | |
- qualifyFunctionTag (st, prev2); | |
+ /* D structure templates */ | |
+ if (isLanguage (Lang_d) && | |
+ (st->declaration == DECL_CLASS || st->declaration == DECL_STRUCT || | |
+ st->declaration == DECL_INTERFACE || st->declaration == DECL_NAMESPACE)) | |
+ qualifyBlockTag (st, prev2); | |
+ else | |
+ { | |
+ st->declaration = DECL_FUNCTION; | |
+ qualifyFunctionTag (st, prev2); | |
+ } | |
} | |
} | |
else if (isContextualStatement (st) || | |
st->declaration == DECL_NAMESPACE || | |
st->declaration == DECL_PROGRAM) | |
{ | |
+ tokenInfo *name_token = (tokenInfo *)prev; | |
+ boolean free_name_token = FALSE; | |
+ | |
if (isType (prev, TOKEN_NAME)) | |
copyToken (st->blockName, prev); | |
+ | |
+ if (isType (name_token, TOKEN_NAME)) | |
+ { | |
+ if (!isLanguage (Lang_vala)) | |
+ copyToken (st->blockName, name_token); | |
+ else | |
+ { | |
+ switch (st->declaration) | |
+ { | |
+ case DECL_CLASS: | |
+ case DECL_ENUM: | |
+ case DECL_INTERFACE: | |
+ case DECL_NAMESPACE: | |
+ case DECL_STRUCT: | |
+ copyToken (st->blockName, name_token); | |
+ break; | |
+ | |
+ /* anything else can be a property */ | |
+ default: | |
+ /* makeTag (prev, st, FALSE, TAG_PROPERTY); */ | |
+ /* FIXME: temporary hack to get properties shown */ | |
+ makeTag (prev, st, FALSE, TAG_FIELD); | |
+ break; | |
+ } | |
+ } | |
+ } | |
else | |
{ | |
- /* For an anonymous struct or union we use a unique ID | |
- * a number, so that the members can be found. | |
- */ | |
- char buf [20]; /* length of "_anon" + digits + null */ | |
- sprintf (buf, "__anon%d", ++AnonymousID); | |
- vStringCopyS (st->blockName->name, buf); | |
- st->blockName->type = TOKEN_NAME; | |
- st->blockName->keyword = KEYWORD_NONE; | |
+ tokenInfo *contextual_token = (tokenInfo *)prev; | |
+ if(isContextualKeyword (contextual_token)) | |
+ { | |
+ char buffer[64]; | |
+ | |
+ name_token = newToken (); | |
+ free_name_token = TRUE; | |
+ copyToken (name_token, contextual_token); | |
+ | |
+ sprintf(buffer, "anon_%s_%d", name_token->name->buffer, contextual_fake_count++); | |
+ vStringClear(name_token->name); | |
+ vStringCatS(name_token->name, buffer); | |
+ | |
+ name_token->type = TOKEN_NAME; | |
+ name_token->keyword = KEYWORD_NONE; | |
+ | |
+ advanceToken (st); | |
+ contextual_token = activeToken (st); | |
+ copyToken (contextual_token, token); | |
+ copyToken ((tokenInfo *const)token, name_token); | |
+ copyToken (st->blockName, name_token); | |
+ copyToken (st->firstToken, name_token); | |
+ } | |
} | |
- qualifyBlockTag (st, prev); | |
+ qualifyBlockTag (st, name_token); | |
+ if (free_name_token) | |
+ deleteToken (name_token); | |
} | |
else if (isLanguage (Lang_csharp)) | |
makeTag (prev, st, FALSE, TAG_PROPERTY); | |
break; | |
- | |
+ case TOKEN_ARRAY: | |
case TOKEN_SEMICOLON: | |
case TOKEN_COMMA: | |
if (insideEnumBody (st)) | |
@@ -2801,6 +3171,8 @@ | |
exception_t exception; | |
boolean retry; | |
+ contextual_fake_count = 0; | |
+ | |
Assert (passCount < 3); | |
cppInit ((boolean) (passCount > 1), isLanguage (Lang_csharp)); | |
Signature = vStringNew (); | |
@@ -2854,12 +3226,36 @@ | |
buildKeywordHash (language, 2); | |
} | |
+static void initializeDParser (const langType language) | |
+{ | |
+ Lang_d = language; | |
+ buildKeywordHash (language, 6); | |
+} | |
+ | |
+static void initializeGLSLParser (const langType language) | |
+{ | |
+ Lang_glsl = language; | |
+ buildKeywordHash (language, 0); /* C keywords */ | |
+} | |
+ | |
+static void initializeFeriteParser (const langType language) | |
+{ | |
+ Lang_ferite = language; | |
+ buildKeywordHash (language, 1); /* C++ keywords */ | |
+} | |
+ | |
static void initializeJavaParser (const langType language) | |
{ | |
Lang_java = language; | |
buildKeywordHash (language, 3); | |
} | |
+static void initializeValaParser (const langType language) | |
+{ | |
+ Lang_vala = language; | |
+ buildKeywordHash (language, 5); | |
+} | |
+ | |
static void initializeVeraParser (const langType language) | |
{ | |
Lang_vera = language; | |
@@ -2882,6 +3278,7 @@ | |
{ | |
static const char *const extensions [] = { | |
"c++", "cc", "cp", "cpp", "cxx", "h", "h++", "hh", "hp", "hpp", "hxx", | |
+ "i", | |
#ifndef CASE_INSENSITIVE_FILENAMES | |
"C", "H", | |
#endif | |
@@ -2920,6 +3317,54 @@ | |
return def; | |
} | |
+extern parserDefinition* DParser (void) | |
+{ | |
+ static const char *const extensions [] = { "d", "di", NULL }; | |
+ parserDefinition* def = parserNew ("D"); | |
+ def->kinds = DKinds; | |
+ def->kindCount = KIND_COUNT (DKinds); | |
+ def->extensions = extensions; | |
+ def->parser2 = findCTags; | |
+ def->initialize = initializeDParser; | |
+ return def; | |
+} | |
+ | |
+extern parserDefinition* GLSLParser (void) | |
+{ | |
+ static const char *const extensions [] = { "glsl", "frag", "vert", NULL }; | |
+ parserDefinition* def = parserNew ("GLSL"); | |
+ def->kinds = CKinds; | |
+ def->kindCount = KIND_COUNT (CKinds); | |
+ def->extensions = extensions; | |
+ def->parser2 = findCTags; | |
+ def->initialize = initializeGLSLParser; | |
+ return def; | |
+} | |
+ | |
+extern parserDefinition* FeriteParser (void) | |
+{ | |
+ static const char *const extensions [] = { "fe", NULL }; | |
+ parserDefinition* def = parserNew ("Ferite"); | |
+ def->kinds = CKinds; | |
+ def->kindCount = KIND_COUNT (CKinds); | |
+ def->extensions = extensions; | |
+ def->parser2 = findCTags; | |
+ def->initialize = initializeFeriteParser; | |
+ return def; | |
+} | |
+ | |
+extern parserDefinition* ValaParser (void) | |
+{ | |
+ static const char *const extensions [] = { "vala", NULL }; | |
+ parserDefinition* def = parserNew ("Vala"); | |
+ def->kinds = ValaKinds; | |
+ def->kindCount = KIND_COUNT (ValaKinds); | |
+ def->extensions = extensions; | |
+ def->parser2 = findCTags; | |
+ def->initialize = initializeValaParser; | |
+ return def; | |
+} | |
+ | |
extern parserDefinition* VeraParser (void) | |
{ | |
static const char *const extensions [] = { "vr", "vri", "vrh", NULL }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment