xref: /Universal-ctags/parsers/tcloo.c (revision 0d95841219d1bdd1e1dfef5488de2ca8c080f09e)
13bae5023SMasatake YAMATO /*
23bae5023SMasatake YAMATO *   Copyright (c) 2017, Masatake YAMATO
33bae5023SMasatake YAMATO *
43bae5023SMasatake YAMATO *   This source code is released for free distribution under the terms of the
53bae5023SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
63bae5023SMasatake YAMATO *
73bae5023SMasatake YAMATO */
83bae5023SMasatake YAMATO 
93bae5023SMasatake YAMATO #include "general.h"  /* must always come first */
103bae5023SMasatake YAMATO #include "tcl.h"
11*0d958412SMasatake YAMATO #include "param.h"
123bae5023SMasatake YAMATO #include "parse.h"
133bae5023SMasatake YAMATO #include "entry.h"
143bae5023SMasatake YAMATO #include "tokeninfo.h"
153bae5023SMasatake YAMATO 
163bae5023SMasatake YAMATO #include <string.h>
173bae5023SMasatake YAMATO 
183bae5023SMasatake YAMATO 
193bae5023SMasatake YAMATO struct tclooSubparser {
203bae5023SMasatake YAMATO 	tclSubparser tcl;
213bae5023SMasatake YAMATO 	bool foundTclOONamespaceImported;
223bae5023SMasatake YAMATO };
233bae5023SMasatake YAMATO 
243bae5023SMasatake YAMATO static scopeSeparator TclOOGenericSeparators [] = {
25f92e6bf2SMasatake YAMATO 	{ KIND_WILDCARD_INDEX, "::" },
263bae5023SMasatake YAMATO };
273bae5023SMasatake YAMATO 
283bae5023SMasatake YAMATO enum TclOOKind {
293bae5023SMasatake YAMATO 	K_CLASS,
303bae5023SMasatake YAMATO 	K_METHOD,
313bae5023SMasatake YAMATO };
323bae5023SMasatake YAMATO 
333bae5023SMasatake YAMATO static kindDefinition TclOOKinds[] = {
343bae5023SMasatake YAMATO 	{ true, 'c', "class", "classes" },
353bae5023SMasatake YAMATO 	{ true, 'm', "method", "methods",
363bae5023SMasatake YAMATO 	  ATTACH_SEPARATORS(TclOOGenericSeparators) },
373bae5023SMasatake YAMATO };
383bae5023SMasatake YAMATO 
39*0d958412SMasatake YAMATO static bool tclooForceUse;
40*0d958412SMasatake YAMATO 
parseMethod(tokenInfo * token,int owner)41ac2f8a0bSMasatake YAMATO static void parseMethod (tokenInfo *token, int owner)
423bae5023SMasatake YAMATO {
433bae5023SMasatake YAMATO 	tokenRead (token);
443bae5023SMasatake YAMATO 	if (tokenIsType (token, TCL_IDENTIFIER))
453bae5023SMasatake YAMATO 	{
463bae5023SMasatake YAMATO 		tagEntryInfo e;
473bae5023SMasatake YAMATO 
485c2563d5SMasatake YAMATO 		initTagEntry(&e, tokenString (token), K_METHOD);
49ac2f8a0bSMasatake YAMATO 		e.extensionFields.scopeIndex = owner;
503bae5023SMasatake YAMATO 		makeTagEntry (&e);
513bae5023SMasatake YAMATO 	}
523bae5023SMasatake YAMATO 	skipToEndOfTclCmdline (token);
533bae5023SMasatake YAMATO }
543bae5023SMasatake YAMATO 
parseSuperclass(tokenInfo * token,int this_class)55ac2f8a0bSMasatake YAMATO static void parseSuperclass (tokenInfo *token, int this_class)
563bae5023SMasatake YAMATO {
573bae5023SMasatake YAMATO 	tokenRead (token);
583bae5023SMasatake YAMATO 	if (tokenIsType (token, TCL_IDENTIFIER))
593bae5023SMasatake YAMATO 	{
60ac2f8a0bSMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue(this_class);
613bae5023SMasatake YAMATO 
620a8850f8SMasatake YAMATO 		if (e)
630a8850f8SMasatake YAMATO 		{
643bae5023SMasatake YAMATO 			if (e->extensionFields.inheritance)
653bae5023SMasatake YAMATO 			{   /* superclass is used twice in a class. */
663bae5023SMasatake YAMATO 				eFree ((void *)e->extensionFields.inheritance);
673bae5023SMasatake YAMATO 			}
683bae5023SMasatake YAMATO 			e->extensionFields.inheritance = eStrdup(tokenString(token));
693bae5023SMasatake YAMATO 		}
700a8850f8SMasatake YAMATO 	}
713bae5023SMasatake YAMATO 	skipToEndOfTclCmdline (token);
723bae5023SMasatake YAMATO }
733bae5023SMasatake YAMATO 
parseClass(tclSubparser * s CTAGS_ATTR_UNUSED,int parentIndex,void * pstate)745d9d66cfSMasatake YAMATO static int parseClass (tclSubparser *s CTAGS_ATTR_UNUSED, int parentIndex,
755d9d66cfSMasatake YAMATO 					   void *pstate)
763bae5023SMasatake YAMATO {
775d9d66cfSMasatake YAMATO 	tokenInfo *token = newTclToken (pstate);
783bae5023SMasatake YAMATO 	int r = CORK_NIL;
793bae5023SMasatake YAMATO 
803bae5023SMasatake YAMATO 	tokenRead (token);
813bae5023SMasatake YAMATO 	if (tokenIsType (token, TCL_IDENTIFIER)
823bae5023SMasatake YAMATO 		&& (strcmp(tokenString(token), "create") == 0))
833bae5023SMasatake YAMATO 	{
843bae5023SMasatake YAMATO 		tokenRead (token);
853bae5023SMasatake YAMATO 		if (tokenIsType (token, TCL_IDENTIFIER))
863bae5023SMasatake YAMATO 		{
873bae5023SMasatake YAMATO 			tagEntryInfo e;
883bae5023SMasatake YAMATO 
895c2563d5SMasatake YAMATO 			initTagEntry(&e, tokenString (token), K_CLASS);
903bae5023SMasatake YAMATO 			e.extensionFields.scopeIndex = parentIndex;
913bae5023SMasatake YAMATO 			r = makeTagEntry (&e);
923bae5023SMasatake YAMATO 		}
933bae5023SMasatake YAMATO 
943bae5023SMasatake YAMATO 		if (tokenSkipToType (token, '{'))
953bae5023SMasatake YAMATO 		{
963bae5023SMasatake YAMATO 			do {
973bae5023SMasatake YAMATO 				tokenRead (token);
983bae5023SMasatake YAMATO 				if (tokenIsType (token, TCL_IDENTIFIER)
993bae5023SMasatake YAMATO 					|| tokenIsType (token, TCL_KEYWORD))
1003bae5023SMasatake YAMATO 				{
1013bae5023SMasatake YAMATO 					if (strcmp(tokenString(token), "method") == 0)
1023bae5023SMasatake YAMATO 						parseMethod(token, r);
1033bae5023SMasatake YAMATO 					else if (strcmp(tokenString(token), "superclass") == 0)
1043bae5023SMasatake YAMATO 						parseSuperclass(token, r);
1053bae5023SMasatake YAMATO 					else
1063bae5023SMasatake YAMATO 						skipToEndOfTclCmdline (token);
1073bae5023SMasatake YAMATO 				}
1083bae5023SMasatake YAMATO 				else if (token->type == '}')
1093bae5023SMasatake YAMATO 					break;
1103bae5023SMasatake YAMATO 			} while (!tokenIsEOF(token));
1113bae5023SMasatake YAMATO 		}
1123bae5023SMasatake YAMATO 	}
1133bae5023SMasatake YAMATO 
1143bae5023SMasatake YAMATO 	skipToEndOfTclCmdline (token);
115a203ce0eSMasatake YAMATO 	tokenDelete(token);
1163bae5023SMasatake YAMATO 	return r;
1173bae5023SMasatake YAMATO }
1183bae5023SMasatake YAMATO 
commandNotify(tclSubparser * s,char * command,int parentIndex,void * pstate)1193bae5023SMasatake YAMATO static int commandNotify (tclSubparser *s, char *command,
1205d9d66cfSMasatake YAMATO 						  int parentIndex, void *pstate)
1213bae5023SMasatake YAMATO {
1223bae5023SMasatake YAMATO 	struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
1233bae5023SMasatake YAMATO 	int r = CORK_NIL;
1243bae5023SMasatake YAMATO 
1253bae5023SMasatake YAMATO 	if ((tcloo->foundTclOONamespaceImported
1263bae5023SMasatake YAMATO 		 && (strcmp (command, "class") == 0))
1273bae5023SMasatake YAMATO 		|| (strcmp (command, "oo::class") == 0))
1285d9d66cfSMasatake YAMATO 		r = parseClass (s, parentIndex, pstate);
1293bae5023SMasatake YAMATO 
1303bae5023SMasatake YAMATO 	return r;
1313bae5023SMasatake YAMATO }
1323bae5023SMasatake YAMATO 
namespaceImportNotify(tclSubparser * s,char * namespace,void * pstate CTAGS_ATTR_UNUSED)1335d9d66cfSMasatake YAMATO static void namespaceImportNotify (tclSubparser *s, char *namespace,
1345d9d66cfSMasatake YAMATO 								   void *pstate CTAGS_ATTR_UNUSED)
1353bae5023SMasatake YAMATO {
1363bae5023SMasatake YAMATO 	struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
1373bae5023SMasatake YAMATO 
1383bae5023SMasatake YAMATO 	if (strcmp(namespace, "oo::*") == 0
1393bae5023SMasatake YAMATO 		|| strcmp(namespace, "oo::class") == 0)
1403bae5023SMasatake YAMATO 		tcloo->foundTclOONamespaceImported = true;
1413bae5023SMasatake YAMATO }
1423bae5023SMasatake YAMATO 
inputStart(subparser * s)1433bae5023SMasatake YAMATO static void inputStart (subparser *s)
1443bae5023SMasatake YAMATO {
1453bae5023SMasatake YAMATO 	struct tclooSubparser *tcloo = (struct tclooSubparser *)s;
1463bae5023SMasatake YAMATO 
147*0d958412SMasatake YAMATO 	tcloo->foundTclOONamespaceImported = tclooForceUse;
1483bae5023SMasatake YAMATO }
1493bae5023SMasatake YAMATO 
150e3ee5398SMasatake YAMATO static struct tclooSubparser tclooSubparser = {
1513bae5023SMasatake YAMATO 	.tcl = {
1523bae5023SMasatake YAMATO 		.subparser = {
1533bae5023SMasatake YAMATO 			.direction = SUBPARSER_BI_DIRECTION,
1543bae5023SMasatake YAMATO 			.inputStart = inputStart,
1553bae5023SMasatake YAMATO 		},
1563bae5023SMasatake YAMATO 		.commandNotify = commandNotify,
1573bae5023SMasatake YAMATO 		.namespaceImportNotify = namespaceImportNotify,
1583bae5023SMasatake YAMATO 	},
1593bae5023SMasatake YAMATO };
1603bae5023SMasatake YAMATO 
findTclOOTags(void)1613bae5023SMasatake YAMATO static void findTclOOTags(void)
1623bae5023SMasatake YAMATO {
1633bae5023SMasatake YAMATO 	scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
1643bae5023SMasatake YAMATO }
1653bae5023SMasatake YAMATO 
tclooForceUseParamHandler(const langType language CTAGS_ATTR_UNUSED,const char * name,const char * arg)166*0d958412SMasatake YAMATO static void tclooForceUseParamHandler (const langType language CTAGS_ATTR_UNUSED,
167*0d958412SMasatake YAMATO 									  const char *name, const char *arg)
168*0d958412SMasatake YAMATO {
169*0d958412SMasatake YAMATO 	tclooForceUse = paramParserBool (arg, tclooForceUse, name, "parameter");
170*0d958412SMasatake YAMATO }
171*0d958412SMasatake YAMATO 
172*0d958412SMasatake YAMATO static parameterHandlerTable TclOOParameterHandlerTable [] = {
173*0d958412SMasatake YAMATO 	{ .name = "forceUse",
174*0d958412SMasatake YAMATO 	  .desc = "enable the parser even when `oo' namespace is not specified in the input (true or [false])" ,
175*0d958412SMasatake YAMATO 	  .handleParameter = tclooForceUseParamHandler,
176*0d958412SMasatake YAMATO 	},
177*0d958412SMasatake YAMATO };
178*0d958412SMasatake YAMATO 
TclOOParser(void)1793bae5023SMasatake YAMATO extern parserDefinition* TclOOParser (void)
1803bae5023SMasatake YAMATO {
1813bae5023SMasatake YAMATO 	parserDefinition* const def = parserNew("TclOO");
1823bae5023SMasatake YAMATO 
1833bae5023SMasatake YAMATO 	static parserDependency dependencies [] = {
1843bae5023SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "Tcl", &tclooSubparser },
1853bae5023SMasatake YAMATO 	};
1863bae5023SMasatake YAMATO 
1873bae5023SMasatake YAMATO 	def->dependencies = dependencies;
1883bae5023SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
1893bae5023SMasatake YAMATO 
1903bae5023SMasatake YAMATO 	def->kindTable = TclOOKinds;
1913bae5023SMasatake YAMATO 	def->kindCount = ARRAY_SIZE(TclOOKinds);
1923bae5023SMasatake YAMATO 
1933bae5023SMasatake YAMATO 	def->parser = findTclOOTags;
1946b1a862eSMasatake YAMATO 	def->useCork = CORK_QUEUE;
1953bae5023SMasatake YAMATO 	def->requestAutomaticFQTag = true;
1963bae5023SMasatake YAMATO 
197*0d958412SMasatake YAMATO 	def->parameterHandlerTable = TclOOParameterHandlerTable;
198*0d958412SMasatake YAMATO 	def->parameterHandlerCount = ARRAY_SIZE(TclOOParameterHandlerTable);
199*0d958412SMasatake YAMATO 
2003bae5023SMasatake YAMATO 	return def;
2013bae5023SMasatake YAMATO }
202