From 9b097070df785fde77e429154655c1a763a0e962 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Fri, 19 May 2023 00:17:49 +0200 Subject: [PATCH] Actions for refreshing managed dependencies and clearing haxelib cache --- .../haxe/buildsystem/lime/LimeOpenFlUtil.java | 29 ++++++++++ .../lime/LimeXmlFileDescription.java | 10 +--- .../lime/OpenflXmlFileDescription.java | 10 +--- .../plugins/haxe/haxelib/HaxelibCache.java | 3 + .../plugins/haxe/haxelib/HaxelibNotifier.java | 26 +++++++++ .../haxe/haxelib/HaxelibProjectUpdater.java | 53 ++++------------- .../plugins/haxe/haxelib/HaxelibUtil.java | 2 + .../ide/HXMLHaxelibCompletionContributor.java | 2 +- .../haxelib/ClearHaxeLibCacheAction.java | 57 +++++++++++++++++++ .../haxelib/SyncProjectLibraryListAction.java | 57 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 21 +++++++ .../resources/messages/HaxeBundle.properties | 5 +- 12 files changed, 214 insertions(+), 61 deletions(-) create mode 100644 src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibNotifier.java create mode 100644 src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/ClearHaxeLibCacheAction.java create mode 100644 src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/SyncProjectLibraryListAction.java diff --git a/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeOpenFlUtil.java b/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeOpenFlUtil.java index 930544f6b..9067c5fb1 100644 --- a/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeOpenFlUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeOpenFlUtil.java @@ -1,7 +1,11 @@ package com.intellij.plugins.haxe.buildsystem.lime; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import lombok.experimental.UtilityClass; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -10,4 +14,29 @@ public class LimeOpenFlUtil { public boolean isOpenfl(XmlTag rootTag) { return Arrays.stream(rootTag.findSubTags("haxelib")).anyMatch(xmlTag -> "openfl".equalsIgnoreCase(xmlTag.getAttribute("name").getValue())); } + + public boolean isOpenFlFile(@NotNull XmlFile file) { + if(!FileUtilRt.extensionEquals(file.getName(), "xml")) return false; + + XmlDocument document = file.getDocument(); + if(document == null) return false; + + XmlTag rootTag = document.getRootTag(); + if(rootTag == null) return false; + + return LimeOpenFlUtil.isOpenfl(rootTag); + } + + public boolean isLimeFile(@NotNull XmlFile file) { + if(!FileUtilRt.extensionEquals(file.getName(), "xml")) return false; + + XmlDocument document = file.getDocument(); + if (document == null) return false; + + XmlTag rootTag = document.getRootTag(); + if (rootTag == null) return false; + + return !LimeOpenFlUtil.isOpenfl(rootTag); + } + } diff --git a/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeXmlFileDescription.java b/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeXmlFileDescription.java index 00998bb90..ddeaa4d36 100644 --- a/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeXmlFileDescription.java +++ b/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/LimeXmlFileDescription.java @@ -28,15 +28,7 @@ public Icon getFileIcon(@Iconable.IconFlags int flags) { @Override public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) { - if(!FileUtilRt.extensionEquals(file.getName(), "xml")) return false; - - XmlDocument document = file.getDocument(); - if (document == null) return false; - - XmlTag rootTag = document.getRootTag(); - if (rootTag == null) return false; - - return !LimeOpenFlUtil.isOpenfl(rootTag); + return LimeOpenFlUtil.isLimeFile(file); } diff --git a/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/OpenflXmlFileDescription.java b/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/OpenflXmlFileDescription.java index 4becba84b..a7f59975a 100644 --- a/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/OpenflXmlFileDescription.java +++ b/src/main/java/com/intellij/plugins/haxe/buildsystem/lime/OpenflXmlFileDescription.java @@ -25,15 +25,7 @@ public Icon getFileIcon(@Iconable.IconFlags int flags) { @Override public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) { - if(!FileUtilRt.extensionEquals(file.getName(), "xml")) return false; - - XmlDocument document = file.getDocument(); - if(document == null) return false; - - XmlTag rootTag = document.getRootTag(); - if(rootTag == null) return false; - - return LimeOpenFlUtil.isOpenfl(rootTag); + return LimeOpenFlUtil.isOpenFlFile(file); } } \ No newline at end of file diff --git a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibCache.java b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibCache.java index 15b729a75..7d173b382 100644 --- a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibCache.java +++ b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibCache.java @@ -60,6 +60,9 @@ public static HaxelibCache getInstance() { return instance; } + public void reload() { + load(); + } private void load() { Module haxeModule = getHaxeModule(); diff --git a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibNotifier.java b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibNotifier.java new file mode 100644 index 000000000..51cc7ee61 --- /dev/null +++ b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibNotifier.java @@ -0,0 +1,26 @@ +package com.intellij.plugins.haxe.haxelib; + +import com.intellij.notification.NotificationGroupManager; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.project.Project; +import com.intellij.plugins.haxe.HaxeBundle; +import org.jetbrains.annotations.Nullable; + +public class HaxelibNotifier { + + public static void notifyMissingLib(@Nullable Project project, String content) { + NotificationGroupManager.getInstance() + .getNotificationGroup("haxe.haxelib.warning") + .createNotification(content, NotificationType.WARNING) + .setTitle(HaxeBundle.message("haxe.haxelib.library.dependencies")) + .setContent(HaxeBundle.message("haxe.haxelib.library.missing", content)) + //.addAction(new DumbAwareAction() { + // //TODO create haxelib install logic + // @Override + // public void actionPerformed(@NotNull AnActionEvent e) { + // + // } + //}) + .notify(project); + } +} diff --git a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibProjectUpdater.java b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibProjectUpdater.java index d5e252cd7..8f1483dcb 100644 --- a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibProjectUpdater.java +++ b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibProjectUpdater.java @@ -98,13 +98,6 @@ public class HaxelibProjectUpdater { * It overrides myRunInForeground. The UI is blocked with no updates. */ private static final boolean myTestInForeground = false; - /** - * Set this true to put up a modal dialog and run in the foreground thread - * (locking up the UI.) - * Set it false to run in a background thread. Progress is updated in the - * status bar and the UI is usable. - */ - private static final boolean myRunInForeground = false; public static final HaxelibProjectUpdater INSTANCE = new HaxelibProjectUpdater(); @@ -146,7 +139,6 @@ public boolean closeProject(Project project) { ProjectTracker tracker = myProjects.get(project); removed = myProjects.remove(project); - tracker.dispose(); if (removed) { myQueue.remove(tracker); if (tracker.equals(myQueue.getUpdatingProject())) { @@ -636,6 +628,7 @@ private static void syncOpenFLModule(@NotNull Module module, else { // TODO: Figure out how to report this to the user. log.warn("Required library 'openfl' is not known to haxelib."); + HaxelibNotifier.notifyMissingLib(project, "openfl"); } // TODO: Pull libs off of the command line, too. @@ -765,7 +758,7 @@ private void syncModuleClasspaths(final ProjectTracker tracker) { } - private void synchronizeClasspaths(@NotNull ProjectTracker tracker) { + public void synchronizeClasspaths(@NotNull ProjectTracker tracker) { // // Either of these commented-out sections will cause indexing to not be attempted @@ -1229,7 +1222,7 @@ public void setPropertiesList(HaxeLibraryList propertiesList) { /** * Tracks the state of a project for updating class paths. */ - public final class ProjectTracker implements Disposable { + public final class ProjectTracker { final Project myProject; boolean myIsDirty; boolean myIsUpdating; @@ -1255,7 +1248,7 @@ public ProjectTracker(Project project) { mySdkManager = new HaxelibLibraryCacheManager(); VirtualFileManager mgr = VirtualFileManager.getInstance(); - mgr.addAsyncFileListener(this::lookForLibChanges, this); + mgr.addAsyncFileListener(this::lookForLibChanges, project); } /** @@ -1385,12 +1378,6 @@ public boolean equalsName(@Nullable ProjectTracker tracker) { return myProject.getName().equals(tracker.getProject().getName()); } - @Override - public void dispose() { - - - } - private AsyncFileListener.ChangeApplier lookForLibChanges(List events) { if(getProject().isDisposed()) return null; List list = events.stream() @@ -1641,31 +1628,15 @@ private void runUpdate() { if (myTestInForeground) { doUpdateWork(); - } else if (myRunInForeground) { - // TODO: Put this string in a resource bundle. - ProgressManager.getInstance().run(new Task.Modal(project, "Synchronizing with haxelib libraries...", false) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - indicator.setIndeterminate(true); - indicator.startNonCancelableSection(); - doUpdateWork(); - indicator.finishNonCancelableSection(); - } - }); } else { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - ProgressManager.getInstance().run( - // TODO: Put this string in a resource bundle. - new Task.Backgroundable(project, "Synchronizing with haxelib libraries...", false, PerformInBackgroundOption.ALWAYS_BACKGROUND) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - doUpdateWork(); - } - }); - } - }); + ApplicationManager.getApplication().invokeLater(() -> ProgressManager.getInstance().run( + // TODO: Put this string in a resource bundle. + new Task.Backgroundable(project, "Synchronizing with haxelib libraries...", false, PerformInBackgroundOption.ALWAYS_BACKGROUND) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + doUpdateWork(); + } + })); } } diff --git a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibUtil.java b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibUtil.java index ff1ef5997..de71696d0 100644 --- a/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibUtil.java +++ b/src/main/java/com/intellij/plugins/haxe/haxelib/HaxelibUtil.java @@ -374,6 +374,8 @@ public static HaxeLibraryList createHaxelibsFromHaxeLibData(@NotNull List haxelibCache = HaxelibCache.getInstance(), "sdadsds", false, null); + ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> haxelibCache = HaxelibCache.getInstance(), "Fetching haxelib list", false, null); // intelliJ 2018 and older extend(CompletionType.BASIC, psiElement(HXMLTypes.VALUE).withParent(HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), getProvider()); diff --git a/src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/ClearHaxeLibCacheAction.java b/src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/ClearHaxeLibCacheAction.java new file mode 100644 index 000000000..db3801560 --- /dev/null +++ b/src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/ClearHaxeLibCacheAction.java @@ -0,0 +1,57 @@ +package com.intellij.plugins.haxe.ide.actions.haxelib; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.plugins.haxe.buildsystem.hxml.psi.HXMLFile; +import com.intellij.plugins.haxe.buildsystem.lime.LimeOpenFlUtil; +import com.intellij.plugins.haxe.haxelib.HaxelibCache; +import com.intellij.psi.xml.XmlFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ClearHaxeLibCacheAction extends AnAction implements DumbAware { + @Override + public @NotNull ActionUpdateThread getActionUpdateThread() { + return ActionUpdateThread.BGT; + } + + @Override + public void update(@NotNull AnActionEvent event) { + super.update(event); + Presentation p = event.getPresentation(); + p.setEnabled(isAvailable(event)); + p.setVisible(isVisible(event)); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent event) { + HaxelibCache.getInstance().reload(); + } + + protected boolean isAvailable(AnActionEvent e) { + return getProject(e) != null && isVisible(e); + } + + protected boolean isVisible(AnActionEvent e) { + return switch (e.getPlace()) { + case "EditorPopup" -> isProjectFile(e); + case "ProjectViewPopup" -> true; + default -> false; + }; + } + + private static boolean isProjectFile(AnActionEvent e) { + Object file = e.getDataContext().getData("psi.File"); + if (file instanceof XmlFile xmlFile) { + return LimeOpenFlUtil.isLimeFile(xmlFile) || LimeOpenFlUtil.isOpenFlFile(xmlFile); + } + return file instanceof HXMLFile; + } + + @Nullable + private static Project getProject(AnActionEvent e) { + DataContext context = e.getDataContext(); + return CommonDataKeys.PROJECT.getData(context); + } +} diff --git a/src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/SyncProjectLibraryListAction.java b/src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/SyncProjectLibraryListAction.java new file mode 100644 index 000000000..64becd8fa --- /dev/null +++ b/src/main/java/com/intellij/plugins/haxe/ide/actions/haxelib/SyncProjectLibraryListAction.java @@ -0,0 +1,57 @@ +package com.intellij.plugins.haxe.ide.actions.haxelib; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.plugins.haxe.buildsystem.hxml.psi.HXMLFile; +import com.intellij.plugins.haxe.buildsystem.lime.LimeOpenFlUtil; +import com.intellij.plugins.haxe.haxelib.HaxelibProjectUpdater; +import com.intellij.psi.xml.XmlFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SyncProjectLibraryListAction extends AnAction implements DumbAware { + + @Override + public void update(@NotNull AnActionEvent event) { + super.update(event); + Presentation p = event.getPresentation(); + p.setEnabled(isAvailable(event)); + p.setVisible(isVisible(event)); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + HaxelibProjectUpdater instance = HaxelibProjectUpdater.INSTANCE; + Project project = getProject(e); + HaxelibProjectUpdater.ProjectTracker tracker = instance.findProjectTracker(project); + if(tracker!= null) instance.synchronizeClasspaths(tracker); + } + + protected boolean isAvailable(AnActionEvent e) { + return getProject(e) != null && isVisible(e); + } + + protected boolean isVisible(AnActionEvent e) { + return switch (e.getPlace()) { + case "EditorPopup" -> isProjectFile(e); + case "ProjectViewPopup" -> true; + default -> false; + }; + } + + private static boolean isProjectFile(AnActionEvent e) { + Object file = e.getDataContext().getData("psi.File"); + if (file instanceof XmlFile xmlFile) { + return LimeOpenFlUtil.isLimeFile(xmlFile) || LimeOpenFlUtil.isOpenFlFile(xmlFile); + } + return file instanceof HXMLFile; + } + + @Nullable + private static Project getProject(AnActionEvent e) { + DataContext context = e.getDataContext(); + return CommonDataKeys.PROJECT.getData(context); + } + +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5e487118c..f1410e6f8 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -309,6 +309,8 @@ + + @@ -344,5 +346,24 @@ text="Getter and Setter"> + + + + + + + + + + + + + + + diff --git a/src/main/resources/messages/HaxeBundle.properties b/src/main/resources/messages/HaxeBundle.properties index d9b6a3104..3a2154095 100644 --- a/src/main/resources/messages/HaxeBundle.properties +++ b/src/main/resources/messages/HaxeBundle.properties @@ -313,4 +313,7 @@ haxe.unused.conditionally.compiled.code=Haxe: Unused conditionally compiled code dialog.import.on.paste.title=Select Classes to Import dialog.paste.on.import.text=The code fragment which you have pasted uses classes that are not accessible by imports in the new context.
Select classes that you want to import to the new file. -action.structureview.show.fields=Show Fields \ No newline at end of file +action.structureview.show.fields=Show Fields + +haxe.haxelib.library.missing=Haxelib could not find library named {0} +haxe.haxelib.library.dependencies=Haxe project dependencies \ No newline at end of file