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.
9 #include "general.h" /* must always come first */
14 #include "tokeninfo.h"
19 struct tclooSubparser
{
21 bool foundTclOONamespaceImported
;
24 static scopeSeparator TclOOGenericSeparators
[] = {
25 { KIND_WILDCARD_INDEX
, "::" },
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
)
44 if (tokenIsType (token
, TCL_IDENTIFIER
))
48 initTagEntry(&e
, tokenString (token
), K_METHOD
);
49 e
.extensionFields
.scopeIndex
= owner
;
52 skipToEndOfTclCmdline (token
);
55 static void parseSuperclass (tokenInfo
*token
, int this_class
)
58 if (tokenIsType (token
, TCL_IDENTIFIER
))
60 tagEntryInfo
*e
= getEntryInCorkQueue(this_class
);
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
,
77 tokenInfo
*token
= newTclToken (pstate
);
81 if (tokenIsType (token
, TCL_IDENTIFIER
)
82 && (strcmp(tokenString(token
), "create") == 0))
85 if (tokenIsType (token
, TCL_IDENTIFIER
))
89 initTagEntry(&e
, tokenString (token
), K_CLASS
);
90 e
.extensionFields
.scopeIndex
= parentIndex
;
91 r
= makeTagEntry (&e
);
94 if (tokenSkipToType (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
);
106 skipToEndOfTclCmdline (token
);
108 else if (token
->type
== '}')
110 } while (!tokenIsEOF(token
));
114 skipToEndOfTclCmdline (token
);
119 static int commandNotify (tclSubparser
*s
, char *command
,
120 int parentIndex
, void *pstate
)
122 struct tclooSubparser
*tcloo
= (struct tclooSubparser
*)s
;
125 if ((tcloo
->foundTclOONamespaceImported
126 && (strcmp (command
, "class") == 0))
127 || (strcmp (command
, "oo::class") == 0))
128 r
= parseClass (s
, parentIndex
, pstate
);
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
= {
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");
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
);