xref: /Universal-ctags/parsers/r-r6class.c (revision 2b0000354518fbf34f719f1b6af5f8d0d0bec916)
130fa30b1SMasatake YAMATO /*
230fa30b1SMasatake YAMATO *   Copyright (c) 2020, Masatake YAMATO
330fa30b1SMasatake YAMATO *   Copyright (c) 2020, Red Hat, Inc.
430fa30b1SMasatake YAMATO *
530fa30b1SMasatake YAMATO *   This source code is released for free distribution under the terms of the
630fa30b1SMasatake YAMATO *   GNU General Public License version 2 or (at your option) any later version.
730fa30b1SMasatake YAMATO *
830fa30b1SMasatake YAMATO *   This module contains functions for generating tags for R6Class.
930fa30b1SMasatake YAMATO *   https://www.rdocumentation.org/packages/R6/versions/2.4.1/topics/R6Class
1030fa30b1SMasatake YAMATO */
1130fa30b1SMasatake YAMATO 
1230fa30b1SMasatake YAMATO 
1330fa30b1SMasatake YAMATO /*
1430fa30b1SMasatake YAMATO *   INCLUDE FILES
1530fa30b1SMasatake YAMATO */
1630fa30b1SMasatake YAMATO #include "general.h"	/* must always come first */
1730fa30b1SMasatake YAMATO 
1830fa30b1SMasatake YAMATO #include "r.h"
1930fa30b1SMasatake YAMATO #include "kind.h"
2030fa30b1SMasatake YAMATO #include "parse.h"
2130fa30b1SMasatake YAMATO #include "entry.h"
2230fa30b1SMasatake YAMATO #include "tokeninfo.h"
2330fa30b1SMasatake YAMATO #include "read.h"
2430fa30b1SMasatake YAMATO 
2530fa30b1SMasatake YAMATO #include <string.h>
2630fa30b1SMasatake YAMATO 
2730fa30b1SMasatake YAMATO 
2830fa30b1SMasatake YAMATO /*
2930fa30b1SMasatake YAMATO *   DATA DECLARATIONS
3030fa30b1SMasatake YAMATO */
3130fa30b1SMasatake YAMATO 
3230fa30b1SMasatake YAMATO struct r6Subparser {
3330fa30b1SMasatake YAMATO 	rSubparser r;
3430fa30b1SMasatake YAMATO 	const char * access;
3530fa30b1SMasatake YAMATO 	bool activeBinding;
3630fa30b1SMasatake YAMATO };
3730fa30b1SMasatake YAMATO 
3830fa30b1SMasatake YAMATO /*
3930fa30b1SMasatake YAMATO * FUNCTION PROTOTYPES
4030fa30b1SMasatake YAMATO */
4130fa30b1SMasatake YAMATO 
4230fa30b1SMasatake YAMATO static int r6ReadRightSideSymbol (rSubparser *s,
4330fa30b1SMasatake YAMATO 								  tokenInfo *const symbol,
4430fa30b1SMasatake YAMATO 								  const char *const assignmentOperator,
4530fa30b1SMasatake YAMATO 								  int parent,
4630fa30b1SMasatake YAMATO 								  tokenInfo *const token);
4730fa30b1SMasatake YAMATO static int r6MakeTagWithTranslation (rSubparser *s,
4830fa30b1SMasatake YAMATO 									 tokenInfo *const token,
4930fa30b1SMasatake YAMATO 									 int parent,
5030fa30b1SMasatake YAMATO 									 bool in_func,
5130fa30b1SMasatake YAMATO 									 int kindInR,
5230fa30b1SMasatake YAMATO 									 const char *const assignmentOperator);
5330fa30b1SMasatake YAMATO static bool r6AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe);
54582f04dcSMasatake YAMATO static bool r6HasFunctionAlikeKind (rSubparser *s, tagEntryInfo *e);
5530fa30b1SMasatake YAMATO 
5630fa30b1SMasatake YAMATO static void parseClass (rSubparser *s, tokenInfo *const token, int classIndex);
5730fa30b1SMasatake YAMATO 
5830fa30b1SMasatake YAMATO 
5930fa30b1SMasatake YAMATO /*
6030fa30b1SMasatake YAMATO *   DATA DEFINITIONS
6130fa30b1SMasatake YAMATO */
6230fa30b1SMasatake YAMATO 
6330fa30b1SMasatake YAMATO typedef enum {
6430fa30b1SMasatake YAMATO 	R6_K_CLASS,
6530fa30b1SMasatake YAMATO 	R6_K_METHOD,
6630fa30b1SMasatake YAMATO 	R6_K_FIELD,
6730fa30b1SMasatake YAMATO 	R6_K_ACTIVE_BINDING_FUNCTION,
6830fa30b1SMasatake YAMATO } r6Kind;
6930fa30b1SMasatake YAMATO 
7030fa30b1SMasatake YAMATO static kindDefinition R6Kinds[] = {
7130fa30b1SMasatake YAMATO 	{ true, 'c', "class",  "classes" },
7230fa30b1SMasatake YAMATO 	{ true, 'm', "method", "methods" },
7330fa30b1SMasatake YAMATO 	{ true, 'f', "field",  "fields" },
7430fa30b1SMasatake YAMATO 	{ true, 'a', "activeBindingFunc", "active binding functions" },
7530fa30b1SMasatake YAMATO };
7630fa30b1SMasatake YAMATO 
7730fa30b1SMasatake YAMATO static struct r6Subparser r6Subparser = {
7830fa30b1SMasatake YAMATO 	.r = {
7930fa30b1SMasatake YAMATO 		.subparser = {
8030fa30b1SMasatake YAMATO 			.direction = SUBPARSER_BI_DIRECTION,
8130fa30b1SMasatake YAMATO 		},
8230fa30b1SMasatake YAMATO 		.readRightSideSymbol = r6ReadRightSideSymbol,
8330fa30b1SMasatake YAMATO 		.makeTagWithTranslation = r6MakeTagWithTranslation,
8430fa30b1SMasatake YAMATO 		.askTagAcceptancy = r6AskTagAcceptancy,
85582f04dcSMasatake YAMATO 		.hasFunctionAlikeKind = r6HasFunctionAlikeKind,
8630fa30b1SMasatake YAMATO 	},
8730fa30b1SMasatake YAMATO 	.access = NULL,
8830fa30b1SMasatake YAMATO 	.activeBinding = false,
8930fa30b1SMasatake YAMATO };
9030fa30b1SMasatake YAMATO 
9130fa30b1SMasatake YAMATO 
9230fa30b1SMasatake YAMATO /*
9330fa30b1SMasatake YAMATO *   FUNCTION DEFINITIONS
9430fa30b1SMasatake YAMATO */
9530fa30b1SMasatake YAMATO 
9630fa30b1SMasatake YAMATO /*
9730fa30b1SMasatake YAMATO  *       parse this area:              V======V
9830fa30b1SMasatake YAMATO  * klass = R6Class("klass", ..., inherit=parent)
9930fa30b1SMasatake YAMATO  */
parseInherit(rSubparser * s,tokenInfo * const token,int classIndex)10030fa30b1SMasatake YAMATO static void parseInherit (rSubparser *s,
10130fa30b1SMasatake YAMATO 							tokenInfo *const token, int classIndex)
10230fa30b1SMasatake YAMATO {
10330fa30b1SMasatake YAMATO 	rTokenReadNoNewline (token);
10430fa30b1SMasatake YAMATO 	if (tokenIsTypeVal (token, '='))
10530fa30b1SMasatake YAMATO 	{
10630fa30b1SMasatake YAMATO 		rTokenReadNoNewline (token);
10730fa30b1SMasatake YAMATO 		if (tokenIsType (token, R_SYMBOL))
10830fa30b1SMasatake YAMATO 		{
10930fa30b1SMasatake YAMATO 			tagEntryInfo *e = getEntryInCorkQueue (classIndex);
11030fa30b1SMasatake YAMATO 			e->extensionFields.inheritance = vStringStrdup (token->string);
11130fa30b1SMasatake YAMATO 		}
11230fa30b1SMasatake YAMATO 		else
11330fa30b1SMasatake YAMATO 			tokenUnread (token);
11430fa30b1SMasatake YAMATO 	}
11530fa30b1SMasatake YAMATO 	else
11630fa30b1SMasatake YAMATO 		tokenUnread (token);
11730fa30b1SMasatake YAMATO }
11830fa30b1SMasatake YAMATO 
11930fa30b1SMasatake YAMATO /*
12030fa30b1SMasatake YAMATO  *       parse this area:              V===V              V===V             V===V
12130fa30b1SMasatake YAMATO  * klass = R6Class("klass", public=list(...), private=list(...), active=list(...), ...)
12230fa30b1SMasatake YAMATO  */
parseListMain(rSubparser * s,tokenInfo * const token,int classIndex,const char * access,bool activeBinding)12330fa30b1SMasatake YAMATO static void parseListMain (rSubparser *s,
12430fa30b1SMasatake YAMATO 							 tokenInfo *const token, int classIndex, const char *access,
12530fa30b1SMasatake YAMATO 							 bool activeBinding)
12630fa30b1SMasatake YAMATO {
12730fa30b1SMasatake YAMATO 	const char *last_access = ((struct r6Subparser *)s)->access;
12830fa30b1SMasatake YAMATO 	((struct r6Subparser *)s)->access = access;
12930fa30b1SMasatake YAMATO 
13030fa30b1SMasatake YAMATO 	bool last_active_binding = ((struct r6Subparser *)s)->activeBinding;
13130fa30b1SMasatake YAMATO 	((struct r6Subparser *)s)->activeBinding = activeBinding;
13230fa30b1SMasatake YAMATO 
13330fa30b1SMasatake YAMATO 	rTokenReadNoNewline (token);
13430fa30b1SMasatake YAMATO 
13519bff7a2SMasatake YAMATO 	while (! tokenIsTypeVal (token, ')'))
13630fa30b1SMasatake YAMATO 	{
13719bff7a2SMasatake YAMATO 		if (!rParseStatement (token, classIndex, false))
13819bff7a2SMasatake YAMATO 			break;
13919bff7a2SMasatake YAMATO 		else if (tokenIsTypeVal (token, '\n'))
14030fa30b1SMasatake YAMATO 			rTokenReadNoNewline (token);
14130fa30b1SMasatake YAMATO 	}
14230fa30b1SMasatake YAMATO 	((struct r6Subparser *)s)->access = last_access;
14330fa30b1SMasatake YAMATO 	((struct r6Subparser *)s)->activeBinding = last_active_binding;
14430fa30b1SMasatake YAMATO }
14530fa30b1SMasatake YAMATO 
14630fa30b1SMasatake YAMATO /*
14730fa30b1SMasatake YAMATO  *       parse this area:        V=====|---V        V=====|---V       V=====|---V
14830fa30b1SMasatake YAMATO  * klass = R6Class("klass", public=list(...), private=list(...), active=list(...), ...)
14930fa30b1SMasatake YAMATO  */
parseList(rSubparser * s,tokenInfo * const token,int classIndex,const char * access,bool activeBinding)15030fa30b1SMasatake YAMATO static void parseList (rSubparser *s,
15130fa30b1SMasatake YAMATO 					   tokenInfo *const token, int classIndex, const char *access,
15230fa30b1SMasatake YAMATO 					   bool activeBinding)
15330fa30b1SMasatake YAMATO {
15430fa30b1SMasatake YAMATO 	rTokenReadNoNewline (token);
15530fa30b1SMasatake YAMATO 	if (tokenIsTypeVal (token, '='))
15630fa30b1SMasatake YAMATO 	{
15730fa30b1SMasatake YAMATO 		rTokenReadNoNewline (token);
158*2b000035SMasatake YAMATO 		if (tokenIsKeyword (token, R_LIST))
15930fa30b1SMasatake YAMATO 		{
16030fa30b1SMasatake YAMATO 			rTokenReadNoNewline (token);
16130fa30b1SMasatake YAMATO 			if (tokenIsTypeVal (token, '('))
16230fa30b1SMasatake YAMATO 				parseListMain (s, token, classIndex, access, activeBinding);
16330fa30b1SMasatake YAMATO 			else
16430fa30b1SMasatake YAMATO 				tokenUnread (token);
16530fa30b1SMasatake YAMATO 		}
16630fa30b1SMasatake YAMATO 		else
16730fa30b1SMasatake YAMATO 			tokenUnread (token);
16830fa30b1SMasatake YAMATO 	}
16930fa30b1SMasatake YAMATO 	else
17030fa30b1SMasatake YAMATO 		tokenUnread (token);
17130fa30b1SMasatake YAMATO }
17230fa30b1SMasatake YAMATO 
17330fa30b1SMasatake YAMATO /*
17430fa30b1SMasatake YAMATO  *      parse this area: V=======|----V=======|----V======|----V=======|----V
17530fa30b1SMasatake YAMATO  * klass = R6Class("klass", public=..., private=..., active=..., inherit=...)
17630fa30b1SMasatake YAMATO  */
parseClass(rSubparser * s,tokenInfo * const token,int classIndex)17730fa30b1SMasatake YAMATO static void parseClass (rSubparser *s,
17830fa30b1SMasatake YAMATO 						  tokenInfo *const token, int classIndex)
17930fa30b1SMasatake YAMATO {
18030fa30b1SMasatake YAMATO 	do
18130fa30b1SMasatake YAMATO 	{
18230fa30b1SMasatake YAMATO 		rTokenReadNoNewline (token);
18330fa30b1SMasatake YAMATO 
18430fa30b1SMasatake YAMATO 		if (tokenIsTypeVal (token, ')'))
18530fa30b1SMasatake YAMATO 			break;
18630fa30b1SMasatake YAMATO 		else if (tokenIsTypeVal (token, '('))
18730fa30b1SMasatake YAMATO 			tokenSkipOverPair (token);
18830fa30b1SMasatake YAMATO 		else if (tokenIsTypeVal (token, '{'))
18930fa30b1SMasatake YAMATO 			tokenSkipOverPair (token);
19030fa30b1SMasatake YAMATO 		else if (tokenIsTypeVal (token, '['))
19130fa30b1SMasatake YAMATO 			tokenSkipOverPair (token);
19230fa30b1SMasatake YAMATO 		else if (tokenIsType (token, R_SYMBOL))
19330fa30b1SMasatake YAMATO 		{
19430fa30b1SMasatake YAMATO 			const char *str = tokenString (token);
19530fa30b1SMasatake YAMATO 			if (strcmp (str, "inherit") == 0)
19630fa30b1SMasatake YAMATO 				parseInherit (s, token, classIndex);
19730fa30b1SMasatake YAMATO 			else if (strcmp (str, "public") == 0)
19830fa30b1SMasatake YAMATO 				parseList (s, token, classIndex, "public", false);
19930fa30b1SMasatake YAMATO 			else if (strcmp (str, "private") == 0)
20030fa30b1SMasatake YAMATO 				parseList (s, token, classIndex, "private", false);
20130fa30b1SMasatake YAMATO 			else if (strcmp (str, "active") == 0)
20230fa30b1SMasatake YAMATO 				parseList (s, token, classIndex, "public", true);
20330fa30b1SMasatake YAMATO 		}
20430fa30b1SMasatake YAMATO 	}
20530fa30b1SMasatake YAMATO 	while (!tokenIsEOF (token));
20630fa30b1SMasatake YAMATO }
20730fa30b1SMasatake YAMATO 
20830fa30b1SMasatake YAMATO /*
20930fa30b1SMasatake YAMATO  *         V=============|-----V: parse this area
21030fa30b1SMasatake YAMATO  * klass = R6Class("klass", ...)
21130fa30b1SMasatake YAMATO  */
r6ReadRightSideSymbol(rSubparser * s,tokenInfo * const symbol,const char * const assignmentOperator,int parent,tokenInfo * const token)21230fa30b1SMasatake YAMATO static int r6ReadRightSideSymbol (rSubparser *s,
21330fa30b1SMasatake YAMATO 								  tokenInfo *const symbol,
21430fa30b1SMasatake YAMATO 								  const char *const assignmentOperator,
21530fa30b1SMasatake YAMATO 								  int parent,
21630fa30b1SMasatake YAMATO 								  tokenInfo *const token)
21730fa30b1SMasatake YAMATO {
21877553cd0SMasatake YAMATO 	tokenInfo * token0 = NULL;
21977553cd0SMasatake YAMATO 	tokenInfo * token1 = NULL;
22077553cd0SMasatake YAMATO 	if (strcmp (tokenString (token), "R6") == 0)
22177553cd0SMasatake YAMATO 	{
22277553cd0SMasatake YAMATO 		tokenInfo * token0 = rNewToken ();
22377553cd0SMasatake YAMATO 		tokenRead (token0);
22477553cd0SMasatake YAMATO 		if (!tokenIsType (token0, R_SCOPE))
22577553cd0SMasatake YAMATO 			goto reject;
22677553cd0SMasatake YAMATO 		if (strcmp (tokenString (token0), "::"))
22777553cd0SMasatake YAMATO 			goto reject;
22877553cd0SMasatake YAMATO 
22977553cd0SMasatake YAMATO 		tokenInfo * token1 = rNewToken ();
23077553cd0SMasatake YAMATO 		tokenRead (token1);
23177553cd0SMasatake YAMATO 		if (!tokenIsType (token1, R_SYMBOL))
23277553cd0SMasatake YAMATO 			goto reject;
23377553cd0SMasatake YAMATO 		if (strcmp (tokenString (token1), "R6Class"))
23477553cd0SMasatake YAMATO 			goto reject;
23577553cd0SMasatake YAMATO 		tokenCopy (token, token1);
23677553cd0SMasatake YAMATO 		tokenDelete (token1);
23777553cd0SMasatake YAMATO 		tokenDelete (token0);
23877553cd0SMasatake YAMATO 		token0 = token1 = NULL;
23977553cd0SMasatake YAMATO 	}
24077553cd0SMasatake YAMATO 	else if (strcmp (tokenString (token), "R6Class") != 0)
24130fa30b1SMasatake YAMATO 		return CORK_NIL;
24277553cd0SMasatake YAMATO 
24330fa30b1SMasatake YAMATO 	rTokenReadNoNewline (token);
24430fa30b1SMasatake YAMATO 	if (tokenIsTypeVal (token, '('))
24530fa30b1SMasatake YAMATO 	{
24630fa30b1SMasatake YAMATO 		int corkIndex = makeSimpleTag (symbol->string, R6_K_CLASS);
24730fa30b1SMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue (corkIndex);
24830fa30b1SMasatake YAMATO 		if (e)
24930fa30b1SMasatake YAMATO 			e->extensionFields.scopeIndex = parent;
25030fa30b1SMasatake YAMATO 		parseClass (s, token, corkIndex);
25130fa30b1SMasatake YAMATO 		return corkIndex;
25230fa30b1SMasatake YAMATO 	}
25330fa30b1SMasatake YAMATO 	return CORK_NIL;
25477553cd0SMasatake YAMATO  reject:
25577553cd0SMasatake YAMATO 	if (token1)
25677553cd0SMasatake YAMATO 		tokenUnread (token1);
25777553cd0SMasatake YAMATO 	if (token0)
25877553cd0SMasatake YAMATO 		tokenUnread (token0);
25977553cd0SMasatake YAMATO 	/* tokenDelete accepts NULL. */
26077553cd0SMasatake YAMATO 	tokenDelete (token1);
26177553cd0SMasatake YAMATO 	tokenDelete (token0);
26277553cd0SMasatake YAMATO 
26377553cd0SMasatake YAMATO 	return CORK_NIL;
26430fa30b1SMasatake YAMATO }
26530fa30b1SMasatake YAMATO 
r6MakeTagWithTranslation(rSubparser * s,tokenInfo * const token,int parent,bool in_func,int kindInR,const char * const assignmentOperator)26630fa30b1SMasatake YAMATO static int r6MakeTagWithTranslation (rSubparser *s,
26730fa30b1SMasatake YAMATO 									 tokenInfo *const token,
26830fa30b1SMasatake YAMATO 									 int parent,
26930fa30b1SMasatake YAMATO 									 bool in_func,
27030fa30b1SMasatake YAMATO 									 int kindInR,
27130fa30b1SMasatake YAMATO 									 const char *const assignmentOperator)
27230fa30b1SMasatake YAMATO {
27330fa30b1SMasatake YAMATO 	tagEntryInfo e;
27430fa30b1SMasatake YAMATO 
27530fa30b1SMasatake YAMATO 	initTagEntry (&e, tokenString (token),
27630fa30b1SMasatake YAMATO 				  in_func
27730fa30b1SMasatake YAMATO 				  ? (((struct r6Subparser*)s)->activeBinding
27830fa30b1SMasatake YAMATO 					 ? R6_K_ACTIVE_BINDING_FUNCTION
27930fa30b1SMasatake YAMATO 					 : R6_K_METHOD)
28030fa30b1SMasatake YAMATO 				  : R6_K_FIELD);
28130fa30b1SMasatake YAMATO 	e.extensionFields.scopeIndex = parent;
28230fa30b1SMasatake YAMATO 	e.extensionFields.access = ((struct r6Subparser*)s)->access;
28330fa30b1SMasatake YAMATO 
28430fa30b1SMasatake YAMATO 	return makeTagEntry (&e);
28530fa30b1SMasatake YAMATO }
28630fa30b1SMasatake YAMATO 
r6AskTagAcceptancy(rSubparser * s,tagEntryInfo * pe)28730fa30b1SMasatake YAMATO static bool r6AskTagAcceptancy (rSubparser *s, tagEntryInfo *pe)
28830fa30b1SMasatake YAMATO {
28930fa30b1SMasatake YAMATO 	return (pe->kindIndex == R6_K_CLASS);
29030fa30b1SMasatake YAMATO }
29130fa30b1SMasatake YAMATO 
r6HasFunctionAlikeKind(rSubparser * s,tagEntryInfo * e)292582f04dcSMasatake YAMATO static bool r6HasFunctionAlikeKind (rSubparser *s,
293582f04dcSMasatake YAMATO 									tagEntryInfo *e)
294582f04dcSMasatake YAMATO {
295582f04dcSMasatake YAMATO 	return e->kindIndex == R6_K_METHOD ||
296582f04dcSMasatake YAMATO 		e->kindIndex == R6_K_ACTIVE_BINDING_FUNCTION;
297582f04dcSMasatake YAMATO }
298582f04dcSMasatake YAMATO 
findR6Tags(void)29930fa30b1SMasatake YAMATO static void findR6Tags(void)
30030fa30b1SMasatake YAMATO {
30130fa30b1SMasatake YAMATO 	r6Subparser.access = NULL;
30230fa30b1SMasatake YAMATO 	scheduleRunningBaseparser (RUN_DEFAULT_SUBPARSERS);
30330fa30b1SMasatake YAMATO }
30430fa30b1SMasatake YAMATO 
R6ClassParser(void)30530fa30b1SMasatake YAMATO extern parserDefinition* R6ClassParser (void)
30630fa30b1SMasatake YAMATO {
30730fa30b1SMasatake YAMATO 	parserDefinition* const def = parserNew("R6Class");
30830fa30b1SMasatake YAMATO 
30930fa30b1SMasatake YAMATO 	static parserDependency dependencies [] = {
31030fa30b1SMasatake YAMATO 		[0] = { DEPTYPE_SUBPARSER, "R", &r6Subparser },
31130fa30b1SMasatake YAMATO 	};
31230fa30b1SMasatake YAMATO 
31330fa30b1SMasatake YAMATO 	def->dependencies = dependencies;
31430fa30b1SMasatake YAMATO 	def->dependencyCount = ARRAY_SIZE (dependencies);
31530fa30b1SMasatake YAMATO 
31630fa30b1SMasatake YAMATO 	def->kindTable = R6Kinds;
31730fa30b1SMasatake YAMATO 	def->kindCount = ARRAY_SIZE(R6Kinds);
31830fa30b1SMasatake YAMATO 
31930fa30b1SMasatake YAMATO 	def->parser =  findR6Tags;
32030fa30b1SMasatake YAMATO 	def->useCork = CORK_QUEUE;
32130fa30b1SMasatake YAMATO 
32230fa30b1SMasatake YAMATO 	return def;
32330fa30b1SMasatake YAMATO }
324