diff --git a/core/src/main/java/org/jboss/jandex/NameTable.java b/core/src/main/java/org/jboss/jandex/NameTable.java index 1cb5be82..44fb348d 100644 --- a/core/src/main/java/org/jboss/jandex/NameTable.java +++ b/core/src/main/java/org/jboss/jandex/NameTable.java @@ -45,7 +45,7 @@ DotName convertToName(String name, char delim) { if (result != null) return result; - int loc = lastIndexOf(name, delim, '$'); + int loc = lastIndexOf(name, delim); String local = intern(name.substring(loc + 1)); DotName prefix = loc < 1 ? null : convertToName(intern(name.substring(0, loc)), delim); result = new DotName(prefix, local, true, loc > 0 && name.charAt(loc) == '$'); @@ -55,16 +55,23 @@ DotName convertToName(String name, char delim) { return result; } - private int lastIndexOf(String name, char delim1, char delim2) { + private int lastIndexOf(String name, char delim) { // Begin at second last position to avoid empty local name int pos = name.length() - 1; while (--pos >= 0) { char c = name.charAt(pos); - if (c == delim1 || c == delim2) { + if (c == delim || c == '$') { break; } } + // avoid splitting on '$' if previous char is a delimiter or the '$' + // is in position 0, because subsequent split would produce an empty + // local name + if (pos >=0 && name.charAt(pos) == '$' && (pos == 0 || name.charAt(pos - 1) == delim)) { + pos--; + } + return pos; } diff --git a/core/src/test/java/$delimiters$/test/$SurroundedByDelimiters$.java b/core/src/test/java/$delimiters$/test/$SurroundedByDelimiters$.java new file mode 100644 index 00000000..0cf9ecc2 --- /dev/null +++ b/core/src/test/java/$delimiters$/test/$SurroundedByDelimiters$.java @@ -0,0 +1,5 @@ +package $delimiters$.test; + +public class $SurroundedByDelimiters$ { + +} diff --git a/core/src/test/java/$pkg/test/$LeadingDelimiter.java b/core/src/test/java/$pkg/test/$LeadingDelimiter.java new file mode 100644 index 00000000..0a837f13 --- /dev/null +++ b/core/src/test/java/$pkg/test/$LeadingDelimiter.java @@ -0,0 +1,5 @@ +package $pkg.test; + +public class $LeadingDelimiter { + +} diff --git a/core/src/test/java/org/jboss/jandex/test/DotNameTestCase.java b/core/src/test/java/org/jboss/jandex/test/DotNameTestCase.java index 102339a7..d08b13e3 100644 --- a/core/src/test/java/org/jboss/jandex/test/DotNameTestCase.java +++ b/core/src/test/java/org/jboss/jandex/test/DotNameTestCase.java @@ -33,6 +33,8 @@ import org.junit.Assert; import org.junit.Test; +import $pkg.test.$LeadingDelimiter; + /** * Since DotName is often used as a key in collections and implements Comparable, * make sure the #compareTo, hashCode, equals and toString are strictly consistent. @@ -231,6 +233,33 @@ public static class Test$ { } + @Test + public void testLeadingInnerClassDelimiterOnClass() throws IOException { + DotName pkg = DotName.createComponentized(null, "$pkg"); + DotName test = DotName.createComponentized(pkg, "test"); + DotName testName = DotName.createComponentized(test, $LeadingDelimiter.class.getSimpleName()); + + Index index = Index.of($LeadingDelimiter.class); + assertEquals(testName, index.getKnownClasses().iterator().next().name()); + assertNotNull(index.getClassByName(DotName.createSimple($LeadingDelimiter.class.getName()))); + assertNotNull(index.getClassByName(testName)); + } + + @Test + public void testClassNameWithDelimitersFirstAndLast() throws IOException { + DotName pkg = DotName.createComponentized(null, "$delimiters$"); + DotName test = DotName.createComponentized(pkg, "test"); + DotName testName = DotName.createComponentized(test, $delimiters$.test.$SurroundedByDelimiters$.class.getSimpleName()); + DotName testNameSimple = DotName.createSimple($delimiters$.test.$SurroundedByDelimiters$.class.getName()); + + Index index = Index.of($delimiters$.test.$SurroundedByDelimiters$.class); + DotName indexedName = index.getKnownClasses().iterator().next().name(); + assertEquals(testName, indexedName); + assertNotNull(index.getClassByName(testNameSimple)); + assertNotNull(index.getClassByName(testName)); + assertEquals("$delimiters$.test.$SurroundedByDelimiters$", indexedName.toString()); + } + private static DotName createRandomDotName() { return r.nextBoolean() ? createRandomComponentised() : createRandomSimple(); }