From bd828bd47cd79e2619f49d8ed28d250ab54f7794 Mon Sep 17 00:00:00 2001 From: I-Al-Istannen Date: Mon, 28 Aug 2023 12:53:53 +0200 Subject: [PATCH] fix: Synchronize access to anonymous type cache --- .../spoon/reflect/factory/TypeFactory.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/spoon/reflect/factory/TypeFactory.java b/src/main/java/spoon/reflect/factory/TypeFactory.java index 3ce53b9c16c..4872cdc2b6e 100644 --- a/src/main/java/spoon/reflect/factory/TypeFactory.java +++ b/src/main/java/spoon/reflect/factory/TypeFactory.java @@ -467,7 +467,7 @@ public boolean matches(CtClass element) { // If the class name is an integer, the class is an anonymous class, otherwise, // it is a standard class. //TODO reset cache when type is modified - return getFromCache(t, className, k -> { + return getAnonymousTypeFromCache(t, className, k -> { //the searching for declaration of anonymous class is expensive //do that only once and store it in cache of CtType final List anonymousClasses = t.getElements(new TypeFilter(CtNewClass.class) { @@ -488,15 +488,19 @@ public boolean matches(CtNewClass element) { return null; } - private static final String CACHE_KEY = TypeFactory.class.getName() + "-AnnonymousTypeCache"; + private static final String ANONYMOUS_TYPES_CACHE_KEY = TypeFactory.class.getName() + "-AnnonymousTypeCache"; - private T getFromCache(CtElement element, K key, Function valueResolver) { - Map cache = (Map) element.getMetadata(CACHE_KEY); - if (cache == null) { - cache = new HashMap<>(); - element.putMetadata(CACHE_KEY, cache); + private T getAnonymousTypeFromCache(CtElement element, K key, Function valueResolver) { + //noinspection SynchronizationOnLocalVariableOrMethodParameter + synchronized (element) { + @SuppressWarnings("unchecked") + Map cache = (Map) element.getMetadata(ANONYMOUS_TYPES_CACHE_KEY); + if (cache == null) { + cache = new HashMap<>(); + element.putMetadata(ANONYMOUS_TYPES_CACHE_KEY, cache); + } + return cache.computeIfAbsent(key, valueResolver); } - return cache.computeIfAbsent(key, valueResolver); } private boolean isNumber(String str) {