diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/document/Chars.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/document/Chars.java index ff198926a5..00be3c739a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/document/Chars.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/document/Chars.java @@ -155,17 +155,47 @@ public final class Chars implements CharSequence { /** * See {@link String#indexOf(String, int)}. */ - public int indexOf(String s, int fromIndex) { - int res = str.indexOf(s, idx(fromIndex)) - start; - return res >= len ? -1 : res; + public int indexOf(String searched, int fromIndex) { + // max index in the string at which the search string may start + final int max = start + len - searched.length(); + + if (fromIndex < 0 || max < start + fromIndex) { + return -1; + } else if (searched.isEmpty()) { + return 0; + } + + final char fst = searched.charAt(0); + int strpos = str.indexOf(fst, start + fromIndex); + while (strpos != -1 && strpos <= max) { + if (str.startsWith(searched, strpos)) { + return strpos - start; + } + strpos = str.indexOf(fst, strpos + 1); + } + return -1; } /** * See {@link String#indexOf(int, int)}. */ public int indexOf(int ch, int fromIndex) { - int res = str.indexOf(ch, idx(fromIndex)) - start; - return res >= len ? -1 : res; + if (fromIndex < 0 || fromIndex >= len) { + return -1; + } + // we want to avoid searching too far in the string + // so we don't use String#indexOf, as it would be looking + // in the rest of the file too, which in the worst case is + // horrible + + int max = start + len; + for (int i = start + fromIndex; i < max; i++) { + char c = str.charAt(i); + if (c == ch) { + return i - start; + } + } + return -1; } /** @@ -402,7 +432,7 @@ public final class Chars implements CharSequence { setNext(subSequence(pos, max)); pos = max; return; - } else if (startsWith("\r", nl - 1)) { + } else if (startsWith('\r', nl - 1)) { setNext(subSequence(pos, nl - 1)); } else { setNext(subSequence(pos, nl)); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/util/document/CharsTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/util/document/CharsTest.java index 7f3ceebfa3..3e161db8d1 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/util/document/CharsTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/util/document/CharsTest.java @@ -42,12 +42,41 @@ public class CharsTest { @Test public void indexOf() { - Chars bc = Chars.wrap("abcdb").slice(1, 2); + Chars bc = Chars.wrap("aaaaabcdb").slice(5, 2); + // -- Assert.assertEquals(0, bc.indexOf('b', 0)); Assert.assertEquals(1, bc.indexOf('c', 0)); Assert.assertEquals(-1, bc.indexOf('b', 1)); Assert.assertEquals(-1, bc.indexOf('d', 0)); + + Assert.assertEquals(-1, bc.indexOf('x', 0)); + Assert.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)); + + 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)); + + Assert.assertEquals(-1, bc.indexOf("x", 0)); + Assert.assertEquals(-1, bc.indexOf("ab", -1)); + + bc = Chars.wrap("aaaaabcdbxdb").slice(5, 5); + // ----- + Assert.assertEquals(3, bc.indexOf("bx", 0)); + + bc = Chars.wrap("aaaaabcbxdb").slice(5, 5); + // ----- + Assert.assertEquals(2, bc.indexOf("bx", 0)); } @Test @@ -63,6 +92,7 @@ public class CharsTest { Assert.assertFalse(bc.startsWith("c", 0)); Assert.assertFalse(bc.startsWith("bcd", 0)); + Assert.assertFalse(bc.startsWith("xcd", 0)); Assert.assertFalse(bc.startsWith("b", -1)); Assert.assertFalse(bc.startsWith("", -1)); Assert.assertFalse(bc.startsWith("", 5)); diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java index e99f8614dc..62cdb3f534 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/AbstractPLSQLNode.java @@ -47,20 +47,6 @@ abstract class AbstractPLSQLNode extends AbstractJjtreeNode