Issues with classes starting with $#671
Conversation
9c0f16e to
3af6d80
Compare
|
@rgrunber I have rebased the PR. |
|
Are the checks supposed to fail? |
No. There are 3 new compiler warnings https://ci.eclipse.org/jdt/job/eclipse.jdt.core-Github/job/PR-671/5/eclipse/ |
|
@snjeza Maybe fix the NLS warning here?
Specifically, this line has |
|
@robstryker @iloveeclipse I have updated the PR. |
|
The tests pass, is there anything else that needs to be done before review? |
|
Is there some other forum that should be used to request review? |
|
@iloveeclipse @stephan-herrmann @jukzi can a JDT committer give this PR some love pretty please? |
d9ab8d9 to
d3e6a46
Compare
There was a problem hiding this comment.
Pull request overview
This pull request fixes issues with Java classes whose names contain or start with the $ character, which were causing problems with code assistance, organize imports, search, and open type functionality.
Changes:
- Modified dollar sign replacement logic across multiple core classes to distinguish between
$as an inner class separator versus$as part of a legitimate class name - Added logic to preserve
$characters at the beginning/end of names and in consecutive sequences (e.g.,$$) - Fixed
ClassFile.getTypeName()to handle classes starting with$correctly by changing the condition fromlastDollar > -1tolastDollar > 0
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| ClassFileMatchLocator.java | Updated dollar-to-dot replacement logic for search functionality (has a critical bug) |
| Util.java | Added getLastDotDollar() helper and updated multiple signature processing methods to preserve $ in class names |
| NamedMember.java | Modified type name processing to preserve $ at boundaries and in consecutive sequences |
| NameLookup.java | Updated type lookup logic for both binary and source packages to handle $ correctly |
| LambdaExpression.java | Added isBinary() override to properly delegate to parent |
| ClassFile.java | Fixed getTypeName() to handle classes starting with $ by changing lastDollar comparison from > -1 to > 0 |
| BinaryType.java | Changed declaring type check from lastDollar == -1 to lastDollar <= 0 |
| Signature.java | Added getLastDotDollar() helper and updated multiple signature methods to preserve $ in class names |
| SignatureTests.java | Added comprehensive tests for classes with $ at start, end, and in consecutive sequences |
| ClassFileTests.java | Added integration tests for fully qualified names with various $ patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
Outdated
Show resolved
Hide resolved
...pse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
Outdated
Show resolved
Hide resolved
| } else { | ||
| // anonymous or local class file | ||
| typeName = classFileName.substring(0, classFileName.lastIndexOf('.'))/*remove .class*/.replace('$', enclosingTypeSeparator); | ||
| // see see https://github.com/eclipse-jdt/eclipse.jdt.core/pull/671 |
There was a problem hiding this comment.
The comment has a duplicate "see" - "see see https://...". Should be just "see https://...".
| // see see https://github.com/eclipse-jdt/eclipse.jdt.core/pull/671 | |
| // see https://github.com/eclipse-jdt/eclipse.jdt.core/pull/671 |
| for (int i = 0, length = binaryName.length; i < length; i++) { | ||
| char c = binaryName[i]; | ||
| if (c == dolar && previous != dot) { | ||
| qualifiedName[i] = dot; | ||
| } else { | ||
| qualifiedName[i] = c; | ||
| } | ||
| previous = c; | ||
| } |
There was a problem hiding this comment.
The logic has a critical flaw. It only checks if the previous character is a dot to determine whether to replace '$' with '.'. This doesn't correctly handle consecutive dollar signs. For example, with input "a.b$$.C" (representing package a.b$$ with class C), the first '$' has previous='b' (not '.'), so it gets replaced with '.', making "a.b.$.C". But consecutive dollars should both be preserved as they're part of the package/class name. The logic needs to also check if the next character is a '$' before deciding to replace. Consider using a similar approach to the other files in this PR that check both isPreviousDollar and isNextDollar.
| case C_DOLLAR: | ||
| break indexFound; | ||
| if (!isNextDollar && !isPreviousDollar && !isLastDollar && i >= lastDot) { | ||
| break indexFound; | ||
| } |
There was a problem hiding this comment.
There is significant code duplication for the logic that determines when to replace '$' with '.' (or vice versa). This same pattern appears in at least 8 different methods across Signature.java, Util.java, NameLookup.java, and NamedMember.java. Consider extracting this logic into a shared utility method to improve maintainability. A method like shouldReplaceDollarWithDot(char[] array, int index, int lastDot, int lastDollar) would reduce duplication and make the logic easier to maintain and test.
org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
Outdated
Show resolved
Hide resolved
org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
Outdated
Show resolved
Hide resolved
| // return this.typeName; | ||
| // Internal class file name doesn't contain ".class" file extension |
There was a problem hiding this comment.
There are multiple lines of commented-out code that should be removed before merging. Commented-out code makes the codebase harder to maintain and understand.
| // return this.typeName; | |
| // Internal class file name doesn't contain ".class" file extension |
| continue; | ||
| } | ||
| boolean isPrevDollar = (i > 0) ? (chars[i - 1] == '$') : false; | ||
| boolean isNextDollar = (i + 1 < chars.length) ? (chars[i + 1] == '$') : false; |
There was a problem hiding this comment.
Test is always true, because of this condition.
Test is always true, because of this condition.
There was a problem hiding this comment.
This is not correct.
See https://github.com/clembo590/issues/tree/vscode-java/issues/2219
An example
public class Main {
public static void main(String[] args) {
String name = "UndertowWebServerFactoryCustomizer$AbstractOptions";
char[] chars = name.toCharArray();
for (int i = 0; i < chars.length; i++) {
boolean isPrevDollar = (i > 0) ? (chars[i - 1] == '$') : false;
boolean isNextDollar = (i + 1 < chars.length) ? (chars[i + 1] == '$') : false;
if (chars[i] == '$' && !isNextDollar && !isPrevDollar) {
System.out.println("*** true" + " " + name + " chars[" + i + "]=" + chars[i] + " " + isPrevDollar + " "
+ isNextDollar);
} else {
System.out.println("XXX false" + " " + name + " chars[" + i + "]=" + chars[i] + " " + isPrevDollar + " "
+ isNextDollar);
}
}
}
}
|
@fbricon : I've rebased on latest & asked Copilot for review. Looks like there is a room for improvement. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
Outdated
Show resolved
Hide resolved
|
@snjeza : could you please squash two commits in one? Thanks. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
perchance is there anything else needed? |
Fixes #670
Signed-off-by: Snjezana Peco snjezana.peco@redhat.com