Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,72 @@ private void mat() {
selected
);
}


// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/4218
// IAE at org.eclipse.jdt.core.Signature.encodeQualifiedName" on hyperlink request
public void testIssue4218() throws CoreException {
this.wc = getWorkingCopy("/Resolve/src/Test.java",
"""
@FunctionalInterface
interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
public class Test {

public static <T> void createObjectBinding(final Callable<T> func) {
return;
}

sealed interface Index {
enum SS implements Index {}
enum TS implements Index {}
}

public abstract sealed class Entity<S extends Index> permits Struct, Time {}

final class Struct extends Entity<Index.SS> {}

final class Time extends Entity<Index.TS> {

Struct getStruct() {
return null;
}

public Object getOther() {
return null;
}
}

private <T> T createMap(Object other) {
return null;
}

private void setMaterials(Time entity) {
var selfIllumImage = createObjectBinding(() -> {
var entity2 = entity.getStruct() == null ? entity : entity.getStruct();
return createMap(entity.getOther());
});
}
}
""");
String str = this.wc.getSource();
String selection = "entity2";
int start = str.lastIndexOf(selection);
int length = selection.length();

IJavaElement[] selected = this.wc.codeSelect(start, length);
assertEquals(1, selected.length);
assertElementsEqual(
"Unexpected elements",
"entity2 [in call() [in <lambda #1> [in setMaterials(Time) [in Entity [in Test [in [Working copy] Test.java [in <default> [in src [in Resolve]]]]]]]]]",
selected
);
}
}
58 changes: 27 additions & 31 deletions org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
Original file line number Diff line number Diff line change
Expand Up @@ -1501,46 +1501,42 @@ private static int encodeTypeSignature(char[] typeName, int start, boolean isRes
end = -1;
}
buffer.append(isResolved ? C_RESOLVED : C_UNRESOLVED);
while (true) { // loop on type[&type]*
while (true) { // loop on qualifiedName[<args>][.qualifiedName[<args>]*
pos = encodeQualifiedName(typeName, pos, length, buffer);
checkPos = checkNextChar(typeName, '<', pos, length, true);
if (checkPos > 0) {
buffer.append(C_GENERIC_START);
// Stop gap fix for <>.
if ((pos = checkNextChar(typeName, '>', checkPos, length, true)) > 0) {
buffer.append(C_GENERIC_END);
} else {

while (true) { // loop on qualifiedName[<args>][.qualifiedName[<args>]*
pos = encodeQualifiedName(typeName, pos, length, buffer);
checkPos = checkNextChar(typeName, '<', pos, length, true);
if (checkPos > 0) {
buffer.append(C_GENERIC_START);
// Stop gap fix for <>.
if ((pos = checkNextChar(typeName, '>', checkPos, length, true)) > 0) {
buffer.append(C_GENERIC_END);
} else {
pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
while ((checkPos = checkNextChar(typeName, ',', pos, length, true)) > 0) {
pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
while ((checkPos = checkNextChar(typeName, ',', pos, length, true)) > 0) {
pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
}
pos = checkNextChar(typeName, '>', pos, length, false);
buffer.append(C_GENERIC_END);
}
}
checkPos = checkNextChar(typeName, '.', pos, length, true);
if (checkPos > 0) {
buffer.append(C_DOT);
pos = checkPos;
} else {
break;
pos = checkNextChar(typeName, '>', pos, length, false);
buffer.append(C_GENERIC_END);
}
}
buffer.append(C_NAME_END);
checkPos = checkNextChar(typeName, '&', pos, length, true);
checkPos = checkNextChar(typeName, '.', pos, length, true);
if (checkPos > 0) {
if (buffer.charAt(0) != C_UNION) // the constant name is wrong, its value is correct :-X
buffer.insert(0, C_UNION);
buffer.append(C_COLON);
pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
if (pos == length) {
break;
}
buffer.append(C_DOT);
pos = checkPos;
} else {
break;
}
}
buffer.append(C_NAME_END);
while ((checkPos = checkNextChar(typeName, '&', pos, length, true)) > 0) {
if (buffer.charAt(0) != C_UNION) // the constant name is wrong, its value is correct :-X
buffer.insert(0, C_UNION);
buffer.append(C_COLON);
pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
if (pos == length) {
break;
}
}
if (end > 0) pos = end; // skip array dimension which were preprocessed
return pos;
}
Expand Down
Loading