xref: /Universal-ctags/peg/kotlin_post.h (revision 2b952e23ef8b50353086c6b9039f9e7f1e5179ab)
1 /*
2  *   Copyright (c) 2021 Jan Dolinár
3  *
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.
6  *
7  *   This module contains functions to generate tags for Kotlin.
8  */
9 
10 /*
11 *   INCLUDE FILES
12 */
13 #include "parse.h"
14 #include "trace.h"
15 
16 /*
17 * FUNCTION DEFINITIONS
18 */
getcFromKotlinFile(struct parserCtx * auxil)19 static int getcFromKotlinFile(struct parserCtx *auxil)
20 {
21     int c = getcFromInputFile();
22     if (auxil->parenthesis_level > 0 && (c == '\r' || c == '\n'))
23     {
24         return ' ';
25     }
26     return c;
27 }
28 
makeKotlinTag(struct parserCtx * auxil,const char * name,long offset,bool pushScope)29 static void makeKotlinTag (struct parserCtx *auxil, const char *name, long offset, bool pushScope)
30 {
31     int k = PEEK_KIND(auxil);
32     if (k == K_IGNORE) return;
33     tagEntryInfo e;
34     char *stripped = NULL;
35     if (*name != '`')
36     {
37         initTagEntry(&e, name, k);
38     } else
39     {
40         size_t len = strlen(name);
41         Assert(len >= 2);
42         len -= 2;
43         stripped = eStrndup (name + 1, len);
44         initTagEntry(&e, stripped, k);
45     }
46     e.lineNumber = getInputLineNumberForFileOffset (offset);
47     e.filePosition = getInputFilePositionForLine (e.lineNumber);
48     e.extensionFields.scopeIndex = BASE_SCOPE(auxil);
49     int scope_index = makeTagEntry (&e);
50     if (pushScope)
51     {
52         SET_SCOPE(auxil, scope_index);
53     }
54     if (stripped)
55         eFree (stripped);
56 }
57 
58 #ifdef DEBUG
reportFailure(struct parserCtx * auxil,long offset)59 static void reportFailure(struct parserCtx *auxil, long offset)
60 {
61     if(auxil->fail_offset < 0)
62     {
63         auxil->fail_offset = offset;
64     }
65 }
66 
resetFailure(struct parserCtx * auxil,long offset)67 static void resetFailure(struct parserCtx *auxil, long offset)
68 {
69     if(auxil->fail_offset >= 0)
70     {
71         unsigned long startLine = getInputLineNumberForFileOffset(auxil->fail_offset);
72         unsigned long endLine = getInputLineNumberForFileOffset(offset-1);
73         if (startLine == endLine)
74         {
75             TRACE_PRINT("Failed to parse '%s' at line %lu!\n", getInputFileName(), startLine);
76         } else
77         {
78             TRACE_PRINT("Failed to parse '%s' from line %lu to line %lu!\n", getInputFileName(), startLine, endLine);
79         }
80     }
81     auxil->fail_offset = -1;
82 }
83 #endif
84 
ctxInit(struct parserCtx * auxil)85 static void ctxInit (struct parserCtx *auxil)
86 {
87     BASE_INIT(auxil, K_INTERFACE);
88     auxil->parenthesis_level = 0;
89     #ifdef DEBUG
90     auxil->fail_offset = -1;
91     #endif
92 }
93 
ctxFini(struct parserCtx * auxil)94 static void ctxFini (struct parserCtx *auxil)
95 {
96     BASE_FINI(auxil);
97 }
98 
findKotlinTags(void)99 static void findKotlinTags (void)
100 {
101     struct parserCtx auxil;
102 
103     ctxInit (&auxil);
104     pkotlin_context_t *pctx = pkotlin_create(&auxil);
105 
106     while (pkotlin_parse(pctx, NULL) && (!BASE_ERROR(&auxil)) );
107 
108     pkotlin_destroy(pctx);
109     ctxFini (&auxil);
110 }
111 
KotlinParser(void)112 extern parserDefinition* KotlinParser (void)
113 {
114     static const char *const extensions [] = { "kt", "kts", NULL };
115     parserDefinition* def = parserNew ("Kotlin");
116     def->kindTable = KotlinKinds;
117     def->kindCount = ARRAY_SIZE (KotlinKinds);
118     def->extensions = extensions;
119     def->parser = findKotlinTags;
120     def->useCork = true;
121     def->requestAutomaticFQTag = true;
122     def->defaultScopeSeparator = ".";
123     def->enabled = true;
124     return def;
125 }
126