Skip to content

Commit

Permalink
When is ReferenceBinding.hashCode() used outside HashMap?
Browse files Browse the repository at this point in the history
  • Loading branch information
EcljpseB0T committed Dec 6, 2024
1 parent 11bf464 commit c2289e5
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.StatementWithFinallyBlock;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
Expand All @@ -52,7 +53,7 @@ public class ExceptionHandlingFlowContext extends FlowContext {
int[] isNeeded;
// WARNING: This is an array that maps to catch blocks, not caught exceptions (which could be more than catch blocks in a multi-catch block)
UnconditionalFlowInfo[] initsOnExceptions;
ObjectCache indexes = new ObjectCache();
Map<ReferenceBinding, Integer> indexes = new HashMap<>();
boolean isMethodContext;

public UnconditionalFlowInfo initsOnReturn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.classfmt.AnnotationInfo;
Expand All @@ -66,7 +68,6 @@
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.compiler.util.Util;

/*
Expand Down Expand Up @@ -104,7 +105,7 @@ public class BinaryTypeBinding extends ReferenceBinding {
// For the link with the principle structure
protected LookupEnvironment environment;

protected SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
protected Map<Binding, AnnotationHolder> storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder

private ReferenceBinding containerAnnotationType;
int defaultNullness = 0;
Expand Down Expand Up @@ -1976,15 +1977,15 @@ public void tagAsHavingDefectiveContainerType() {
}

@Override
SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) {
Map<Binding, AnnotationHolder> storedAnnotations(boolean forceInitialize, boolean forceStore) {

if (!isPrototype())
return this.prototype.storedAnnotations(forceInitialize, forceStore);

if (forceInitialize && this.storedAnnotations == null) {
if (!this.environment.globalOptions.storeAnnotations && !forceStore)
return null; // not supported during this compile
this.storedAnnotations = new SimpleLookupTable(3);
this.storedAnnotations = new HashMap<>();
}
return this.storedAnnotations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,16 +295,16 @@ void checkForMissingHashCodeMethod() {
void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
if (superInterfaces == Binding.NO_SUPERINTERFACES) return;

SimpleSet interfacesToCheck = new SimpleSet(superInterfaces.length);
SimpleSet redundantInterfaces = null; // bark but once.
Set<ReferenceBinding> interfacesToCheck = new HashSet<>(superInterfaces.length);
Set<ReferenceBinding> redundantInterfaces = null; // bark but once.
for (int i = 0, l = superInterfaces.length; i < l; i++) {
ReferenceBinding toCheck = superInterfaces[i];
for (int j = 0; j < l; j++) {
ReferenceBinding implementedInterface = superInterfaces[j];
if (i != j && toCheck.implementsInterface(implementedInterface, true)) {
if (redundantInterfaces == null) {
redundantInterfaces = new SimpleSet(3);
} else if (redundantInterfaces.includes(implementedInterface)) {
redundantInterfaces = new HashSet<>();
} else if (redundantInterfaces.contains(implementedInterface)) {
continue;
}
redundantInterfaces.add(implementedInterface);
Expand All @@ -321,16 +321,16 @@ void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBind
}

ReferenceBinding[] itsInterfaces = null;
SimpleSet inheritedInterfaces = new SimpleSet(5);
Set<ReferenceBinding> inheritedInterfaces = new HashSet<>();
ReferenceBinding superType = superclass;
while (superType != null && superType.isValidBinding()) {
if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
for (ReferenceBinding inheritedInterface : itsInterfaces) {
if (!inheritedInterfaces.includes(inheritedInterface) && inheritedInterface.isValidBinding()) {
if (interfacesToCheck.includes(inheritedInterface)) {
if (!inheritedInterfaces.contains(inheritedInterface) && inheritedInterface.isValidBinding()) {
if (interfacesToCheck.contains(inheritedInterface)) {
if (redundantInterfaces == null) {
redundantInterfaces = new SimpleSet(3);
} else if (redundantInterfaces.includes(inheritedInterface)) {
redundantInterfaces = new HashSet<>();
} else if (redundantInterfaces.contains(inheritedInterface)) {
continue;
}
redundantInterfaces.add(inheritedInterface);
Expand All @@ -350,10 +350,9 @@ void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBind
superType = superType.superclass();
}

int nextPosition = inheritedInterfaces.elementSize;
int nextPosition = inheritedInterfaces.size();
if (nextPosition == 0) return;
ReferenceBinding[] interfacesToVisit = new ReferenceBinding[nextPosition];
inheritedInterfaces.asArray(interfacesToVisit);
ReferenceBinding[] interfacesToVisit = inheritedInterfaces.toArray(ReferenceBinding[]::new);
for (int i = 0; i < nextPosition; i++) {
superType = interfacesToVisit[i];
if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
Expand All @@ -362,11 +361,11 @@ void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBind
System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
for (int a = 0; a < itsLength; a++) {
ReferenceBinding inheritedInterface = itsInterfaces[a];
if (!inheritedInterfaces.includes(inheritedInterface) && inheritedInterface.isValidBinding()) {
if (interfacesToCheck.includes(inheritedInterface)) {
if (!inheritedInterfaces.contains(inheritedInterface) && inheritedInterface.isValidBinding()) {
if (interfacesToCheck.contains(inheritedInterface)) {
if (redundantInterfaces == null) {
redundantInterfaces = new SimpleSet(3);
} else if (redundantInterfaces.includes(inheritedInterface)) {
redundantInterfaces = new HashSet<>();
} else if (redundantInterfaces.contains(inheritedInterface)) {
continue;
}
redundantInterfaces.add(inheritedInterface);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
Expand All @@ -65,7 +67,6 @@
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;

/*
Not all fields defined by this type (& its subclasses) are initialized when it is created.
Expand All @@ -88,7 +89,7 @@ abstract public class ReferenceBinding extends TypeBinding {
char[] constantPoolName;
char[] signature;

private SimpleLookupTable compatibleCache;
private Map<TypeBinding, Boolean> compatibleCache;

int typeBits; // additional bits characterizing this type
protected MethodBinding [] singleAbstractMethod;
Expand Down Expand Up @@ -1206,6 +1207,16 @@ public TypeVariableBinding getTypeVariable(char[] variableName) {

@Override
public int hashCode() {
if (!StackWalker.
getInstance().
walk(stream -> stream.anyMatch(s->"java.util.HashMap".equals(s.getClassName())))) //$NON-NLS-1$

{
RuntimeException e=new RuntimeException("called outside HashMap"); //$NON-NLS-1$
e.printStackTrace();
throw e;
}

// ensure ReferenceBindings hash to the same position as UnresolvedReferenceBindings so they can be replaced without rehashing
// ALL ReferenceBindings are unique when created so equals() is the same as ==
return (this.compoundName == null || this.compoundName.length == 0)
Expand Down Expand Up @@ -1450,7 +1461,7 @@ public boolean isCompatibleWith(TypeBinding otherType, /*@Nullable*/ Scope captu
return true;
Object result;
if (this.compatibleCache == null) {
this.compatibleCache = new SimpleLookupTable(3);
this.compatibleCache = new HashMap<>();
result = null;
} else {
result = this.compatibleCache.get(otherType); // [dbg reset] this.compatibleCache.put(otherType,null)
Expand Down Expand Up @@ -1901,8 +1912,8 @@ protected void appendNullAnnotation(StringBuilder nameBuffer, CompilerOptions op
}

public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
SimpleLookupTable store = storedAnnotations(forceInitialization, false);
return store == null ? null : (AnnotationHolder) store.get(binding);
Map<Binding, AnnotationHolder> store = storedAnnotations(forceInitialization, false);
return store == null ? null : store.get(binding);
}

AnnotationBinding[] retrieveAnnotations(Binding binding) {
Expand Down Expand Up @@ -2067,11 +2078,11 @@ public TypeBinding downwardsProjection(Scope scope, TypeBinding[] mentionedTypeV

void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
if (holder == null) {
SimpleLookupTable store = storedAnnotations(false, false);
Map<Binding, AnnotationHolder> store = storedAnnotations(false, false);
if (store != null)
store.removeKey(binding);
store.remove(binding);
} else {
SimpleLookupTable store = storedAnnotations(true, false);
Map<Binding, AnnotationHolder> store = storedAnnotations(true, false);
if (store != null)
store.put(binding, holder);
}
Expand All @@ -2080,21 +2091,21 @@ void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
void storeAnnotations(Binding binding, AnnotationBinding[] annotations, boolean forceStore) {
AnnotationHolder holder = null;
if (annotations == null || annotations.length == 0) {
SimpleLookupTable store = storedAnnotations(false, forceStore);
Map<Binding, AnnotationHolder> store = storedAnnotations(false, forceStore);
if (store != null)
holder = (AnnotationHolder) store.get(binding);
holder = store.get(binding);
if (holder == null) return; // nothing to delete
} else {
SimpleLookupTable store = storedAnnotations(true, forceStore);
Map<Binding, AnnotationHolder> store = storedAnnotations(true, forceStore);
if (store == null) return; // not supported
holder = (AnnotationHolder) store.get(binding);
holder = store.get(binding);
if (holder == null)
holder = new AnnotationHolder();
}
storeAnnotationHolder(binding, holder.setAnnotations(annotations));
}

SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) {
Map<Binding, AnnotationHolder> storedAnnotations(boolean forceInitialize, boolean forceStore) {
return null; // overrride if interested in storing annotations for the receiver, its fields and methods
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.jdt.internal.compiler.util.ObjectVector;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.compiler.util.SimpleSet;

@SuppressWarnings({ "rawtypes", "unchecked" })
Expand Down Expand Up @@ -5395,7 +5394,7 @@ public MethodBinding getStaticFactory (ParameterizedTypeBinding allocationType,
MethodBinding targetMethod = isInterface ? new MethodBinding(method.original(), genericType) : method.original();
MethodBinding staticFactory = new SyntheticFactoryMethodBinding(targetMethod, environment, originalEnclosingType);
staticFactory.typeVariables = new TypeVariableBinding[factoryArity];
final SimpleLookupTable map = new SimpleLookupTable(factoryArity);
Map<TypeBinding, TypeVariableBinding> map = new HashMap<>(factoryArity);

// Rename each type variable T of the type to T' or T'' or T''' based on the enclosing level to avoid a clash.
String prime = ""; //$NON-NLS-1$
Expand Down Expand Up @@ -5430,15 +5429,15 @@ public boolean isRawSubstitution() {
}
@Override
public TypeBinding substitute(TypeVariableBinding typeVariable) {
TypeBinding retVal = (TypeBinding) map.get(typeVariable.unannotated());
TypeBinding retVal = map.get(typeVariable.unannotated());
return retVal == null ? typeVariable : typeVariable.hasTypeAnnotations() ? environment().createAnnotatedType(retVal, typeVariable.getTypeAnnotations()) : retVal;
}
};

// initialize new variable bounds
for (int j = 0; j < factoryArity; j++) {
TypeVariableBinding originalVariable = j < classTypeVariablesArity ? classTypeVariables[j] : methodTypeVariables[j - classTypeVariablesArity];
TypeVariableBinding substitutedVariable = (TypeVariableBinding) map.get(originalVariable.unannotated());
TypeVariableBinding substitutedVariable = map.get(originalVariable.unannotated());

TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -77,7 +78,6 @@
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.compiler.util.Util;

@SuppressWarnings({ "rawtypes", "unchecked" })
Expand Down Expand Up @@ -106,7 +106,7 @@ public class SourceTypeBinding extends ReferenceBinding {
Map[] synthetics;
char[] genericReferenceTypeSignature;

private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
private Map<Binding, AnnotationHolder> storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder

public int defaultNullness;
boolean memberTypesSorted = false;
Expand Down Expand Up @@ -3150,7 +3150,7 @@ public final int sourceStart() {
return this.scope.referenceContext.sourceStart;
}
@Override
SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) {
Map<Binding, AnnotationHolder> storedAnnotations(boolean forceInitialize, boolean forceStore) {
if (!isPrototype())
return this.prototype.storedAnnotations(forceInitialize, forceStore);

Expand All @@ -3159,7 +3159,7 @@ SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore)
final CompilerOptions globalOptions = this.scope.environment().globalOptions;
if (!globalOptions.storeAnnotations && !forceStore)
return null; // not supported during this compile
this.storedAnnotations = new SimpleLookupTable(3);
this.storedAnnotations = new HashMap<>();
}
return this.storedAnnotations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;


public class TypeBindingVisitor {

private SimpleLookupTable visitedCache;
private Map<TypeBinding, Boolean> visitedCache;

public void reset() {
this.visitedCache = null;
Expand Down Expand Up @@ -72,9 +73,9 @@ public static void visit(TypeBindingVisitor visitor, TypeBinding type) {
if (type == null)
return;

SimpleLookupTable visitedCache = visitor.visitedCache;
Map<TypeBinding, Boolean> visitedCache = visitor.visitedCache;
if (visitedCache == null) {
visitor.visitedCache = new SimpleLookupTable(3);
visitor.visitedCache = new HashMap<>(3);
visitedCache = visitor.visitedCache;
}

Expand Down
Loading

0 comments on commit c2289e5

Please sign in to comment.