Skip to content

Commit 2b08c9e

Browse files
authored
Merge pull request #1941 from idodeclare/feature/kotlin_tests
Feature/kotlin tests
2 parents 66dfb31 + c878e76 commit 2b08c9e

File tree

11 files changed

+1353
-53
lines changed

11 files changed

+1353
-53
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* The contents of this file are subject to the terms of the
5+
* Common Development and Distribution License (the "License").
6+
* You may not use this file except in compliance with the License.
7+
*
8+
* See LICENSE.txt included in this distribution for the specific
9+
* language governing permissions and limitations under the License.
10+
*
11+
* When distributing Covered Code, include this CDDL HEADER in each
12+
* file and include the License file at LICENSE.txt.
13+
* If applicable, add the following below this CDDL HEADER, with the
14+
* fields enclosed by brackets "[]" replaced with your own identifying
15+
* information: Portions Copyright [yyyy] [name of copyright owner]
16+
*
17+
* CDDL HEADER END
18+
*/
19+
20+
/*
21+
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
23+
*/
24+
25+
/* TODO: prohibit '$' in identifiers? */
26+
Identifier = [:jletter:] [:jletterdigit:]*
27+
28+
Number = ({Hexadecimal} | {Binary} | {Decimal} | {Floating})
29+
Hexadecimal = 0[x][0-9a-fA-F_]*[0-9a-fA-F] [L]?
30+
Binary = 0[b][01_]*[01] [L]?
31+
Decimal = {Decimal_digits} [L]?
32+
Decimal_digits = ([0-9]+ | [0-9][0-9_]*[0-9])
33+
Floating = ({Decimal_digits}\.{Decimal_digits} |
34+
{Decimal_digits}) ([eE][+-]?[0-9_]*[0-9])? [fF]?

src/org/opensolaris/opengrok/analysis/kotlin/KotlinSymbolTokenizer.lex

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@
2323
*/
2424

2525
/*
26-
* Gets Java symbols - ignores comments, strings, keywords
26+
* Gets Kotlin symbols - ignores comments, strings, keywords
2727
*/
2828

2929
// comments can be nested in kotlin, so below logic doesn't allow that with yybegin we save only one nesting
3030
// same for strings
3131

3232
package org.opensolaris.opengrok.analysis.kotlin;
33-
import org.opensolaris.opengrok.analysis.JFlexTokenizer;
3433

34+
import java.io.IOException;
35+
import org.opensolaris.opengrok.analysis.JFlexTokenizer;
3536
%%
3637
%public
3738
%class KotlinSymbolTokenizer
@@ -44,11 +45,20 @@ super(in);
4445
%int
4546
%include CommonTokenizer.lexh
4647
%char
48+
%{
49+
private int nestedComment;
4750

48-
Identifier = [:jletter:] [:jletterdigit:]*
51+
@Override
52+
public void reset() throws IOException {
53+
super.reset();
54+
nestedComment = 0;
55+
}
56+
%}
4957

5058
%state STRING COMMENT SCOMMENT QSTRING TSTRING
5159

60+
%include Common.lexh
61+
%include Kotlin.lexh
5262
%%
5363

5464
/* TODO : support identifiers escaped by ` `*/
@@ -58,36 +68,67 @@ Identifier = [:jletter:] [:jletterdigit:]*
5868
setAttribs(id, yychar, yychar + yylength());
5969
return yystate(); }
6070
}
61-
71+
{Number} {}
6272
\" { yybegin(STRING); }
6373
\' { yybegin(QSTRING); }
6474
\"\"\" { yybegin(TSTRING); }
65-
"/*" { yybegin(COMMENT); }
6675
"//" { yybegin(SCOMMENT); }
6776

6877
}
6978

7079
<STRING> {
80+
\\[\"\$\\] {}
7181
\" { yybegin(YYINITIAL); }
72-
\\\\ | \\\" {}
7382
}
7483

7584
<QSTRING> {
85+
\\[\'\\] {}
7686
\' { yybegin(YYINITIAL); }
7787
}
7888

7989
<TSTRING> {
90+
/*
91+
* "raw string ... doesn't support backslash escaping"
92+
*/
8093
\"\"\" { yybegin(YYINITIAL); }
8194
}
8295

96+
<STRING, TSTRING> {
97+
/*
98+
* TODO : support template expressions inside curly brackets
99+
*/
100+
\$ {Identifier} {
101+
String capture = yytext();
102+
String sigil = capture.substring(0, 1);
103+
String id = capture.substring(1);
104+
if (!Consts.kwd.contains(id)) {
105+
setAttribs(id, yychar + 1, yychar + yylength());
106+
return yystate();
107+
}
108+
}
109+
}
110+
111+
<YYINITIAL, COMMENT> {
112+
"/*" {
113+
if (nestedComment++ == 0) {
114+
yybegin(COMMENT);
115+
}
116+
}
117+
}
118+
83119
<COMMENT> {
84-
"*/" { yybegin(YYINITIAL);}
120+
"*/" {
121+
if (--nestedComment == 0) {
122+
yybegin(YYINITIAL);
123+
}
124+
}
85125
}
86126

87127
<SCOMMENT> {
88-
\n { yybegin(YYINITIAL);}
128+
{EOL} { yybegin(YYINITIAL);}
89129
}
90130

91131
<YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING, TSTRING> {
132+
{WhiteSpace} |
92133
[^] {}
93134
}

src/org/opensolaris/opengrok/analysis/kotlin/KotlinXref.lex

Lines changed: 121 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,14 @@
2424

2525
package org.opensolaris.opengrok.analysis.kotlin;
2626

27-
import org.opensolaris.opengrok.analysis.JFlexXref;
28-
import java.io.IOException;
29-
import java.io.Writer;
30-
import java.io.Reader;
27+
import org.opensolaris.opengrok.analysis.JFlexXrefSimple;
28+
import org.opensolaris.opengrok.util.StringUtils;
29+
import org.opensolaris.opengrok.web.HtmlConsts;
3130
import org.opensolaris.opengrok.web.Util;
32-
3331
%%
3432
%public
3533
%class KotlinXref
36-
%extends JFlexXref
34+
%extends JFlexXrefSimple
3735
%unicode
3836
%ignorecase
3937
%int
@@ -42,19 +40,26 @@ import org.opensolaris.opengrok.web.Util;
4240
/* Must match {WhiteSpace} regex */
4341
private final static String WHITE_SPACE = "[ \\t\\f]+";
4442

43+
private int nestedComment;
44+
45+
@Override
46+
public void reset() {
47+
super.reset();
48+
nestedComment = 0;
49+
}
50+
4551
// TODO move this into an include file when bug #16053 is fixed
4652
@Override
4753
protected int getLineNumber() { return yyline; }
4854
@Override
4955
protected void setLineNumber(int x) { yyline = x; }
5056
%}
5157

52-
/* TODO: prohibit '$' in identifiers? */
53-
Identifier = [:jletter:] [:jletterdigit:]*
54-
55-
File = [a-zA-Z]{FNameChar}* "." ("java"|"properties"|"props"|"xml"|"conf"|"txt"|"htm"|"html"|"ini"|"jnlp"|"jad"|"diff"|"patch")
56-
57-
Number = (0[xX][0-9a-fA-F]+|[0-9]+\.[0-9]+|[0-9]+)(([eE][+-]?[0-9]+)?[ufdlUFDL]*)?
58+
File = [a-zA-Z]{FNameChar}* "." ([Jj][Aa][Vv][Aa] |
59+
[Pp][Rr][Oo][Pp][Ee][Rr][Tt][Ii][Ee][Ss] | [Pp][Rr][Oo][Pp][Ss] |
60+
[Xx][Mm][Ll] | [Cc][Oo][Nn][Ff] | [Tt][Xx][Tt] | [Hh][Tt][Mm][Ll]? |
61+
[Ii][Nn][Ii] | [Jj][Nn][Ll][Pp] | [Jj][Aa][Dd] | [Dd][Ii][Ff][Ff] |
62+
[Pp][Aa][Tt][Cc][Hh])
5863

5964
KdocWithClassArg = "@throws" | "@exception"
6065
KdocWithParamNameArg = "@param"
@@ -67,6 +72,7 @@ ParamName = {Identifier} | "<" {Identifier} ">"
6772
%include Common.lexh
6873
%include CommonURI.lexh
6974
%include CommonPath.lexh
75+
%include Kotlin.lexh
7076
%%
7177
<YYINITIAL>{
7278
\{ { incScope(); writeUnicodeChar(yycharat(0)); }
@@ -91,41 +97,104 @@ ParamName = {Identifier} | "<" {Identifier} ">"
9197
out.write("&gt;");
9298
}
9399

94-
/*{Hier}
95-
{ out.write(Util.breadcrumbPath(urlPrefix+"defs=",yytext(),'.'));}
96-
*/
97-
{Number} { out.write("<span class=\"n\">"); out.write(yytext()); out.write("</span>"); }
98-
99-
\" { yybegin(STRING);out.write("<span class=\"s\">\"");}
100-
\' { yybegin(QSTRING);out.write("<span class=\"s\">\'");}
101-
\"\"\" { yybegin(TSTRING);out.write("<span class=\"s\">\"\"\"");}
102-
"/**" / [^/] { yybegin(KDOC);out.write("<span class=\"c\">/**");}
103-
"/*" { yybegin(COMMENT);out.write("<span class=\"c\">/*");}
104-
"//" { yybegin(SCOMMENT);out.write("<span class=\"c\">//");}
100+
{Number} {
101+
disjointSpan(HtmlConsts.NUMBER_CLASS);
102+
out.write(yytext());
103+
disjointSpan(null);
104+
}
105+
106+
\" {
107+
pushSpan(STRING, HtmlConsts.STRING_CLASS);
108+
out.write(htmlize(yytext()));
109+
}
110+
\' {
111+
pushSpan(QSTRING, HtmlConsts.STRING_CLASS);
112+
out.write(htmlize(yytext()));
113+
}
114+
\"\"\" {
115+
pushSpan(TSTRING, HtmlConsts.STRING_CLASS);
116+
out.write(htmlize(yytext()));
117+
}
118+
"/**" / [^/] {
119+
if (nestedComment++ == 0) {
120+
pushSpan(KDOC, HtmlConsts.COMMENT_CLASS);
121+
}
122+
out.write(yytext());
123+
}
124+
"//" {
125+
pushSpan(SCOMMENT, HtmlConsts.COMMENT_CLASS);
126+
out.write(yytext());
127+
}
105128
}
106-
/* TODO : support raw """ strings */
129+
107130
<STRING> {
108-
\" {WhiteSpace} \" { out.write(yytext());}
109-
\" { yybegin(YYINITIAL); out.write("\"</span>"); }
110-
\\\\ { out.write("\\\\"); }
111-
\\\" { out.write("\\\""); }
131+
\\[\"\$\\] { out.write(htmlize(yytext())); }
132+
\" {
133+
out.write(htmlize(yytext()));
134+
yypop();
135+
}
112136
}
113137

114138
<QSTRING> {
115-
"\\\\" { out.write("\\\\"); }
116-
"\\\'" { out.write("\\\'"); }
117-
\' {WhiteSpace} \' { out.write(yytext()); }
118-
\' { yybegin(YYINITIAL); out.write("'</span>"); }
139+
\\[\'\\] |
140+
\' {WhiteSpace} \' { out.write(htmlize(yytext())); }
141+
\' {
142+
out.write(htmlize(yytext()));
143+
yypop();
144+
}
119145
}
120146

121147
<TSTRING> {
122-
"\\\\" { out.write("\\\\"); }
123-
"\\\"" { out.write("\\\""); }
124-
\"\"\" { yybegin(YYINITIAL); out.write("\"\"\"</span>"); }
148+
/*
149+
* "raw string ... doesn't support backslash escaping"
150+
*/
151+
\"\"\" {
152+
out.write(htmlize(yytext()));
153+
yypop();
154+
}
155+
}
156+
157+
<STRING, TSTRING> {
158+
/*
159+
* TODO : support template expressions inside curly brackets
160+
*/
161+
\$ {Identifier} {
162+
String capture = yytext();
163+
String sigil = capture.substring(0, 1);
164+
String id = capture.substring(1);
165+
out.write(sigil);
166+
disjointSpan(null);
167+
writeSymbol(id, Consts.kwd, yyline);
168+
disjointSpan(HtmlConsts.STRING_CLASS);
169+
}
170+
{WhspChar}*{EOL} {
171+
disjointSpan(null);
172+
startNewLine();
173+
disjointSpan(HtmlConsts.STRING_CLASS);
174+
}
175+
}
176+
177+
<YYINITIAL, COMMENT, KDOC> {
178+
"/*" {
179+
if (nestedComment++ == 0) {
180+
pushSpan(COMMENT, HtmlConsts.COMMENT_CLASS);
181+
}
182+
out.write(yytext());
183+
}
125184
}
126185

127186
<COMMENT, KDOC> {
128-
"*/" { yybegin(YYINITIAL); out.write("*/</span>"); }
187+
"*/" {
188+
out.write(yytext());
189+
if (--nestedComment == 0) {
190+
yypop();
191+
}
192+
}
193+
{WhspChar}*{EOL} {
194+
disjointSpan(null);
195+
startNewLine();
196+
disjointSpan(HtmlConsts.COMMENT_CLASS);
197+
}
129198
}
130199

131200
<KDOC> {
@@ -145,23 +214,22 @@ ParamName = {Identifier} | "<" {Identifier} ">"
145214

146215
<SCOMMENT> {
147216
{WhspChar}*{EOL} {
148-
yybegin(YYINITIAL); out.write("</span>");
217+
yypop();
149218
startNewLine();
150219
}
151220
}
152221

153222

154223
<YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING, KDOC, TSTRING> {
155-
"&" {out.write( "&amp;");}
156-
"<" {out.write( "&lt;");}
157-
">" {out.write( "&gt;");}
224+
[&<>\'\"] { out.write(htmlize(yytext())); }
225+
158226
{WhspChar}*{EOL} { startNewLine(); }
159227
{WhiteSpace} { out.write(yytext()); }
160228
[!-~] { out.write(yycharat(0)); }
161229
[^\n] { writeUnicodeChar(yycharat(0)); }
162230
}
163231

164-
<STRING, COMMENT, SCOMMENT, STRING, QSTRING, TSTRING, KDOC> {
232+
<STRING, COMMENT, SCOMMENT, QSTRING, TSTRING, KDOC> {
165233
{FPath}
166234
{ out.write(Util.breadcrumbPath(urlPrefix+"path=",yytext(),'/'));}
167235

@@ -175,12 +243,20 @@ ParamName = {Identifier} | "<" {Identifier} ">"
175243
out.write(path);
176244
out.write("</a>");}
177245

178-
{BrowseableURI} {
179-
appendLink(yytext(), true);
180-
}
181-
182246
{FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+
183247
{
184248
writeEMailAddress(yytext());
185249
}
186250
}
251+
252+
<STRING, SCOMMENT, QSTRING, TSTRING> {
253+
{BrowseableURI} {
254+
appendLink(yytext(), true);
255+
}
256+
}
257+
258+
<COMMENT, KDOC> {
259+
{BrowseableURI} {
260+
appendLink(yytext(), true, StringUtils.END_C_COMMENT);
261+
}
262+
}

0 commit comments

Comments
 (0)