Update Russian translation (#3918)
[geany-mirror.git] / ctags / parsers / tcloo.c
blobae3338b8375d116934e1c66fde3294d2b3e825d1
1 /*
2 * Copyright (c) 2017, Masatake YAMATO
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
7 */
9 #include "general.h" /* must always come first */
10 #include "tcl.h"
11 #include "param.h"
12 #include "parse.h"
13 #include "entry.h"
14 #include "tokeninfo.h"
16 #include <string.h>
19 struct tclooSubparser {
20 tclSubparser tcl;
21 bool foundTclOONamespaceImported;
24 static scopeSeparator TclOOGenericSeparators [] = {
25 { KIND_WILDCARD_INDEX, "::" },
28 enum TclOOKind {
29 K_CLASS,
30 K_METHOD,
33 static kindDefinition TclOOKinds[] = {
34 { true, 'c', "class", "classes" },
35 { true, 'm', "method", "methods",
36 ATTACH_SEPARATORS(TclOOGenericSeparators) },
39 static bool tclooForceUse;
41 static void parseMethod (tokenInfo *token, int owner)
43 tokenRead (token);
44 if (tokenIsType (token, TCL_IDENTIFIER))
46 tagEntryInfo e;
48 initTagEntry(&e, tokenString (token), K_METHOD);
49 e.extensionFields.scopeIndex = owner;
50 makeTagEntry (&e);
52 skipToEndOfTclCmdline (token);
55 static void parseSuperclass (tokenInfo *token, int this_class)
57 tokenRead (token);
58 if (tokenIsType (token, TCL_IDENTIFIER))
60 tagEntryInfo *e = getEntryInCorkQueue(this_class);
62 if (e)
64 if (e->extensionFields.inheritance)
65 { /* superclass is used twice in a class. */
66 eFree ((void *)e->extensionFields.inheritance);
68 e->extensionFields.inheritance = eStrdup(tokenString(token));
71 skipToEndOfTclCmdline (token);
74 static int parseClass (tclSubparser *s CTAGS_ATTR_UNUSED, int parentIndex,
75 void *pstate)
77 tokenInfo *token = newTclToken (pstate);
78 int r = CORK_NIL;
80 tokenRead (token);
81 if (tokenIsType (token, TCL_IDENTIFIER)
82 && (strcmp(tokenString(token), "create") == 0))
84 tokenRead (token);
85 if (tokenIsType (token, TCL_IDENTIFIER))
87 tagEntryInfo e;
89 initTagEntry(&e, tokenString (token), K_CLASS);
90 e.extensionFields.scopeIndex = parentIndex;
91 r = makeTagEntry (&e);
94 if (tokenSkipToType (token, '{'))
96 do {
97 tokenRead (token);
98 if (tokenIsType (token, TCL_IDENTIFIER)
99 || tokenIsType (token, TCL_KEYWORD))
101 if (strcmp(tokenString(token), "method") == 0)
102 parseMethod(token, r);
103 else if (strcmp(tokenString(token), "superclass") == 0)
104 parseSuperclass(token, r);
105 else
106 skipToEndOfTclCmdline (token);
108 else if (token->type == '}')
109 break;
110 } while (!tokenIsEOF(token));
114 skipToEndOfTclCmdline (token);
115 tokenDelete(token);
116 return r;
119 static int commandNotify (tclSubparser *s, char *command,
120 int parentIndex, void *pstate)
122 struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
123 int r = CORK_NIL;
125 if ((tcloo->foundTclOONamespaceImported
126 && (strcmp (command, "class") == 0))
127 || (strcmp (command, "oo::class") == 0))
128 r = parseClass (s, parentIndex, pstate);
130 return r;
133 static void namespaceImportNotify (tclSubparser *s, char *namespace,
134 void *pstate CTAGS_ATTR_UNUSED)
136 struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
138 if (strcmp(namespace, "oo::*") == 0
139 || strcmp(namespace, "oo::class") == 0)
140 tcloo->foundTclOONamespaceImported = true;
143 static void inputStart (subparser *s)
145 struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
147 tcloo->foundTclOONamespaceImported = tclooForceUse;
150 static struct tclooSubparser tclooSubparser = {
151 .tcl = {
152 .subparser = {
153 .direction = SUBPARSER_BI_DIRECTION,
154 .inputStart = inputStart,
156 .commandNotify = commandNotify,
157 .namespaceImportNotify = namespaceImportNotify,
161 static void findTclOOTags(void)
163 scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
166 static bool tclooForceUseParamHandler (const langType language CTAGS_ATTR_UNUSED,
167 const char *name, const char *arg)
169 tclooForceUse = paramParserBool (arg, tclooForceUse, name, "parameter");
170 return true;
173 static paramDefinition TclOOParams [] = {
174 { .name = "forceUse",
175 .desc = "enable the parser even when `oo' namespace is not specified in the input (true or [false])" ,
176 .handleParam = tclooForceUseParamHandler,
180 extern parserDefinition* TclOOParser (void)
182 parserDefinition* const def = parserNew("TclOO");
184 static parserDependency dependencies [] = {
185 [0] = { DEPTYPE_SUBPARSER, "Tcl", &tclooSubparser },
188 def->dependencies = dependencies;
189 def->dependencyCount = ARRAY_SIZE (dependencies);
191 def->kindTable = TclOOKinds;
192 def->kindCount = ARRAY_SIZE(TclOOKinds);
194 def->parser = findTclOOTags;
195 def->useCork = CORK_QUEUE;
196 def->requestAutomaticFQTag = true;
198 def->paramTable = TclOOParams;
199 def->paramCount = ARRAY_SIZE(TclOOParams);
201 return def;