mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
TreeChangePreprocessorBase: extract common code and simplify
This commit is contained in:
@@ -17,34 +17,24 @@ package com.intellij.json.psi.impl;
|
||||
|
||||
import com.intellij.json.JsonLanguage;
|
||||
import com.intellij.json.psi.JsonFile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessorBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class JsonTreeChangePreprocessor extends PsiTreeChangePreprocessorBase {
|
||||
public JsonTreeChangePreprocessor(@NotNull Project project) {
|
||||
super(project);
|
||||
public JsonTreeChangePreprocessor(@NotNull PsiManager psiManager) {
|
||||
super(psiManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
if (event.getFile() instanceof JsonFile) {
|
||||
super.treeChanged(event);
|
||||
}
|
||||
protected boolean acceptsEvent(@NotNull PsiTreeChangeEventImpl event) {
|
||||
return event.getFile() instanceof JsonFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInsideCodeBlock(@Nullable PsiElement element) {
|
||||
if (element instanceof PsiFileSystemItem) {
|
||||
return false;
|
||||
}
|
||||
if (element == null || element.getParent() == null) {
|
||||
return true;
|
||||
}
|
||||
return !(element.getLanguage() instanceof JsonLanguage);
|
||||
protected boolean isOutOfCodeBlock(@NotNull PsiElement element) {
|
||||
return element.getLanguage() instanceof JsonLanguage;
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -86,7 +85,6 @@ public class PsiManagerImpl extends PsiManagerEx {
|
||||
myFileManager = isProjectDefault ? new EmptyFileManager(this) : new FileManagerImpl(this, fileDocumentManager, fileIndex);
|
||||
|
||||
myTreeChangePreprocessors.add((PsiTreeChangePreprocessor)modificationTracker);
|
||||
Collections.addAll(myTreeChangePreprocessors, Extensions.getExtensions(PsiTreeChangePreprocessor.EP_NAME, myProject));
|
||||
|
||||
Disposer.register(project, new Disposable() {
|
||||
@Override
|
||||
@@ -361,6 +359,9 @@ public class PsiManagerImpl extends PsiManagerEx {
|
||||
for (PsiTreeChangePreprocessor preprocessor : myTreeChangePreprocessors) {
|
||||
preprocessor.treeChanged(event);
|
||||
}
|
||||
for (PsiTreeChangePreprocessor preprocessor : Extensions.getExtensions(PsiTreeChangePreprocessor.EP_NAME, myProject)) {
|
||||
preprocessor.treeChanged(event);
|
||||
}
|
||||
|
||||
for (PsiTreeChangeListener listener : myTreeChangeListeners) {
|
||||
try {
|
||||
|
||||
@@ -29,6 +29,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType.CHILD_MOVED;
|
||||
import static com.intellij.psi.impl.PsiTreeChangeEventImpl.PsiEventType.PROPERTY_CHANGED;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
* Date: Jul 18, 2002
|
||||
@@ -88,12 +91,17 @@ public class PsiModificationTrackerImpl implements PsiModificationTracker, PsiTr
|
||||
return;
|
||||
}
|
||||
|
||||
PsiTreeChangeEventImpl.PsiEventType code = event.getCode();
|
||||
boolean outOfCodeBlock =
|
||||
code == PROPERTY_CHANGED ? event.getPropertyName() == PsiTreeChangeEvent.PROP_UNLOADED_PSI :
|
||||
code == CHILD_MOVED ? event.getOldParent() instanceof PsiDirectory || event.getNewParent() instanceof PsiDirectory :
|
||||
event.getParent() instanceof PsiDirectory;
|
||||
|
||||
myModificationCount.getAndIncrement();
|
||||
if (event.getParent() instanceof PsiDirectory
|
||||
|| event.getOldParent() instanceof PsiDirectory /* move events */) {
|
||||
if (outOfCodeBlock) {
|
||||
myJavaStructureModificationCount.getAndIncrement();
|
||||
myOutOfCodeBlockModificationCount.getAndIncrement();
|
||||
}
|
||||
|
||||
fireEvent();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,84 +16,111 @@
|
||||
|
||||
package com.intellij.psi.impl;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class PsiTreeChangePreprocessorBase implements PsiTreeChangePreprocessor {
|
||||
@NotNull private final Project myProject;
|
||||
|
||||
public PsiTreeChangePreprocessorBase(@NotNull Project project) {
|
||||
myProject = project;
|
||||
protected final PsiManager myPsiManager;
|
||||
|
||||
public PsiTreeChangePreprocessorBase(@NotNull PsiManager psiManager) {
|
||||
myPsiManager = psiManager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Project getProject() {
|
||||
return myProject;
|
||||
protected abstract boolean acceptsEvent(@NotNull PsiTreeChangeEventImpl event);
|
||||
|
||||
/**
|
||||
* Shall return true <em>if and only if</em> the element is considered to be "out of code block"
|
||||
* (the exact meaning is language- or technology-specific); otherwise false.
|
||||
*
|
||||
* @see PsiModificationTrackerImpl#getOutOfCodeBlockModificationCount()
|
||||
*/
|
||||
protected abstract boolean isOutOfCodeBlock(@NotNull PsiElement element);
|
||||
|
||||
protected boolean isOutOfCodeBlock(@NotNull PsiFileSystemItem file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isOutOfCodeBlockInvalid(@NotNull PsiElement element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean outOfCodeBlock(@Nullable PsiElement element) {
|
||||
if (element == null) 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
public final void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
if (!PsiModificationTrackerImpl.canAffectPsi(event)) {
|
||||
return;
|
||||
}
|
||||
if (!acceptsEvent(event)) {
|
||||
return;
|
||||
}
|
||||
onTreeChanged(event);
|
||||
}
|
||||
|
||||
boolean changedInsideCodeBlock = false;
|
||||
protected void onTreeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
boolean outOfCodeBlock;
|
||||
|
||||
switch (event.getCode()) {
|
||||
case BEFORE_CHILDREN_CHANGE:
|
||||
if (event.getParent() instanceof PsiFile) {
|
||||
changedInsideCodeBlock = true;
|
||||
break; // May be caused by fake PSI event from PomTransaction. A real event will anyway follow.
|
||||
}
|
||||
case BEFORE_PROPERTY_CHANGE:
|
||||
case BEFORE_CHILD_MOVEMENT:
|
||||
case BEFORE_CHILD_ADDITION:
|
||||
case BEFORE_CHILD_REMOVAL:
|
||||
case BEFORE_CHILD_REPLACEMENT:
|
||||
outOfCodeBlock = false;
|
||||
break;
|
||||
|
||||
case BEFORE_CHILDREN_CHANGE:
|
||||
case CHILDREN_CHANGED:
|
||||
if (event.isGenericChange()) {
|
||||
return;
|
||||
}
|
||||
changedInsideCodeBlock = isInsideCodeBlock(event.getParent());
|
||||
outOfCodeBlock = outOfCodeBlock(event.getParent());
|
||||
break;
|
||||
|
||||
case BEFORE_CHILD_ADDITION:
|
||||
case BEFORE_CHILD_REMOVAL:
|
||||
case CHILD_ADDED:
|
||||
case CHILD_REMOVED:
|
||||
case BEFORE_CHILD_REPLACEMENT:
|
||||
case CHILD_REPLACED :
|
||||
changedInsideCodeBlock = isInsideCodeBlock(event.getParent()) &&
|
||||
isInsideCodeBlock(event.getChild()) &&
|
||||
isInsideCodeBlock(event.getOldChild()) &&
|
||||
isInsideCodeBlock(event.getNewChild());
|
||||
case CHILD_REPLACED:
|
||||
outOfCodeBlock = outOfCodeBlock(event.getParent()) ||
|
||||
outOfCodeBlock(event.getChild()) ||
|
||||
outOfCodeBlock(event.getOldChild()) ||
|
||||
outOfCodeBlock(event.getNewChild());
|
||||
break;
|
||||
|
||||
case BEFORE_PROPERTY_CHANGE:
|
||||
case PROPERTY_CHANGED:
|
||||
changedInsideCodeBlock = false;
|
||||
outOfCodeBlock = true;
|
||||
break;
|
||||
|
||||
case BEFORE_CHILD_MOVEMENT:
|
||||
case CHILD_MOVED:
|
||||
changedInsideCodeBlock = isInsideCodeBlock(event.getOldParent()) &&
|
||||
isInsideCodeBlock(event.getNewParent()) &&
|
||||
isInsideCodeBlock(event.getChild());
|
||||
outOfCodeBlock = outOfCodeBlock(event.getOldParent()) ||
|
||||
outOfCodeBlock(event.getNewParent()) ||
|
||||
outOfCodeBlock(event.getChild());
|
||||
break;
|
||||
default:
|
||||
outOfCodeBlock = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!changedInsideCodeBlock) {
|
||||
processOutOfCodeBlockModification(event);
|
||||
if (outOfCodeBlock) {
|
||||
onOutOfCodeBlockModification(event);
|
||||
doIncOutOfCodeBlockCounter();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiModificationTrackerImpl getModificationTracker() {
|
||||
return (PsiModificationTrackerImpl)PsiManager.getInstance(myProject).getModificationTracker();
|
||||
protected void onOutOfCodeBlockModification(@NotNull PsiTreeChangeEventImpl event) {
|
||||
}
|
||||
|
||||
protected void processOutOfCodeBlockModification(final PsiTreeChangeEventImpl event) {
|
||||
getModificationTracker().incOutOfCodeBlockModificationCounter();
|
||||
protected void doIncOutOfCodeBlockCounter() {
|
||||
((PsiModificationTrackerImpl)myPsiManager.getModificationTracker()).incOutOfCodeBlockModificationCounter();
|
||||
}
|
||||
|
||||
protected abstract boolean isInsideCodeBlock(PsiElement element);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package org.jetbrains.yaml.psi;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessorBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -13,41 +12,33 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author oleg
|
||||
*/
|
||||
final class YAMLPsiManager extends PsiTreeChangePreprocessorBase {
|
||||
public YAMLPsiManager(@NotNull Project project) {
|
||||
super(project);
|
||||
public YAMLPsiManager(@NotNull PsiManager psiManager) {
|
||||
super(psiManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInsideCodeBlock(PsiElement element) {
|
||||
if (element instanceof PsiFileSystemItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (element == null || element.getParent() == null) {
|
||||
return true;
|
||||
}
|
||||
protected boolean acceptsEvent(@NotNull PsiTreeChangeEventImpl event) {
|
||||
return event.getFile() instanceof YAMLFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isOutOfCodeBlock(@NotNull PsiElement element) {
|
||||
while (true) {
|
||||
if (element instanceof YAMLFile) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (element instanceof PsiFile || element instanceof PsiDirectory) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof YAMLFile ||
|
||||
parent instanceof YAMLKeyValue ||
|
||||
parent instanceof YAMLCompoundValue ||
|
||||
parent instanceof YAMLDocument)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
element = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
if (!(event.getFile() instanceof YAMLFile)) return;
|
||||
super.treeChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
*/
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessorBase;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
@@ -27,34 +26,27 @@ import com.jetbrains.python.psi.PyFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PythonPsiManager extends PsiTreeChangePreprocessorBase {
|
||||
public PythonPsiManager(@NotNull Project project) {
|
||||
super(project);
|
||||
public PythonPsiManager(@NotNull PsiManager psiManager) {
|
||||
super(psiManager);
|
||||
}
|
||||
|
||||
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
if (event.getFile() instanceof PyFile) {
|
||||
super.treeChanged(event);
|
||||
}
|
||||
@Override
|
||||
protected boolean acceptsEvent(@NotNull PsiTreeChangeEventImpl event) {
|
||||
return event.getFile() instanceof PyFile;
|
||||
}
|
||||
|
||||
protected boolean isInsideCodeBlock(PsiElement element) {
|
||||
if (element instanceof PsiFileSystemItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (element == null || !element.isValid() || element.getParent() == null) return true;
|
||||
|
||||
protected boolean isOutOfCodeBlock(@NotNull PsiElement element) {
|
||||
while (true) {
|
||||
if (element instanceof PyFile) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (element instanceof PsiFile || element instanceof PsiDirectory || element == null) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
PsiElement pparent = element.getParent();
|
||||
if (pparent instanceof PyFunction) {
|
||||
final PyFunction pyFunction = (PyFunction)pparent;
|
||||
return !(element == pyFunction.getParameterList() || element == pyFunction.getNameIdentifier());
|
||||
PyFunction pyFunction = (PyFunction)pparent;
|
||||
return element == pyFunction.getParameterList() || element == pyFunction.getNameIdentifier();
|
||||
}
|
||||
element = pparent;
|
||||
}
|
||||
|
||||
@@ -1,36 +1,28 @@
|
||||
package com.intellij.xml;
|
||||
|
||||
import com.intellij.lang.xml.XMLLanguage;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessorBase;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class XmlPsiTreeChangePreprocessor extends PsiTreeChangePreprocessorBase {
|
||||
public XmlPsiTreeChangePreprocessor(@NotNull Project project) {
|
||||
super(project);
|
||||
public XmlPsiTreeChangePreprocessor(@NotNull PsiManager psiManager) {
|
||||
super(psiManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInsideCodeBlock(PsiElement element) {
|
||||
if (element instanceof PsiFileSystemItem) {
|
||||
return false;
|
||||
}
|
||||
protected boolean acceptsEvent(@NotNull PsiTreeChangeEventImpl event) {
|
||||
return event.getFile() instanceof XmlFile;
|
||||
}
|
||||
|
||||
if (element == null || element.getParent() == null) return true;
|
||||
|
||||
final boolean isXml = element.getLanguage() instanceof XMLLanguage;
|
||||
@Override
|
||||
protected boolean isOutOfCodeBlock(@NotNull PsiElement element) {
|
||||
// any xml element isn't inside a "code block"
|
||||
// cause we display even attributes and tag values in structure view
|
||||
return !isXml;
|
||||
return element.getLanguage() instanceof XMLLanguage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeChanged(@NotNull PsiTreeChangeEventImpl event) {
|
||||
if (!(event.getFile() instanceof XmlFile)) return;
|
||||
super.treeChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user