diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java index cd5a1a1474d8..f7389043a7c8 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java @@ -24,13 +24,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.NotNullLazyKey; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiType; -import com.intellij.psi.PsiVariable; +import com.intellij.psi.*; import com.intellij.psi.impl.AnyPsiChangeListener; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.PsiManagerImpl; +import com.intellij.psi.impl.source.PsiClassReferenceType; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Function; @@ -54,6 +52,7 @@ public class JavaResolveCache { } private final ConcurrentMap myCalculatedTypes = new ConcurrentWeakHashMap(); + private final ConcurrentMap myCachedReferencesInPsiTypes = new ConcurrentWeakHashMap(); private final Map myVarToConstValueMap1; private final Map myVarToConstValueMap2; @@ -78,6 +77,7 @@ public class JavaResolveCache { private void clearCaches(boolean isPhysical) { myCalculatedTypes.clear(); + myCachedReferencesInPsiTypes.clear(); if (isPhysical) { myVarToConstValueMap1.clear(); } @@ -97,20 +97,31 @@ public class JavaResolveCache { type = TypeConversionUtil.NULL_TYPE; } type = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type); - DebugUtil.trackInvalidation(expr, new Processor() { - @Override - public boolean process(PsiElement element) { - PsiType cached = myCalculatedTypes.get(element); - if (cached != null) { - LOG.error(element + " is invalid and yet it is still cached: " + cached); + if (type instanceof PsiClassReferenceType) { + PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)type).getReference(); + myCachedReferencesInPsiTypes.put(reference, type); + } + if (DebugUtil.DO_EXPENSIVE_CHECKS) { + DebugUtil.trackInvalidation(expr, new Processor() { + @Override + public boolean process(PsiElement element) { + PsiType cached = myCalculatedTypes.get(element); + if (cached != null) { + LOG.error(element + " is invalid and yet it is still cached: " + cached); + } + + PsiType cachedRef = myCachedReferencesInPsiTypes.get(element); + if (cachedRef != null) { + LOG.error(element + " is invalid and yet it is still cached (inside PsiType): " + cachedRef); + } + return true; } - return true; - } - }); + }); + } } if (!type.isValid()) { if (expr.isValid()) { - LOG.error("Type is invalid: " + type + "; expr: '" + expr + "' is valid"); + LOG.error("Type is invalid: " + type + " (" + type.getClass() + "); expr: '" + expr + "' is valid"); } else { LOG.error("Expression: '"+expr+"' is invalid, must not be used for getType()"); diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DebugUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/DebugUtil.java index 8f9cdde45ad8..f65f1c1ee540 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/DebugUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/DebugUtil.java @@ -79,6 +79,7 @@ public class DebugUtil { } public static /*final*/ boolean CHECK = false; + public static final boolean DO_EXPENSIVE_CHECKS = true; public static final boolean CHECK_INSIDE_ATOMIC_ACTION_ENABLED = false; public static String psiTreeToString(@NotNull final PsiElement element, final boolean skipWhitespaces) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java index 75071a7c2f1b..3112ca401d2e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/PsiDocumentManagerImpl.java @@ -347,7 +347,7 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec if (success) { runAfterCommitActions(document); - if (LOG.isDebugEnabled()) { + if (DebugUtil.DO_EXPENSIVE_CHECKS) { checkAllElementsValid(document, reason, event); } }