diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java index 8f4888588ae2..df49c0cbd753 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java @@ -49,9 +49,12 @@ import java.text.StringCharacterIterator; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Pattern; @SuppressWarnings({"HardCodedStringLiteral"}) public class ClsStubBuilder { + private static final Pattern REGEX_PATTERN = Pattern.compile("(?<=[^\\$])\\${1}(?=[^\\$])"); + private ClsStubBuilder() { } @@ -677,6 +680,12 @@ public class ClsStubBuilder { private static String getTypeText(final Type type) { final String raw = type.getClassName(); - return raw.replace('$', '.'); + // As the '$' char is a valid java identifier and is actively used by bytecode genarators, the problem is + // which occurrences of this char should be replaced and which should not. + // Heuristic: replace only those $ occurrences that are surrounded non-"$" chars + // (most likely generated by javac to separate inner or anonymoys class name) + // Leading and trailing $ chars should be left unchanged. + return raw.contains("$")? REGEX_PATTERN.matcher(raw).replaceAll("\\.") : raw; } + }