Skip to content

Commit

Permalink
Guard lookup in BoundSet::allSuperPairsWithCommonGenericTypeRecursive (
Browse files Browse the repository at this point in the history
…#3411)

correction:
+ use of .prototype() fails with ParameterizedTypeBinding
+ instead use the binding id for detecting visited types

polish:
+ clarify logical relationship between code blocks
+ avoid instantiating lots of lists

Contributes to
#3327

---------

Co-authored-by: Stephan Herrmann <stephan.herrmann@berlin.de>
  • Loading branch information
fedejeanne and stephan-herrmann authored Dec 8, 2024
1 parent 11bf464 commit 922cbbb
Showing 1 changed file with 22 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1264,33 +1264,38 @@ private boolean superOnlyRaw(TypeBinding g, TypeBinding s, LookupEnvironment env
}

protected List<Pair<TypeBinding>> allSuperPairsWithCommonGenericType(TypeBinding s, TypeBinding t) {
return allSuperPairsWithCommonGenericTypeRecursive(s, t, new HashSet<>());
ArrayList<Pair<TypeBinding>> result = new ArrayList<>();
allSuperPairsWithCommonGenericTypeRecursive(s, t, result, new HashSet<>());
return result;
}

private List<Pair<TypeBinding>> allSuperPairsWithCommonGenericTypeRecursive(TypeBinding s, TypeBinding t, HashSet<TypeBinding> visited) {
private void allSuperPairsWithCommonGenericTypeRecursive(TypeBinding s, TypeBinding t, List<Pair<TypeBinding>> result, HashSet<Integer> visited) {
if (s == null || s.id == TypeIds.T_JavaLangObject || t == null || t.id == TypeIds.T_JavaLangObject)
return Collections.emptyList();
if (!visited.add(s.prototype()))
return Collections.emptyList();
List<Pair<TypeBinding>> result = new ArrayList<>();
if (s.isParameterizedType() && t.isParameterizedType() // optimization #1: clients of this method only want to compare type arguments
&& TypeBinding.equalsEquals(s.original(), t.original())) {
result.add(new Pair<>(s, t));
}
return;
if (!visited.add(s.id))
return;

// optimization: nothing interesting above equal types
if (TypeBinding.equalsEquals(s, t))
return result; // optimization #2: nothing interesting above equal types
TypeBinding tSuper = t.findSuperTypeOriginatingFrom(s);
if (tSuper != null && s.isParameterizedType() && tSuper.isParameterizedType()) { // optimization #1 again
result.add(new Pair<>(s, tSuper));
return;

if (s.isParameterizedType()) { // optimization here and below: clients of this method only want to compare type arguments
if (TypeBinding.equalsEquals(s.original(), t.original())) {
if (t.isParameterizedType())
result.add(new Pair<>(s, t));
} else {
TypeBinding tSuper = t.findSuperTypeOriginatingFrom(s);
if (tSuper != null && tSuper.isParameterizedType())
result.add(new Pair<>(s, tSuper));
}
}
result.addAll(allSuperPairsWithCommonGenericTypeRecursive(s.superclass(), t, visited));
allSuperPairsWithCommonGenericTypeRecursive(s.superclass(), t, result, visited);
ReferenceBinding[] superInterfaces = s.superInterfaces();
if (superInterfaces != null) {
for (ReferenceBinding superInterface : superInterfaces) {
result.addAll(allSuperPairsWithCommonGenericTypeRecursive(superInterface, t, visited));
allSuperPairsWithCommonGenericTypeRecursive(superInterface, t, result, visited);
}
}
return result;
}

public TypeBinding getEquivalentOuterVariable(InferenceVariable variable, InferenceVariable[] outerVariables) {
Expand Down

0 comments on commit 922cbbb

Please sign in to comment.