From 3b8d7a32a7a57723cdfcb83d824d53c50138d0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 7 Mar 2022 19:59:50 +0100 Subject: [PATCH] Cleanups --- .../ast/impl/javacc/CharStreamFactory.java | 29 +--- .../pmd/lang/document/TextRegion.java | 6 +- .../pmd/lang/document/CharsTest.java | 161 ++++++++++-------- .../pmd/lang/document/TextDocumentTest.java | 14 ++ .../net/sourceforge/pmd/cpd/CPPTokenizer.java | 2 +- .../pmd/lang/cpp/ast/CppCharStream.java | 6 +- .../sourceforge/pmd/cpd/JavaTokenizer.java | 2 +- .../sourceforge/pmd/cpd/PythonTokenizer.java | 3 +- 8 files changed, 119 insertions(+), 104 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/CharStreamFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/CharStreamFactory.java index d9fb97d693..ef409157d0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/CharStreamFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/CharStreamFactory.java @@ -23,15 +23,17 @@ public final class CharStreamFactory { /** * A char stream that doesn't perform any escape translation. */ - public static CharStream simpleCharStream(Reader input) { + public static CharStream simpleCharStream(Reader input) throws IOException { return simpleCharStream(input, JavaccTokenDocument::new); } /** * A char stream that doesn't perform any escape translation. */ - public static CharStream simpleCharStream(Reader input, Function documentMaker) { - String source = toString(input); + public static CharStream simpleCharStream(Reader input, + Function documentMaker) + throws IOException { + String source = IOUtils.toString(input); JavaccTokenDocument document = documentMaker.apply(TextDocument.readOnlyString(source, CpdCompat.dummyVersion())); return new SimpleCharStream(document); } @@ -39,31 +41,18 @@ public final class CharStreamFactory { /** * A char stream that translates java unicode sequences. */ - public static CharStream javaCharStream(Reader input) { + public static CharStream javaCharStream(Reader input) throws IOException { return javaCharStream(input, JavaccTokenDocument::new); } /** * A char stream that translates java unicode sequences. */ - public static CharStream javaCharStream(Reader input, Function documentMaker) { - String source = toString(input); + public static CharStream javaCharStream(Reader input, Function documentMaker) + throws IOException { + String source = IOUtils.toString(input); JavaccTokenDocument tokens = documentMaker.apply(TextDocument.readOnlyString(source, CpdCompat.dummyVersion())); return new JavaCharStream(tokens); } - /** - * @deprecated This shouldn't be used. IOExceptions should be handled properly, - * ie it should be expected that creating a parse may throw an IOException, - * in both CPD and PMD - */ - @Deprecated - public static String toString(Reader dstream) { - try (Reader r = dstream) { - return IOUtils.toString(r); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java index ff3b4c210d..d62454224f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextRegion.java @@ -119,8 +119,7 @@ public final class TextRegion implements Comparable { * characters before this region. If the delta is negative, then this * shifts the start of the region to the right (but the end stays fixed). * - * @throws AssertionError If startOffset - delta is negative - * @throws AssertionError If delta is negative and the + * @throws AssertionError If the parameter cannot produce a valid region */ public TextRegion growLeft(int delta) { assert (delta + length) >= 0 : "Left delta " + delta + " would produce a negative length region" + parThis(); @@ -148,8 +147,7 @@ public final class TextRegion implements Comparable { * * @return The intersection, if it exists */ - @Nullable - public static TextRegion intersect(TextRegion r1, TextRegion r2) { + public static @Nullable TextRegion intersect(TextRegion r1, TextRegion r2) { int start = Math.max(r1.getStartOffset(), r2.getStartOffset()); int end = Math.min(r1.getEndOffset(), r2.getEndOffset()); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/CharsTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/CharsTest.java index b15b9ea1b3..762bf68b2a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/CharsTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/CharsTest.java @@ -5,12 +5,18 @@ package net.sourceforge.pmd.lang.document; import static net.sourceforge.pmd.util.CollectionUtil.listOf; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.StringWriter; import java.util.List; -import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.util.CollectionUtil; @@ -23,46 +29,46 @@ public class CharsTest { @Test public void wrapStringRoundTrip() { String s = "ooo"; - Assert.assertSame(s, Chars.wrap(s).toString()); + assertSame(s, Chars.wrap(s).toString()); } @Test public void wrapCharsRoundTrip() { Chars s = Chars.wrap("ooo"); - Assert.assertSame(s, Chars.wrap(s)); + assertSame(s, Chars.wrap(s)); } @Test public void appendChars() { StringBuilder sb = new StringBuilder(); Chars bc = Chars.wrap("abcd").slice(1, 2); - Assert.assertEquals("bc", bc.toString()); + assertEquals("bc", bc.toString()); bc.appendChars(sb); - Assert.assertEquals("bc", sb.toString()); + assertEquals("bc", sb.toString()); } @Test public void appendCharsWithOffsets() { StringBuilder sb = new StringBuilder(); Chars bc = Chars.wrap("abcd").slice(1, 2); - Assert.assertEquals("bc", bc.toString()); + assertEquals("bc", bc.toString()); bc.appendChars(sb, 0, 1); - Assert.assertEquals("b", sb.toString()); + assertEquals("b", sb.toString()); } @Test public void write() throws IOException { StringWriter writer = new StringWriter(); Chars bc = Chars.wrap("abcd").slice(1, 2); - Assert.assertEquals("bc", bc.toString()); + assertEquals("bc", bc.toString()); bc.write(writer, 0, 1); - Assert.assertEquals("b", writer.toString()); + assertEquals("b", writer.toString()); writer = new StringWriter(); bc.writeFully(writer); - Assert.assertEquals("bc", writer.toString()); + assertEquals("bc", writer.toString()); } @Test @@ -71,97 +77,97 @@ public class CharsTest { Chars bc = Chars.wrap("abcd").slice(1, 2); bc.getChars(0, arr, 1, 2); - Assert.assertArrayEquals(arr, new char[] {0, 'b', 'c', 0}); + assertArrayEquals(arr, new char[] {0, 'b', 'c', 0}); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(2, arr, 0, 1)); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(-1, arr, 0, 1)); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(0, arr, 0, 3)); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(0, arr, 4, 3)); - Assert.assertThrows(NullPointerException.class, () -> bc.getChars(0, null, 0, 0)); + assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(2, arr, 0, 1)); + assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(-1, arr, 0, 1)); + assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(0, arr, 0, 3)); + assertThrows(IndexOutOfBoundsException.class, () -> bc.getChars(0, arr, 4, 3)); + assertThrows(NullPointerException.class, () -> bc.getChars(0, null, 0, 0)); } @Test public void indexOf() { Chars bc = Chars.wrap("aaaaabcdb").slice(5, 2); // -- - Assert.assertEquals(0, bc.indexOf('b', 0)); - Assert.assertEquals(1, bc.indexOf('c', 0)); + assertEquals(0, bc.indexOf('b', 0)); + assertEquals(1, bc.indexOf('c', 0)); - Assert.assertEquals(-1, bc.indexOf('b', 1)); - Assert.assertEquals(-1, bc.indexOf('d', 0)); + assertEquals(-1, bc.indexOf('b', 1)); + assertEquals(-1, bc.indexOf('d', 0)); - Assert.assertEquals(-1, bc.indexOf('x', 0)); - Assert.assertEquals(-1, bc.indexOf('a', -1)); + assertEquals(-1, bc.indexOf('x', 0)); + assertEquals(-1, bc.indexOf('a', -1)); } @Test public void indexOfString() { Chars bc = Chars.wrap("aaaaabcdb").slice(5, 2); // -- - Assert.assertEquals(0, bc.indexOf("b", 0)); - Assert.assertEquals(0, bc.indexOf("bc", 0)); - Assert.assertEquals(1, bc.indexOf("c", 0)); + assertEquals(0, bc.indexOf("b", 0)); + assertEquals(0, bc.indexOf("bc", 0)); + assertEquals(1, bc.indexOf("c", 0)); - Assert.assertEquals(-1, bc.indexOf("b", 1)); - Assert.assertEquals(-1, bc.indexOf("bc", 1)); - Assert.assertEquals(-1, bc.indexOf("d", 0)); - Assert.assertEquals(-1, bc.indexOf("bcd", 0)); + assertEquals(-1, bc.indexOf("b", 1)); + assertEquals(-1, bc.indexOf("bc", 1)); + assertEquals(-1, bc.indexOf("d", 0)); + assertEquals(-1, bc.indexOf("bcd", 0)); - Assert.assertEquals(-1, bc.indexOf("x", 0)); - Assert.assertEquals(-1, bc.indexOf("ab", -1)); + assertEquals(-1, bc.indexOf("x", 0)); + assertEquals(-1, bc.indexOf("ab", -1)); bc = Chars.wrap("aaaaabcdbxdb").slice(5, 5); // ----- - Assert.assertEquals(3, bc.indexOf("bx", 0)); + assertEquals(3, bc.indexOf("bx", 0)); bc = Chars.wrap("aaaaabcbxdb").slice(5, 5); // ----- - Assert.assertEquals(2, bc.indexOf("bx", 0)); + assertEquals(2, bc.indexOf("bx", 0)); } @Test public void startsWith() { Chars bc = Chars.wrap("abcdb").slice(1, 2); - Assert.assertTrue(bc.startsWith("bc")); - Assert.assertTrue(bc.startsWith("bc", 0)); - Assert.assertTrue(bc.startsWith("c", 1)); - Assert.assertTrue(bc.startsWith('c', 1)); //with a char - Assert.assertTrue(bc.startsWith("", 1)); - Assert.assertTrue(bc.startsWith("", 0)); + assertTrue(bc.startsWith("bc")); + assertTrue(bc.startsWith("bc", 0)); + assertTrue(bc.startsWith("c", 1)); + assertTrue(bc.startsWith('c', 1)); //with a char + assertTrue(bc.startsWith("", 1)); + assertTrue(bc.startsWith("", 0)); - Assert.assertFalse(bc.startsWith("c", 0)); - Assert.assertFalse(bc.startsWith('c', 0)); //with a char + assertFalse(bc.startsWith("c", 0)); + assertFalse(bc.startsWith('c', 0)); //with a char - Assert.assertFalse(bc.startsWith("bcd", 0)); - Assert.assertFalse(bc.startsWith("xcd", 0)); + assertFalse(bc.startsWith("bcd", 0)); + assertFalse(bc.startsWith("xcd", 0)); - Assert.assertFalse(bc.startsWith("b", -1)); - Assert.assertFalse(bc.startsWith('b', -1)); //with a char + assertFalse(bc.startsWith("b", -1)); + assertFalse(bc.startsWith('b', -1)); //with a char - Assert.assertFalse(bc.startsWith("", -1)); - Assert.assertFalse(bc.startsWith("", 5)); + assertFalse(bc.startsWith("", -1)); + assertFalse(bc.startsWith("", 5)); } @Test public void trimNoop() { Chars bc = Chars.wrap("abcdb").slice(1, 2); - Assert.assertEquals("bc", bc.toString()); - Assert.assertEquals("bc", bc.trimStart().toString()); - Assert.assertEquals("bc", bc.trimEnd().toString()); - Assert.assertEquals("bc", bc.trim().toString()); + assertEquals("bc", bc.toString()); + assertEquals("bc", bc.trimStart().toString()); + assertEquals("bc", bc.trimEnd().toString()); + assertEquals("bc", bc.trim().toString()); } @Test public void trimStartAndEnd() { Chars bc = Chars.wrap("a bc db").slice(1, 6); // ------ - Assert.assertEquals(" bc ", bc.toString()); - Assert.assertEquals("bc ", bc.trimStart().toString()); - Assert.assertEquals(" bc", bc.trimEnd().toString()); - Assert.assertEquals("bc", bc.trim().toString()); + assertEquals(" bc ", bc.toString()); + assertEquals("bc ", bc.trimStart().toString()); + assertEquals(" bc", bc.trimEnd().toString()); + assertEquals("bc", bc.trim().toString()); } @Test @@ -169,12 +175,12 @@ public class CharsTest { Chars bc = Chars.wrap("a bc db").slice(1, 6); // ------ - Assert.assertEquals(' ', bc.charAt(0)); - Assert.assertEquals('b', bc.charAt(3)); - Assert.assertEquals('c', bc.charAt(4)); - Assert.assertEquals(' ', bc.charAt(5)); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.charAt(-1)); - Assert.assertThrows(IndexOutOfBoundsException.class, () -> bc.charAt(7)); + assertEquals(' ', bc.charAt(0)); + assertEquals('b', bc.charAt(3)); + assertEquals('c', bc.charAt(4)); + assertEquals(' ', bc.charAt(5)); + assertThrows(IndexOutOfBoundsException.class, () -> bc.charAt(-1)); + assertThrows(IndexOutOfBoundsException.class, () -> bc.charAt(7)); } @Test @@ -183,7 +189,14 @@ public class CharsTest { Chars bc = Chars.wrap("a \n \r\nbc db").slice(1, 9); // ------------ List lines = CollectionUtil.map(bc.lines(), Chars::toString); - Assert.assertEquals(listOf(" ", " ", "bc "), lines); + assertEquals(listOf(" ", " ", "bc "), lines); + } + + @Test + public void linesTest2() { + Chars bc = Chars.wrap("aa\n"); + List lines = CollectionUtil.map(bc.lines(), Chars::toString); + assertEquals(listOf("aa"), lines); } @Test @@ -192,14 +205,14 @@ public class CharsTest { Chars chars = Chars.wrap("a_a_b_c_s").slice(2, 5); // ----- - Assert.assertEquals(Chars.wrap("a_b_c"), chars); - Assert.assertNotEquals("a_b_c", chars); + assertEquals(Chars.wrap("a_b_c"), chars); + assertNotEquals("a_b_c", chars); - Assert.assertEquals(Chars.wrap("a_b_c").hashCode(), chars.hashCode()); - Assert.assertEquals(chars, chars); + assertEquals(Chars.wrap("a_b_c").hashCode(), chars.hashCode()); + assertEquals(chars, chars); - Assert.assertEquals("a_b_c".hashCode(), Chars.wrap("a_b_c").hashCode()); - Assert.assertEquals("a_b_c".hashCode(), chars.hashCode()); + assertEquals("a_b_c".hashCode(), Chars.wrap("a_b_c").hashCode()); + assertEquals("a_b_c".hashCode(), chars.hashCode()); } @@ -209,14 +222,14 @@ public class CharsTest { Chars chars = Chars.wrap("a_a_b_c_s").slice(2, 5); // ----- - Assert.assertTrue(chars.contentEquals("a_b_c")); - Assert.assertTrue(chars.contentEquals(Chars.wrap("a_b_c"))); + assertTrue(chars.contentEquals("a_b_c")); + assertTrue(chars.contentEquals(Chars.wrap("a_b_c"))); - Assert.assertFalse(chars.contentEquals("a_b_c_--")); - Assert.assertFalse(chars.contentEquals(Chars.wrap("a_b_c_"))); - Assert.assertFalse(chars.contentEquals(Chars.wrap("a_b-c"))); + assertFalse(chars.contentEquals("a_b_c_--")); + assertFalse(chars.contentEquals(Chars.wrap("a_b_c_"))); + assertFalse(chars.contentEquals(Chars.wrap("a_b-c"))); - Assert.assertTrue(chars.contentEquals(Chars.wrap("A_B_C"), true)); + assertTrue(chars.contentEquals(Chars.wrap("A_B_C"), true)); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextDocumentTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextDocumentTest.java index e7b1c23781..af8bb8894a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextDocumentTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextDocumentTest.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.document; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import org.junit.Rule; import org.junit.Test; @@ -139,6 +140,19 @@ public class TextDocumentTest { assertEquals(1 + "bonjour".length(), withLines.getEndColumn()); } + @Test + public void testLineRange() { + TextDocument doc = TextDocument.readOnlyString("bonjour\noha\ntristesse", dummyVersion); + + assertEquals(Chars.wrap("bonjour\n"), doc.sliceText(doc.createLineRange(1, 1))); + assertEquals(Chars.wrap("bonjour\noha\n"), doc.sliceText(doc.createLineRange(1, 2))); + assertEquals(Chars.wrap("oha\n"), doc.sliceText(doc.createLineRange(2, 2))); + assertEquals(Chars.wrap("oha\ntristesse"), doc.sliceText(doc.createLineRange(2, 3))); + assertThrows(IndexOutOfBoundsException.class, () -> doc.createLineRange(2, 1)); + assertThrows(IndexOutOfBoundsException.class, () -> doc.createLineRange(1, 5)); + assertThrows(IndexOutOfBoundsException.class, () -> doc.createLineRange(0, 2)); + } + @Test public void testRegionOutOfBounds() { TextDocument doc = TextDocument.readOnlyString("bonjour\noha\ntristesse", dummyVersion); diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java index 3649a46ad8..6593706b55 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java @@ -86,7 +86,7 @@ public class CPPTokenizer extends JavaCCTokenizer { @Override - protected CharStream makeCharStream(Reader sourceCode) { + protected CharStream makeCharStream(Reader sourceCode) throws IOException { return CppCharStream.newCppCharStream(sourceCode); } diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/ast/CppCharStream.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/ast/CppCharStream.java index aeb7422477..0f42fd5f08 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/ast/CppCharStream.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/lang/cpp/ast/CppCharStream.java @@ -8,9 +8,9 @@ import java.io.IOException; import java.io.Reader; import java.util.regex.Pattern; +import org.apache.commons.io.IOUtils; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.lang.ast.impl.javacc.CharStreamFactory; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccTokenDocument; import net.sourceforge.pmd.lang.ast.impl.javacc.SimpleCharStream; import net.sourceforge.pmd.lang.document.CpdCompat; @@ -67,8 +67,8 @@ public class CppCharStream extends SimpleCharStream { return CONTINUATION.matcher(image).replaceAll(""); } - public static CppCharStream newCppCharStream(Reader dstream) { - String source = CharStreamFactory.toString(dstream); + public static CppCharStream newCppCharStream(Reader dstream) throws IOException { + String source = IOUtils.toString(dstream); JavaccTokenDocument document = new JavaccTokenDocument(TextDocument.readOnlyString(source, CpdCompat.dummyVersion())) { @Override protected @Nullable String describeKindImpl(int kind) { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java index b57c509d2e..bf27ea61b0 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java @@ -44,7 +44,7 @@ public class JavaTokenizer extends JavaCCTokenizer { } @Override - protected CharStream makeCharStream(Reader sourceCode) { + protected CharStream makeCharStream(Reader sourceCode) throws IOException { return CharStreamFactory.javaCharStream(sourceCode, InternalApiBridge::javaTokenDoc); } diff --git a/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java b/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java index e923325703..65b651e9f4 100644 --- a/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java +++ b/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.cpd; +import java.io.IOException; import java.io.Reader; import java.util.regex.Pattern; @@ -31,7 +32,7 @@ public class PythonTokenizer extends JavaCCTokenizer { } @Override - protected CharStream makeCharStream(Reader sourceCode) { + protected CharStream makeCharStream(Reader sourceCode) throws IOException { return CharStreamFactory.simpleCharStream(sourceCode, PythonTokenDocument::new); }