remove unnecessary RecursionGuard instantiations, explain when to use them in javadoc

This commit is contained in:
peter
2019-04-08 19:50:41 +02:00
parent ce65addf39
commit e1488eddc8
40 changed files with 84 additions and 136 deletions
@@ -313,7 +313,7 @@ public class MethodCandidateInfo extends CandidateInfo{
PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
PsiMethod method = getElement();
if (myTypeArguments == null) {
final RecursionGuard.StackStamp stackStamp = PsiDiamondType.ourDiamondGuard.markStack();
RecursionGuard.StackStamp stackStamp = RecursionManager.markStack();
myApplicabilityError.remove();
try {
@@ -143,12 +143,11 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
return mySubstitutionMap != null ? mySubstitutionMap.hashCode() : 0;
}
private static final RecursionGuard ourGuard = RecursionManager.createGuard("substituteGuard");
private PsiType rawTypeForTypeParameter(@NotNull PsiTypeParameter typeParameter) {
final PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes();
if (extendsTypes.length > 0) {
// First bound
return ourGuard.doPreventingRecursion(extendsTypes[0], true, () -> substitute(extendsTypes[0]));
return RecursionManager.doPreventingRecursion(extendsTypes[0], true, () -> substitute(extendsTypes[0]));
}
// Object
return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope());
@@ -55,7 +55,6 @@ class ScopedClassHierarchy {
return o1.getManager().areElementsEquivalent(o1, o2);
}
};
private static final RecursionGuard ourGuard = RecursionManager.createGuard("ScopedClassHierarchy");
private final PsiClass myPlaceClass;
private final GlobalSearchScope myResolveScope;
private volatile Map<PsiClass, PsiClassType.ClassResolveResult> mySupersWithSubstitutors;
@@ -110,7 +109,7 @@ class ScopedClassHierarchy {
Map<PsiClass, PsiClassType.ClassResolveResult> map = hierarchy.mySupersWithSubstitutors;
if (map == null) {
map = ContainerUtil.newTroveMap(CLASS_HASHING_STRATEGY);
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
hierarchy.visitType(JavaPsiFacade.getElementFactory(derivedClass.getProject()).createType(derivedClass, PsiSubstitutor.EMPTY), map);
if (stamp.mayCacheNow()) {
hierarchy.mySupersWithSubstitutors = map;
@@ -143,8 +142,8 @@ class ScopedClassHierarchy {
List<PsiClassType.ClassResolveResult> getImmediateSupersWithCapturing() {
List<PsiClassType.ClassResolveResult> list = myImmediateSupersWithCapturing;
if (list == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
list = ourGuard.doPreventingRecursion(this, true, () -> calcImmediateSupersWithCapturing());
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
list = RecursionManager.doPreventingRecursion(this, true, () -> calcImmediateSupersWithCapturing());
if (list == null) {
return Collections.emptyList();
}
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.impl.source;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
@@ -28,8 +27,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
public class JavaVarTypeUtil {
public static final RecursionGuard ourVarGuard = RecursionManager.createGuard("var.guard");
public static PsiType getUpwardProjection(@NotNull PsiType t) {
return t.accept(new UpwardProjectionTypeVisitor());
}
@@ -53,7 +50,6 @@ public class JavaVarTypeUtil {
}
private static class UpwardProjectionTypeVisitor extends PsiTypeVisitorEx<PsiType> {
private static final RecursionGuard upwardGuard = RecursionManager.createGuard("upwardProjectionGuard");
@Override
public PsiType visitType(PsiType type) {
return type;
@@ -114,7 +110,7 @@ public class JavaVarTypeUtil {
}
else {
PsiType U = upwardGuard.doPreventingRecursion(ai, true, () -> ai.accept(this));
PsiType U = RecursionManager.doPreventingRecursion(ai, true, () -> ai.accept(this));
if (U == null) {
targetSubstitutor = targetSubstitutor.put(parameter, PsiWildcardType.createUnbounded(manager));
}
@@ -17,6 +17,7 @@ package com.intellij.psi.impl.source;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.impl.PsiImplUtil;
@@ -172,7 +173,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
if (!(e instanceof PsiArrayInitializerExpression) &&
!isSelfReferenced((PsiExpression)e, parent)) {
PsiExpression expression = (PsiExpression)e;
PsiType type = JavaVarTypeUtil.ourVarGuard.doPreventingRecursion(expression, true, () -> expression.getType());
PsiType type = RecursionManager.doPreventingRecursion(expression, true, () -> expression.getType());
return type == null ? null : JavaVarTypeUtil.getUpwardProjection(type);
}
return null;
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.impl.AnyPsiChangeListener;
import com.intellij.psi.impl.PsiManagerImpl;
@@ -86,7 +87,7 @@ public class JavaResolveCache {
PsiType type = isOverloadCheck && polyExpression ? null : map.get(expr);
if (type == null) {
final RecursionGuard.StackStamp dStackStamp = PsiDiamondType.ourDiamondGuard.markStack();
RecursionGuard.StackStamp dStackStamp = RecursionManager.markStack();
type = f.fun(expr);
if (!dStackStamp.mayCacheNow()) {
return type;
@@ -6,6 +6,7 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -39,7 +40,7 @@ public class PsiOldInferenceHelper implements PsiInferenceHelper {
if (argument == null) continue;
if (argument instanceof PsiMethodCallExpression && PsiResolveHelper.ourGuard.currentStack().contains(argument)) continue;
final RecursionGuard.StackStamp stackStamp = PsiDiamondType.ourDiamondGuard.markStack();
RecursionGuard.StackStamp stackStamp = RecursionManager.markStack();
argTypes[j] = argument.getType();
if (!stackStamp.mayCacheNow()) {
argTypes[j] = null;
@@ -42,7 +42,6 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
public class ResolveCache {
private final AtomicReferenceArray<Map> myPhysicalMaps = new AtomicReferenceArray<>(4); //boolean incompleteCode, boolean isPoly
private final AtomicReferenceArray<Map> myNonPhysicalMaps = new AtomicReferenceArray<>(4); //boolean incompleteCode, boolean isPoly
private final RecursionGuard myGuard = RecursionManager.createGuard("resolveCache");
public static ResolveCache getInstance(Project project) {
ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
@@ -145,8 +144,8 @@ public class ResolveCache {
return result;
}
RecursionGuard.StackStamp stamp = myGuard.markStack();
result = needToPreventRecursion ? myGuard.doPreventingRecursion(Trinity.create(ref, incompleteCode, isPoly), true,
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
result = needToPreventRecursion ? RecursionManager.doPreventingRecursion(Trinity.create(ref, incompleteCode, isPoly), true,
() -> resolver.resolve(ref, incompleteCode)) : resolver.resolve(ref, incompleteCode);
if (result instanceof ResolveResult) {
ensureValidPsi((ResolveResult)result);
@@ -198,8 +197,8 @@ public class ResolveCache {
return result;
}
RecursionGuard.StackStamp stamp = myGuard.markStack();
result = needToPreventRecursion ? myGuard.doPreventingRecursion(Pair.create(ref, incompleteCode), true,
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
result = needToPreventRecursion ? RecursionManager.doPreventingRecursion(Pair.create(ref, incompleteCode), true,
() -> resolver.resolve(ref, containingFile, incompleteCode)) : resolver.resolve(ref, containingFile, incompleteCode);
if (result != null) {
ensureValidResults(result);
@@ -22,7 +22,6 @@ import java.util.List;
*/
public abstract class CachedValueBase<T> {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.CachedValueImpl");
private static final RecursionGuard ourGuard = RecursionManager.createGuard("cachedValue");
private final boolean myTrackValue;
private volatile SoftReference<Data<T>> myData;
@@ -236,10 +235,10 @@ public abstract class CachedValueBase<T> {
return data.getValue();
}
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
Computable<Data<T>> calcData = () -> computeData(doCompute(param));
data = ourGuard.doPreventingRecursion(this, true, calcData);
data = RecursionManager.doPreventingRecursion(this, true, calcData);
if (data == null) {
data = calcData.compute();
}
@@ -24,7 +24,6 @@ import java.util.concurrent.ThreadLocalRandom;
public class IdempotenceChecker {
private static final Logger LOG = Logger.getInstance(IdempotenceChecker.class);
private static final Set<Class> ourReportedValueClasses = Collections.synchronizedSet(ContainerUtil.newTroveSet());
private static final RecursionGuard ourGuard = RecursionManager.createGuard("IdempotenceChecker");
private static final ThreadLocal<Integer> ourRandomCheckNesting = ThreadLocal.withInitial(() -> 0);
private static final RegistryValue ourRateCheckProperty = Registry.get("platform.random.idempotence.check.rate");
@@ -257,7 +256,7 @@ public class IdempotenceChecker {
*/
public static <T> void applyForRandomCheck(T data, Object provider, Computable<? extends T> recomputeValue) {
if (areRandomChecksEnabled() && shouldPerformRandomCheck()) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
Integer prevNesting = ourRandomCheckNesting.get();
ourRandomCheckNesting.set(prevNesting + 1);
try {
@@ -23,7 +23,6 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.ui.*;
import com.intellij.ui.components.JBPanelWithEmptyText;
@@ -87,8 +86,6 @@ class ServiceView extends JPanel implements Disposable {
@NotNull private final Project myProject;
@NotNull private final ServiceViewState myState;
private final RecursionGuard myGuard = RecursionManager.createGuard("ServiceView.getData");
ServiceView(@NotNull Project project, @NotNull ServiceViewState state) {
super(new BorderLayout());
myProject = project;
@@ -125,7 +122,7 @@ class ServiceView extends JPanel implements Disposable {
ServiceViewContributor.ViewDescriptor descriptor = getSelectedDescriptor();
DataProvider dataProvider = descriptor == null ? null : descriptor.getDataProvider();
if (dataProvider != null) {
return myGuard.doPreventingRecursion(this, false, () -> dataProvider.getData(dataId));
return RecursionManager.doPreventingRecursion(this, false, () -> dataProvider.getData(dataId));
}
return null;
});
@@ -150,7 +150,7 @@ public class SemServiceImpl extends SemService {
ensureInitialized();
RecursionGuard.StackStamp stamp = RecursionManager.createGuard("semService").markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
LinkedHashSet<T> result = new LinkedHashSet<>();
final Map<SemKey, List<SemElement>> map = new THashMap<>();
@@ -27,7 +27,7 @@ class RecursionPreventingSafePublicationLazy<T>(recursionKey: Any?, initializer:
return ourNotNullizer.nullize(valueRef.get())
}
val stamp = ourRecursionGuard.markStack()
val stamp = RecursionManager.markStack()
val newValue = ourRecursionGuard.doPreventingRecursion(recursionKey, false, initializerValue)
// In case of recursion don't update [valueRef] and don't clear [initializer].
if (newValue === null) {
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
* @author peter
*/
public abstract class AtomicNotNullLazyValue<T> extends NotNullLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("AtomicNotNullLazyValue");
private volatile T myValue;
@Override
@@ -34,7 +33,7 @@ public abstract class AtomicNotNullLazyValue<T> extends NotNullLazyValue<T> {
synchronized (this) {
value = myValue;
if (value == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = compute();
if (stamp.mayCacheNow()) {
myValue = value;
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
* @author peter
*/
public abstract class AtomicNullableLazyValue<T> extends NullableLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("AtomicNullableLazyValue");
private volatile T myValue;
private volatile boolean myComputed;
@@ -39,7 +38,7 @@ public abstract class AtomicNullableLazyValue<T> extends NullableLazyValue<T> {
computed = myComputed;
value = myValue;
if (!computed) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = compute();
if (stamp.mayCacheNow()) {
myValue = value;
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
* Thread-safe version: {@link AtomicClearableLazyValue}.
*/
public abstract class ClearableLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("ClearableLazyValue");
@NotNull
public static <T> ClearableLazyValue<T> create(final Computable<? extends T> computable) {
@@ -44,7 +43,7 @@ public abstract class ClearableLazyValue<T> {
public T getValue() {
T result = myValue;
if (result == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
result = compute();
if (stamp.mayCacheNow()) {
myValue = result;
@@ -19,7 +19,6 @@ package com.intellij.openapi.util;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public abstract class FieldCache<T, Owner,AccessorParameter,Parameter> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("fieldCache");
private final ReentrantReadWriteLock.ReadLock r;
private final ReentrantReadWriteLock.WriteLock w;
@@ -45,7 +44,7 @@ public abstract class FieldCache<T, Owner,AccessorParameter,Parameter> {
try {
result = getValue(owner, a);
if (result == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
result = compute(owner, p);
if (stamp.mayCacheNow()) {
putValue(result, owner, a);
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
* @author peter
*/
public class NotNullLazyKey<T,H extends UserDataHolder> extends Key<T>{
private static final RecursionGuard ourGuard = RecursionManager.createGuard("NotNullLazyKey");
private final NotNullFunction<? super H, ? extends T> myFunction;
private NotNullLazyKey(@NotNull @NonNls String name, @NotNull NotNullFunction<? super H, ? extends T> function) {
@@ -35,7 +34,7 @@ public class NotNullLazyKey<T,H extends UserDataHolder> extends Key<T>{
public final T getValue(@NotNull H h) {
T data = h.getUserData(this);
if (data == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
data = myFunction.fun(h);
if (stamp.mayCacheNow()) {
if (h instanceof UserDataHolderEx) {
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
* @author peter
*/
public abstract class NotNullLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("NotNullLazyValue");
private T myValue;
@NotNull
@@ -35,7 +34,7 @@ public abstract class NotNullLazyValue<T> {
public T getValue() {
T result = myValue;
if (result == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
result = compute();
if (stamp.mayCacheNow()) {
myValue = result;
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
* @author peter
*/
public class NullableLazyKey<T,H extends UserDataHolder> extends Key<T>{
private static final RecursionGuard ourGuard = RecursionManager.createGuard("NullableLazyKey");
private final NullableFunction<? super H, ? extends T> myFunction;
private NullableLazyKey(@NonNls String name, final NullableFunction<? super H, ? extends T> function) {
@@ -36,7 +35,7 @@ public class NullableLazyKey<T,H extends UserDataHolder> extends Key<T>{
public final T getValue(H h) {
T data = h.getUserData(this);
if (data == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
data = myFunction.fun(h);
if (stamp.mayCacheNow()) {
//noinspection unchecked
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.Nullable;
* @author peter
*/
public abstract class NullableLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("NullableLazyValue");
private boolean myComputed;
@Nullable private T myValue;
@@ -33,7 +32,7 @@ public abstract class NullableLazyValue<T> {
public T getValue() {
T value = myValue;
if (!myComputed) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = compute();
if (stamp.mayCacheNow()) {
myValue = value;
@@ -32,21 +32,25 @@ public abstract class RecursionGuard {
* @param key an id of the computation. It's stored internally to ensure that a recursive calls with the same key won't lead to endless recursion.
* @param memoize whether the result of the computation may be cached thread-locally until the last currently active {@code doPreventingRecursion} call
* completes. May be used to speed up things when recursion re-entrance happens: otherwise nothing would be cached at all and
* in some cases exponential performance may be observed. Pass {@code true} if your computation has no side effects.
* in some cases exponential performance may be observed. Pass {@code true} if your computation has no side effects
* and doesn't depend on method parameters.
* @param computation a piece of code to compute.
* @return the result of the computation or {@code null} if we're entering a computation with this key on this thread recursively,
*/
@Nullable
public abstract <T> T doPreventingRecursion(@NotNull Object key, boolean memoize, @NotNull Computable<T> computation);
/** Use {@link RecursionManager#markStack()} instead */
/** @deprecated Use {@link RecursionManager#markStack()} instead */
@NotNull
@Deprecated
public StackStamp markStack() {
return RecursionManager.markStack();
}
/**
* @return the current thread-local stack of keys passed to {@link #doPreventingRecursion(Object, boolean, Computable)}
* Note: if you make decisions based on the result of this method, you'd better couple it with {@link #prohibitResultCaching},
* otherwise you might cache inconsistent values.
* @return the current thread-local stack of keys passed to {@link #doPreventingRecursion(Object, boolean, Computable)}.
*/
@NotNull
public abstract List<Object> currentStack();
@@ -71,7 +75,7 @@ public abstract class RecursionGuard {
* re-entrant recursive results. When such non-reliable results exist in the thread's call stack, returns false, otherwise true.<p></p>
*
* If you use this with {@link RecursionGuard#doPreventingRecursion(Object, boolean, Computable)}, then the
* {@link RecursionGuard#markStack()}+{@link #mayCacheNow()} should be outside of recursion prevention call. Otherwise
* {@link RecursionManager#markStack()}+{@link #mayCacheNow()} should be outside of recursion prevention call. Otherwise
* even the outer recursive computation result won't be cached. In particular, {@code doPreventingRecursion} calls should
* be inside your {@link com.intellij.psi.util.CachedValue} provider, not outside cached value access.
*/
@@ -44,7 +44,7 @@ import java.util.stream.Stream;
* {@code RecursionManager} assists in distinguishing this situation and allowing caching outside that loop, but disallowing it inside.<p></p>
*
* To prevent caching incorrect values, please create a {@code private static final} field of {@link #createGuard} call, and then use
* {@link RecursionGuard#markStack()} and {@link RecursionGuard.StackStamp#mayCacheNow()}
* {@link RecursionManager#markStack()} and {@link RecursionGuard.StackStamp#mayCacheNow()}
* on it.<p></p>
*
* Note that the above only helps with idempotent recursion loops, that is, the ones that stabilize after one iteration, so that
@@ -73,6 +73,7 @@ public class RecursionManager {
/**
* @param id just some string to separate different recursion prevention policies from each other
* @return a helper object which allow you to perform reentrancy-safe computations and check whether caching will be safe.
* Don't use it unless you need to call it from several places in the code, inspect the computation stack and/or prohibit result caching.
*/
@NotNull
public static RecursionGuard createGuard(@NonNls final String id) {
@@ -19,7 +19,6 @@ package com.intellij.openapi.util;
import org.jetbrains.annotations.NonNls;
public abstract class UserDataCache<T, Owner extends UserDataHolder, Param> extends FieldCache<T, Owner, Key<T>, Param> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("userDataCache");
private final Key<T> myKey;
protected UserDataCache() {
@@ -52,7 +51,7 @@ public abstract class UserDataCache<T, Owner extends UserDataHolder, Param> exte
public T get(Key<T> a, Owner owner, Param p) {
T value = owner.getUserData(a);
if (value == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = compute(owner, p);
if (stamp.mayCacheNow()) {
value = ((UserDataHolderEx)owner).putUserDataIfAbsent(a, value);
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
* @author peter
*/
public abstract class VolatileNotNullLazyValue<T> extends NotNullLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("VolatileNotNullLazyValue");
private volatile T myValue;
@Override
@@ -33,7 +32,7 @@ public abstract class VolatileNotNullLazyValue<T> extends NotNullLazyValue<T> {
public final T getValue() {
T value = myValue;
if (value == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = compute();
if (stamp.mayCacheNow()) {
myValue = value;
@@ -11,7 +11,6 @@ import org.jetbrains.annotations.Nullable;
* @author peter
*/
public abstract class VolatileNullableLazyValue<T> extends NullableLazyValue<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("VolatileNullableLazyValue");
private volatile boolean myComputed;
@Nullable private volatile T myValue;
@@ -24,7 +23,7 @@ public abstract class VolatileNullableLazyValue<T> extends NullableLazyValue<T>
public T getValue() {
T value = myValue;
if (!myComputed) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = compute();
if (stamp.mayCacheNow()) {
myValue = value;
@@ -18,8 +18,6 @@ import java.util.function.Supplier;
* For not thread-safe (but possible faster and more memory-efficient) alternative please use {@link FactoryMap}
*/
public abstract class ConcurrentFactoryMap<K,V> implements ConcurrentMap<K,V> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("factoryMap");
private final ConcurrentMap<K, V> myMap = createMap();
/**
@@ -44,7 +42,7 @@ public abstract class ConcurrentFactoryMap<K,V> implements ConcurrentMap<K,V> {
K k = notNull(key);
V value = map.get(k);
if (value == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = create((K)key);
if (stamp.mayCacheNow()) {
V v = notNull(value);
@@ -33,8 +33,6 @@ import java.util.function.Supplier;
* For thread-safe alternative please use {@link ConcurrentFactoryMap}
*/
public abstract class FactoryMap<K,V> implements Map<K, V> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("factoryMap");
private Map<K, V> myMap;
/**
@@ -58,7 +56,7 @@ public abstract class FactoryMap<K,V> implements Map<K, V> {
K k = notNull(key);
V value = map.get(k);
if (value == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = create((K)key);
if (stamp.mayCacheNow()) {
V v = notNull(value);
@@ -130,7 +130,7 @@ public class GroovyPsiManager {
private static <K extends GroovyPsiElement> PsiType getTypeWithCaching(@NotNull K key, @NotNull ConcurrentMap<? super K, PsiType> map, @NotNull Function<? super K, ? extends PsiType> calculator) {
PsiType type = map.get(key);
if (type == null) {
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
type = calculator.fun(key);
if (type == null) {
type = UNKNOWN_TYPE;
@@ -41,8 +41,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public abstract class GrVariableBaseImpl<T extends GrVariableStubBase> extends GrStubElementBase<T> implements GrVariable, StubBasedPsiElement<T> {
public static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.lang.psi.impl.statements.GrVariableImpl");
private static final RecursionGuard ourGuard = RecursionManager.createGuard("grVariableInitializer");
protected GrVariableBaseImpl(ASTNode node) {
super(node);
}
@@ -151,7 +149,7 @@ public abstract class GrVariableBaseImpl<T extends GrVariableStubBase> extends G
}
if (initializer != null) {
PsiType initializerType = ourGuard.doPreventingRecursion(this, true, initializer::getType);
PsiType initializerType = RecursionManager.doPreventingRecursion(this, true, initializer::getType);
if (declaredType == null) return initializerType;
if (initializerType instanceof PsiClassType && TypesUtil.isAssignable(declaredType, initializerType, this)) {
return initializerType;
@@ -15,8 +15,6 @@
*/
package org.jetbrains.plugins.groovy.util;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
@@ -32,11 +30,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
*/
public class GroovyStdTypeCalculators {
private static final RecursionGuard ourGuard = RecursionManager.createGuard("GrDescriptorReturnTypeCalculator getClosureReturnType");
private GroovyStdTypeCalculators() {
}
public static class ClosureTypeExtractor implements PairFunction<GrMethodCall, PsiMethod, PsiType> {
@Override
public PsiType fun(GrMethodCall methodCall, PsiMethod method) {
@@ -54,7 +47,7 @@ public class GroovyStdTypeCalculators {
final GrClosableBlock finalClosure = closure;
return ourGuard.doPreventingRecursion(methodCall, true, (NullableComputable<PsiType>)() -> {
return RecursionManager.doPreventingRecursion(methodCall, true, () -> {
PsiType returnType = finalClosure.getReturnType();
if (PsiType.VOID.equals(returnType)) return null;
return returnType;
@@ -24,9 +24,6 @@ import org.jetbrains.annotations.TestOnly;
import java.util.concurrent.atomic.AtomicReference;
public class NotNullCachedComputableWrapper<T> implements NotNullComputable<T> {
private static final RecursionGuard ourGuard = RecursionManager.createGuard(NotNullCachedComputableWrapper.class.getName());
private volatile NotNullComputable<T> myComputable;
private final AtomicReference<T> myValueRef = new AtomicReference<>();
@@ -44,7 +41,7 @@ public class NotNullCachedComputableWrapper<T> implements NotNullComputable<T> {
final NotNullComputable<T> computable = myComputable;
if (computable == null) continue; // computable is null only after some thread succeeds CAS
RecursionGuard.StackStamp stamp = ourGuard.markStack();
RecursionGuard.StackStamp stamp = RecursionManager.markStack();
value = computable.compute();
if (stamp.mayCacheNow()) {
if (myValueRef.compareAndSet(null, value)) { // try to cache value
@@ -28,7 +28,7 @@ class RecursionAwareSafePublicationLazy<T>(initializer: () -> T) : Lazy<T> {
return valueRef.get()
}
val stamp = ourRecursionGuard.markStack()
val stamp = RecursionManager.markStack()
val newValue = initializerValue()
if (!stamp.mayCacheNow()) {
// In case of recursion don't update [valueRef] and don't clear [initializer].
@@ -49,7 +49,6 @@ class RecursionAwareSafePublicationLazy<T>(initializer: () -> T) : Lazy<T> {
override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
companion object {
private val ourRecursionGuard = RecursionManager.createGuard("RecursionAwareSafePublicationLazy")
private val UNINITIALIZED_VALUE: Any = ObjectUtils.sentinel("RecursionAwareSafePublicationLazy initial value")
}
}
@@ -275,7 +275,6 @@ public class JavaFxPsiUtil {
}
private static final Key<CachedValue<PsiClass>> INJECTED_CONTROLLER = Key.create("javafx.injected.controller");
private static final RecursionGuard ourGuard = RecursionManager.createGuard("javafx.controller");
public static PsiClass getControllerClass(final PsiFile containingFile) {
if (containingFile instanceof XmlFile) {
@@ -1194,7 +1193,7 @@ public class JavaFxPsiUtil {
@Nullable
private static CachedValueProvider.Result<PsiClass> computeInjectedControllerClass(PsiFile containingFile) {
return ourGuard.doPreventingRecursion(containingFile, true, () -> {
return RecursionManager.doPreventingRecursion(containingFile, true, () -> {
final Project project = containingFile.getProject();
final Ref<PsiClass> injectedController = new Ref<>();
final PsiClass fxmlLoader =
@@ -82,8 +82,6 @@ private fun isCallExpressionParameter(argumentExpression: UExpression,
return call.getArgumentForParameter(parameterIndex) == unwrapPolyadic(argumentExpression) && callPattern.accepts(call)
}
private val GUARD = RecursionManager.createGuard("isPropertyAssignCall")
private fun isPropertyAssignCall(argument: UElement, methodPattern: ElementPattern<out PsiMethod>): Boolean {
val uBinaryExpression = (argument.uastParent as? UBinaryExpression) ?: return false
if (uBinaryExpression.operator != UastBinaryOperator.ASSIGN) return false
@@ -95,7 +93,7 @@ private fun isPropertyAssignCall(argument: UElement, methodPattern: ElementPatte
is UReferenceExpression -> leftOperand
else -> return false
}
val references = GUARD.doPreventingRecursion(argument, false) {
val references = RecursionManager.doPreventingRecursion(argument, false) {
uastReference.sourcePsi?.references // via `sourcePsi` because of KT-27385
} ?: return false
return references.any { methodPattern.accepts(it.resolve()) }
@@ -97,9 +97,6 @@ private fun getOrCreateCachedElement(element: PsiElement,
element.toUElement(it)
}.firstOrNull()?.also { context?.put(cachedUElement, it) }
//resolving uast-elements during pattern evaluation could bring us here again
private val PATTERN_ADAPTER_RECURSION_GUARD = RecursionManager.createGuard("add.uast.reference.provider")
private class UastPatternAdapter(
val predicate: (UElement, ProcessingContext) -> Boolean,
val supportedUElementTypes: List<Class<out UElement>>
@@ -108,7 +105,7 @@ private class UastPatternAdapter(
override fun accepts(o: Any?): Boolean = accepts(o, null)
override fun accepts(o: Any?, context: ProcessingContext?): Boolean = when (o) {
is PsiElement -> PATTERN_ADAPTER_RECURSION_GUARD.doPreventingRecursion(this, false) {
is PsiElement -> RecursionManager.doPreventingRecursion(this, false) {
getOrCreateCachedElement(o, context, supportedUElementTypes)
?.let { predicate(it, (context ?: ProcessingContext()).apply { put(REQUESTED_PSI_ELEMENT, o) }) }
?: false
@@ -3,8 +3,6 @@ package com.intellij.util.xml.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
@@ -18,7 +16,6 @@ import com.intellij.semantic.SemContributor;
import com.intellij.semantic.SemRegistrar;
import com.intellij.semantic.SemService;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.xml.EvaluatedXmlName;
import com.intellij.util.xml.EvaluatedXmlNameImpl;
import com.intellij.util.xml.XmlName;
@@ -131,46 +128,40 @@ final class DomSemContributor extends SemContributor {
return null;
});
registrar.registerSemElementProvider(DomManagerImpl.DOM_CUSTOM_HANDLER_KEY, nonRootTag, new NullableFunction<XmlTag, CollectionElementInvocationHandler>() {
private final RecursionGuard myGuard = RecursionManager.createGuard("customDomParent");
registrar.registerSemElementProvider(DomManagerImpl.DOM_CUSTOM_HANDLER_KEY, nonRootTag, tag -> {
if (StringUtil.isEmpty(tag.getName())) return null;
@Override
public CollectionElementInvocationHandler fun(XmlTag tag) {
if (StringUtil.isEmpty(tag.getName())) return null;
XmlTag parentTag = PhysicalDomParentStrategy.getParentTag(tag);
assert parentTag != null;
final XmlTag parentTag = PhysicalDomParentStrategy.getParentTag(tag);
assert parentTag != null;
DomInvocationHandler parent = RecursionManager.doPreventingRecursion(tag, true, () -> getParentDom(parentTag));
if (parent == null) return null;
DomInvocationHandler parent = myGuard.doPreventingRecursion(tag, true,
(NullableComputable<DomInvocationHandler>)() -> getParentDom(parentTag));
if (parent == null) return null;
DomGenericInfoEx info = parent.getGenericInfo();
List<? extends CustomDomChildrenDescription> customs = info.getCustomNameChildrenDescription();
if (customs.isEmpty()) return null;
DomGenericInfoEx info = parent.getGenericInfo();
final List<? extends CustomDomChildrenDescription> customs = info.getCustomNameChildrenDescription();
if (customs.isEmpty()) return null;
if (semService.getSemElement(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, tag) == null &&
semService.getSemElement(DomManagerImpl.DOM_COLLECTION_HANDLER_KEY, tag) == null) {
if (semService.getSemElement(DomManagerImpl.DOM_INDEXED_HANDLER_KEY, tag) == null &&
semService.getSemElement(DomManagerImpl.DOM_COLLECTION_HANDLER_KEY, tag) == null) {
String localName = tag.getLocalName();
XmlFile file = parent.getFile();
for (final DomFixedChildDescription description : info.getFixedChildrenDescriptions()) {
XmlName xmlName = description.getXmlName();
if (localName.equals(xmlName.getLocalName()) && DomImplUtil.isNameSuitable(xmlName, tag, parent, file)) {
return null;
}
String localName = tag.getLocalName();
XmlFile file = parent.getFile();
for (DomFixedChildDescription description : info.getFixedChildrenDescriptions()) {
XmlName xmlName = description.getXmlName();
if (localName.equals(xmlName.getLocalName()) && DomImplUtil.isNameSuitable(xmlName, tag, parent, file)) {
return null;
}
for (CustomDomChildrenDescription description : customs) {
if (description.getTagNameDescriptor() != null) {
AbstractCollectionChildDescription desc = (AbstractCollectionChildDescription)description;
Type type = description.getType();
return new CollectionElementInvocationHandler(type, tag, desc, parent, null);
}
}
for (CustomDomChildrenDescription description : customs) {
if (description.getTagNameDescriptor() != null) {
AbstractCollectionChildDescription desc = (AbstractCollectionChildDescription)description;
Type type = description.getType();
return new CollectionElementInvocationHandler(type, tag, desc, parent, null);
}
}
return null;
}
return null;
});
registrar.registerSemElementProvider(DomManagerImpl.DOM_ATTRIBUTE_HANDLER_KEY,
@@ -3,7 +3,6 @@ package com.intellij.util.xml.impl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.xml.XmlFile;
import com.intellij.reference.SoftReference;
@@ -30,7 +29,6 @@ import java.util.Set;
*/
public class DynamicGenericInfo extends DomGenericInfoEx {
private static final Key<SoftReference<WeakInterner<ChildrenDescriptionsHolder>>> HOLDERS_CACHE = Key.create("DOM_CHILDREN_HOLDERS_CACHE");
private static final RecursionGuard ourGuard = RecursionManager.createGuard("dynamicGenericInfo");
private final StaticGenericInfo myStaticGenericInfo;
@NotNull private final DomInvocationHandler myInvocationHandler;
private volatile boolean myInitialized;
@@ -60,7 +58,7 @@ public class DynamicGenericInfo extends DomGenericInfoEx {
if (!myInvocationHandler.exists()) return true;
return ourGuard.doPreventingRecursion(myInvocationHandler, false, () -> {
return RecursionManager.doPreventingRecursion(myInvocationHandler, false, () -> {
DomExtensionsRegistrarImpl registrar = runDomExtenders();
synchronized (myInvocationHandler) {
@@ -63,7 +63,6 @@ import java.util.stream.Collectors;
public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenceHost {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlTagImpl");
@NonNls private static final String XML_NS_PREFIX = "xml";
private static final RecursionGuard ourGuard = RecursionManager.createGuard("xmlTag");
private static final Key<CachedValue<XmlTag[]>> SUBTAGS_WITH_INCLUDES_KEY = Key.create("subtags with includes");
private static final Key<CachedValue<XmlTag[]>> SUBTAGS_WITHOUT_INCLUDES_KEY = Key.create("subtags without includes");
private static final Comparator<TextRange> RANGE_COMPARATOR = Comparator.comparingInt(TextRange::getStartOffset);
@@ -467,7 +466,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
@Override
public XmlElementDescriptor getDescriptor() {
return CachedValuesManager.getCachedValue(this, () -> {
XmlElementDescriptor descriptor = ourGuard.doPreventingRecursion(this, true, this::computeElementDescriptor);
XmlElementDescriptor descriptor = RecursionManager.doPreventingRecursion(this, true, this::computeElementDescriptor);
return Result.create(descriptor, PsiModificationTracker.MODIFICATION_COUNT, externalResourceModificationTracker());
});
}
@@ -795,7 +794,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag, HintedReferenc
// When there is no namespace declarations then qualified names should be just used in dtds
// this implies that we may have "" namespace prefix ! (see last paragraph in Namespaces in Xml, Section 5)
String result = ourGuard.doPreventingRecursion(Trinity.create("getNsByPrefix", this, prefix), true, () -> {
String result = RecursionManager.doPreventingRecursion(Trinity.create("getNsByPrefix", this, prefix), true, () -> {
final String nsFromEmptyPrefix = getNamespaceByPrefix("");
if (nsFromEmptyPrefix.isEmpty()) return nsFromEmptyPrefix;
@@ -20,7 +20,6 @@ import com.intellij.javaee.ExternalResourceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.text.StringUtil;
@@ -71,9 +70,8 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
private static final Set<String> UNDECLARED_STD_TYPES = new HashSet<>();
@NonNls private static final String INCLUDE_TAG_NAME = "include";
@NonNls private static final String REDEFINE_TAG_NAME = "redefine";
private static final RecursionGuard myRedefinedDescriptorsInProcessing = RecursionManager.createGuard("myRedefinedDescriptorsInProcessing");
private final Map<QNameKey, CachedValue<XmlElementDescriptor>> myDescriptorsMap = Collections.synchronizedMap(new HashMap<QNameKey, CachedValue<XmlElementDescriptor>>());
private final Map<Pair<QNameKey, XmlTag>, CachedValue<TypeDescriptor>> myTypesMap = Collections.synchronizedMap(new HashMap<Pair<QNameKey,XmlTag>, CachedValue<TypeDescriptor>>());
private final Map<QNameKey, CachedValue<XmlElementDescriptor>> myDescriptorsMap = Collections.synchronizedMap(new HashMap<>());
private final Map<Pair<QNameKey, XmlTag>, CachedValue<TypeDescriptor>> myTypesMap = Collections.synchronizedMap(new HashMap<>());
private XmlFile myFile;
private XmlTag myTag;
private String myTargetNamespace;
@@ -104,7 +102,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
addDependency(xmlFile, visited);
}
} else if (equalsToSchemaName(tag, REDEFINE_TAG_NAME)) {
myRedefinedDescriptorsInProcessing.doPreventingRecursion(tag, false, () -> {
RecursionManager.doPreventingRecursion(tag, false, () -> {
final XmlFile file = getRedefinedElementDescriptorFile(tag);
addDependency(file, visited);
return null;