Skip to content

Commit a041397

Browse files
committed
#46 implemented jcp comment remover, added tests
1 parent ddde808 commit a041397

8 files changed

Lines changed: 413 additions & 165 deletions

File tree

jcp/src/main/java/com/igormaznitsa/jcp/removers/AbstractCommentRemover.java

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,79 @@ public static AbstractCommentRemover makeCommentRemover(
3131
switch (keepComments) {
3232
case KEEP_ALL: return new JustCopyRemover(src, dst, whiteSpaceAllowed);
3333
case REMOVE_C_STYLE: return new CStyleCommentRemover(src, dst, whiteSpaceAllowed);
34-
case REMOVE_JCP_ONLY: return new JcpCommentsRemover(src, dst, whiteSpaceAllowed);
34+
case REMOVE_JCP_ONLY:
35+
return new JcpCommentLineRemover(src, dst, whiteSpaceAllowed);
3536
default: throw new IllegalStateException("Unsupported keep comments value: " + keepComments);
3637
}
3738
}
3839

40+
protected void skipTillNextString() throws IOException {
41+
while (!Thread.currentThread().isInterrupted()) {
42+
final int chr = srcReader.read();
43+
if (chr < 0) {
44+
return;
45+
}
46+
47+
if (chr == '\n') {
48+
this.dstWriter.write(chr);
49+
return;
50+
}
51+
}
52+
}
53+
54+
protected void skipTillClosingJavaComments() throws IOException {
55+
boolean starFound = false;
56+
57+
while (!Thread.currentThread().isInterrupted()) {
58+
final int chr = srcReader.read();
59+
if (chr < 0) {
60+
return;
61+
}
62+
if (starFound) {
63+
if (chr == '/') {
64+
return;
65+
} else {
66+
starFound = chr == '*';
67+
}
68+
} else if (chr == '*') {
69+
starFound = true;
70+
}
71+
}
72+
}
73+
74+
protected void copyTillClosingJavaComments() throws IOException {
75+
boolean starFound = false;
76+
77+
while (!Thread.currentThread().isInterrupted()) {
78+
final int chr = this.srcReader.read();
79+
if (chr < 0) {
80+
return;
81+
}
82+
this.dstWriter.write(chr);
83+
if (starFound) {
84+
if (chr == '/') {
85+
return;
86+
} else {
87+
starFound = chr == '*';
88+
}
89+
} else if (chr == '*') {
90+
starFound = true;
91+
}
92+
}
93+
}
94+
95+
protected void copyTillNextString() throws IOException {
96+
while (!Thread.currentThread().isInterrupted()) {
97+
final int chr = srcReader.read();
98+
if (chr < 0) {
99+
return;
100+
} else {
101+
this.dstWriter.write(chr);
102+
if (chr == '\n') {
103+
break;
104+
}
105+
}
106+
}
107+
}
108+
39109
}

jcp/src/main/java/com/igormaznitsa/jcp/removers/CStyleCommentRemover.java

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -36,41 +36,6 @@ public CStyleCommentRemover(final Reader src, final Writer dst, final boolean wh
3636
super(src, dst, whiteSpacesAllowed);
3737
}
3838

39-
private void skipUntilNextString() throws IOException {
40-
while (!Thread.currentThread().isInterrupted()) {
41-
final int chr = srcReader.read();
42-
if (chr < 0) {
43-
return;
44-
}
45-
46-
if (chr == '\n') {
47-
this.dstWriter.write(chr);
48-
return;
49-
}
50-
}
51-
}
52-
53-
private void skipUntilClosingComments() throws IOException {
54-
boolean starFound = false;
55-
56-
while (!Thread.currentThread().isInterrupted()) {
57-
final int chr = srcReader.read();
58-
if (chr < 0) {
59-
return;
60-
}
61-
if (starFound) {
62-
if (chr == '/') {
63-
return;
64-
} else {
65-
starFound = chr == '*';
66-
}
67-
} else if (chr == '*') {
68-
starFound = true;
69-
}
70-
}
71-
}
72-
73-
7439
@Override
7540
public Writer process() throws IOException {
7641
final int STATE_NORMAL = 0;
@@ -108,12 +73,12 @@ public Writer process() throws IOException {
10873
case STATE_FORWARD_SLASH: {
10974
switch (chr) {
11075
case '*': {
111-
skipUntilClosingComments();
76+
skipTillClosingJavaComments();
11277
state = STATE_NORMAL;
11378
}
11479
break;
11580
case '/': {
116-
skipUntilNextString();
81+
skipTillNextString();
11782
state = STATE_NORMAL;
11883
}
11984
break;

jcp/src/main/java/com/igormaznitsa/jcp/removers/JcpCommentsRemover.java renamed to jcp/src/main/java/com/igormaznitsa/jcp/removers/JcpCommentLineRemover.java

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,58 +26,28 @@
2626
import java.io.Writer;
2727

2828
/**
29-
* A remover allows to cut off all Java like comments contains JCP directives from a reader and write the result into a writer
29+
* A remover allows to cut off all Java like comments contains JCP directives (single line comments started by '#' or '$')
30+
* from a reader and write the result into a writer.
3031
*
3132
* @author Igor Maznitsa (igor.maznitsa@igormaznitsa.com)
33+
* @since 7.1.0
3234
*/
33-
public class JcpCommentsRemover extends AbstractCommentRemover {
35+
public class JcpCommentLineRemover extends AbstractCommentRemover {
3436

35-
public JcpCommentsRemover(final Reader src, final Writer dst,
36-
final boolean whiteSpaceAllowed) {
37+
public JcpCommentLineRemover(final Reader src, final Writer dst,
38+
final boolean whiteSpaceAllowed) {
3739
super(src, dst, whiteSpaceAllowed);
3840
}
3941

40-
private void skipUntilNextString() throws IOException {
41-
while (!Thread.currentThread().isInterrupted()) {
42-
final int chr = srcReader.read();
43-
if (chr < 0) {
44-
return;
45-
}
46-
47-
if (chr == '\n') {
48-
this.dstWriter.write(chr);
49-
return;
50-
}
51-
}
52-
}
53-
54-
private void skipUntilClosingComments() throws IOException {
55-
boolean starFound = false;
56-
57-
while (!Thread.currentThread().isInterrupted()) {
58-
final int chr = srcReader.read();
59-
if (chr < 0) {
60-
return;
61-
}
62-
if (starFound) {
63-
if (chr == '/') {
64-
return;
65-
} else {
66-
starFound = chr == '*';
67-
}
68-
} else if (chr == '*') {
69-
starFound = true;
70-
}
71-
}
72-
}
73-
74-
7542
@Override
7643
public Writer process() throws IOException {
7744
final int STATE_NORMAL = 0;
7845
final int STATE_INSIDE_STRING = 1;
7946
final int STATE_NEXT_SPECIAL_CHAR = 2;
8047
final int STATE_FORWARD_SLASH = 3;
48+
final int STATE_POSSIBLE_JCP = 4;
49+
50+
final StringBuilder jcpBuffer = new StringBuilder();
8151

8252
int state = STATE_NORMAL;
8353

@@ -106,16 +76,40 @@ public Writer process() throws IOException {
10676
}
10777
}
10878
break;
79+
case STATE_POSSIBLE_JCP: {
80+
switch (chr) {
81+
case '$':
82+
case '#': {
83+
jcpBuffer.setLength(0);
84+
skipTillNextString();
85+
state = STATE_NORMAL;
86+
}
87+
break;
88+
default: {
89+
if (Character.isSpaceChar(chr) && this.whiteSpaceAllowed) {
90+
jcpBuffer.append((char) chr);
91+
} else {
92+
this.dstWriter.write(jcpBuffer.toString());
93+
this.dstWriter.write(chr);
94+
jcpBuffer.setLength(0);
95+
this.copyTillNextString();
96+
state = STATE_NORMAL;
97+
}
98+
}
99+
}
100+
}
101+
break;
109102
case STATE_FORWARD_SLASH: {
110103
switch (chr) {
111104
case '*': {
112-
skipUntilClosingComments();
105+
this.dstWriter.write("/*");
106+
copyTillClosingJavaComments();
113107
state = STATE_NORMAL;
114108
}
115109
break;
116110
case '/': {
117-
skipUntilNextString();
118-
state = STATE_NORMAL;
111+
jcpBuffer.append("//");
112+
state = STATE_POSSIBLE_JCP;
119113
}
120114
break;
121115
default: {
@@ -140,18 +134,21 @@ public Writer process() throws IOException {
140134
default:
141135
break;
142136
}
143-
dstWriter.write(chr);
137+
this.dstWriter.write(chr);
144138
}
145139
break;
146140
case STATE_NEXT_SPECIAL_CHAR: {
147-
dstWriter.write(chr);
141+
this.dstWriter.write(chr);
148142
state = STATE_INSIDE_STRING;
149143
}
150144
break;
151145
default:
152146
throw new IllegalStateException("Unexpected state: " + state);
153147
}
154148
}
155-
return dstWriter;
149+
if (jcpBuffer.length() > 0) {
150+
this.dstWriter.write(jcpBuffer.toString());
151+
}
152+
return this.dstWriter;
156153
}
157154
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.igormaznitsa.jcp.removers;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.fail;
5+
6+
import java.io.IOException;
7+
import java.io.Reader;
8+
import java.io.StringReader;
9+
import java.io.StringWriter;
10+
import java.io.Writer;
11+
import java.util.Arrays;
12+
import java.util.Collection;
13+
import org.junit.runner.RunWith;
14+
import org.junit.runners.Parameterized;
15+
16+
@RunWith(Parameterized.class)
17+
public abstract class AbstractCommentRemoverTest {
18+
protected final boolean whiteSpaced;
19+
20+
public AbstractCommentRemoverTest(final boolean whiteSpaced) {
21+
this.whiteSpaced = whiteSpaced;
22+
}
23+
24+
@Parameterized.Parameters
25+
public static Collection<Boolean> data() {
26+
return Arrays.asList(Boolean.FALSE, Boolean.TRUE);
27+
}
28+
29+
protected abstract AbstractCommentRemover makeCommentRemoverInstance(Reader reader, Writer writer,
30+
boolean whiteSpaceAllowed);
31+
32+
public void assertCommentRemove(final String source, final String expected) {
33+
final Reader sourceReader = new StringReader(source);
34+
final Writer writer = new StringWriter();
35+
final AbstractCommentRemover remover =
36+
this.makeCommentRemoverInstance(sourceReader, writer, this.whiteSpaced);
37+
try (Writer resultWriter = remover.process()) {
38+
assertEquals(expected, resultWriter.toString());
39+
} catch (IOException ex) {
40+
fail("Unexpected error: " + ex.getMessage());
41+
}
42+
}
43+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2002-2019 Igor Maznitsa (http://www.igormaznitsa.com)
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
package com.igormaznitsa.jcp.removers;
23+
24+
import java.io.Reader;
25+
import java.io.Writer;
26+
import org.junit.Test;
27+
28+
public class CStyleCommentsRemoverTest extends AbstractCommentRemoverTest {
29+
30+
public CStyleCommentsRemoverTest(boolean whiteSpaced) {
31+
super(whiteSpaced);
32+
}
33+
34+
@Override
35+
protected AbstractCommentRemover makeCommentRemoverInstance(final Reader reader,
36+
final Writer writer,
37+
final boolean whiteSpaceAllowed) {
38+
return new CStyleCommentRemover(reader, writer, whiteSpaceAllowed);
39+
}
40+
41+
@Test
42+
public void testRemovingSingleStringComments() throws Exception {
43+
this.assertCommentRemove(
44+
"class main() {\n// hello world\nSystem.out.println(\"hello // world\");// a comment\n}",
45+
"class main() {\n\nSystem.out.println(\"hello // world\");\n}");
46+
}
47+
48+
@Test
49+
public void testMultilineStringComments() throws Exception {
50+
this.assertCommentRemove(
51+
"class main() {/**\ntest\n*/\n\n// hello world\nSystem.out.println(\"hello /*ooo*/ world\");/* a comment*/\n/* aslajdhkajhdkqwiueyoqiweuoqwueoqwiue}",
52+
"class main() {\n\n\nSystem.out.println(\"hello /*ooo*/ world\");\n");
53+
}
54+
55+
@Test
56+
public void testMultipleStarsAtComments() throws Exception {
57+
this.assertCommentRemove(
58+
"class main() {/**\ntest\n**/\n\n// hello world\nSystem.out.println(/**** some *** comment** ***/\"hello /*ooo*/ world\"/**** some *** comment*/);/* a comment*/\n/* aslajdhkajhdkqwiueyoqiweuoqwueoqwiue}",
59+
"class main() {\n\n\nSystem.out.println(\"hello /*ooo*/ world\");\n");
60+
}
61+
62+
@Test
63+
public void testTabulation() throws Exception {
64+
this.assertCommentRemove("\thello world();//test", "\thello world();");
65+
}
66+
67+
@Test
68+
public void testJcpDirectivesInComments() throws Exception {
69+
this.assertCommentRemove(
70+
"// hello world\n//#if DEBUG\nSystem.out.println(\"DEBUG\");\n//#else\nSystem.out.println(\"RELEASE\");\n//#endif\n// end",
71+
"\n\nSystem.out.println(\"DEBUG\");\n\nSystem.out.println(\"RELEASE\");\n\n"
72+
);
73+
}
74+
75+
@Test
76+
public void testLineCommentInTheEnd() throws Exception {
77+
this.assertCommentRemove("\thello world();//test\n// Hello", "\thello world();\n");
78+
}
79+
}

0 commit comments

Comments
 (0)