mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-21 14:37:45 +07:00
tests fixed, restored ourGraphGuard for IDEA-CR-33227
This commit is contained in:
@@ -30,9 +30,7 @@ import com.intellij.psi.scope.PsiConflictResolver;
|
||||
import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver;
|
||||
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
@@ -158,8 +156,9 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
|
||||
}
|
||||
|
||||
private static JavaResolveResult getStaticFactory(@NotNull PsiNewExpression newExpression, @NotNull PsiElement context) {
|
||||
return JavaResolveCache.getInstance(newExpression.getProject()).getNewExpressionStaticFactory(newExpression, context,
|
||||
PsiDiamondTypeImpl::getStaticFactoryCandidateInfo);
|
||||
return context != newExpression || MethodCandidateInfo.isOverloadCheck() ? getStaticFactoryCandidateInfo(newExpression, context) :
|
||||
JavaResolveCache.getInstance(newExpression.getProject()).getNewExpressionStaticFactory(newExpression,
|
||||
newExp -> getStaticFactoryCandidateInfo(newExp, newExp));
|
||||
}
|
||||
|
||||
public static DiamondInferenceResult resolveInferredTypesNoCheck(@NotNull PsiNewExpression newExpression, @NotNull PsiElement context) {
|
||||
|
||||
@@ -44,7 +44,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements PsiField, PsiVariableEx, Queryable {
|
||||
private volatile Reference<PsiType> myCachedType;
|
||||
@@ -266,15 +265,6 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
|
||||
return ElementPresentationUtil.addVisibilityIcon(this, flags, baseIcon);
|
||||
}
|
||||
|
||||
private static class OurConstValueComputer implements BiFunction<PsiFieldImpl, Set<PsiVariable>, Object> {
|
||||
private static final OurConstValueComputer INSTANCE = new OurConstValueComputer();
|
||||
|
||||
@Override
|
||||
public Object apply(PsiFieldImpl variable, Set<PsiVariable> visitedVars) {
|
||||
return variable.doComputeConstantValue(visitedVars);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object doComputeConstantValue(@Nullable Set<PsiVariable> visitedVars) {
|
||||
PsiType type = getType();
|
||||
@@ -295,7 +285,7 @@ public class PsiFieldImpl extends JavaStubPsiElement<PsiFieldStub> implements Ps
|
||||
public Object computeConstantValue(Set<PsiVariable> visitedVars) {
|
||||
if (!hasModifierProperty(PsiModifier.FINAL)) return null;
|
||||
|
||||
return JavaResolveCache.getInstance(getProject()).computeConstantValueWithCaching(this, visitedVars, OurConstValueComputer.INSTANCE);
|
||||
return JavaResolveCache.getInstance(getProject()).getFieldConstantValue(this, visitedVars, (field, variables)->field.doComputeConstantValue(variables));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.PsiJavaParserFacadeImpl;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveCache;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -38,7 +39,8 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeElement {
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
/** created implicitly by {@link JavaElementType.JavaCompositeElementType#createCompositeNode()} */
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public PsiTypeElementImpl() {
|
||||
this(JavaElementType.TYPE);
|
||||
}
|
||||
@@ -60,7 +62,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiType getType() {
|
||||
return CachedValuesManager.getCachedValue(this, () -> CachedValueProvider.Result.create(calculateType(), PsiModificationTracker.MODIFICATION_COUNT));
|
||||
return JavaResolveCache.getInstance(getProject()).getTypeElementType(this, element -> element.calculateType());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.intellij.psi.impl.PsiManagerImpl;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.PsiFieldImpl;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.impl.source.PsiTypeElementImpl;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
@@ -45,6 +46,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@@ -53,10 +55,11 @@ public class JavaResolveCache {
|
||||
|
||||
private static final NotNullLazyKey<JavaResolveCache, Project> INSTANCE_KEY = ServiceManager.createLazyKey(JavaResolveCache.class);
|
||||
|
||||
private final AtomicReference<Map<PsiExpression, PsiType>> myCalculatedTypes = new AtomicReference<>();
|
||||
private final AtomicReference<Map<PsiExpression, PsiType>> myExpressionTypes = new AtomicReference<>();
|
||||
private final AtomicReference<Map<PsiTypeElementImpl, Object>> myTypeElementTypes = new AtomicReference<>(); // PsiType or NULL
|
||||
private final AtomicReference<Map<PsiFieldImpl,Object>> myFieldToConstValueMapPhysical = new AtomicReference<>();
|
||||
private final AtomicReference<Map<PsiFieldImpl,Object>> myFieldToConstValueMapNonPhysical = new AtomicReference<>();
|
||||
private final AtomicReference<Map<PsiNewExpression, Object>> myStaticFactories = new AtomicReference<>(); // JavaResolveResult or NULL
|
||||
private final AtomicReference<ConcurrentMap<PsiNewExpression, Object>> myStaticFactories = new AtomicReference<>(); // JavaResolveResult or NULL
|
||||
private final AtomicReference<Map<PsiCall, Object>> myTopLevelInferenceSessions = new AtomicReference<>(); // InferenceSession or NULL
|
||||
|
||||
private static final Object NULL = Key.create("NULL"); // the object to put into maps to denote resolvers return null
|
||||
@@ -77,7 +80,8 @@ public class JavaResolveCache {
|
||||
}
|
||||
|
||||
private void clearCaches(boolean isPhysical) {
|
||||
myCalculatedTypes.set(null);
|
||||
myExpressionTypes.set(null);
|
||||
myTypeElementTypes.set(null);
|
||||
if (isPhysical) {
|
||||
myFieldToConstValueMapPhysical.set(null);
|
||||
}
|
||||
@@ -91,8 +95,8 @@ public class JavaResolveCache {
|
||||
final boolean isOverloadCheck = MethodCandidateInfo.isOverloadCheck() || LambdaUtil.isLambdaParameterCheck();
|
||||
final boolean polyExpression = PsiPolyExpressionUtil.isPolyExpression(expr);
|
||||
|
||||
Map<PsiExpression, PsiType> map = myCalculatedTypes.get();
|
||||
if (map == null) map = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, ContainerUtil.createConcurrentWeakKeySoftValueMap());
|
||||
Map<PsiExpression, PsiType> map = myExpressionTypes.get();
|
||||
if (map == null) map = ConcurrencyUtil.cacheOrGet(myExpressionTypes, ContainerUtil.createConcurrentWeakKeySoftValueMap());
|
||||
|
||||
PsiType type = isOverloadCheck && polyExpression ? null : map.get(expr);
|
||||
if (type == null) {
|
||||
@@ -136,9 +140,9 @@ public class JavaResolveCache {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object computeConstantValueWithCaching(@NotNull PsiFieldImpl variable,
|
||||
@Nullable Set<PsiVariable> visitedVars,
|
||||
@NotNull BiFunction<? super PsiFieldImpl, ? super Set<PsiVariable>, Object> computer){
|
||||
public Object getFieldConstantValue(@NotNull PsiFieldImpl variable,
|
||||
@Nullable Set<PsiVariable> visitedVars,
|
||||
@NotNull BiFunction<? super PsiFieldImpl, ? super Set<PsiVariable>, Object> computer){
|
||||
boolean physical = variable.isPhysical();
|
||||
|
||||
AtomicReference<Map<PsiFieldImpl, Object>> ref = physical ? myFieldToConstValueMapPhysical : myFieldToConstValueMapNonPhysical;
|
||||
@@ -155,22 +159,24 @@ public class JavaResolveCache {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JavaResolveResult getNewExpressionStaticFactory(@NotNull PsiNewExpression newExpression, @NotNull PsiElement context, @NotNull BiFunction<? super PsiNewExpression, ? super PsiElement, ? extends JavaResolveResult> computer) {
|
||||
AtomicReference<Map<PsiNewExpression, Object>> ref = myStaticFactories;
|
||||
Map<PsiNewExpression, Object> map = ref.get();
|
||||
public JavaResolveResult getNewExpressionStaticFactory(@NotNull PsiNewExpression newExpression,
|
||||
@NotNull Function<? super PsiNewExpression, ? extends JavaResolveResult> computer) {
|
||||
AtomicReference<ConcurrentMap<PsiNewExpression, Object>> ref = myStaticFactories;
|
||||
ConcurrentMap<PsiNewExpression, Object> map = ref.get();
|
||||
if (map == null) map = ConcurrencyUtil.cacheOrGet(ref, ContainerUtil.createConcurrentWeakMap());
|
||||
|
||||
Object cached = map.get(newExpression);
|
||||
if (cached == null) {
|
||||
JavaResolveResult result = computer.fun(newExpression);
|
||||
cached = ConcurrencyUtil.cacheOrGet(map, newExpression, result == null ? NULL : result);
|
||||
}
|
||||
if (cached == NULL) return null;
|
||||
if (cached != null) return (JavaResolveResult)cached;
|
||||
|
||||
JavaResolveResult result = computer.apply(newExpression, context);
|
||||
map.put(newExpression, result == null ? NULL : result);
|
||||
return result;
|
||||
return (JavaResolveResult)cached;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InferenceSession getTopLevelInferenceSession(@NotNull PsiCall topLevelCall, @NotNull Function<? super PsiCall, ? extends InferenceSession> computer) {
|
||||
public InferenceSession getTopLevelInferenceSession(@NotNull PsiCall topLevelCall,
|
||||
@NotNull Function<? super PsiCall, ? extends InferenceSession> computer) {
|
||||
AtomicReference<Map<PsiCall, Object>> ref = myTopLevelInferenceSessions;
|
||||
Map<PsiCall, Object> map = ref.get();
|
||||
if (map == null) map = ConcurrencyUtil.cacheOrGet(ref, ContainerUtil.createConcurrentWeakMap());
|
||||
@@ -183,4 +189,19 @@ public class JavaResolveCache {
|
||||
map.put(topLevelCall, result == null ? NULL : result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public PsiType getTypeElementType(@NotNull PsiTypeElementImpl typeElement,
|
||||
@NotNull Function<? super PsiTypeElementImpl, ? extends PsiType> computer) {
|
||||
AtomicReference<Map<PsiTypeElementImpl, Object>> ref = myTypeElementTypes;
|
||||
Map<PsiTypeElementImpl, Object> map = ref.get();
|
||||
if (map == null) map = ConcurrencyUtil.cacheOrGet(ref, ContainerUtil.createConcurrentWeakMap());
|
||||
|
||||
Object cached = map.get(typeElement);
|
||||
if (cached == NULL) return null;
|
||||
if (cached != null) return (PsiType)cached;
|
||||
|
||||
PsiType result = computer.fun(typeElement);
|
||||
map.put(typeElement, result == null ? NULL : result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -76,9 +76,13 @@ public class InferenceSessionContainer {
|
||||
//But overload resolution can depend on type of lambda parameter. As it can't depend on lambda body,
|
||||
//traversing down would stop at lambda level and won't take into account overloaded method
|
||||
!MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argumentList)) {
|
||||
final PsiCall topLevelCall =
|
||||
parent instanceof PsiExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression)parent) ? null :
|
||||
LambdaUtil.treeWalkUp(parent);
|
||||
final PsiCall topLevelCall = PsiResolveHelper.ourGraphGuard.doPreventingRecursion(parent, false,
|
||||
() -> {
|
||||
if (parent instanceof PsiExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression)parent)) {
|
||||
return null;
|
||||
}
|
||||
return LambdaUtil.treeWalkUp(parent);
|
||||
});
|
||||
|
||||
if (topLevelCall != null) {
|
||||
InferenceSession session;
|
||||
|
||||
Reference in New Issue
Block a user