From e5627428a0fa216bd02862bd95df01a7ed54dfae Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 24 Jan 2017 17:56:51 +0300 Subject: [PATCH] IDEA-CR-17604 TreeChangePreprocessorBase: restore original hasClasses() logic --- .../JavaCodeBlockModificationListener.java | 24 +++++++++++++++---- .../impl/PsiTreeChangePreprocessorBase.java | 7 +----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java index 0350673c48f7..a907d437fc6c 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaCodeBlockModificationListener.java @@ -15,8 +15,11 @@ */ package com.intellij.psi.impl; +import com.intellij.openapi.util.Conditions; import com.intellij.psi.*; +import com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType; import com.intellij.psi.impl.source.jsp.jspXml.JspDirective; +import com.intellij.psi.util.PsiModificationTracker; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +38,7 @@ public class JavaCodeBlockModificationListener extends PsiTreeChangePreprocessor protected boolean isOutOfCodeBlock(@NotNull PsiElement element) { for (PsiElement e : SyntaxTraverser.psiApi().parents(element)) { if (e instanceof PsiModifiableCodeBlock) { - if (hasClassesInside(e)) break; + // trigger OOCBM for final variables initialized in constructors & class initializers if (!((PsiModifiableCodeBlock)e).shouldChangeModificationCount(element)) return false; } if (e instanceof PsiClass) break; @@ -53,8 +56,20 @@ public class JavaCodeBlockModificationListener extends PsiTreeChangePreprocessor } @Override - protected boolean isOutOfCodeBlockInvalid(@NotNull PsiElement element) { - return hasClassesInside(element); + protected void onTreeChanged(@NotNull PsiTreeChangeEventImpl event) { + PsiModificationTracker tracker = myPsiManager.getModificationTracker(); + long cur = tracker.getOutOfCodeBlockModificationCount(); + super.onTreeChanged(event); + if (cur == tracker.getOutOfCodeBlockModificationCount()) { + PsiEventType code = event.getCode(); + if (code == PsiEventType.CHILD_ADDED || code == PsiEventType.CHILD_REMOVED || code == PsiEventType.CHILD_REPLACED) { + if (hasClassesInside(event.getOldChild()) || + event.getOldChild() != event.getChild() && hasClassesInside(event.getChild())) { + onOutOfCodeBlockModification(event); + doIncOutOfCodeBlockCounter(); + } + } + } } @Override @@ -63,7 +78,8 @@ public class JavaCodeBlockModificationListener extends PsiTreeChangePreprocessor } private static boolean hasClassesInside(@Nullable PsiElement element) { - return !SyntaxTraverser.psiTraverser(element).filter(PsiClass.class).isEmpty(); + return !SyntaxTraverser.psiTraverser(element).traverse() + .filter(Conditions.instanceOf(PsiClass.class, PsiLambdaExpression.class)).isEmpty(); } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java index 6c377695c022..43a4b2d092ba 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiTreeChangePreprocessorBase.java @@ -45,14 +45,9 @@ public abstract class PsiTreeChangePreprocessorBase implements PsiTreeChangePrep return true; } - protected boolean isOutOfCodeBlockInvalid(@NotNull PsiElement element) { - return false; - } - private boolean outOfCodeBlock(@Nullable PsiElement element) { - if (element == null) return false; + if (element == null || !element.isValid()) return false; if (element instanceof PsiDirectory) return false; // handled by PsiModificationTrackerImpl#treeChanged() - if (!element.isValid()) return !(element instanceof PsiFileSystemItem) && isOutOfCodeBlockInvalid(element); if (element instanceof PsiFileSystemItem) return isOutOfCodeBlock((PsiFileSystemItem)element); return isOutOfCodeBlock(element); }