diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java index fba9dfdb38d8..2cfa83700986 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java @@ -47,18 +47,8 @@ public class TypeEvalContext { private final Map myEvaluated = new HashMap<>(); private final Map myEvaluatedReturn = new HashMap<>(); - private final ThreadLocal> myEvaluating = new ThreadLocal>() { - @Override - protected Set initialValue() { - return new HashSet<>(); - } - }; - private final ThreadLocal> myEvaluatingReturn = new ThreadLocal>() { - @Override - protected Set initialValue() { - return new HashSet<>(); - } - }; + private final ThreadLocal> myEvaluating = ThreadLocal.withInitial(HashSet::new); + private final ThreadLocal> myEvaluatingReturn = ThreadLocal.withInitial(HashSet::new); private TypeEvalContext(boolean allowDataFlow, boolean allowStubToAST, boolean allowCallContext, @Nullable PsiFile origin) { myConstraints = new TypeEvalConstraints(allowDataFlow, allowStubToAST, allowCallContext, origin); @@ -254,7 +244,7 @@ public class TypeEvalContext { } /** - * @return context constraints (see {@link com.jetbrains.python.psi.types.TypeEvalConstraints} + * @return context constraints (see {@link TypeEvalConstraints} */ @NotNull TypeEvalConstraints getConstraints() { diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextBasedCache.java b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextBasedCache.java index cd094a073208..338adc7ccc45 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextBasedCache.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextBasedCache.java @@ -20,9 +20,9 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** @@ -68,8 +68,9 @@ public final class TypeEvalContextBasedCache { return value; } final T newValue = myProvider.fun(context); - map.put(key, newValue); // ConcurrentMap guarantees happens-before so from this moment get() should work in other threads - return newValue; + T oldValue = + map.putIfAbsent(key, newValue);// ConcurrentMap guarantees happens-before so from this moment get() should work in other threads + return oldValue == null ? newValue : oldValue; } /** @@ -81,7 +82,7 @@ public final class TypeEvalContextBasedCache { public Result> compute() { // This method is called if cache is empty. Create new map for it. // Concurrent map allows several threads to call get and put, so it is thread safe but not atomic - final ConcurrentHashMap map = new ConcurrentHashMap<>(); + final ConcurrentMap map = ContainerUtil.createConcurrentSoftValueMap(); return new Result<>(map, PsiModificationTracker.MODIFICATION_COUNT); } }