From d0cfcde4b2d33e314cc5d1b08bd1b836c0e438a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= Date: Fri, 6 Dec 2024 14:14:00 +0100 Subject: [PATCH] When is ReferenceBinding.hashCode() used outside HashMap? https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3412 --- .../flow/ExceptionHandlingFlowContext.java | 5 ++- .../compiler/lookup/BinaryTypeBinding.java | 9 +++-- .../compiler/lookup/LookupEnvironment.java | 18 ++++----- .../compiler/lookup/MethodVerifier.java | 31 ++++++++-------- .../compiler/lookup/ReferenceBinding.java | 37 ++++++++++++------- .../jdt/internal/compiler/lookup/Scope.java | 7 ++-- .../compiler/lookup/SourceTypeBinding.java | 8 ++-- .../compiler/lookup/TypeBindingVisitor.java | 9 +++-- .../internal/compiler/lookup/TypeSystem.java | 21 ++++------- 9 files changed, 76 insertions(+), 69 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java index 8eeccfb7ff2..80818d2831e 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java @@ -20,7 +20,9 @@ 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; @@ -28,7 +30,6 @@ 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; @@ -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 indexes = new HashMap<>(); boolean isMethodContext; public UnconditionalFlowInfo initsOnReturn; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java index e5f6ffa46a2..09fa2b086d7 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java @@ -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; @@ -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; /* @@ -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 storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder private ReferenceBinding containerAnnotationType; int defaultNullness = 0; @@ -1976,7 +1977,7 @@ public void tagAsHavingDefectiveContainerType() { } @Override -SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) { +Map storedAnnotations(boolean forceInitialize, boolean forceStore) { if (!isPrototype()) return this.prototype.storedAnnotations(forceInitialize, forceStore); @@ -1984,7 +1985,7 @@ SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean 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; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index 303fe765988..f31a508d2ed 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -109,11 +109,11 @@ public class LookupEnvironment implements ProblemReasons, TypeConstants { private CompleteTypeBindingsSteps stepCompleted = CompleteTypeBindingsSteps.NONE; // ROOT_ONLY public ITypeRequestor typeRequestor; // SHARED - private SimpleLookupTable uniqueParameterizedGenericMethodBindings; + private Map uniqueParameterizedGenericMethodBindings; // key is a string with the method selector value is an array of method bindings private SimpleLookupTable uniquePolymorphicMethodBindings; - private SimpleLookupTable uniqueGetClassMethodBinding; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300734 + private Map uniqueGetClassMethodBinding; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300734 boolean useModuleSystem; // true when compliance >= 9 and nameEnvironment is module aware // key is a string with the module name value is a module binding @@ -215,7 +215,7 @@ public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOpt this.defaultImports = null; this.nameEnvironment = nameEnvironment; this.knownPackages = new HashtableOfPackage(); - this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3); + this.uniqueParameterizedGenericMethodBindings = new HashMap<>(); this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3); this.missingTypes = null; this.accessRestrictions = new HashMap(3); @@ -240,7 +240,7 @@ public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOpt this.defaultImports = null; this.nameEnvironment = rootEnv.nameEnvironment; this.knownPackages = new HashtableOfPackage(); - this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3); + this.uniqueParameterizedGenericMethodBindings = new HashMap<>(); this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3); this.missingTypes = null; this.accessRestrictions = new HashMap(3); @@ -1194,7 +1194,7 @@ public PlainPackageBinding createPlainPackage(char[][] compoundName) { public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, RawTypeBinding rawType) { // cached info is array of already created parameterized types for this type - ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod); + ParameterizedGenericMethodBinding[] cachedInfo = this.uniqueParameterizedGenericMethodBindings.get(genericMethod); boolean needToGrow = false; int index = 0; if (cachedInfo != null){ @@ -1234,7 +1234,7 @@ public ParameterizedGenericMethodBinding createParameterizedGenericMethod(Method boolean inferredWithUncheckedConversion, boolean hasReturnProblem, TypeBinding targetType) { // cached info is array of already created parameterized types for this type - ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod); + ParameterizedGenericMethodBinding[] cachedInfo = this.uniqueParameterizedGenericMethodBindings.get(genericMethod); int argLength = typeArguments == null ? 0: typeArguments.length; boolean needToGrow = false; int index = 0; @@ -1382,9 +1382,9 @@ public ParameterizedMethodBinding createGetClassMethod(TypeBinding receiverType, // see if we have already cached this method for the given receiver type. ParameterizedMethodBinding retVal = null; if (this.uniqueGetClassMethodBinding == null) { - this.uniqueGetClassMethodBinding = new SimpleLookupTable(3); + this.uniqueGetClassMethodBinding = new HashMap<>(); } else { - retVal = (ParameterizedMethodBinding)this.uniqueGetClassMethodBinding.get(receiverType); + retVal = this.uniqueGetClassMethodBinding.get(receiverType); } if (retVal == null) { retVal = ParameterizedMethodBinding.instantiateGetClass(receiverType, originalMethod, scope); @@ -2322,7 +2322,7 @@ public void reset() { this.verifier = null; // NOTE: remember to fix #updateCaches(...) when adding unique binding caches - this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3); + this.uniqueParameterizedGenericMethodBindings = new HashMap<>(); this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3); this.uniqueGetClassMethodBinding = null; this.missingTypes = null; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java index ca6c3dee197..08a2a5ae459 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java @@ -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 interfacesToCheck = new HashSet<>(superInterfaces.length); + Set 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); @@ -321,16 +321,16 @@ void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBind } ReferenceBinding[] itsInterfaces = null; - SimpleSet inheritedInterfaces = new SimpleSet(5); + Set 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); @@ -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) { @@ -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); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java index 33286162ac6..d8db6413b0a 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java @@ -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; @@ -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. @@ -88,7 +89,7 @@ abstract public class ReferenceBinding extends TypeBinding { char[] constantPoolName; char[] signature; - private SimpleLookupTable compatibleCache; + private Map compatibleCache; int typeBits; // additional bits characterizing this type protected MethodBinding [] singleAbstractMethod; @@ -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) @@ -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) @@ -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 store = storedAnnotations(forceInitialization, false); + return store == null ? null : store.get(binding); } AnnotationBinding[] retrieveAnnotations(Binding binding) { @@ -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 store = storedAnnotations(false, false); if (store != null) - store.removeKey(binding); + store.remove(binding); } else { - SimpleLookupTable store = storedAnnotations(true, false); + Map store = storedAnnotations(true, false); if (store != null) store.put(binding, holder); } @@ -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 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 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 storedAnnotations(boolean forceInitialize, boolean forceStore) { return null; // overrride if interested in storing annotations for the receiver, its fields and methods } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java index fe5bbebe33b..2b13659423b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -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" }) @@ -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 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$ @@ -5430,7 +5429,7 @@ 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; } }; @@ -5438,7 +5437,7 @@ public TypeBinding substitute(TypeVariableBinding typeVariable) { // 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); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java index 881161fe30e..dbee8e55626 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java @@ -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; @@ -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" }) @@ -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 storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder public int defaultNullness; boolean memberTypesSorted = false; @@ -3150,7 +3150,7 @@ public final int sourceStart() { return this.scope.referenceContext.sourceStart; } @Override -SimpleLookupTable storedAnnotations(boolean forceInitialize, boolean forceStore) { +Map storedAnnotations(boolean forceInitialize, boolean forceStore) { if (!isPrototype()) return this.prototype.storedAnnotations(forceInitialize, forceStore); @@ -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; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java index f0ff19ee373..a7574c9aa4f 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java @@ -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 visitedCache; public void reset() { this.visitedCache = null; @@ -72,9 +73,9 @@ public static void visit(TypeBindingVisitor visitor, TypeBinding type) { if (type == null) return; - SimpleLookupTable visitedCache = visitor.visitedCache; + Map visitedCache = visitor.visitedCache; if (visitedCache == null) { - visitor.visitedCache = new SimpleLookupTable(3); + visitor.visitedCache = new HashMap<>(3); visitedCache = visitor.visitedCache; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java index c7de83d7eaa..6c0c9e18766 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java @@ -23,7 +23,6 @@ import java.util.function.Consumer; import java.util.function.Supplier; import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; import org.eclipse.jdt.internal.compiler.util.Util; /* TypeSystem: An abstraction responsible for keeping track of types that undergo "derivation" of some sort and the derived types produced thus. @@ -219,12 +218,12 @@ void put (ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBi private int typeid = TypeIds.T_LastWellKnownTypeId; private TypeBinding [][] types; protected HashedParameterizedTypes parameterizedTypes; // auxiliary fast lookup table for parameterized types. - private SimpleLookupTable annotationTypes; // cannot store in types, since AnnotationBinding is not a TypeBinding and we don't want types to operate at Binding level. + private HashMap annotationTypes; // cannot store in types, since AnnotationBinding is not a TypeBinding and we don't want types to operate at Binding level. LookupEnvironment environment; public TypeSystem(LookupEnvironment environment) { this.environment = environment; - this.annotationTypes = new SimpleLookupTable(16); + this.annotationTypes = new HashMap<>(); this.typeid = TypeIds.T_LastWellKnownTypeId; this.types = new TypeBinding[TypeIds.T_LastWellKnownTypeId * 2][]; this.parameterizedTypes = new HashedParameterizedTypes(); @@ -560,7 +559,7 @@ alternate code paths. Unless care is exercised, we will end up with duplicate ob We may return a resolved annotation when requested for unresolved one, but not vice versa. */ public final AnnotationBinding getAnnotationType(ReferenceBinding annotationType, boolean requiredResolved) { - AnnotationBinding annotation = (AnnotationBinding) this.annotationTypes.get(annotationType); + AnnotationBinding annotation = this.annotationTypes.get(annotationType); if (annotation == null) { if (requiredResolved) annotation = new AnnotationBinding(annotationType, Binding.NO_ELEMENT_VALUE_PAIRS); @@ -589,7 +588,7 @@ public void cleanUp(int typeId) { } public void reset() { - this.annotationTypes = new SimpleLookupTable(16); + this.annotationTypes = new HashMap<>(); this.typeid = TypeIds.T_LastWellKnownTypeId; this.types = new TypeBinding[TypeIds.T_LastWellKnownTypeId * 2][]; this.parameterizedTypes = new HashedParameterizedTypes(); @@ -613,14 +612,10 @@ public void updateCaches(UnresolvedReferenceBinding unresolvedType, ReferenceBin } } } - if (this.annotationTypes.get(unresolvedType) != null) { // update the key - Object[] keys = this.annotationTypes.keyTable; - for (int i = 0, l = keys.length; i < l; i++) { - if (keys[i] == unresolvedType) { - keys[i] = resolvedType; // hashCode is based on compoundName so this works. - break; - } - } + AnnotationBinding removed = this.annotationTypes.remove(unresolvedType); + if (removed != null) { + // update the key + this.annotationTypes.put(resolvedType, removed); } }