mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[workspace model] migrate ExternalAnnotationsManager (IDEA-295111)
GitOrigin-RevId: 49ab4d729342875a697b8612a04c27c7aeb3981f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2ff41b74ef
commit
51fb599b8f
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
@@ -46,6 +46,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.NlsActions;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
@@ -73,7 +74,15 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.OptionsMessageDialog;
|
||||
import com.intellij.workspaceModel.ide.WorkspaceModelChangeListener;
|
||||
import com.intellij.workspaceModel.ide.WorkspaceModelTopics;
|
||||
import com.intellij.workspaceModel.storage.EntityChange;
|
||||
import com.intellij.workspaceModel.storage.VersionedStorageChange;
|
||||
import com.intellij.workspaceModel.storage.WorkspaceEntity;
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.LibraryEntity;
|
||||
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleCustomImlDataEntity;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.*;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
@@ -85,6 +94,7 @@ import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -104,9 +114,12 @@ public final class ExternalAnnotationsManagerImpl extends ReadableExternalAnnota
|
||||
|
||||
myBus = project.getMessageBus();
|
||||
MessageBusConnection connection = myBus.connect(this);
|
||||
|
||||
WorkspaceModelTopics.getInstance(project).subscribeAfterModuleLoading(connection, new ExternalAnnotationsRootListener());
|
||||
connection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
|
||||
@Override
|
||||
public void rootsChanged(@NotNull ModuleRootEvent event) {
|
||||
if (event.isCausedByWorkspaceModelChangesOnly()) return;
|
||||
dropAnnotationsCache();
|
||||
}
|
||||
});
|
||||
@@ -1110,4 +1123,59 @@ public final class ExternalAnnotationsManagerImpl extends ReadableExternalAnnota
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ExternalAnnotationsRootListener implements WorkspaceModelChangeListener {
|
||||
@Override
|
||||
public void changed(@NotNull VersionedStorageChange event) {
|
||||
if (hasAnnotationRootInChanges(event, LibraryEntity.class, this::hasAnnotationRoot) ||
|
||||
hasAnnotationRootInChanges(event, ModuleCustomImlDataEntity.class, this::hasAnnotationRoot)) {
|
||||
dropAnnotationsCache();
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends WorkspaceEntity> boolean hasAnnotationRootInChanges(@NotNull VersionedStorageChange event,
|
||||
@NotNull Class<T> entityClass,
|
||||
@NotNull Predicate<T> hasAnnotationRoot) {
|
||||
for (EntityChange<T> change : event.getChanges(entityClass)) {
|
||||
if (change instanceof EntityChange.Added<?>) {
|
||||
if (hasAnnotationRoot.test(((EntityChange.Added<T>)change).getEntity())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (change instanceof EntityChange.Removed<?>) {
|
||||
if (hasAnnotationRoot.test(((EntityChange.Removed<T>)change).getEntity())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (change instanceof EntityChange.Replaced<?>) {
|
||||
if (hasAnnotationRoot.test(((EntityChange.Replaced<T>)change).getOldEntity()) ||
|
||||
hasAnnotationRoot.test(((EntityChange.Replaced<T>)change).getNewEntity())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasAnnotationRoot(LibraryEntity e) {
|
||||
return e.getRoots().stream().anyMatch(root -> "ANNOTATIONS".equals(root.getType().getName()));
|
||||
}
|
||||
|
||||
private boolean hasAnnotationRoot(ModuleCustomImlDataEntity e) {
|
||||
String tagCustomData = e.getRootManagerTagCustomData();
|
||||
if (tagCustomData != null) {
|
||||
try {
|
||||
Element element = JDOMUtil.load(tagCustomData);
|
||||
Element child = element.getChild("annotation-paths");
|
||||
if (child != null && !child.getChildren("root").isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<root>
|
||||
<item name='rootRemoved.Foo'>
|
||||
<annotation name='java.lang.Deprecated'/>
|
||||
</item>
|
||||
</root>
|
||||
@@ -0,0 +1,3 @@
|
||||
package rootRemoved;
|
||||
public class Foo {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
@@ -15,10 +15,7 @@ import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.roots.AnnotationOrderRootType;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -384,6 +381,27 @@ public class AddAnnotationFixTest extends UsefulTestCase {
|
||||
file.refresh(false, false);
|
||||
});
|
||||
stopListeningAndCheckEvents();
|
||||
}
|
||||
|
||||
public void testLibraryAnnotationRootsChanged() throws IOException {
|
||||
addDefaultLibrary();
|
||||
myFixture.configureByFiles("content/anno/p/annotations.xml");
|
||||
PsiFile[] files = myFixture.configureByFiles("lib/p/TestDeannotation.java");
|
||||
|
||||
PsiClass aClass = ((PsiJavaFile)files[0]).getClasses()[0];
|
||||
assertNotNull(aClass);
|
||||
assertTrue(AnnotationUtil.isAnnotated(aClass.getMethods()[0], AnnotationUtil.NOT_NULL, AnnotationUtil.CHECK_EXTERNAL));
|
||||
|
||||
ModuleRootModificationUtil.updateModel(myFixture.getModule(), model -> {
|
||||
final LibraryTable libraryTable = model.getModuleLibraryTable();
|
||||
Library library = libraryTable.getModifiableModel().getLibraryByName("test");
|
||||
Library.ModifiableModel libraryModifiableModel = library.getModifiableModel();
|
||||
libraryModifiableModel.removeRoot(VfsUtilCore.pathToUrl(myFixture.getTempDirPath() + "/content/anno"),
|
||||
AnnotationOrderRootType.getInstance());
|
||||
libraryModifiableModel.commit();
|
||||
});
|
||||
|
||||
assertFalse(AnnotationUtil.isAnnotated(aClass.getMethods()[0], AnnotationUtil.NOT_NULL, AnnotationUtil.CHECK_EXTERNAL));
|
||||
}
|
||||
|
||||
public void testAnnotationsUpdatedWhenFileEdited() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
|
||||
@@ -11,13 +11,17 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.JavaModuleExternalPaths;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
public class ExternalAnnotationsTest extends UsefulTestCase {
|
||||
private CodeInsightTestFixture myFixture;
|
||||
@@ -116,4 +120,18 @@ public class ExternalAnnotationsTest extends UsefulTestCase {
|
||||
true);
|
||||
|
||||
}
|
||||
|
||||
public void testExternalAnnotationsRootRemoved() {
|
||||
myFixture.configureByFiles("src/rootRemoved/Foo.java", "content/anno/rootRemoved/annotations.xml");
|
||||
Project project = myFixture.getProject();
|
||||
PsiClass aClass = JavaPsiFacade.getInstance(project)
|
||||
.findClass("rootRemoved.Foo", GlobalSearchScope.projectScope(project));
|
||||
assertNotNull(aClass);
|
||||
assertTrue(aClass.isDeprecated());
|
||||
ModuleRootModificationUtil.updateModel(myFixture.getModule(), model -> {
|
||||
final JavaModuleExternalPaths extension = model.getModuleExtension(JavaModuleExternalPaths.class);
|
||||
extension.setExternalAnnotationUrls(ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
});
|
||||
assertFalse(aClass.isDeprecated());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user