Skip to content

Commit 8f3d658

Browse files
authored
Merge pull request #1880 from idodeclare/feature/extract_interfaces1
Extract JFlexLexer, JFlexStateStacker, JFlexXrefSimple
2 parents 95f26c0 + 535f5d4 commit 8f3d658

File tree

21 files changed

+585
-179
lines changed

21 files changed

+585
-179
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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, Chris Fraire <[email protected]>.
22+
*/
23+
24+
package org.opensolaris.opengrok.analysis;
25+
26+
import java.io.IOException;
27+
import java.io.Reader;
28+
29+
/**
30+
* Represents an API for lexers created by JFlex for {@code %type int}.
31+
* <p>http://jflex.de
32+
*/
33+
public interface JFlexLexer {
34+
35+
/**
36+
* Gets the matched input text as documented by JFlex.
37+
* @return "the matched input text region"
38+
*/
39+
String yytext();
40+
41+
/**
42+
* Gets the matched input text length as documented by JFlex.
43+
* @return "the length of the matched input text region (does not require a
44+
* String object to be created)"
45+
*/
46+
int yylength();
47+
48+
/**
49+
* Gets a character from the matched input text as documented by JFlex.
50+
* @param pos "a value from 0 to {@link #yylength()}-1"
51+
* @return "the character at position {@code pos} from the matched text. It
52+
* is equivalent to {@link #yytext()} then {@link String#charAt(int)} --
53+
* but faster."
54+
*/
55+
char yycharat(int pos);
56+
57+
/**
58+
* "Closes the input stream [as documented by JFlex]. All subsequent calls
59+
* to the scanning method will return the end of file value."
60+
* @throws IOException if an error occurs while closing
61+
*/
62+
void yyclose() throws IOException;
63+
64+
/**
65+
* "Closes the current input stream [as documented by JFlex], and resets
66+
* the scanner to read from a new Reader."
67+
* @param reader the new reader
68+
*/
69+
void yyreset(Reader reader);
70+
71+
/**
72+
* Gets the current lexical state as documented by JFlex.
73+
* @return "the current lexical state of the scanner."
74+
*/
75+
int yystate();
76+
77+
/**
78+
* "Enters the lexical state {@code lexicalState} [as documented by
79+
* JFlex]."
80+
* @param lexicalState the new state
81+
*/
82+
void yybegin(int lexicalState);
83+
84+
/**
85+
* "Pushes {@code number} characters of the matched text back into the
86+
* input stream [as documented by JFlex].
87+
* <p>[The characters] will be read again in the next call of the scanning
88+
* method.
89+
* <p>The number of characters to be read again must not be greater than
90+
* the length of the matched text. The pushed back characters will not be
91+
* included in {@link #yylength()} and {@link #yytext()}."
92+
* @param number the [constrained] number of characters
93+
*/
94+
void yypushback(int number);
95+
96+
/**
97+
* "Runs the scanner [as documented by JFlex].
98+
* <p>[The method] can be used to get the next token from the input."
99+
* <p>"Consume[s] input until one of the expressions in the specification
100+
* is matched or an error occurs."
101+
* @return a value returned by the lexer specification if defined or the
102+
* {@code EOF} value upon reading end-of-file
103+
* @throws IOException if an error occurs reading the input
104+
*/
105+
int yylex() throws IOException;
106+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright 2011 Jens Elkner.
23+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
24+
*/
25+
26+
package org.opensolaris.opengrok.analysis;
27+
28+
import java.io.IOException;
29+
30+
/**
31+
* Represents an API for an extension of {@link JFlexLexer} that needs to track
32+
* a state stack.
33+
*/
34+
public interface JFlexStackingLexer extends JFlexLexer {
35+
36+
/**
37+
* Saves current {@link #yystate()} to stack, and enters the specified
38+
* {@code newState} with {@link #yybegin(int)}.
39+
* @param newState state id
40+
*/
41+
void yypush(int newState);
42+
43+
/**
44+
* Pops the last state from the stack, and enters the state with
45+
* {@link #yybegin(int)}.
46+
* @throws IOException if any error occurs while effecting the pop
47+
*/
48+
void yypop() throws IOException;
49+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright 2011 Jens Elkner.
23+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
24+
*/
25+
26+
package org.opensolaris.opengrok.analysis;
27+
28+
import java.io.IOException;
29+
import java.util.Stack;
30+
31+
/**
32+
* Represents an abstract base class for resettable lexers that need to track
33+
* a state stack.
34+
*/
35+
public abstract class JFlexStateStacker implements Resettable,
36+
JFlexStackingLexer {
37+
38+
protected final Stack<Integer> stack = new Stack<>();
39+
40+
/**
41+
* Resets the instance using {@link #clearStack()}.
42+
*/
43+
@Override
44+
public void reset() {
45+
clearStack();
46+
}
47+
48+
/**
49+
* Saves current {@link #yystate()} to stack, and enters the specified
50+
* {@code newState} with {@link #yybegin(int)}.
51+
* @param newState state id
52+
*/
53+
public void yypush(int newState) {
54+
this.stack.push(yystate());
55+
yybegin(newState);
56+
}
57+
58+
/**
59+
* Pops the last state from the stack, and enters the state with
60+
* {@link #yybegin(int)}.
61+
* @throws IOException if any error occurs while effecting the pop
62+
*/
63+
public void yypop() throws IOException {
64+
yybegin(this.stack.pop());
65+
}
66+
67+
/**
68+
* Calls {@link #clearStack()}, and enters the specified {@code newState}
69+
* with {@link #yybegin(int)}.
70+
* @param newState state id
71+
*/
72+
public void yyjump(int newState) {
73+
clearStack();
74+
yybegin(newState);
75+
}
76+
77+
/**
78+
* Clears the instance stack.
79+
*/
80+
protected void clearStack() {
81+
stack.clear();
82+
}
83+
}

src/org/opensolaris/opengrok/analysis/JFlexXref.java

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,28 @@
2828
import java.io.IOException;
2929
import java.io.Reader;
3030
import java.io.Writer;
31-
import java.lang.reflect.Field;
3231
import java.util.Comparator;
3332
import java.util.HashMap;
3433
import java.util.List;
3534
import java.util.Map;
3635
import java.util.Set;
3736
import java.util.SortedSet;
38-
import java.util.Stack;
3937
import java.util.TreeSet;
4038
import org.opensolaris.opengrok.analysis.Definitions.Tag;
4139
import org.opensolaris.opengrok.analysis.Scopes.Scope;
4240
import org.opensolaris.opengrok.configuration.Project;
4341
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
4442
import org.opensolaris.opengrok.history.Annotation;
4543
import org.opensolaris.opengrok.util.StringUtils;
44+
import org.opensolaris.opengrok.web.HtmlConsts;
4645
import org.opensolaris.opengrok.web.Util;
4746

4847
/**
4948
* Base class for Xref lexers.
5049
*
5150
* @author Lubos Kosco
5251
*/
53-
public abstract class JFlexXref {
52+
public abstract class JFlexXref extends JFlexStateStacker {
5453

5554
public Writer out;
5655
public String urlPrefix = RuntimeEnvironment.getInstance().getUrlPrefix();
@@ -81,8 +80,12 @@ public abstract class JFlexXref {
8180
* @see #startNewLine()
8281
*/
8382
protected String userPageSuffix;
84-
protected Stack<Integer> stack = new Stack<>();
85-
protected Stack<String> stackPopString = new Stack<>();
83+
84+
/**
85+
* The span class name from the last call to
86+
* {@link #disjointSpan(java.lang.String)}.
87+
*/
88+
private String disjointSpanClassName;
8689

8790
/**
8891
* Description of the style to use for a type of definitions.
@@ -164,8 +167,18 @@ public void reInit(char[] contents, int length) {
164167
*/
165168
public void reInit(Reader reader) {
166169
this.yyreset(reader);
167-
annotation = null;
170+
reset();
171+
}
172+
173+
/**
174+
* Resets the xref tracked state after {@link #reset()}.
175+
*/
176+
@Override
177+
public void reset() {
178+
super.reset();
168179

180+
annotation = null;
181+
disjointSpanClassName = null;
169182
scopes = new Scopes();
170183
scope = null;
171184
scopeLevel = 0;
@@ -352,6 +365,26 @@ public Scopes getScopes() {
352365
*/
353366
public abstract int getYYEOF();
354367

368+
/**
369+
* Writes the closing of an open span tag previously opened by this method
370+
* and the opening -- if {@code className} is non-null -- of a new span
371+
* tag.
372+
* <p>This method's disjoint spans are independent of any span used for
373+
* scopes.
374+
* <p>Any open span is closed at the end of {@link #write(java.io.Writer)}
375+
* just before any open scope is closed.
376+
* @param className the class name for the new tag or {@code null} just to
377+
* close an open tag.
378+
* @throws IOException if an output error occurs
379+
*/
380+
public void disjointSpan(String className) throws IOException {
381+
if (disjointSpanClassName != null) out.write(HtmlConsts.ZSPAN);
382+
if (className != null) {
383+
out.write(String.format(HtmlConsts.SPAN_FMT, className));
384+
}
385+
disjointSpanClassName = className;
386+
}
387+
355388
/**
356389
* Write xref to the specified {@code Writer}.
357390
*
@@ -367,6 +400,8 @@ public void write(Writer out) throws IOException {
367400
// nothing to do here, yylex() will do the work
368401
}
369402

403+
disjointSpan(null);
404+
370405
// terminate scopes
371406
if (scopeOpen) {
372407
out.write("</span>");
@@ -757,45 +792,4 @@ protected void writeEMailAddress(String address) throws IOException {
757792
out.write(address);
758793
}
759794
}
760-
761-
/**
762-
* save current yy state to stack
763-
* @param newState state id
764-
* @param popString string for the state
765-
*/
766-
public void yypush(int newState, String popString) {
767-
this.stack.push(yystate());
768-
this.stackPopString.push(popString);
769-
yybegin(newState);
770-
}
771-
772-
/**
773-
* save current yy state to stack
774-
* @param newState state id
775-
*/
776-
public void yypush(int newState) {
777-
yypush(newState, null);
778-
}
779-
780-
/**
781-
* pop last state from stack
782-
* @throws IOException in case of any I/O problem
783-
*/
784-
public void yypop() throws IOException {
785-
yybegin(this.stack.pop());
786-
String popString = this.stackPopString.pop();
787-
if (popString != null) {
788-
out.write(popString);
789-
}
790-
}
791-
792-
/**
793-
* reset current yy state, and clear stack
794-
* @param newState state id
795-
*/
796-
public void yyjump(int newState) {
797-
yybegin(newState);
798-
this.stack.clear();
799-
this.stackPopString.clear();
800-
}
801795
}

0 commit comments

Comments
 (0)