From e87d266f3d5905470071f3b970d4652ea0a795ff Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Sat, 15 Nov 2014 19:55:25 +0100 Subject: [PATCH 001/518] Initial commit for intellij save-actions plugin Add idea specific configuration folder (idea folder based structure). Add plugin meta information, plugin components and settings. --- .gitignore | 5 + .idea/.name | 1 + .idea/compiler.xml | 23 ++++ .idea/copyright/profiles_settings.xml | 3 + .idea/encodings.xml | 5 + .idea/misc.xml | 10 ++ .idea/modules.xml | 9 ++ .idea/save-actions.iml | 9 ++ .idea/scopes/scope_settings.xml | 5 + .idea/vcs.xml | 7 ++ LICENSE.txt | 21 ++++ META-INF/plugin.xml | 46 +++++++ README.md | 18 +++ save-actions.iml | 13 ++ src/com/dubreuia/Component.java | 82 +++++++++++++ src/com/dubreuia/Configuration.java | 168 ++++++++++++++++++++++++++ src/com/dubreuia/Settings.java | 68 +++++++++++ 17 files changed, 493 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.name create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/save-actions.iml create mode 100644 .idea/scopes/scope_settings.xml create mode 100644 .idea/vcs.xml create mode 100644 LICENSE.txt create mode 100644 META-INF/plugin.xml create mode 100644 README.md create mode 100644 save-actions.iml create mode 100644 src/com/dubreuia/Component.java create mode 100644 src/com/dubreuia/Configuration.java create mode 100644 src/com/dubreuia/Settings.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57a44a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Intellij user specific (see https://intellij-support.jetbrains.com/entries/23393067) +.idea/tasks.xml +.idea/workspace.xml +# Generated java classes +out diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..cff67bf --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +save-actions \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..217af47 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bbf9cbf --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ac10c77 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.idea/save-actions.iml b/.idea/save-actions.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/save-actions.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..def6a6a --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..32eff30 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Alexandre DuBreuil + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml new file mode 100644 index 0000000..4d62fe4 --- /dev/null +++ b/META-INF/plugin.xml @@ -0,0 +1,46 @@ + + + com.dubreuia + Save Actions + 0.1 + Alexandre DuBreuil + + github | twitter). + ]]> + + +
0.1
+
+
    +
  • Organize imports support
  • +
  • Reformat code support with only changed text option
  • +
  • Rearrange code support
  • +
  • Simple option page to activate / deactivate save actions
  • +
+
+ + ]]> +
+ + + + + + + + + + + com.dubreuia.Component + + + + + + + + + +
diff --git a/README.md b/README.md new file mode 100644 index 0000000..c891f4c --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Intellij Save Actions Plugin + +Supports configurable save actions, including "organize imports", "reformat code" and "rearrange code". + +# Features + +- Organize imports support +- Reformat code support with only changed text option +- Rearrange code support +- Simple option page to activate / deactivate save actions + +# Installation + +The plugin is available from the Intellij IDEA Plugin Repository (TODO https://plugins.jetbrains.com/?idea) and you can install it directly from Intellij IDEA. Go in "File > Settings > Plugins > Browse repositories" and search for "Save Actions". + +# Licence + +MIT License ([here](LICENSE.txt)) diff --git a/save-actions.iml b/save-actions.iml new file mode 100644 index 0000000..b2f3591 --- /dev/null +++ b/save-actions.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/com/dubreuia/Component.java b/src/com/dubreuia/Component.java new file mode 100644 index 0000000..e7c95e4 --- /dev/null +++ b/src/com/dubreuia/Component.java @@ -0,0 +1,82 @@ +package com.dubreuia; + +import com.intellij.AppTopics; +import com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor; +import com.intellij.codeInsight.actions.OptimizeImportsProcessor; +import com.intellij.codeInsight.actions.RearrangeCodeProcessor; +import com.intellij.codeInsight.actions.ReformatCodeProcessor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; +import org.jetbrains.annotations.NotNull; + +public class Component implements ApplicationComponent { + + private Settings settings = ServiceManager.getService(Settings.class); + + public void initComponent() { + MessageBus bus = ApplicationManager.getApplication().getMessageBus(); + MessageBusConnection connection = bus.connect(); + connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, getFileDocumentManagerAdapter()); + } + + private FileDocumentManagerAdapter getFileDocumentManagerAdapter() { + return new FileDocumentManagerAdapter() { + @Override + public void beforeDocumentSaving(@NotNull Document document) { + for (Project project : ProjectManager.getInstance().getOpenProjects()) { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (null != psiFile) { + AbstractLayoutCodeProcessor processor; + processor = getReformatCodeProcessor(project, psiFile); + processor = getRearrangeCodeProcessor(processor); + processor = getOptimizeImportsProcessor(processor, project, psiFile); + if (null != processor) { + processor.run(); + } + } + } + } + }; + } + + private AbstractLayoutCodeProcessor getOptimizeImportsProcessor(AbstractLayoutCodeProcessor processor, Project project, PsiFile psiFile) { + if (null != processor && settings.isImports()) { + return new OptimizeImportsProcessor(processor); + } else if (settings.isImports()) { + return new OptimizeImportsProcessor(project, psiFile); + } + return processor; + } + + private AbstractLayoutCodeProcessor getRearrangeCodeProcessor(AbstractLayoutCodeProcessor processor) { + if (null != processor && settings.isRearrange()) { + return new RearrangeCodeProcessor(processor, null); + } + return processor; + } + + private AbstractLayoutCodeProcessor getReformatCodeProcessor(Project project, PsiFile psiFile) { + if (settings.isReformat()) { + return new ReformatCodeProcessor(project, psiFile, null, settings.isReformatChangedCode()); + } + return null; + } + + public void disposeComponent() { + } + + @NotNull + public String getComponentName() { + return "Save Action"; + } + +} \ No newline at end of file diff --git a/src/com/dubreuia/Configuration.java b/src/com/dubreuia/Configuration.java new file mode 100644 index 0000000..4a4a42f --- /dev/null +++ b/src/com/dubreuia/Configuration.java @@ -0,0 +1,168 @@ +package com.dubreuia; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.*; + +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.ui.IdeBorderFactory; + +public class Configuration implements Configurable { + + private static final String TEXT_TITLE_OPTIONS = "Formatting options"; + private static final String TEXT_TITLE_ACTIONS = "Actions to perform on save"; + + private static final String TEXT_ACTIVATE = "Activate save actions"; + private static final String TEXT_IMPORTS = "Organize imports"; + private static final String TEXT_REFORMAT = "Reformat code"; + private static final String TEXT_REFORMAT_CHANGED_CODE = "Format and rearrange only changed code"; + private static final String TEXT_REARRANGE = "Rearrange code"; + + private static final String TEXT_DISPLAY_NAME = "Save Actions"; + + private Settings settings = ServiceManager.getService(Settings.class); + + private JCheckBox activate; + private JCheckBox imports; + private JCheckBox reformat; + private JCheckBox reformatChangedCode; + private JCheckBox rearrange; + + @Nullable + @Override + public JComponent createComponent() { + JPanel panel = initComponent(); + initActionListeners(); + return panel; + } + + private void initActionListeners() { + activate.addActionListener(getActionListener()); + imports.addActionListener(getActionListener()); + reformat.addActionListener(getActionListener()); + reformatChangedCode.addActionListener(getActionListener()); + rearrange.addActionListener(getActionListener()); + } + + @Override + public boolean isModified() { + boolean modified = settings.isActivate() != activate.isSelected(); + modified = modified || settings.isImports() != imports.isSelected(); + modified = modified || settings.isReformat() != reformat.isSelected(); + modified = modified || settings.isReformatChangedCode() != reformatChangedCode.isSelected(); + modified = modified || settings.isRearrange() != rearrange.isSelected(); + return modified; + } + + @Override + public void apply() throws ConfigurationException { + settings.setActivate(activate.isSelected()); + settings.setImports(imports.isSelected()); + settings.setReformat(reformat.isSelected()); + settings.setReformatChangedCode(reformatChangedCode.isSelected()); + settings.setRearrange(rearrange.isSelected()); + } + + @Override + public void reset() { + activate.setSelected(settings.isActivate()); + imports.setSelected(settings.isImports()); + reformat.setSelected(settings.isReformat()); + reformatChangedCode.setSelected(settings.isReformatChangedCode()); + rearrange.setSelected(settings.isRearrange()); + updateDependencies(); + } + + @Override + public void disposeUIResources() { + + } + + @Nls + @Override + public String getDisplayName() { + return TEXT_DISPLAY_NAME; + } + + @Nullable + @Override + public String getHelpTopic() { + return null; + } + + private ActionListener getActionListener() { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateDependencies(); + } + }; + } + + private JPanel initComponent() { + JPanel actions = initActions(); + JPanel options = initOptions(); + return initPanel(actions, options); + } + + private JPanel initActions() { + JPanel actions = new JPanel(); + actions.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); + actions.setLayout(new BoxLayout(actions, BoxLayout.PAGE_AXIS)); + actions.add(imports = new JCheckBox(TEXT_IMPORTS)); + actions.add(reformat = new JCheckBox(TEXT_REFORMAT)); + actions.add(rearrange = new JCheckBox(TEXT_REARRANGE)); + actions.add(Box.createHorizontalGlue()); + return actions; + } + + private JPanel initOptions() { + JPanel options = new JPanel(); + options.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_OPTIONS)); + options.setLayout(new BoxLayout(options, BoxLayout.PAGE_AXIS)); + options.add(reformatChangedCode = new JCheckBox(TEXT_REFORMAT_CHANGED_CODE)); + options.add(Box.createHorizontalGlue()); + return options; + } + + private JPanel initPanel(JPanel actions, JPanel options) { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); + panel.add(activate = new JCheckBox(TEXT_ACTIVATE)); + panel.add(actions); + panel.add(options); + panel.add(Box.createHorizontalGlue()); + return panel; + } + + private void updateDependencies() { + updateEnabled(); + updateSelected(); + } + + private void updateEnabled() { + imports.setEnabled(activate.isSelected()); + reformat.setEnabled(activate.isSelected()); + reformatChangedCode.setEnabled(activate.isSelected() && reformat.isSelected()); + rearrange.setEnabled(activate.isSelected() && reformat.isSelected()); + } + + private void updateSelected() { + if (!activate.isSelected()) { + imports.setSelected(false); + reformat.setSelected(false); + reformatChangedCode.setSelected(false); + rearrange.setSelected(false); + } + if (!reformat.isSelected()) { + reformatChangedCode.setSelected(false); + rearrange.setSelected(false); + } + } + +} \ No newline at end of file diff --git a/src/com/dubreuia/Settings.java b/src/com/dubreuia/Settings.java new file mode 100644 index 0000000..aafa127 --- /dev/null +++ b/src/com/dubreuia/Settings.java @@ -0,0 +1,68 @@ +package com.dubreuia; + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.components.StoragePathMacros; +import com.intellij.util.xmlb.XmlSerializerUtil; + +@State(name = "SaveActionSettings", + storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/saveactions_settings.xml")}) +public class Settings implements PersistentStateComponent { + + private boolean activate; + private boolean imports; + private boolean reformat; + private boolean reformatChangedCode; + private boolean rearrange; + + public Settings getState() { + return this; + } + + public void loadState(Settings state) { + XmlSerializerUtil.copyBean(state, this); + } + + public boolean isActivate() { + return activate; + } + + public void setActivate(boolean activate) { + this.activate = activate; + } + + public boolean isImports() { + return imports; + } + + public void setImports(boolean imports) { + this.imports = imports; + } + + public boolean isReformat() { + return reformat; + } + + public void setReformat(boolean reformat) { + this.reformat = reformat; + } + + public boolean isReformatChangedCode() { + return reformatChangedCode; + } + + public void setReformatChangedCode(boolean reformatChangedCode) { + this.reformatChangedCode = reformatChangedCode; + } + + public boolean isRearrange() { + return rearrange; + } + + public void setRearrange(boolean rearrange) { + this.rearrange = rearrange; + } + +} + From 1ba6facdf23ff8bc1da49c127b4103c8bbf0ebe3 Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Tue, 23 Dec 2014 00:14:12 +0100 Subject: [PATCH 002/518] Add plugin jar to sources Temporary workaround since I cannot upload to the plugin repository. --- save-actions.jar | Bin 0 -> 8548 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 save-actions.jar diff --git a/save-actions.jar b/save-actions.jar new file mode 100644 index 0000000000000000000000000000000000000000..cc6e2bbfb19405e762f8cd34040a0b89974cbad6 GIT binary patch literal 8548 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 ME{~UR Date: Tue, 23 Dec 2014 00:17:18 +0100 Subject: [PATCH 003/518] Correct README to point to jar --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c891f4c..b4a2b27 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,17 @@ Supports configurable save actions, including "organize imports", "reformat code" and "rearrange code". -# Features +## Features - Organize imports support - Reformat code support with only changed text option - Rearrange code support - Simple option page to activate / deactivate save actions -# Installation +## Installation -The plugin is available from the Intellij IDEA Plugin Repository (TODO https://plugins.jetbrains.com/?idea) and you can install it directly from Intellij IDEA. Go in "File > Settings > Plugins > Browse repositories" and search for "Save Actions". +The plugin is not yet available in the plugin repository, you'll have to download the [save-actions.jar](https://github.com/dubreuia/intellij-plugin-save-actions/blob/master/save-actions.jar?raw=true) and add it to your editor from "File > Settings > Plugins > Install plugin from disk...". -# Licence +## Licence MIT License ([here](LICENSE.txt)) From 638a13f8c4975c45217ff5ed5ee0a30291892293 Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Tue, 23 Dec 2014 00:22:07 +0100 Subject: [PATCH 004/518] Add README section about configuration --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b4a2b27..b9be272 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,10 @@ Supports configurable save actions, including "organize imports", "reformat code The plugin is not yet available in the plugin repository, you'll have to download the [save-actions.jar](https://github.com/dubreuia/intellij-plugin-save-actions/blob/master/save-actions.jar?raw=true) and add it to your editor from "File > Settings > Plugins > Install plugin from disk...". +## Configuration + +Activate the plugin from "File > Settings > Other Settings > Save Actions", then configure the actions you need (import, reformat, etc.). + ## Licence MIT License ([here](LICENSE.txt)) From 7f1136035d8249eaac41a46472c30c8a8cb03063 Mon Sep 17 00:00:00 2001 From: adu Date: Wed, 24 Dec 2014 11:43:31 +0100 Subject: [PATCH 005/518] Update README with plugin repository --- README.md | 10 ++++++++-- save-actions.jar | Bin 8548 -> 0 bytes 2 files changed, 8 insertions(+), 2 deletions(-) delete mode 100644 save-actions.jar diff --git a/README.md b/README.md index b9be272..bdce2ce 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,18 @@ Supports configurable save actions, including "organize imports", "reformat code ## Installation -The plugin is not yet available in the plugin repository, you'll have to download the [save-actions.jar](https://github.com/dubreuia/intellij-plugin-save-actions/blob/master/save-actions.jar?raw=true) and add it to your editor from "File > Settings > Plugins > Install plugin from disk...". +Install it from the plugin repository in Intellij IDEA, go to "File > Settings > Plugins > Browser repositories... > Search 'Save Actions' > Category 'Code tools'". + +The plugin is available from the [Intellij IDEA Community Edition plugin repository](https://plugins.jetbrains.com/plugin/7642) and you can also download the jar from there then add it to your editor from "File > Settings > Plugins > Install plugin from disk...". ## Configuration Activate the plugin from "File > Settings > Other Settings > Save Actions", then configure the actions you need (import, reformat, etc.). +## Bugs / features + +Dat plugin do not work ? You can [https://twitter.com/dubreuia](ask me on twitter) or [https://github.com/dubreuia/intellij-plugin-save-actions/issues](create an issue on github). + ## Licence -MIT License ([here](LICENSE.txt)) +[MIT License](LICENSE.txt) diff --git a/save-actions.jar b/save-actions.jar deleted file mode 100644 index cc6e2bbfb19405e762f8cd34040a0b89974cbad6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8548 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 ME{~UR Date: Wed, 24 Dec 2014 11:46:55 +0100 Subject: [PATCH 006/518] Correct links in README --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bdce2ce..e578cdb 100644 --- a/README.md +++ b/README.md @@ -11,17 +11,24 @@ Supports configurable save actions, including "organize imports", "reformat code ## Installation -Install it from the plugin repository in Intellij IDEA, go to "File > Settings > Plugins > Browser repositories... > Search 'Save Actions' > Category 'Code tools'". +Install it from the plugin repository in Intellij IDEA : -The plugin is available from the [Intellij IDEA Community Edition plugin repository](https://plugins.jetbrains.com/plugin/7642) and you can also download the jar from there then add it to your editor from "File > Settings > Plugins > Install plugin from disk...". +- "File > Settings > Plugins > Browse repositories... > Search 'Save Actions' > Category 'Code tools'" + +The plugin is available from the [Intellij IDEA Community Edition plugin repository](https://plugins.jetbrains.com/plugin/7642) and you can also download the jar from there then add it in Intellij IDEA : + +- "File > Settings > Plugins > Install plugin from disk..." ## Configuration -Activate the plugin from "File > Settings > Other Settings > Save Actions", then configure the actions you need (import, reformat, etc.). +Activate the plugin in Intellij IDEA : + +- "File > Settings > Other Settings > Save Actions" +- Then configure the actions you need (import, reformat, etc.) ## Bugs / features -Dat plugin do not work ? You can [https://twitter.com/dubreuia](ask me on twitter) or [https://github.com/dubreuia/intellij-plugin-save-actions/issues](create an issue on github). +Dat plugin do not work ? You can [ask me on twitter](https://twitter.com/dubreuia) or [create an issue on github](https://github.com/dubreuia/intellij-plugin-save-actions/issues). ## Licence From ec70844d4f52f5a15d0f043bac9a8eea85504ad5 Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Tue, 30 Dec 2014 01:19:13 +0100 Subject: [PATCH 007/518] Correct issue #1 Support for multiple open projects and some code cleanup. --- META-INF/plugin.xml | 79 +++++++++++++------ README.md | 14 ++-- src/com/dubreuia/Component.java | 50 ++++-------- src/com/dubreuia/Configuration.java | 22 ++++-- src/com/dubreuia/Settings.java | 7 +- .../dubreuia/processors/ProcessorFactory.java | 50 ++++++++++++ src/com/dubreuia/utils/PsiFiles.java | 23 ++++++ 7 files changed, 171 insertions(+), 74 deletions(-) create mode 100644 src/com/dubreuia/processors/ProcessorFactory.java create mode 100644 src/com/dubreuia/utils/PsiFiles.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 4d62fe4..3a72c5a 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,46 +1,75 @@ - com.dubreuia - Save Actions - 0.1 - Alexandre DuBreuil + com.dubreuia + Save Actions + 0.2 + Alexandre DuBreuil - github | twitter). + Supports configurable, Eclipse like, save actions, including "organize imports", "reformat code" and "rearrange code". The plugin executes the configured actions when the file is synchronised (or saved) on disk.

+ +

features

+ +
    +
  • Organize imports
  • +
  • Reformat code (only changed text or all)
  • +
  • Rearrange code (reorder methods, fields, etc.)
  • +
  • Simple option page to activate / deactivate actions
  • +
+ +

github

+ + + +

twitter

+ + + +

issues

+ + ]]>
- +
0.2
+
+ +
0.1
    -
  • Organize imports support
  • -
  • Reformat code support with only changed text option
  • -
  • Rearrange code support
  • +
  • Organize imports
  • +
  • Reformat code
  • +
  • Reformat only changed code
  • +
  • Rearrange code
  • Simple option page to activate / deactivate save actions
]]> -
+ - + - - - - + + + + - - - com.dubreuia.Component - - + + + com.dubreuia.Component + + - - + + - - + +
diff --git a/README.md b/README.md index e578cdb..0e51e9a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # Intellij Save Actions Plugin -Supports configurable save actions, including "organize imports", "reformat code" and "rearrange code". +Supports configurable, Eclipse like, save actions, including "organize imports", "reformat code" and "rearrange code". The plugin executes the configured actions when the file is synchronised (or saved) on disk. ## Features -- Organize imports support -- Reformat code support with only changed text option -- Rearrange code support -- Simple option page to activate / deactivate save actions +- Organize imports +- Reformat code (only changed text or all) +- Rearrange code (reorder methods, fields, etc.) +- Simple option page to activate / deactivate actions ## Installation @@ -30,6 +30,10 @@ Activate the plugin in Intellij IDEA : Dat plugin do not work ? You can [ask me on twitter](https://twitter.com/dubreuia) or [create an issue on github](https://github.com/dubreuia/intellij-plugin-save-actions/issues). +## Compatibility + +This plugin works with Java 6+ and Intellij IDEA Community Edition after 131 (around version 13). + ## Licence [MIT License](LICENSE.txt) diff --git a/src/com/dubreuia/Component.java b/src/com/dubreuia/Component.java index e7c95e4..cfeaeff 100644 --- a/src/com/dubreuia/Component.java +++ b/src/com/dubreuia/Component.java @@ -1,13 +1,11 @@ package com.dubreuia; +import com.dubreuia.processors.ProcessorFactory; +import com.dubreuia.utils.PsiFiles; import com.intellij.AppTopics; import com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor; -import com.intellij.codeInsight.actions.OptimizeImportsProcessor; -import com.intellij.codeInsight.actions.RearrangeCodeProcessor; -import com.intellij.codeInsight.actions.ReformatCodeProcessor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; import com.intellij.openapi.project.Project; @@ -20,7 +18,7 @@ public class Component implements ApplicationComponent { - private Settings settings = ServiceManager.getService(Settings.class); + public static final String COMPONENT_NAME = "Save Actions"; public void initComponent() { MessageBus bus = ApplicationManager.getApplication().getMessageBus(); @@ -34,11 +32,14 @@ private FileDocumentManagerAdapter getFileDocumentManagerAdapter() { public void beforeDocumentSaving(@NotNull Document document) { for (Project project : ProjectManager.getInstance().getOpenProjects()) { PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); - if (null != psiFile) { - AbstractLayoutCodeProcessor processor; - processor = getReformatCodeProcessor(project, psiFile); - processor = getRearrangeCodeProcessor(processor); - processor = getOptimizeImportsProcessor(processor, project, psiFile); + /* + * The psi files seems to be shared between projects, so we need to check if the file is physically + * in that project before reformating, or else the file is formatted twice and intellij will ask to + * confirm unlocking of non-project file in the other project (very annoying). + */ + if (null != psiFile && PsiFiles.isPsiFilePhysicallyInProject(project, psiFile)) { + AbstractLayoutCodeProcessor processor = + ProcessorFactory.INSTANCE.getSaveActionsProcessor(project, psiFile); if (null != processor) { processor.run(); } @@ -48,35 +49,12 @@ public void beforeDocumentSaving(@NotNull Document document) { }; } - private AbstractLayoutCodeProcessor getOptimizeImportsProcessor(AbstractLayoutCodeProcessor processor, Project project, PsiFile psiFile) { - if (null != processor && settings.isImports()) { - return new OptimizeImportsProcessor(processor); - } else if (settings.isImports()) { - return new OptimizeImportsProcessor(project, psiFile); - } - return processor; - } - - private AbstractLayoutCodeProcessor getRearrangeCodeProcessor(AbstractLayoutCodeProcessor processor) { - if (null != processor && settings.isRearrange()) { - return new RearrangeCodeProcessor(processor, null); - } - return processor; - } - - private AbstractLayoutCodeProcessor getReformatCodeProcessor(Project project, PsiFile psiFile) { - if (settings.isReformat()) { - return new ReformatCodeProcessor(project, psiFile, null, settings.isReformatChangedCode()); - } - return null; + @NotNull + public String getComponentName() { + return COMPONENT_NAME; } public void disposeComponent() { } - @NotNull - public String getComponentName() { - return "Save Action"; - } - } \ No newline at end of file diff --git a/src/com/dubreuia/Configuration.java b/src/com/dubreuia/Configuration.java index 4a4a42f..22c6b49 100644 --- a/src/com/dubreuia/Configuration.java +++ b/src/com/dubreuia/Configuration.java @@ -1,26 +1,30 @@ package com.dubreuia; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.*; - -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.Nullable; - import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.ui.IdeBorderFactory; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; public class Configuration implements Configurable { private static final String TEXT_TITLE_OPTIONS = "Formatting options"; + private static final String TEXT_TITLE_ACTIONS = "Actions to perform on save"; private static final String TEXT_ACTIVATE = "Activate save actions"; + private static final String TEXT_IMPORTS = "Organize imports"; + private static final String TEXT_REFORMAT = "Reformat code"; + private static final String TEXT_REFORMAT_CHANGED_CODE = "Format and rearrange only changed code"; + private static final String TEXT_REARRANGE = "Rearrange code"; private static final String TEXT_DISPLAY_NAME = "Save Actions"; @@ -28,9 +32,13 @@ public class Configuration implements Configurable { private Settings settings = ServiceManager.getService(Settings.class); private JCheckBox activate; + private JCheckBox imports; + private JCheckBox reformat; + private JCheckBox reformatChangedCode; + private JCheckBox rearrange; @Nullable diff --git a/src/com/dubreuia/Settings.java b/src/com/dubreuia/Settings.java index aafa127..26367a8 100644 --- a/src/com/dubreuia/Settings.java +++ b/src/com/dubreuia/Settings.java @@ -7,13 +7,18 @@ import com.intellij.util.xmlb.XmlSerializerUtil; @State(name = "SaveActionSettings", - storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/saveactions_settings.xml")}) + storages = { + @Storage(file = StoragePathMacros.APP_CONFIG + "/saveactions_settings.xml")}) public class Settings implements PersistentStateComponent { private boolean activate; + private boolean imports; + private boolean reformat; + private boolean reformatChangedCode; + private boolean rearrange; public Settings getState() { diff --git a/src/com/dubreuia/processors/ProcessorFactory.java b/src/com/dubreuia/processors/ProcessorFactory.java new file mode 100644 index 0000000..08b980d --- /dev/null +++ b/src/com/dubreuia/processors/ProcessorFactory.java @@ -0,0 +1,50 @@ +package com.dubreuia.processors; + +import com.dubreuia.Settings; +import com.intellij.codeInsight.actions.AbstractLayoutCodeProcessor; +import com.intellij.codeInsight.actions.OptimizeImportsProcessor; +import com.intellij.codeInsight.actions.RearrangeCodeProcessor; +import com.intellij.codeInsight.actions.ReformatCodeProcessor; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +public enum ProcessorFactory { + + INSTANCE; + + private Settings settings = ServiceManager.getService(Settings.class); + + public AbstractLayoutCodeProcessor getSaveActionsProcessor(Project project, PsiFile psiFile) { + AbstractLayoutCodeProcessor processor; + processor = getReformatCodeProcessor(project, psiFile); + processor = getRearrangeCodeProcessor(processor); + processor = getOptimizeImportsProcessor(processor, project, psiFile); + return processor; + } + + private AbstractLayoutCodeProcessor getOptimizeImportsProcessor(AbstractLayoutCodeProcessor processor, + Project project, PsiFile psiFile) { + if (null != processor && settings.isImports()) { + return new OptimizeImportsProcessor(processor); + } else if (settings.isImports()) { + return new OptimizeImportsProcessor(project, psiFile); + } + return processor; + } + + private AbstractLayoutCodeProcessor getRearrangeCodeProcessor(AbstractLayoutCodeProcessor processor) { + if (null != processor && settings.isRearrange()) { + return new RearrangeCodeProcessor(processor, null); + } + return processor; + } + + private AbstractLayoutCodeProcessor getReformatCodeProcessor(Project project, PsiFile psiFile) { + if (settings.isReformat()) { + return new ReformatCodeProcessor(project, psiFile, null, settings.isReformatChangedCode()); + } + return null; + } + +} diff --git a/src/com/dubreuia/utils/PsiFiles.java b/src/com/dubreuia/utils/PsiFiles.java new file mode 100644 index 0000000..24c6582 --- /dev/null +++ b/src/com/dubreuia/utils/PsiFiles.java @@ -0,0 +1,23 @@ +package com.dubreuia.utils; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; + +public class PsiFiles { + + public static boolean isPsiFilePhysicallyInProject(Project project, PsiFile psiFile) { + return isPsiFilePhysicallyInProject(project, psiFile.getParent()); + } + + public static boolean isPsiFilePhysicallyInProject(Project project, PsiDirectory psiDirectory) { + if (psiDirectory != null) { + if (project.getBaseDir().equals(psiDirectory.getVirtualFile())) { + return true; + } + return isPsiFilePhysicallyInProject(project, psiDirectory.getParent()); + } + return false; + } + +} From a9c7394051d79a4aeceac80fe8c11f887e30ade1 Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Sun, 5 Apr 2015 01:03:12 +0200 Subject: [PATCH 008/518] ISSUE 7 NoSuchMethodError when rearrange code is activated Changed method call for compatible api. --- .idea/misc.xml | 5 ++- .idea/save-actions.iml | 9 ---- META-INF/plugin.xml | 32 +++++++++++---- README.md | 10 +++-- save-actions.iml | 2 +- src/com/dubreuia/Component.java | 14 ++++--- src/com/dubreuia/Configuration.java | 9 ++-- src/com/dubreuia/Settings.java | 13 +++--- .../dubreuia/processors/ProcessorFactory.java | 41 +++++++++++-------- 9 files changed, 78 insertions(+), 57 deletions(-) delete mode 100644 .idea/save-actions.iml diff --git a/.idea/misc.xml b/.idea/misc.xml index bbf9cbf..ceae5ec 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,8 @@ - + - \ No newline at end of file + + diff --git a/.idea/save-actions.iml b/.idea/save-actions.iml deleted file mode 100644 index d6ebd48..0000000 --- a/.idea/save-actions.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 3a72c5a..26611e7 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -2,13 +2,13 @@ com.dubreuia Save Actions - 0.2 + 0.3 Alexandre DuBreuil Supports configurable, Eclipse like, save actions, including "organize imports", "reformat code" and "rearrange code". The plugin executes the configured actions when the file is synchronised (or saved) on disk.

-

features

+

Features

  • Organize imports
  • @@ -17,25 +17,39 @@
  • Simple option page to activate / deactivate actions
-

github

+

Configuration

- +
    +
  • Activate the plugin in Intellij IDEA: "File > Settings > Other Settings > Save Actions"
  • +
  • Then configure the actions you need (import, reformat, etc.)
  • +
  • If you want to see / configure the rearrangement options: "File > Settings > Code Style > Java > Arrangement"
  • +
-

twitter

+

Compatibility

- +

This plugin works with Java 6+ and Intellij IDEA Community Edition after 131 (around version 13).

-

issues

+

Resources

- + ]]> From a960d93bd2065f01780de47e150ffd7d388c753a Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Wed, 18 Dec 2019 13:34:29 +0100 Subject: [PATCH 248/518] Fix #288: Add non injectable annotation storage --- src/main/java/com/dubreuia/model/Storage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/dubreuia/model/Storage.java b/src/main/java/com/dubreuia/model/Storage.java index c6e7d56..e935809 100644 --- a/src/main/java/com/dubreuia/model/Storage.java +++ b/src/main/java/com/dubreuia/model/Storage.java @@ -21,6 +21,7 @@ public class Storage implements PersistentStateComponent { private String configurationPath; private List quickLists; + @NonInjectable public Storage() { firstLaunch = true; actions = new HashSet<>(); From e42e6a2398fec89232bd54db9c2f07ba62ec6d40 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 23 Jan 2020 17:04:06 +0000 Subject: [PATCH 249/518] fix non reloading config --- src/main/java/com/dubreuia/model/Storage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/dubreuia/model/Storage.java b/src/main/java/com/dubreuia/model/Storage.java index e935809..6121d63 100644 --- a/src/main/java/com/dubreuia/model/Storage.java +++ b/src/main/java/com/dubreuia/model/Storage.java @@ -11,7 +11,7 @@ import java.util.List; import java.util.Set; -@State(name = "SaveActionSettings", storages = {@com.intellij.openapi.components.Storage("./saveactions_settings.xml")}) +@State(name = "SaveActionSettings", storages = {@com.intellij.openapi.components.Storage("saveactions_settings.xml")}) public class Storage implements PersistentStateComponent { private boolean firstLaunch; From a8f1bbdd160136be3f2fd3fec06d291dc01cd9fc Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Sat, 1 Feb 2020 18:49:46 +0100 Subject: [PATCH 250/518] Fix #284: Discontinue 2016.3, merge 2018 and 2019 --- build.gradle | 4 ++++ src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e7da256..2ebad9f 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,10 @@ compileJava { // See https://www.jetbrains.com/intellij-repository/snapshots // See https://www.jetbrains.com/intellij-repository/releases intellij { + // From branch 2018.3 + // version '2018.3' + // From branch 2019.3 + // version '193.3519.25-EAP-SNAPSHOT' version 'LATEST-EAP-SNAPSHOT' plugins = ['java', 'coverage'] pluginName 'Save Actions' diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index a6aabd9..82d26e0 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -58,7 +58,7 @@ ]]> - + com.intellij.modules.java From 7e6b1eef014f6d9ac827c9ef2147c67c621f6a22 Mon Sep 17 00:00:00 2001 From: Alexandre DuBreuil Date: Sat, 1 Feb 2020 19:13:18 +0100 Subject: [PATCH 251/518] Fix #284: Update releasing documentation --- .idea/saveactions_settings.xml | 2 -- RELEASING.md | 43 ++++++++++++---------------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/.idea/saveactions_settings.xml b/.idea/saveactions_settings.xml index f40d218..1d9abf8 100644 --- a/.idea/saveactions_settings.xml +++ b/.idea/saveactions_settings.xml @@ -10,8 +10,6 @@
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..0f7bc51 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be49cc5..486b8f7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,3 @@ Intellij should refresh and the project is now configured as a gradle project. Y ./gradlew runIde ``` -## Code style - -The code style is located in `config/code-style.xml`, you can import it by doing "File > Settings > Editor > Code Style > Scheme > (wheel) > Import scheme > Intellij IDEA code style XML". General style should resemble existing code. - diff --git a/config/checkstyle/save-actions.xml b/config/checkstyle/checkstyle.xml similarity index 100% rename from config/checkstyle/save-actions.xml rename to config/checkstyle/checkstyle.xml From 6206169269de8cb6ee889846c289d359c76b471c Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 10:11:49 +0200 Subject: [PATCH 307/518] Introduce workflows --- .github/dependabot.yml | 22 ++++++++++++ .github/workflows/checkBuild.yml | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/checkBuild.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b59099a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 +updates: +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + # Run it at a specific time so that we don't get emails all day long + time: "00:00" + open-pull-requests-limit: 10 + ignore: + - dependency-name: "*" + # GitHub actions are using git tags (v1 = v1.2 = v1.2.3) which should be compatible until a major change is performed + update-types: + - "version-update:semver-minor" + - "version-update:semver-patch" +- package-ecosystem: gradle + directory: "/" + schedule: + interval: daily + # Run it at a specific time so that we don't get emails all day long + time: "00:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml new file mode 100644 index 0000000..518c195 --- /dev/null +++ b/.github/workflows/checkBuild.yml @@ -0,0 +1,59 @@ +name: Check Build + +on: + workflow_dispatch: + push: + branches: [ develop ] + paths-ignore: + - '**.md' + pull_request: + branches: [ develop ] + paths-ignore: + - '**.md' + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + java: [17] + distribution: [temurin] + + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + distribution: ${{ matrix.distribution }} + java-version: ${{ matrix.java }} + cache: 'maven' + + - name: Build + run: ./gradlew build buildPlugin + + - name: Check for uncommited changes + run: | + if [[ "$(git status --porcelain)" != "" ]]; then + echo ---------------------------------------- + echo git status + echo ---------------------------------------- + git status + echo ---------------------------------------- + echo git diff + echo ---------------------------------------- + git diff + echo ---------------------------------------- + echo Troubleshooting + echo ---------------------------------------- + echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && mvn -B clean package" + exit 1 + fi + + - name: Upload plugin files + uses: actions/upload-artifact@v3 + with: + name: plugin-files-java-${{ matrix.java }} + path: build/libs/intellij-plugin-save-actions-*.jar + if-no-files-found: error From 8b1a4e2a2a254ba3a37297ee974c950aae3e9f50 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 10:12:38 +0200 Subject: [PATCH 308/518] Gradle cache --- .github/workflows/checkBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 518c195..b0cd88f 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -28,7 +28,7 @@ jobs: with: distribution: ${{ matrix.distribution }} java-version: ${{ matrix.java }} - cache: 'maven' + cache: 'gradle' - name: Build run: ./gradlew build buildPlugin From 841a5d2fe06bf53e583a64e12b33789f42ec165b Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Wed, 21 Jun 2023 10:15:42 +0200 Subject: [PATCH 309/518] Update README.md --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a7520be..b9e26d3 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # Save Actions Plugin icon light Save Actions Plugin - XDEV Edition -This plugin is a fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) and is kept in maintenance mode: -* Keep the plugin up-to-date with the latest IDEA versions -* Distribute the plugin on the IDEA marketplace -* Fix serious bugs -* Keep the repo in sync with XDEV's standards -* Hardly used features may be removed to speed up development - -There is no guarantee that work outside of this scope will be done. - ---- +> **ℹ️About** +> +> This plugin is a fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) and is kept in maintenance mode: +> * Keep the plugin up-to-date with the latest IDEA versions +> * Distribute the plugin on the IDEA marketplace +> * Fix serious bugs +> * Keep the repo in sync with XDEV's standards +> * Hardly used features may be removed to speed up development +> +> There is no guarantee that work outside of this scope will be done. Supports configurable, Eclipse like, save actions, including "optimize imports", "reformat code", "rearrange code", "compile file" and some quick fixes like "add / remove 'this' qualifier", etc. The plugin executes the configured actions when the file is synchronized (or saved) on disk. From bfed2a7743301bcd777412eca2eaa6f7f9530a84 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 10:18:58 +0200 Subject: [PATCH 310/518] Update test dependencies --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 66377a9..626f379 100644 --- a/build.gradle +++ b/build.gradle @@ -21,10 +21,10 @@ repositories { // Add dependencies to test, junit5 api (annotations) and engine (runtime) dependencies { - testImplementation platform('org.junit:junit-bom:5.9.0'), + testImplementation platform('org.junit:junit-bom:5.9.3'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', - 'org.assertj:assertj-core:3.23.1' + 'org.assertj:assertj-core:3.24.2' testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") } From b0af99351e399c722687574dd4a37d921282f083 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Wed, 21 Jun 2023 10:21:10 +0200 Subject: [PATCH 311/518] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9e26d3..f8e4a4c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Save Actions Plugin icon light Save Actions Plugin - XDEV Edition +# Save Actions Plugin icon light Save Actions Plugin - XDEV Edition > **ℹ️About** > From 52bfb05cad8f3f79e7bb4f333d485edae95d358d Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 10:52:18 +0200 Subject: [PATCH 312/518] Move docs -> assets --- README.md | 8 ++++---- {docs => assets}/icon-intellij-idea.svg | 0 {docs => assets}/icon-save-actions-dark.svg | 0 {docs => assets}/icon-save-actions.grid | 0 {docs => assets}/icon-save-actions.svg | 0 .../intellij-save-actions-plugin-action-menu.png | Bin ...ellij-save-actions-plugin-settings-page-java.png | Bin .../intellij-save-actions-plugin-settings-page.png | Bin 8 files changed, 4 insertions(+), 4 deletions(-) rename {docs => assets}/icon-intellij-idea.svg (100%) rename {docs => assets}/icon-save-actions-dark.svg (100%) rename {docs => assets}/icon-save-actions.grid (100%) rename {docs => assets}/icon-save-actions.svg (100%) rename {docs => assets}/intellij-save-actions-plugin-action-menu.png (100%) rename {docs => assets}/intellij-save-actions-plugin-settings-page-java.png (100%) rename {docs => assets}/intellij-save-actions-plugin-settings-page.png (100%) diff --git a/README.md b/README.md index f8e4a4c..d11a243 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Save Actions Plugin icon light Save Actions Plugin - XDEV Edition +# Save Actions Plugin icon light Save Actions Plugin - XDEV Edition > **ℹ️About** > @@ -44,7 +44,7 @@ The code style applied by the save actions plugin is the one configured your set - Uses a settings file per project you can commit (see [Files location](#files-location)) - Available keymaps and actions for activation (see [Keymap and actions](#keymap-and-actions)) -![Save actions plugin settings page](./docs/intellij-save-actions-plugin-settings-page.png) +![Save actions plugin settings page](./assets/intellij-save-actions-plugin-settings-page.png) ### Java IDE products @@ -55,7 +55,7 @@ Works in JetBrains IDE with Java support, like Intellij IDEA and AndroidStudio. - Eclipse configuration file `.epf` support (see [Eclipse support](#eclipse-support)) - Automatically fix Java inspections (see [Java quick fixes](#java-fixes)) -![Save actions plugin settings page for Java](./docs/intellij-save-actions-plugin-settings-page-java.png) +![Save actions plugin settings page for Java](./assets/intellij-save-actions-plugin-settings-page-java.png) ## Installation @@ -92,7 +92,7 @@ The plugin actions are grouped under the menu "Code > Save Actions". You can ass - **Execute Save Actions on multiple files (default: not binded)** will show a popup to select the files (or a scope) on which to trigger the plugin (needs to be activated with "Activate save actions on batch" in [activation](#activation)).

- Save Actions Plugin Action menu + Save Actions Plugin Action menu

## Configuration diff --git a/docs/icon-intellij-idea.svg b/assets/icon-intellij-idea.svg similarity index 100% rename from docs/icon-intellij-idea.svg rename to assets/icon-intellij-idea.svg diff --git a/docs/icon-save-actions-dark.svg b/assets/icon-save-actions-dark.svg similarity index 100% rename from docs/icon-save-actions-dark.svg rename to assets/icon-save-actions-dark.svg diff --git a/docs/icon-save-actions.grid b/assets/icon-save-actions.grid similarity index 100% rename from docs/icon-save-actions.grid rename to assets/icon-save-actions.grid diff --git a/docs/icon-save-actions.svg b/assets/icon-save-actions.svg similarity index 100% rename from docs/icon-save-actions.svg rename to assets/icon-save-actions.svg diff --git a/docs/intellij-save-actions-plugin-action-menu.png b/assets/intellij-save-actions-plugin-action-menu.png similarity index 100% rename from docs/intellij-save-actions-plugin-action-menu.png rename to assets/intellij-save-actions-plugin-action-menu.png diff --git a/docs/intellij-save-actions-plugin-settings-page-java.png b/assets/intellij-save-actions-plugin-settings-page-java.png similarity index 100% rename from docs/intellij-save-actions-plugin-settings-page-java.png rename to assets/intellij-save-actions-plugin-settings-page-java.png diff --git a/docs/intellij-save-actions-plugin-settings-page.png b/assets/intellij-save-actions-plugin-settings-page.png similarity index 100% rename from docs/intellij-save-actions-plugin-settings-page.png rename to assets/intellij-save-actions-plugin-settings-page.png From 4b10e6e22e80b08820bb52ed127fb9f4ca7722bb Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 10:52:56 +0200 Subject: [PATCH 313/518] Sonar integration --- .github/workflows/sonar.yml | 57 +++++++++++++++++++++++++++++++++++++ build.gradle | 1 + 2 files changed, 58 insertions(+) create mode 100644 .github/workflows/sonar.yml diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml new file mode 100644 index 0000000..23b666f --- /dev/null +++ b/.github/workflows/sonar.yml @@ -0,0 +1,57 @@ +name: Sonar + +on: + workflow_dispatch: + push: + branches: [ develop ] + paths-ignore: + - '**.md' + - 'assets/**' + - 'config/**' + pull_request: + types: [opened, synchronize, reopened] + paths-ignore: + - '**.md' + - 'assets/**' + - 'config/**' + +env: + SONARCLOUD_ORG: ${{ github.event.organization.login }} + SONARCLOUD_HOST: https://sonarcloud.io + +jobs: + sonar: + name: SonarCloud Scan + runs-on: ubuntu-latest + # Dependabot PRs have no access to secrets (SONAR_TOKEN) -> Ignore them + if: ${{ github.event_name != 'pull_request' || !startsWith(github.head_ref, 'dependabot/') }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 17 + + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Build + run: ./gradlew build sonarqube --info -Dsonar.projectKey=${{ env.SONARCLOUD_ORG }}_${{ github.event.repository.name }} -Dsonar.organization=${{ env.SONARCLOUD_ORG }} -Dsonar.host.url=${{ env.SONARCLOUD_HOST }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/build.gradle b/build.gradle index 626f379..cccd565 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { id 'java' id 'idea' id 'org.jetbrains.intellij' version '1.13.3' + id 'org.sonarqube' version '4.2.1.3168' } // Add coverage plugin From c87e2548669a27def58549aeefde8a0e9f55acbe Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Wed, 21 Jun 2023 10:54:14 +0200 Subject: [PATCH 314/518] Add badges --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d11a243..1824d6c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/checkBuild.yml?branch=develop)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/checkBuild.yml?query=branch%3Adevelop) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_intellij-plugin-save-actions&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_intellij-plugin-save-actions) + # Save Actions Plugin icon light Save Actions Plugin - XDEV Edition > **ℹ️About** From 937bc2515f02263c1a62358f0726baf49de4261b Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 11:16:16 +0200 Subject: [PATCH 315/518] Update gradle wrapper --- build.gradle | 6 ------ gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 62076 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 19 ++++++++++++------- gradlew.bat | 1 + 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index cccd565..fe2bb8a 100644 --- a/build.gradle +++ b/build.gradle @@ -77,9 +77,3 @@ jacocoTestReport { html.required = false } } - -wrapper() { - gradleVersion = '7.5.1' - distributionUrl = distributionUrl.replace('bin', 'all') -} - diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 39834 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 G$^QWPgI3l6 delta 38507 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 Date: Wed, 21 Jun 2023 11:24:04 +0200 Subject: [PATCH 316/518] =?UTF-8?q?``com.dubreuia``=20=E2=86=92=20``softwa?= =?UTF-8?q?re.xdev.saveactions``?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- build.gradle | 2 +- .../xdev/saveactions}/core/ExecutionMode.java | 2 +- .../saveactions}/core/action/BatchAction.java | 13 +- .../core/action/ShortcutAction.java | 13 +- .../core/action/ToggleAnAction.java | 6 +- .../saveactions}/core/component/Engine.java | 23 +- .../SaveActionsDocumentManagerListener.java | 13 +- .../core/service/SaveActionsService.java | 6 +- .../service/SaveActionsServiceManager.java | 6 +- .../impl/AbstractSaveActionsService.java | 16 +- .../impl/SaveActionsDefaultService.java | 8 +- .../service/impl/SaveActionsJavaService.java | 10 +- .../xdev/saveactions}/model/Action.java | 10 +- .../xdev/saveactions}/model/ActionType.java | 2 +- .../xdev/saveactions}/model/Storage.java | 2 +- .../saveactions}/model/StorageFactory.java | 4 +- .../saveactions}/model/java/EpfAction.java | 4 +- .../xdev/saveactions}/model/java/EpfKey.java | 2 +- .../saveactions}/model/java/EpfStorage.java | 8 +- .../processors/BuildProcessor.java | 10 +- .../processors/GlobalProcessor.java | 6 +- .../saveactions}/processors/Processor.java | 6 +- .../xdev/saveactions}/processors/Result.java | 2 +- .../saveactions}/processors/ResultCode.java | 2 +- .../saveactions}/processors/SaveCommand.java | 6 +- .../processors/SaveReadCommand.java | 13 +- .../processors/SaveWriteCommand.java | 13 +- .../processors/java/InspectionRunnable.java | 4 +- .../processors/java/JavaProcessor.java | 16 +- .../inspection/CustomLocalCanBeFinal.java | 2 +- ...bleHasSerialVersionUidFieldInspection.java | 2 +- ...erialVersionUIDFieldInspectionWrapper.java | 6 +- .../xdev/saveactions}/ui/BuildPanel.java | 12 +- .../xdev/saveactions}/ui/Configuration.java | 30 +-- .../ui/FileMaskExclusionPanel.java | 2 +- .../ui/FileMaskInclusionPanel.java | 2 +- .../xdev/saveactions}/ui/FileMaskPanel.java | 2 +- .../xdev/saveactions}/ui/FormattingPanel.java | 14 +- .../xdev/saveactions}/ui/GeneralPanel.java | 12 +- .../saveactions}/ui/java/IdeSupportPanel.java | 9 +- .../saveactions}/ui/java/InspectionPanel.java | 8 +- .../xdev/saveactions}/utils/Helper.java | 2 +- src/main/resources/META-INF/plugin-java.xml | 2 +- src/main/resources/META-INF/plugin.xml | 22 +- .../integration/JavaIntegrationTest.java | 255 ------------------ .../core/action/BatchActionConstants.java | 3 +- .../core/action/ShortcutActionConstants.java | 3 +- .../core/component/PsiFileTest.java | 5 +- .../component/SaveActionManagerConstants.java | 8 +- .../integration/ActionTestFile.java | 2 +- .../integration/GlobalIntegrationTest.java | 45 ++-- .../integration/IntegrationTest.java | 27 +- .../integration/JavaIntegrationTest.java | 215 +++++++++++++++ .../xdev/saveactions}/junit/JUnit5Utils.java | 2 +- .../model/java/EpfActionTest.java | 7 +- .../saveactions}/model/java/EpfKeyTest.java | 15 +- .../model/java/EpfStorageTest.java | 38 +-- .../model/java/EpfTestConstants.java | 2 +- .../processors/BuildProcessorTest.java | 8 +- .../processors/GlobalProcessorTest.java | 8 +- .../processors/java/JavaProcessorTest.java | 11 +- .../integration/AccessCanBeTightened_KO.java | 4 +- .../integration/AccessCanBeTightened_OK.java | 4 +- ...ustomUnqualifiedStaticMemberAccess_KO.java | 4 +- ...ustomUnqualifiedStaticMemberAccess_OK.java | 4 +- .../ExplicitTypeCanBeDiamond_KO.java | 2 +- .../ExplicitTypeCanBeDiamond_OK.java | 2 +- .../integration/FieldCanBeFinal_KO.java | 2 +- .../integration/FieldCanBeFinal_OK.java | 2 +- .../integration/FinalPrivateMethod_KO.java | 2 +- .../integration/FinalPrivateMethod_OK.java | 2 +- .../GenerateSerialVersionUID_KO.java | 2 +- .../GenerateSerialVersionUID_OK.java | 2 +- .../integration/InspectionsAll_KO.java | 4 +- .../integration/InspectionsAll_OK.java | 4 +- .../LocalCanBeFinalExceptImplicit_KO.java | 2 +- .../LocalCanBeFinalExceptImplicit_OK.java | 2 +- .../integration/LocalCanBeFinal_KO.java | 2 +- .../integration/LocalCanBeFinal_OK.java | 2 +- .../integration/MethodMayBeStatic_KO.java | 2 +- .../integration/MethodMayBeStatic_OK.java | 2 +- .../MissingOverrideAnnotation_KO.java | 2 +- .../MissingOverrideAnnotation_OK.java | 2 +- .../integration/Reformat_KO_Import_KO.java | 10 +- .../integration/Reformat_KO_Import_OK.java | 4 +- .../integration/Reformat_KO_Rearrange_KO.java | 4 +- .../integration/Reformat_KO_Rearrange_OK.java | 4 +- .../integration/Reformat_OK_Import_KO.java | 10 +- .../integration/Reformat_OK_Import_OK.java | 4 +- .../integration/Reformat_OK_Rearrange_OK.java | 4 +- .../SingleStatementInBlock_KO.java | 2 +- .../SingleStatementInBlock_OK.java | 2 +- .../integration/SuppressAnnotation_KO.java | 2 +- .../integration/SuppressAnnotation_OK.java | 2 +- ...aryFinalOnLocalVariableOrParameter_KO.java | 2 +- ...aryFinalOnLocalVariableOrParameter_OK.java | 2 +- .../integration/UnnecessarySemicolon_KO.java | 2 +- .../integration/UnnecessarySemicolon_OK.java | 2 +- .../integration/UnnecessaryThis_KO.java | 2 +- .../integration/UnnecessaryThis_OK.java | 2 +- .../UnqualifiedFieldAccess_KO.java | 2 +- .../UnqualifiedFieldAccess_OK.java | 2 +- .../UnqualifiedMethodAccess_KO.java | 2 +- .../UnqualifiedMethodAccess_OK.java | 2 +- .../UnqualifiedStaticMemberAccess_KO.java | 4 +- .../UnqualifiedStaticMemberAccess_OK.java | 4 +- .../integration/UseBlocks_KO.java | 2 +- .../integration/UseBlocks_OK.java | 2 +- .../xdev/saveactions}/model/example0.epf | 0 .../xdev/saveactions}/model/example1.epf | 0 .../xdev/saveactions}/model/example2.epf | 0 112 files changed, 544 insertions(+), 603 deletions(-) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/ExecutionMode.java (98%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/action/BatchAction.java (86%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/action/ShortcutAction.java (85%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/action/ToggleAnAction.java (93%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/component/Engine.java (94%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/listener/SaveActionsDocumentManagerListener.java (90%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/service/SaveActionsService.java (92%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/service/SaveActionsServiceManager.java (91%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/service/impl/AbstractSaveActionsService.java (91%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/service/impl/SaveActionsDefaultService.java (88%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/core/service/impl/SaveActionsJavaService.java (87%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/Action.java (94%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/ActionType.java (96%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/Storage.java (99%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/StorageFactory.java (94%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfAction.java (97%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfKey.java (98%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfStorage.java (95%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/BuildProcessor.java (95%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/GlobalProcessor.java (96%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/Processor.java (92%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/Result.java (97%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/ResultCode.java (96%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/SaveCommand.java (94%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/SaveReadCommand.java (86%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/SaveWriteCommand.java (87%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/java/InspectionRunnable.java (97%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/java/JavaProcessor.java (93%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/java/inspection/CustomLocalCanBeFinal.java (97%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java (96%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java (94%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/BuildPanel.java (94%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/Configuration.java (91%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/FileMaskExclusionPanel.java (98%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/FileMaskInclusionPanel.java (98%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/FileMaskPanel.java (99%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/FormattingPanel.java (85%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/GeneralPanel.java (85%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/java/IdeSupportPanel.java (92%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/ui/java/InspectionPanel.java (90%) rename src/main/java/{com/dubreuia => software/xdev/saveactions}/utils/Helper.java (97%) delete mode 100644 src/test/java/com/dubreuia/integration/JavaIntegrationTest.java rename src/test/java/{com/dubreuia => software/xdev/saveactions}/core/action/BatchActionConstants.java (94%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/core/action/ShortcutActionConstants.java (96%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/core/component/PsiFileTest.java (96%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/core/component/SaveActionManagerConstants.java (89%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/integration/ActionTestFile.java (98%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/integration/GlobalIntegrationTest.java (65%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/integration/IntegrationTest.java (75%) create mode 100644 src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java rename src/test/java/{com/dubreuia => software/xdev/saveactions}/junit/JUnit5Utils.java (98%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfActionTest.java (92%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfKeyTest.java (86%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfStorageTest.java (80%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/model/java/EpfTestConstants.java (97%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/processors/BuildProcessorTest.java (88%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/processors/GlobalProcessorTest.java (88%) rename src/test/java/{com/dubreuia => software/xdev/saveactions}/processors/java/JavaProcessorTest.java (88%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/AccessCanBeTightened_KO.java (75%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/AccessCanBeTightened_OK.java (75%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/CustomUnqualifiedStaticMemberAccess_KO.java (90%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/CustomUnqualifiedStaticMemberAccess_OK.java (90%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/ExplicitTypeCanBeDiamond_KO.java (85%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/ExplicitTypeCanBeDiamond_OK.java (84%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/FieldCanBeFinal_KO.java (85%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/FieldCanBeFinal_OK.java (86%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/FinalPrivateMethod_KO.java (60%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/FinalPrivateMethod_OK.java (58%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/GenerateSerialVersionUID_KO.java (62%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/GenerateSerialVersionUID_OK.java (76%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/InspectionsAll_KO.java (81%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/InspectionsAll_OK.java (82%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/LocalCanBeFinalExceptImplicit_KO.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/LocalCanBeFinalExceptImplicit_OK.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/LocalCanBeFinal_KO.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/LocalCanBeFinal_OK.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/MethodMayBeStatic_KO.java (72%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/MethodMayBeStatic_OK.java (73%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/MissingOverrideAnnotation_KO.java (88%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/MissingOverrideAnnotation_OK.java (89%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_KO_Import_KO.java (82%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_KO_Import_OK.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_KO_Rearrange_KO.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_KO_Rearrange_OK.java (94%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_OK_Import_KO.java (84%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_OK_Import_OK.java (95%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/Reformat_OK_Rearrange_OK.java (95%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/SingleStatementInBlock_KO.java (93%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/SingleStatementInBlock_OK.java (90%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/SuppressAnnotation_KO.java (80%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/SuppressAnnotation_OK.java (77%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java (77%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java (75%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnnecessarySemicolon_KO.java (71%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnnecessarySemicolon_OK.java (69%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnnecessaryThis_KO.java (87%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnnecessaryThis_OK.java (87%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnqualifiedFieldAccess_KO.java (81%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnqualifiedFieldAccess_OK.java (81%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnqualifiedMethodAccess_KO.java (81%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnqualifiedMethodAccess_OK.java (82%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnqualifiedStaticMemberAccess_KO.java (90%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UnqualifiedStaticMemberAccess_OK.java (90%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UseBlocks_KO.java (92%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/integration/UseBlocks_OK.java (93%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/model/example0.epf (100%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/model/example1.epf (100%) rename src/test/resources/{com/dubreuia => software/xdev/saveactions}/model/example2.epf (100%) diff --git a/README.md b/README.md index 1824d6c..6438dd5 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,7 @@ Some things to note when using other plugins with the Save Actions plugin: ## Files location -- **idea.log**: The log file the save actions plugin writes in. It contains debug information, prefixed with `com.dubreuia.SaveActionManager`. If you are using default locations, it would be in `~/.IntelliJIdeaVERSION/system/log/idea.log`. +- **idea.log**: The log file the save actions plugin writes in. It contains debug information, prefixed with `software.xdev.saveactions.SaveActionManager`. If you are using default locations, it would be in `~/.IntelliJIdeaVERSION/system/log/idea.log`. - **saveactions_settings.xml**: The settings file is saved by project in the `.idea` folder. That file can be committed in git thus shared in your development team. If you are using the default locations, it would be in `~/IdeaProjects/PROJECT_NAME/.idea/saveactions_settings.xml` ## Contributions diff --git a/build.gradle b/build.gradle index fe2bb8a..0a74e46 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ apply plugin: 'org.jetbrains.intellij' apply plugin: 'java' // Add plugin group and version -group "com.dubreuia" +group "software.xdev.saveactions" version "2.6.0" // Add build script repository to maven central diff --git a/src/main/java/com/dubreuia/core/ExecutionMode.java b/src/main/java/software/xdev/saveactions/core/ExecutionMode.java similarity index 98% rename from src/main/java/com/dubreuia/core/ExecutionMode.java rename to src/main/java/software/xdev/saveactions/core/ExecutionMode.java index d4f8daa..02bb6f1 100644 --- a/src/main/java/com/dubreuia/core/ExecutionMode.java +++ b/src/main/java/software/xdev/saveactions/core/ExecutionMode.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.core; +package software.xdev.saveactions.core; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; diff --git a/src/main/java/com/dubreuia/core/action/BatchAction.java b/src/main/java/software/xdev/saveactions/core/action/BatchAction.java similarity index 86% rename from src/main/java/com/dubreuia/core/action/BatchAction.java rename to src/main/java/software/xdev/saveactions/core/action/BatchAction.java index 989f6bc..5bec1f3 100644 --- a/src/main/java/com/dubreuia/core/action/BatchAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/BatchAction.java @@ -22,10 +22,10 @@ * SOFTWARE. * */ -package com.dubreuia.core.action; +package software.xdev.saveactions.core.action; -import com.dubreuia.core.service.SaveActionsService; -import com.dubreuia.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; import com.intellij.analysis.AnalysisScope; import com.intellij.analysis.BaseAnalysisAction; import com.intellij.openapi.diagnostic.Logger; @@ -33,17 +33,18 @@ import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; +import software.xdev.saveactions.model.Action; import java.util.HashSet; import java.util.Set; -import static com.dubreuia.core.ExecutionMode.batch; -import static com.dubreuia.model.Action.activateOnBatch; +import static software.xdev.saveactions.core.ExecutionMode.batch; +import static software.xdev.saveactions.model.Action.activateOnBatch; import static java.util.Collections.synchronizedSet; /** * This action runs the save actions on the given scope of files, only if property - * {@link com.dubreuia.model.Action#activateOnShortcut} is enabled. The user is asked for the scope using a standard + * {@link Action#activateOnShortcut} is enabled. The user is asked for the scope using a standard * IDEA dialog. It delegates to {@link SaveActionsService}. Originally based on * {@link com.intellij.codeInspection.inferNullity.InferNullityAnnotationsAction}. * diff --git a/src/main/java/com/dubreuia/core/action/ShortcutAction.java b/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java similarity index 85% rename from src/main/java/com/dubreuia/core/action/ShortcutAction.java rename to src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java index 83d1882..6f7f783 100644 --- a/src/main/java/com/dubreuia/core/action/ShortcutAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java @@ -23,27 +23,28 @@ * */ -package com.dubreuia.core.action; +package software.xdev.saveactions.core.action; -import com.dubreuia.core.service.SaveActionsService; -import com.dubreuia.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; +import software.xdev.saveactions.model.Action; import java.util.HashSet; import java.util.Set; -import static com.dubreuia.core.ExecutionMode.shortcut; -import static com.dubreuia.model.Action.activateOnShortcut; +import static software.xdev.saveactions.core.ExecutionMode.shortcut; +import static software.xdev.saveactions.model.Action.activateOnShortcut; import static com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE; import static java.util.Collections.singletonList; /** - * This action runs the plugin on shortcut, only if property {@link com.dubreuia.model.Action#activateOnShortcut} is + * This action runs the plugin on shortcut, only if property {@link Action#activateOnShortcut} is * enabled. It delegates to {@link SaveActionsService}. * * @see SaveActionsServiceManager diff --git a/src/main/java/com/dubreuia/core/action/ToggleAnAction.java b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java similarity index 93% rename from src/main/java/com/dubreuia/core/action/ToggleAnAction.java rename to src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java index 1ddb956..ecaf895 100644 --- a/src/main/java/com/dubreuia/core/action/ToggleAnAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java @@ -23,15 +23,15 @@ * */ -package com.dubreuia.core.action; +package software.xdev.saveactions.core.action; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import static com.dubreuia.model.Action.activate; +import static software.xdev.saveactions.model.Action.activate; /** * This action toggles on and off the plugin, by modifying the underlying storage. diff --git a/src/main/java/com/dubreuia/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java similarity index 94% rename from src/main/java/com/dubreuia/core/component/Engine.java rename to src/main/java/software/xdev/saveactions/core/component/Engine.java index 62c57e9..522cc11 100644 --- a/src/main/java/com/dubreuia/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -23,16 +23,16 @@ * */ -package com.dubreuia.core.component; - -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.core.service.SaveActionsService; -import com.dubreuia.model.Action; -import com.dubreuia.model.Storage; -import com.dubreuia.processors.Processor; -import com.dubreuia.processors.Result; -import com.dubreuia.processors.ResultCode; -import com.dubreuia.processors.SaveCommand; +package software.xdev.saveactions.core.component; + +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; +import software.xdev.saveactions.processors.Processor; +import software.xdev.saveactions.processors.Result; +import software.xdev.saveactions.processors.ResultCode; +import software.xdev.saveactions.processors.SaveCommand; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -51,7 +51,6 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import static com.dubreuia.core.ExecutionMode.batch; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; @@ -171,7 +170,7 @@ private boolean isPsiFileIncluded(PsiFile psiFile) { } private boolean isPsiFileFresh(PsiFile psiFile) { - if (mode == batch) { + if (mode == ExecutionMode.batch) { return true; } boolean isFresh = psiFile.getModificationStamp() != 0; diff --git a/src/main/java/com/dubreuia/core/listener/SaveActionsDocumentManagerListener.java b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java similarity index 90% rename from src/main/java/com/dubreuia/core/listener/SaveActionsDocumentManagerListener.java rename to src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java index c2f5358..2cff54d 100644 --- a/src/main/java/com/dubreuia/core/listener/SaveActionsDocumentManagerListener.java +++ b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.core.listener; +package software.xdev.saveactions.core.listener; -import com.dubreuia.core.service.SaveActionsService; -import com.dubreuia.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -34,6 +34,8 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import java.util.Arrays; import java.util.List; @@ -41,9 +43,6 @@ import java.util.Set; import java.util.stream.Collectors; -import static com.dubreuia.core.ExecutionMode.saveAll; -import static com.dubreuia.model.Action.activate; - /** * FileDocumentManagerListener to catch save events. This listener is registered as ExtensionPoint. */ @@ -78,7 +77,7 @@ public void beforeDocumentsSaving(List documents) { .map(psiDocumentManager::getPsiFile) .filter(Objects::nonNull) .collect(Collectors.toSet()); - SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, activate, saveAll); + SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, Action.activate, ExecutionMode.saveAll); } private synchronized void initPsiDocManager() { diff --git a/src/main/java/com/dubreuia/core/service/SaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java similarity index 92% rename from src/main/java/com/dubreuia/core/service/SaveActionsService.java rename to src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java index da36a5f..6b7de14 100644 --- a/src/main/java/com/dubreuia/core/service/SaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.core.service; +package software.xdev.saveactions.core.service; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.components.Service; import com.intellij.openapi.project.Project; diff --git a/src/main/java/com/dubreuia/core/service/SaveActionsServiceManager.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java similarity index 91% rename from src/main/java/com/dubreuia/core/service/SaveActionsServiceManager.java rename to src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java index e880195..4cdbc21 100644 --- a/src/main/java/com/dubreuia/core/service/SaveActionsServiceManager.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.core.service; +package software.xdev.saveactions.core.service; -import com.dubreuia.core.service.impl.SaveActionsDefaultService; -import com.dubreuia.core.service.impl.SaveActionsJavaService; +import software.xdev.saveactions.core.service.impl.SaveActionsDefaultService; +import software.xdev.saveactions.core.service.impl.SaveActionsJavaService; import com.intellij.openapi.application.ApplicationManager; /** diff --git a/src/main/java/com/dubreuia/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java similarity index 91% rename from src/main/java/com/dubreuia/core/service/impl/AbstractSaveActionsService.java rename to src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index 7e6f3c2..3d3777a 100644 --- a/src/main/java/com/dubreuia/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -23,14 +23,14 @@ * */ -package com.dubreuia.core.service.impl; +package software.xdev.saveactions.core.service.impl; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.core.component.Engine; -import com.dubreuia.core.service.SaveActionsService; -import com.dubreuia.model.Action; -import com.dubreuia.model.StorageFactory; -import com.dubreuia.processors.Processor; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.component.Engine; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.StorageFactory; +import software.xdev.saveactions.processors.Processor; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; import com.intellij.openapi.application.ApplicationManager; @@ -47,7 +47,7 @@ import java.util.Set; import java.util.stream.Stream; -import static com.dubreuia.model.StorageFactory.JAVA; +import static software.xdev.saveactions.model.StorageFactory.JAVA; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; diff --git a/src/main/java/com/dubreuia/core/service/impl/SaveActionsDefaultService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java similarity index 88% rename from src/main/java/com/dubreuia/core/service/impl/SaveActionsDefaultService.java rename to src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java index d08e704..082d4c4 100644 --- a/src/main/java/com/dubreuia/core/service/impl/SaveActionsDefaultService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java @@ -23,12 +23,12 @@ * */ -package com.dubreuia.core.service.impl; +package software.xdev.saveactions.core.service.impl; -import com.dubreuia.processors.BuildProcessor; -import com.dubreuia.processors.GlobalProcessor; +import software.xdev.saveactions.processors.BuildProcessor; +import software.xdev.saveactions.processors.GlobalProcessor; -import static com.dubreuia.model.StorageFactory.DEFAULT; +import static software.xdev.saveactions.model.StorageFactory.DEFAULT; /** * This ApplicationService implementation is used for all IDE flavors that are not handling JAVA. diff --git a/src/main/java/com/dubreuia/core/service/impl/SaveActionsJavaService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java similarity index 87% rename from src/main/java/com/dubreuia/core/service/impl/SaveActionsJavaService.java rename to src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java index 0de65a4..4110870 100644 --- a/src/main/java/com/dubreuia/core/service/impl/SaveActionsJavaService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java @@ -23,13 +23,13 @@ * */ -package com.dubreuia.core.service.impl; +package software.xdev.saveactions.core.service.impl; -import com.dubreuia.processors.BuildProcessor; -import com.dubreuia.processors.GlobalProcessor; -import com.dubreuia.processors.java.JavaProcessor; +import software.xdev.saveactions.processors.BuildProcessor; +import software.xdev.saveactions.processors.GlobalProcessor; +import software.xdev.saveactions.processors.java.JavaProcessor; -import static com.dubreuia.model.StorageFactory.JAVA; +import static software.xdev.saveactions.model.StorageFactory.JAVA; /** * This ApplicationService implementation is used for all JAVA based IDE flavors. diff --git a/src/main/java/com/dubreuia/model/Action.java b/src/main/java/software/xdev/saveactions/model/Action.java similarity index 94% rename from src/main/java/com/dubreuia/model/Action.java rename to src/main/java/software/xdev/saveactions/model/Action.java index 40051d2..6f7ae3f 100644 --- a/src/main/java/com/dubreuia/model/Action.java +++ b/src/main/java/software/xdev/saveactions/model/Action.java @@ -23,16 +23,16 @@ * */ -package com.dubreuia.model; +package software.xdev.saveactions.model; import java.util.Arrays; import java.util.Set; import java.util.stream.Stream; -import static com.dubreuia.model.ActionType.activation; -import static com.dubreuia.model.ActionType.build; -import static com.dubreuia.model.ActionType.global; -import static com.dubreuia.model.ActionType.java; +import static software.xdev.saveactions.model.ActionType.activation; +import static software.xdev.saveactions.model.ActionType.build; +import static software.xdev.saveactions.model.ActionType.global; +import static software.xdev.saveactions.model.ActionType.java; import static java.util.stream.Collectors.toSet; public enum Action { diff --git a/src/main/java/com/dubreuia/model/ActionType.java b/src/main/java/software/xdev/saveactions/model/ActionType.java similarity index 96% rename from src/main/java/com/dubreuia/model/ActionType.java rename to src/main/java/software/xdev/saveactions/model/ActionType.java index 04f7c5f..698e3a9 100644 --- a/src/main/java/com/dubreuia/model/ActionType.java +++ b/src/main/java/software/xdev/saveactions/model/ActionType.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.model; +package software.xdev.saveactions.model; public enum ActionType { diff --git a/src/main/java/com/dubreuia/model/Storage.java b/src/main/java/software/xdev/saveactions/model/Storage.java similarity index 99% rename from src/main/java/com/dubreuia/model/Storage.java rename to src/main/java/software/xdev/saveactions/model/Storage.java index 6314f32..175ea0f 100644 --- a/src/main/java/com/dubreuia/model/Storage.java +++ b/src/main/java/software/xdev/saveactions/model/Storage.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.model; +package software.xdev.saveactions.model; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.Service; diff --git a/src/main/java/com/dubreuia/model/StorageFactory.java b/src/main/java/software/xdev/saveactions/model/StorageFactory.java similarity index 94% rename from src/main/java/com/dubreuia/model/StorageFactory.java rename to src/main/java/software/xdev/saveactions/model/StorageFactory.java index a8d8d99..db5e108 100644 --- a/src/main/java/com/dubreuia/model/StorageFactory.java +++ b/src/main/java/software/xdev/saveactions/model/StorageFactory.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.model; +package software.xdev.saveactions.model; -import com.dubreuia.model.java.EpfStorage; +import software.xdev.saveactions.model.java.EpfStorage; import com.intellij.openapi.project.Project; import java.util.function.Function; diff --git a/src/main/java/com/dubreuia/model/java/EpfAction.java b/src/main/java/software/xdev/saveactions/model/java/EpfAction.java similarity index 97% rename from src/main/java/com/dubreuia/model/java/EpfAction.java rename to src/main/java/software/xdev/saveactions/model/java/EpfAction.java index 2430831..61a203c 100644 --- a/src/main/java/com/dubreuia/model/java/EpfAction.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfAction.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; -import com.dubreuia.model.Action; +import software.xdev.saveactions.model.Action; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/com/dubreuia/model/java/EpfKey.java b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java similarity index 98% rename from src/main/java/com/dubreuia/model/java/EpfKey.java rename to src/main/java/software/xdev/saveactions/model/java/EpfKey.java index d53dbd4..13a0d62 100644 --- a/src/main/java/com/dubreuia/model/java/EpfKey.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; import java.util.Arrays; import java.util.Collections; diff --git a/src/main/java/com/dubreuia/model/java/EpfStorage.java b/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java similarity index 95% rename from src/main/java/com/dubreuia/model/java/EpfStorage.java rename to src/main/java/software/xdev/saveactions/model/java/EpfStorage.java index c759066..dcad32d 100644 --- a/src/main/java/com/dubreuia/model/java/EpfStorage.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java @@ -23,11 +23,11 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; -import com.dubreuia.core.service.SaveActionsService; -import com.dubreuia.model.Action; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.diagnostic.Logger; import java.io.FileInputStream; diff --git a/src/main/java/com/dubreuia/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java similarity index 95% rename from src/main/java/com/dubreuia/processors/BuildProcessor.java rename to src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index d2a3551..2b18e3d 100644 --- a/src/main/java/com/dubreuia/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -23,11 +23,11 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.core.service.SaveActionsServiceManager; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.HotSwapUI; @@ -49,7 +49,7 @@ import java.util.function.BiFunction; import java.util.stream.Stream; -import static com.dubreuia.utils.Helper.toVirtualFiles; +import static software.xdev.saveactions.utils.Helper.toVirtualFiles; import static com.intellij.openapi.actionSystem.ActionPlaces.UNKNOWN; import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR; import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT; diff --git a/src/main/java/com/dubreuia/processors/GlobalProcessor.java b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java similarity index 96% rename from src/main/java/com/dubreuia/processors/GlobalProcessor.java rename to src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java index f70e1ae..f89c0e5 100644 --- a/src/main/java/com/dubreuia/processors/GlobalProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.actions.OptimizeImportsProcessor; import com.intellij.codeInsight.actions.RearrangeCodeProcessor; diff --git a/src/main/java/com/dubreuia/processors/Processor.java b/src/main/java/software/xdev/saveactions/processors/Processor.java similarity index 92% rename from src/main/java/com/dubreuia/processors/Processor.java rename to src/main/java/software/xdev/saveactions/processors/Processor.java index 2affc38..be63d86 100644 --- a/src/main/java/com/dubreuia/processors/Processor.java +++ b/src/main/java/software/xdev/saveactions/processors/Processor.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; diff --git a/src/main/java/com/dubreuia/processors/Result.java b/src/main/java/software/xdev/saveactions/processors/Result.java similarity index 97% rename from src/main/java/com/dubreuia/processors/Result.java rename to src/main/java/software/xdev/saveactions/processors/Result.java index 0e42de9..d47812c 100644 --- a/src/main/java/com/dubreuia/processors/Result.java +++ b/src/main/java/software/xdev/saveactions/processors/Result.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; /** * Composite of {@link com.intellij.openapi.application.Result} and {@link com.intellij.openapi.application.RunResult}. diff --git a/src/main/java/com/dubreuia/processors/ResultCode.java b/src/main/java/software/xdev/saveactions/processors/ResultCode.java similarity index 96% rename from src/main/java/com/dubreuia/processors/ResultCode.java rename to src/main/java/software/xdev/saveactions/processors/ResultCode.java index 08c9204..830f1e5 100644 --- a/src/main/java/com/dubreuia/processors/ResultCode.java +++ b/src/main/java/software/xdev/saveactions/processors/ResultCode.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; /** * The result code for the run of {@link SaveWriteCommand}. diff --git a/src/main/java/com/dubreuia/processors/SaveCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveCommand.java similarity index 94% rename from src/main/java/com/dubreuia/processors/SaveCommand.java rename to src/main/java/software/xdev/saveactions/processors/SaveCommand.java index f64732f..eba2195 100644 --- a/src/main/java/com/dubreuia/processors/SaveCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveCommand.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; diff --git a/src/main/java/com/dubreuia/processors/SaveReadCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java similarity index 86% rename from src/main/java/com/dubreuia/processors/SaveReadCommand.java rename to src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java index d64ffd5..68e36fe 100644 --- a/src/main/java/com/dubreuia/processors/SaveReadCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java @@ -23,19 +23,16 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import java.util.Set; import java.util.function.BiFunction; -import static com.dubreuia.processors.ResultCode.FAILED; -import static com.dubreuia.processors.ResultCode.OK; - /** * Implements a read action that returns a {@link Result}. */ @@ -52,9 +49,9 @@ public SaveReadCommand( public synchronized Result execute() { try { getCommand().apply(getProject(), getPsiFilesAsArray()).run(); - return new Result<>(OK); + return new Result<>(ResultCode.OK); } catch (Exception e) { - return new Result<>(FAILED); + return new Result<>(ResultCode.FAILED); } } diff --git a/src/main/java/com/dubreuia/processors/SaveWriteCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java similarity index 87% rename from src/main/java/com/dubreuia/processors/SaveWriteCommand.java rename to src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java index 79a847a..31f02be 100644 --- a/src/main/java/com/dubreuia/processors/SaveWriteCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; @@ -34,9 +34,6 @@ import java.util.Set; import java.util.function.BiFunction; -import static com.dubreuia.processors.ResultCode.FAILED; -import static com.dubreuia.processors.ResultCode.OK; - /** * Implements a write action that encapsulates {@link com.intellij.openapi.command.WriteCommandAction} that returns * a {@link Result}. @@ -53,9 +50,9 @@ public synchronized Result execute() { try { WriteCommandAction.writeCommandAction(getProject(), getPsiFilesAsArray()) .run(() -> getCommand().apply(getProject(), getPsiFilesAsArray()).run()); - return new Result<>(OK); + return new Result<>(ResultCode.OK); } catch (Exception e) { - return new Result<>(FAILED); + return new Result<>(ResultCode.FAILED); } } } diff --git a/src/main/java/com/dubreuia/processors/java/InspectionRunnable.java b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java similarity index 97% rename from src/main/java/com/dubreuia/processors/java/InspectionRunnable.java rename to src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java index 5a3a91c..1806e0f 100644 --- a/src/main/java/com/dubreuia/processors/java/InspectionRunnable.java +++ b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.processors.java; +package software.xdev.saveactions.processors.java; -import com.dubreuia.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsService; import com.intellij.codeInspection.GlobalInspectionContext; import com.intellij.codeInspection.InspectionEngine; import com.intellij.codeInspection.InspectionManager; diff --git a/src/main/java/com/dubreuia/processors/java/JavaProcessor.java b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java similarity index 93% rename from src/main/java/com/dubreuia/processors/java/JavaProcessor.java rename to src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java index 41961ea..3826bf3 100644 --- a/src/main/java/com/dubreuia/processors/java/JavaProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java @@ -23,14 +23,14 @@ * */ -package com.dubreuia.processors.java; - -import com.dubreuia.core.ExecutionMode; -import com.dubreuia.model.Action; -import com.dubreuia.processors.Processor; -import com.dubreuia.processors.SaveWriteCommand; -import com.dubreuia.processors.java.inspection.CustomLocalCanBeFinal; -import com.dubreuia.processors.java.inspection.SerializableHasSerialVersionUIDFieldInspectionWrapper; +package software.xdev.saveactions.processors.java; + +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.processors.Processor; +import software.xdev.saveactions.processors.SaveWriteCommand; +import software.xdev.saveactions.processors.java.inspection.CustomLocalCanBeFinal; +import software.xdev.saveactions.processors.java.inspection.SerializableHasSerialVersionUIDFieldInspectionWrapper; import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection; diff --git a/src/main/java/com/dubreuia/processors/java/inspection/CustomLocalCanBeFinal.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java similarity index 97% rename from src/main/java/com/dubreuia/processors/java/inspection/CustomLocalCanBeFinal.java rename to src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java index 401d810..c77e26f 100644 --- a/src/main/java/com/dubreuia/processors/java/inspection/CustomLocalCanBeFinal.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.processors.java.inspection; +package software.xdev.saveactions.processors.java.inspection; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.ProblemDescriptor; diff --git a/src/main/java/com/dubreuia/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java similarity index 96% rename from src/main/java/com/dubreuia/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java rename to src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java index 2a4facc..b90630f 100644 --- a/src/main/java/com/dubreuia/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java @@ -1,4 +1,4 @@ -package com.dubreuia.processors.java.inspection; +package software.xdev.saveactions.processors.java.inspection; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.ProblemDescriptor; diff --git a/src/main/java/com/dubreuia/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java similarity index 94% rename from src/main/java/com/dubreuia/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java rename to src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java index 185eba9..1271b42 100644 --- a/src/main/java/com/dubreuia/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.processors.java.inspection; +package software.xdev.saveactions.processors.java.inspection; -import com.dubreuia.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsService; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.openapi.diagnostic.Logger; @@ -56,7 +56,7 @@ public static LocalInspectionTool get() { private enum SerializableClass { CLASS_NAME_INTELLIJ_2021_3("com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection", - "com.dubreuia.processors.java.inspection.CustomSerializableHasSerialVersionUidFieldInspection"), + "software.xdev.saveactions.processors.java.inspection.CustomSerializableHasSerialVersionUidFieldInspection"), CLASS_NAME_INTELLIJ_2018_3("com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspection", "com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspection"), CLASS_NAME_INTELLIJ_2016("com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspectionBase", diff --git a/src/main/java/com/dubreuia/ui/BuildPanel.java b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java similarity index 94% rename from src/main/java/com/dubreuia/ui/BuildPanel.java rename to src/main/java/software/xdev/saveactions/ui/BuildPanel.java index d2220c8..d093314 100644 --- a/src/main/java/com/dubreuia/ui/BuildPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; -import com.dubreuia.core.service.SaveActionsServiceManager; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; import com.intellij.openapi.ui.ComboBox; @@ -48,9 +48,9 @@ import java.util.List; import java.util.Map; -import static com.dubreuia.model.Action.compile; -import static com.dubreuia.model.Action.executeAction; -import static com.dubreuia.model.Action.reload; +import static software.xdev.saveactions.model.Action.compile; +import static software.xdev.saveactions.model.Action.executeAction; +import static software.xdev.saveactions.model.Action.reload; import static java.text.MessageFormat.format; import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toList; diff --git a/src/main/java/com/dubreuia/ui/Configuration.java b/src/main/java/software/xdev/saveactions/ui/Configuration.java similarity index 91% rename from src/main/java/com/dubreuia/ui/Configuration.java rename to src/main/java/software/xdev/saveactions/ui/Configuration.java index 7c4b61a..8e67612 100644 --- a/src/main/java/com/dubreuia/ui/Configuration.java +++ b/src/main/java/software/xdev/saveactions/ui/Configuration.java @@ -23,13 +23,13 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; -import com.dubreuia.model.Action; -import com.dubreuia.model.Storage; -import com.dubreuia.model.java.EpfStorage; -import com.dubreuia.ui.java.IdeSupportPanel; -import com.dubreuia.ui.java.InspectionPanel; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; +import software.xdev.saveactions.model.java.EpfStorage; +import software.xdev.saveactions.ui.java.IdeSupportPanel; +import software.xdev.saveactions.ui.java.InspectionPanel; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.Nls; @@ -52,15 +52,15 @@ import java.util.Map; import java.util.Set; -import static com.dubreuia.model.Action.activate; -import static com.dubreuia.model.Action.activateOnBatch; -import static com.dubreuia.model.Action.activateOnShortcut; -import static com.dubreuia.model.Action.compile; -import static com.dubreuia.model.Action.customUnqualifiedStaticMemberAccess; -import static com.dubreuia.model.Action.reformat; -import static com.dubreuia.model.Action.reformatChangedCode; -import static com.dubreuia.model.Action.reload; -import static com.dubreuia.model.Action.unqualifiedStaticMemberAccess; +import static software.xdev.saveactions.model.Action.activate; +import static software.xdev.saveactions.model.Action.activateOnBatch; +import static software.xdev.saveactions.model.Action.activateOnShortcut; +import static software.xdev.saveactions.model.Action.compile; +import static software.xdev.saveactions.model.Action.customUnqualifiedStaticMemberAccess; +import static software.xdev.saveactions.model.Action.reformat; +import static software.xdev.saveactions.model.Action.reformatChangedCode; +import static software.xdev.saveactions.model.Action.reload; +import static software.xdev.saveactions.model.Action.unqualifiedStaticMemberAccess; public class Configuration implements Configurable { diff --git a/src/main/java/com/dubreuia/ui/FileMaskExclusionPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java similarity index 98% rename from src/main/java/com/dubreuia/ui/FileMaskExclusionPanel.java rename to src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java index e878858..60f2d6d 100644 --- a/src/main/java/com/dubreuia/ui/FileMaskExclusionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; import java.util.Set; diff --git a/src/main/java/com/dubreuia/ui/FileMaskInclusionPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java similarity index 98% rename from src/main/java/com/dubreuia/ui/FileMaskInclusionPanel.java rename to src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java index 9443889..981b741 100644 --- a/src/main/java/com/dubreuia/ui/FileMaskInclusionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; import java.util.Set; diff --git a/src/main/java/com/dubreuia/ui/FileMaskPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java similarity index 99% rename from src/main/java/com/dubreuia/ui/FileMaskPanel.java rename to src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java index e931b1f..0da6065 100644 --- a/src/main/java/com/dubreuia/ui/FileMaskPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; import com.intellij.openapi.ui.InputValidator; import com.intellij.openapi.ui.Messages; diff --git a/src/main/java/com/dubreuia/ui/FormattingPanel.java b/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java similarity index 85% rename from src/main/java/com/dubreuia/ui/FormattingPanel.java rename to src/main/java/software/xdev/saveactions/ui/FormattingPanel.java index 65d7249..e6f165b 100644 --- a/src/main/java/com/dubreuia/ui/FormattingPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; -import com.dubreuia.model.Action; +import software.xdev.saveactions.model.Action; import com.intellij.ui.IdeBorderFactory; import javax.swing.Box; @@ -35,10 +35,10 @@ import java.awt.Dimension; import java.util.Map; -import static com.dubreuia.model.Action.organizeImports; -import static com.dubreuia.model.Action.rearrange; -import static com.dubreuia.model.Action.reformat; -import static com.dubreuia.model.Action.reformatChangedCode; +import static software.xdev.saveactions.model.Action.organizeImports; +import static software.xdev.saveactions.model.Action.rearrange; +import static software.xdev.saveactions.model.Action.reformat; +import static software.xdev.saveactions.model.Action.reformatChangedCode; class FormattingPanel { @@ -63,4 +63,4 @@ JPanel getPanel() { return panel; } -} \ No newline at end of file +} diff --git a/src/main/java/com/dubreuia/ui/GeneralPanel.java b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java similarity index 85% rename from src/main/java/com/dubreuia/ui/GeneralPanel.java rename to src/main/java/software/xdev/saveactions/ui/GeneralPanel.java index 1a4f7ba..41d07f7 100644 --- a/src/main/java/com/dubreuia/ui/GeneralPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.ui; +package software.xdev.saveactions.ui; -import com.dubreuia.model.Action; +import software.xdev.saveactions.model.Action; import com.intellij.ui.IdeBorderFactory; import javax.swing.Box; @@ -35,10 +35,10 @@ import java.awt.Dimension; import java.util.Map; -import static com.dubreuia.model.Action.activate; -import static com.dubreuia.model.Action.activateOnBatch; -import static com.dubreuia.model.Action.activateOnShortcut; -import static com.dubreuia.model.Action.noActionIfCompileErrors; +import static software.xdev.saveactions.model.Action.activate; +import static software.xdev.saveactions.model.Action.activateOnBatch; +import static software.xdev.saveactions.model.Action.activateOnShortcut; +import static software.xdev.saveactions.model.Action.noActionIfCompileErrors; class GeneralPanel { diff --git a/src/main/java/com/dubreuia/ui/java/IdeSupportPanel.java b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java similarity index 92% rename from src/main/java/com/dubreuia/ui/java/IdeSupportPanel.java rename to src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java index 5227b43..6e00a64 100644 --- a/src/main/java/com/dubreuia/ui/java/IdeSupportPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.ui.java; +package software.xdev.saveactions.ui.java; -import com.dubreuia.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileChooser.FileChooserFactory; @@ -34,14 +34,13 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBLabel; import org.jetbrains.annotations.NotNull; +import software.xdev.saveactions.ui.Configuration; import javax.swing.JButton; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Dimension; -import static com.dubreuia.ui.Configuration.BOX_LAYOUT_MAX_HEIGHT; -import static com.dubreuia.ui.Configuration.BOX_LAYOUT_MAX_WIDTH; import static com.intellij.openapi.ui.TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT; import static java.awt.BorderLayout.CENTER; import static java.awt.BorderLayout.EAST; @@ -76,7 +75,7 @@ public JPanel getPanel(String configurationPath) { panel.add(path, CENTER); panel.add(reset, EAST); - panel.setMaximumSize(new Dimension(BOX_LAYOUT_MAX_WIDTH, BOX_LAYOUT_MAX_HEIGHT)); + panel.setMaximumSize(new Dimension(Configuration.BOX_LAYOUT_MAX_WIDTH, Configuration.BOX_LAYOUT_MAX_HEIGHT)); return panel; } diff --git a/src/main/java/com/dubreuia/ui/java/InspectionPanel.java b/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java similarity index 90% rename from src/main/java/com/dubreuia/ui/java/InspectionPanel.java rename to src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java index af22f86..cb2f4f1 100644 --- a/src/main/java/com/dubreuia/ui/java/InspectionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java @@ -23,10 +23,10 @@ * */ -package com.dubreuia.ui.java; +package software.xdev.saveactions.ui.java; -import com.dubreuia.core.service.SaveActionsServiceManager; -import com.dubreuia.model.Action; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; import com.intellij.ui.IdeBorderFactory; import javax.swing.Box; @@ -36,7 +36,7 @@ import java.awt.Dimension; import java.util.Map; -import static com.dubreuia.model.ActionType.java; +import static software.xdev.saveactions.model.ActionType.java; public class InspectionPanel { diff --git a/src/main/java/com/dubreuia/utils/Helper.java b/src/main/java/software/xdev/saveactions/utils/Helper.java similarity index 97% rename from src/main/java/com/dubreuia/utils/Helper.java rename to src/main/java/software/xdev/saveactions/utils/Helper.java index e05627b..c6f2efa 100644 --- a/src/main/java/com/dubreuia/utils/Helper.java +++ b/src/main/java/software/xdev/saveactions/utils/Helper.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.utils; +package software.xdev.saveactions.utils; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; diff --git a/src/main/resources/META-INF/plugin-java.xml b/src/main/resources/META-INF/plugin-java.xml index 9f124e5..c225c5a 100644 --- a/src/main/resources/META-INF/plugin-java.xml +++ b/src/main/resources/META-INF/plugin-java.xml @@ -3,7 +3,7 @@ - + diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index bb8ac95..2333258 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -2,7 +2,7 @@ - com.dubreuia + software.xdev.saveactions Save Actions 2.6.0 Alexandre DuBreuil @@ -64,39 +64,39 @@ com.intellij.modules.java - + - + - - - - - diff --git a/src/test/java/com/dubreuia/integration/JavaIntegrationTest.java b/src/test/java/com/dubreuia/integration/JavaIntegrationTest.java deleted file mode 100644 index 9f996f2..0000000 --- a/src/test/java/com/dubreuia/integration/JavaIntegrationTest.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -package com.dubreuia.integration; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import static com.dubreuia.integration.ActionTestFile.AccessCanBeTightened_KO; -import static com.dubreuia.integration.ActionTestFile.AccessCanBeTightened_OK; -import static com.dubreuia.integration.ActionTestFile.CustomUnqualifiedStaticMemberAccess_KO; -import static com.dubreuia.integration.ActionTestFile.CustomUnqualifiedStaticMemberAccess_OK; -import static com.dubreuia.integration.ActionTestFile.ExplicitTypeCanBeDiamond_KO; -import static com.dubreuia.integration.ActionTestFile.ExplicitTypeCanBeDiamond_OK; -import static com.dubreuia.integration.ActionTestFile.FieldCanBeFinal_KO; -import static com.dubreuia.integration.ActionTestFile.FieldCanBeFinal_OK; -import static com.dubreuia.integration.ActionTestFile.FinalPrivateMethod_KO; -import static com.dubreuia.integration.ActionTestFile.FinalPrivateMethod_OK; -import static com.dubreuia.integration.ActionTestFile.GenerateSerialVersionUID_KO; -import static com.dubreuia.integration.ActionTestFile.GenerateSerialVersionUID_OK; -import static com.dubreuia.integration.ActionTestFile.InspectionsAll_KO; -import static com.dubreuia.integration.ActionTestFile.InspectionsAll_OK; -import static com.dubreuia.integration.ActionTestFile.LocalCanBeFinalExceptImplicit_KO; -import static com.dubreuia.integration.ActionTestFile.LocalCanBeFinalExceptImplicit_OK; -import static com.dubreuia.integration.ActionTestFile.LocalCanBeFinal_KO; -import static com.dubreuia.integration.ActionTestFile.LocalCanBeFinal_OK; -import static com.dubreuia.integration.ActionTestFile.MethodMayBeStatic_KO; -import static com.dubreuia.integration.ActionTestFile.MethodMayBeStatic_OK; -import static com.dubreuia.integration.ActionTestFile.MissingOverrideAnnotation_KO; -import static com.dubreuia.integration.ActionTestFile.MissingOverrideAnnotation_OK; -import static com.dubreuia.integration.ActionTestFile.SingleStatementInBlock_KO; -import static com.dubreuia.integration.ActionTestFile.SingleStatementInBlock_OK; -import static com.dubreuia.integration.ActionTestFile.SuppressAnnotation_KO; -import static com.dubreuia.integration.ActionTestFile.SuppressAnnotation_OK; -import static com.dubreuia.integration.ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_KO; -import static com.dubreuia.integration.ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_OK; -import static com.dubreuia.integration.ActionTestFile.UnnecessarySemicolon_KO; -import static com.dubreuia.integration.ActionTestFile.UnnecessarySemicolon_OK; -import static com.dubreuia.integration.ActionTestFile.UnnecessaryThis_KO; -import static com.dubreuia.integration.ActionTestFile.UnnecessaryThis_OK; -import static com.dubreuia.integration.ActionTestFile.UnqualifiedFieldAccess_KO; -import static com.dubreuia.integration.ActionTestFile.UnqualifiedFieldAccess_OK; -import static com.dubreuia.integration.ActionTestFile.UnqualifiedMethodAccess_KO; -import static com.dubreuia.integration.ActionTestFile.UnqualifiedMethodAccess_OK; -import static com.dubreuia.integration.ActionTestFile.UnqualifiedStaticMemberAccess_KO; -import static com.dubreuia.integration.ActionTestFile.UnqualifiedStaticMemberAccess_OK; -import static com.dubreuia.integration.ActionTestFile.UseBlocks_KO; -import static com.dubreuia.integration.ActionTestFile.UseBlocks_OK; -import static com.dubreuia.model.Action.accessCanBeTightened; -import static com.dubreuia.model.Action.activate; -import static com.dubreuia.model.Action.activateOnBatch; -import static com.dubreuia.model.Action.activateOnShortcut; -import static com.dubreuia.model.Action.customUnqualifiedStaticMemberAccess; -import static com.dubreuia.model.Action.explicitTypeCanBeDiamond; -import static com.dubreuia.model.Action.fieldCanBeFinal; -import static com.dubreuia.model.Action.finalPrivateMethod; -import static com.dubreuia.model.Action.generateSerialVersionUID; -import static com.dubreuia.model.Action.localCanBeFinal; -import static com.dubreuia.model.Action.localCanBeFinalExceptImplicit; -import static com.dubreuia.model.Action.methodMayBeStatic; -import static com.dubreuia.model.Action.missingOverrideAnnotation; -import static com.dubreuia.model.Action.singleStatementInBlock; -import static com.dubreuia.model.Action.suppressAnnotation; -import static com.dubreuia.model.Action.unnecessaryFinalOnLocalVariableOrParameter; -import static com.dubreuia.model.Action.unnecessarySemicolon; -import static com.dubreuia.model.Action.unnecessaryThis; -import static com.dubreuia.model.Action.unqualifiedFieldAccess; -import static com.dubreuia.model.Action.unqualifiedMethodAccess; -import static com.dubreuia.model.Action.unqualifiedStaticMemberAccess; -import static com.dubreuia.model.Action.useBlocks; - -class JavaIntegrationTest extends IntegrationTest { - - @Test - void should_fieldCanBeFinal_add_final_to_field() { - storage.setEnabled(activate, true); - storage.setEnabled(fieldCanBeFinal, true); - assertSaveAction(FieldCanBeFinal_KO, FieldCanBeFinal_OK); - } - - @Test - void should_fieldCanBeFinal_add_final_to_field_on_shortcut() { - storage.setEnabled(activateOnShortcut, true); - storage.setEnabled(fieldCanBeFinal, true); - assertSaveActionShortcut(FieldCanBeFinal_KO, FieldCanBeFinal_OK); - } - - @Test - void should_fieldCanBeFinal_add_final_to_field_on_batch() { - storage.setEnabled(activateOnBatch, true); - storage.setEnabled(fieldCanBeFinal, true); - assertSaveActionBatch(FieldCanBeFinal_KO, FieldCanBeFinal_OK); - } - - @Test - void should_localCanBeFinal_add_final_to_local_variable_and_parameters() { - storage.setEnabled(activate, true); - storage.setEnabled(localCanBeFinal, true); - assertSaveAction(LocalCanBeFinal_KO, LocalCanBeFinal_OK); - } - - @Test - void should_localCanBeFinalExceptImplicit_add_final_to_variable_but_not_resources() { - storage.setEnabled(activate, true); - storage.setEnabled(localCanBeFinalExceptImplicit, true); - assertSaveAction(LocalCanBeFinalExceptImplicit_KO, LocalCanBeFinalExceptImplicit_OK); - } - - @Test - @Disabled("do not work") - void should_methodMayBeStatic_add_static_keyword_to_method() { - storage.setEnabled(activate, true); - storage.setEnabled(methodMayBeStatic, true); - assertSaveAction(MethodMayBeStatic_KO, MethodMayBeStatic_OK); - } - - @Test - void should_unqualifiedFieldAccess_add_this_to_field_access() { - storage.setEnabled(activate, true); - storage.setEnabled(unqualifiedFieldAccess, true); - assertSaveAction(UnqualifiedFieldAccess_KO, UnqualifiedFieldAccess_OK); - } - - @Test - void should_unqualifiedMethodAccess_add_this_to_method_access() { - storage.setEnabled(activate, true); - storage.setEnabled(unqualifiedMethodAccess, true); - assertSaveAction(UnqualifiedMethodAccess_KO, UnqualifiedMethodAccess_OK); - } - - @Test - void should_unqualifiedStaticMemberAccess_add_this_to_method_access() { - storage.setEnabled(activate, true); - storage.setEnabled(unqualifiedStaticMemberAccess, true); - assertSaveAction(UnqualifiedStaticMemberAccess_KO, UnqualifiedStaticMemberAccess_OK); - } - - @Test - void should_customUnqualifiedStaticMemberAccess_add_this_to_method_access() { - storage.setEnabled(activate, true); - storage.setEnabled(customUnqualifiedStaticMemberAccess, true); - assertSaveAction(CustomUnqualifiedStaticMemberAccess_KO, CustomUnqualifiedStaticMemberAccess_OK); - } - - @Test - void should_missingOverrideAnnotation_add_override_annotation() { - storage.setEnabled(activate, true); - storage.setEnabled(missingOverrideAnnotation, true); - assertSaveAction(MissingOverrideAnnotation_KO, MissingOverrideAnnotation_OK); - } - - @Test - void should_useBlocks_add_blocks_to_if_else_while_for() { - storage.setEnabled(activate, true); - storage.setEnabled(useBlocks, true); - assertSaveAction(UseBlocks_KO, UseBlocks_OK); - } - - @Test - @Disabled("do not work") - void should_generateSerialVersionUID_generates_serial_version_uid_for_serializable_class() { - storage.setEnabled(activate, true); - storage.setEnabled(generateSerialVersionUID, true); - assertSaveAction(GenerateSerialVersionUID_KO, GenerateSerialVersionUID_OK); - } - - @Test - void should_unnecessaryThis_removes_this_on_method_and_field() { - storage.setEnabled(activate, true); - storage.setEnabled(unnecessaryThis, true); - assertSaveAction(UnnecessaryThis_KO, UnnecessaryThis_OK); - } - - @Test - void should_finalPrivateMethod_removes_final_on_private_methods() { - storage.setEnabled(activate, true); - storage.setEnabled(finalPrivateMethod, true); - assertSaveAction(FinalPrivateMethod_KO, FinalPrivateMethod_OK); - } - - @Test - void should_unnecessaryFinalOnLocalVariableOrParameter_removes_final_on_local_varible_and_parameters() { - storage.setEnabled(activate, true); - storage.setEnabled(unnecessaryFinalOnLocalVariableOrParameter, true); - assertSaveAction(UnnecessaryFinalOnLocalVariableOrParameter_KO, UnnecessaryFinalOnLocalVariableOrParameter_OK); - } - - @Test - @Disabled("do not work") - void should_explicitTypeCanBeDiamond_removes_explicit_diamond() { - storage.setEnabled(activate, true); - storage.setEnabled(explicitTypeCanBeDiamond, true); - assertSaveAction(ExplicitTypeCanBeDiamond_KO, ExplicitTypeCanBeDiamond_OK); - } - - @Test - void should_suppressAnnotation_remove_unnecessary_suppress_warning_annotation() { - storage.setEnabled(activate, true); - storage.setEnabled(suppressAnnotation, true); - assertSaveAction(SuppressAnnotation_KO, SuppressAnnotation_OK); - } - - @Test - void should_unnecessarySemicolon_remove_unnecessary_semicolon() { - storage.setEnabled(activate, true); - storage.setEnabled(unnecessarySemicolon, true); - assertSaveAction(UnnecessarySemicolon_KO, UnnecessarySemicolon_OK); - } - - @Test - void should_accessCanBeTightened_remove_unnecessary_semicolon() { - storage.setEnabled(activate, true); - storage.setEnabled(accessCanBeTightened, true); - assertSaveAction(AccessCanBeTightened_KO, AccessCanBeTightened_OK); - } - - @Test - void should_singleStatementInBlock_remove_braces() { - storage.setEnabled(activate, true); - storage.setEnabled(singleStatementInBlock, true); - assertSaveAction(SingleStatementInBlock_KO, SingleStatementInBlock_OK); - } - - @Test - void should_inspectionsAll_boogaloo() { - storage.setEnabled(activate, true); - storage.setEnabled(useBlocks, true); - storage.setEnabled(accessCanBeTightened, true); - storage.setEnabled(unnecessarySemicolon, true); - assertSaveAction(InspectionsAll_KO, InspectionsAll_OK); - } - -} diff --git a/src/test/java/com/dubreuia/core/action/BatchActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java similarity index 94% rename from src/test/java/com/dubreuia/core/action/BatchActionConstants.java rename to src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java index 6e0e503..9e59efa 100644 --- a/src/test/java/com/dubreuia/core/action/BatchActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java @@ -23,11 +23,12 @@ * */ -package com.dubreuia.core.action; +package software.xdev.saveactions.core.action; import com.intellij.analysis.AnalysisScope; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; +import software.xdev.saveactions.core.action.BatchAction; import java.util.function.Consumer; diff --git a/src/test/java/com/dubreuia/core/action/ShortcutActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java similarity index 96% rename from src/test/java/com/dubreuia/core/action/ShortcutActionConstants.java rename to src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java index 582e627..ea677e6 100644 --- a/src/test/java/com/dubreuia/core/action/ShortcutActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.core.action; +package software.xdev.saveactions.core.action; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; @@ -32,6 +32,7 @@ import com.intellij.openapi.actionSystem.impl.SimpleDataContext; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; +import software.xdev.saveactions.core.action.ShortcutAction; import java.util.function.Consumer; diff --git a/src/test/java/com/dubreuia/core/component/PsiFileTest.java b/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java similarity index 96% rename from src/test/java/com/dubreuia/core/component/PsiFileTest.java rename to src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java index 9cb0b41..9efc5ab 100644 --- a/src/test/java/com/dubreuia/core/component/PsiFileTest.java +++ b/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java @@ -23,10 +23,11 @@ * */ -package com.dubreuia.core.component; +package software.xdev.saveactions.core.component; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.core.component.Engine; +import software.xdev.saveactions.model.Storage; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; diff --git a/src/test/java/com/dubreuia/core/component/SaveActionManagerConstants.java b/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java similarity index 89% rename from src/test/java/com/dubreuia/core/component/SaveActionManagerConstants.java rename to src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java index 8e5bb85..723f61d 100644 --- a/src/test/java/com/dubreuia/core/component/SaveActionManagerConstants.java +++ b/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java @@ -23,9 +23,9 @@ * */ -package com.dubreuia.core.component; +package software.xdev.saveactions.core.component; -import com.dubreuia.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsService; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.PsiFile; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; @@ -34,8 +34,8 @@ import java.util.Set; import java.util.function.BiConsumer; -import static com.dubreuia.core.ExecutionMode.saveAll; -import static com.dubreuia.model.Action.activate; +import static software.xdev.saveactions.core.ExecutionMode.saveAll; +import static software.xdev.saveactions.model.Action.activate; import static java.util.Collections.singleton; public interface SaveActionManagerConstants { diff --git a/src/test/java/com/dubreuia/integration/ActionTestFile.java b/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java similarity index 98% rename from src/test/java/com/dubreuia/integration/ActionTestFile.java rename to src/test/java/software/xdev/saveactions/integration/ActionTestFile.java index 55f21d1..fb847c7 100644 --- a/src/test/java/com/dubreuia/integration/ActionTestFile.java +++ b/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public enum ActionTestFile { diff --git a/src/test/java/com/dubreuia/integration/GlobalIntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java similarity index 65% rename from src/test/java/com/dubreuia/integration/GlobalIntegrationTest.java rename to src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java index 84a3b61..c094916 100644 --- a/src/test/java/com/dubreuia/integration/GlobalIntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java @@ -23,78 +23,71 @@ * */ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import org.junit.jupiter.api.Test; -import static com.dubreuia.integration.ActionTestFile.Reformat_KO_Import_KO; -import static com.dubreuia.integration.ActionTestFile.Reformat_KO_Import_OK; -import static com.dubreuia.integration.ActionTestFile.Reformat_KO_Rearrange_KO; -import static com.dubreuia.integration.ActionTestFile.Reformat_KO_Rearrange_OK; -import static com.dubreuia.integration.ActionTestFile.Reformat_OK_Import_KO; -import static com.dubreuia.integration.ActionTestFile.Reformat_OK_Import_OK; -import static com.dubreuia.integration.ActionTestFile.Reformat_OK_Rearrange_OK; -import static com.dubreuia.model.Action.activate; -import static com.dubreuia.model.Action.activateOnBatch; -import static com.dubreuia.model.Action.activateOnShortcut; -import static com.dubreuia.model.Action.organizeImports; -import static com.dubreuia.model.Action.rearrange; -import static com.dubreuia.model.Action.reformat; +import static software.xdev.saveactions.model.Action.activate; +import static software.xdev.saveactions.model.Action.activateOnBatch; +import static software.xdev.saveactions.model.Action.activateOnShortcut; +import static software.xdev.saveactions.model.Action.organizeImports; +import static software.xdev.saveactions.model.Action.rearrange; +import static software.xdev.saveactions.model.Action.reformat; class GlobalIntegrationTest extends IntegrationTest { @Test void should_reformat_without_activation_produces_same_file() { storage.setEnabled(reformat, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_KO_Import_KO); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); } @Test void should_reformat_with_activation_produces_indented_file() { storage.setEnabled(activate, true); storage.setEnabled(reformat, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_OK_Import_KO); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); } @Test void should_reformat_with_shortcut_produces_same_file() { storage.setEnabled(activateOnShortcut, true); storage.setEnabled(reformat, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_KO_Import_KO); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); } @Test void should_reformat_with_shortcut_produces_indented_file_on_shortcut() { storage.setEnabled(activateOnShortcut, true); storage.setEnabled(reformat, true); - assertSaveActionShortcut(Reformat_KO_Import_KO, Reformat_OK_Import_KO); + assertSaveActionShortcut(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); } @Test void should_reformat_as_batch_produces_indented_file() { storage.setEnabled(activateOnBatch, true); storage.setEnabled(reformat, true); - assertSaveActionBatch(Reformat_KO_Import_KO, Reformat_OK_Import_KO); + assertSaveActionBatch(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); } @Test void should_reformat_as_batch_on_shortcut_produces_same_file() { storage.setEnabled(activateOnShortcut, true); storage.setEnabled(reformat, true); - assertSaveActionBatch(Reformat_KO_Import_KO, Reformat_KO_Import_KO); + assertSaveActionBatch(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); } @Test void should_import_without_activation_produces_same_file() { storage.setEnabled(organizeImports, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_KO_Import_KO); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); } @Test void should_import_with_activation_produces_cleaned_import_file() { storage.setEnabled(activate, true); storage.setEnabled(organizeImports, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_KO_Import_OK); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_OK); } @Test @@ -102,20 +95,20 @@ void should_import_and_format_with_activation_produces_cleaned_import_and_format storage.setEnabled(activate, true); storage.setEnabled(organizeImports, true); storage.setEnabled(reformat, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_OK_Import_OK); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_OK); } @Test void should_rearrange_without_activation_produces_same_file() { storage.setEnabled(rearrange, true); - assertSaveAction(Reformat_KO_Import_KO, Reformat_KO_Import_KO); + assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); } @Test void should_rearrange_with_activation_produces_ordered_file() { storage.setEnabled(activate, true); storage.setEnabled(rearrange, true); - assertSaveAction(Reformat_KO_Rearrange_KO, Reformat_KO_Rearrange_OK); + assertSaveAction(ActionTestFile.Reformat_KO_Rearrange_KO, ActionTestFile.Reformat_KO_Rearrange_OK); } @Test @@ -123,7 +116,7 @@ void should_rearrange_and_format_with_activation_produces_ordered_file_and_forma storage.setEnabled(activate, true); storage.setEnabled(reformat, true); storage.setEnabled(rearrange, true); - assertSaveAction(Reformat_KO_Rearrange_KO, Reformat_OK_Rearrange_OK); + assertSaveAction(ActionTestFile.Reformat_KO_Rearrange_KO, ActionTestFile.Reformat_OK_Rearrange_OK); } } diff --git a/src/test/java/com/dubreuia/integration/IntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java similarity index 75% rename from src/test/java/com/dubreuia/integration/IntegrationTest.java rename to src/test/java/software/xdev/saveactions/integration/IntegrationTest.java index fe5ad64..667e260 100644 --- a/src/test/java/com/dubreuia/integration/IntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java @@ -23,10 +23,14 @@ * */ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.core.service.SaveActionsServiceManager; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.core.action.BatchActionConstants; +import software.xdev.saveactions.core.action.ShortcutActionConstants; +import software.xdev.saveactions.core.component.SaveActionManagerConstants; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.junit.JUnit5Utils; +import software.xdev.saveactions.model.Storage; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; @@ -38,10 +42,7 @@ import java.nio.file.Path; import java.nio.file.Paths; -import static com.dubreuia.core.action.BatchActionConstants.SAVE_ACTION_BATCH_MANAGER; -import static com.dubreuia.core.action.ShortcutActionConstants.SAVE_ACTION_SHORTCUT_MANAGER; -import static com.dubreuia.core.component.SaveActionManagerConstants.SAVE_ACTION_MANAGER; -import static com.dubreuia.junit.JUnit5Utils.rethrowAsJunit5Error; +import static software.xdev.saveactions.junit.JUnit5Utils.rethrowAsJunit5Error; import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; public abstract class IntegrationTest { @@ -68,20 +69,20 @@ public void after() throws Exception { void assertSaveAction(ActionTestFile before, ActionTestFile after) { fixture.configureByFile(before.getFilename()); - SAVE_ACTION_MANAGER.accept(fixture, SaveActionsServiceManager.getService()); - rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); + SaveActionManagerConstants.SAVE_ACTION_MANAGER.accept(fixture, SaveActionsServiceManager.getService()); + JUnit5Utils.rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); } void assertSaveActionShortcut(ActionTestFile before, ActionTestFile after) { fixture.configureByFile(before.getFilename()); - SAVE_ACTION_SHORTCUT_MANAGER.accept(fixture); - rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); + ShortcutActionConstants.SAVE_ACTION_SHORTCUT_MANAGER.accept(fixture); + JUnit5Utils.rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); } void assertSaveActionBatch(ActionTestFile before, ActionTestFile after) { fixture.configureByFile(before.getFilename()); - SAVE_ACTION_BATCH_MANAGER.accept(fixture); - rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); + BatchActionConstants.SAVE_ACTION_BATCH_MANAGER.accept(fixture); + JUnit5Utils.rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); } private String getTestDataPath() { diff --git a/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java new file mode 100644 index 0000000..ffb00ca --- /dev/null +++ b/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java @@ -0,0 +1,215 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Alexandre DuBreuil + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package software.xdev.saveactions.integration; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import static software.xdev.saveactions.model.Action.accessCanBeTightened; +import static software.xdev.saveactions.model.Action.activate; +import static software.xdev.saveactions.model.Action.activateOnBatch; +import static software.xdev.saveactions.model.Action.activateOnShortcut; +import static software.xdev.saveactions.model.Action.customUnqualifiedStaticMemberAccess; +import static software.xdev.saveactions.model.Action.explicitTypeCanBeDiamond; +import static software.xdev.saveactions.model.Action.fieldCanBeFinal; +import static software.xdev.saveactions.model.Action.finalPrivateMethod; +import static software.xdev.saveactions.model.Action.generateSerialVersionUID; +import static software.xdev.saveactions.model.Action.localCanBeFinal; +import static software.xdev.saveactions.model.Action.localCanBeFinalExceptImplicit; +import static software.xdev.saveactions.model.Action.methodMayBeStatic; +import static software.xdev.saveactions.model.Action.missingOverrideAnnotation; +import static software.xdev.saveactions.model.Action.singleStatementInBlock; +import static software.xdev.saveactions.model.Action.suppressAnnotation; +import static software.xdev.saveactions.model.Action.unnecessaryFinalOnLocalVariableOrParameter; +import static software.xdev.saveactions.model.Action.unnecessarySemicolon; +import static software.xdev.saveactions.model.Action.unnecessaryThis; +import static software.xdev.saveactions.model.Action.unqualifiedFieldAccess; +import static software.xdev.saveactions.model.Action.unqualifiedMethodAccess; +import static software.xdev.saveactions.model.Action.unqualifiedStaticMemberAccess; +import static software.xdev.saveactions.model.Action.useBlocks; + +class JavaIntegrationTest extends IntegrationTest { + + @Test + void should_fieldCanBeFinal_add_final_to_field() { + storage.setEnabled(activate, true); + storage.setEnabled(fieldCanBeFinal, true); + assertSaveAction(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); + } + + @Test + void should_fieldCanBeFinal_add_final_to_field_on_shortcut() { + storage.setEnabled(activateOnShortcut, true); + storage.setEnabled(fieldCanBeFinal, true); + assertSaveActionShortcut(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); + } + + @Test + void should_fieldCanBeFinal_add_final_to_field_on_batch() { + storage.setEnabled(activateOnBatch, true); + storage.setEnabled(fieldCanBeFinal, true); + assertSaveActionBatch(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); + } + + @Test + void should_localCanBeFinal_add_final_to_local_variable_and_parameters() { + storage.setEnabled(activate, true); + storage.setEnabled(localCanBeFinal, true); + assertSaveAction(ActionTestFile.LocalCanBeFinal_KO, ActionTestFile.LocalCanBeFinal_OK); + } + + @Test + void should_localCanBeFinalExceptImplicit_add_final_to_variable_but_not_resources() { + storage.setEnabled(activate, true); + storage.setEnabled(localCanBeFinalExceptImplicit, true); + assertSaveAction(ActionTestFile.LocalCanBeFinalExceptImplicit_KO, ActionTestFile.LocalCanBeFinalExceptImplicit_OK); + } + + @Test + @Disabled("do not work") + void should_methodMayBeStatic_add_static_keyword_to_method() { + storage.setEnabled(activate, true); + storage.setEnabled(methodMayBeStatic, true); + assertSaveAction(ActionTestFile.MethodMayBeStatic_KO, ActionTestFile.MethodMayBeStatic_OK); + } + + @Test + void should_unqualifiedFieldAccess_add_this_to_field_access() { + storage.setEnabled(activate, true); + storage.setEnabled(unqualifiedFieldAccess, true); + assertSaveAction(ActionTestFile.UnqualifiedFieldAccess_KO, ActionTestFile.UnqualifiedFieldAccess_OK); + } + + @Test + void should_unqualifiedMethodAccess_add_this_to_method_access() { + storage.setEnabled(activate, true); + storage.setEnabled(unqualifiedMethodAccess, true); + assertSaveAction(ActionTestFile.UnqualifiedMethodAccess_KO, ActionTestFile.UnqualifiedMethodAccess_OK); + } + + @Test + void should_unqualifiedStaticMemberAccess_add_this_to_method_access() { + storage.setEnabled(activate, true); + storage.setEnabled(unqualifiedStaticMemberAccess, true); + assertSaveAction(ActionTestFile.UnqualifiedStaticMemberAccess_KO, ActionTestFile.UnqualifiedStaticMemberAccess_OK); + } + + @Test + void should_customUnqualifiedStaticMemberAccess_add_this_to_method_access() { + storage.setEnabled(activate, true); + storage.setEnabled(customUnqualifiedStaticMemberAccess, true); + assertSaveAction(ActionTestFile.CustomUnqualifiedStaticMemberAccess_KO, ActionTestFile.CustomUnqualifiedStaticMemberAccess_OK); + } + + @Test + void should_missingOverrideAnnotation_add_override_annotation() { + storage.setEnabled(activate, true); + storage.setEnabled(missingOverrideAnnotation, true); + assertSaveAction(ActionTestFile.MissingOverrideAnnotation_KO, ActionTestFile.MissingOverrideAnnotation_OK); + } + + @Test + void should_useBlocks_add_blocks_to_if_else_while_for() { + storage.setEnabled(activate, true); + storage.setEnabled(useBlocks, true); + assertSaveAction(ActionTestFile.UseBlocks_KO, ActionTestFile.UseBlocks_OK); + } + + @Test + @Disabled("do not work") + void should_generateSerialVersionUID_generates_serial_version_uid_for_serializable_class() { + storage.setEnabled(activate, true); + storage.setEnabled(generateSerialVersionUID, true); + assertSaveAction(ActionTestFile.GenerateSerialVersionUID_KO, ActionTestFile.GenerateSerialVersionUID_OK); + } + + @Test + void should_unnecessaryThis_removes_this_on_method_and_field() { + storage.setEnabled(activate, true); + storage.setEnabled(unnecessaryThis, true); + assertSaveAction(ActionTestFile.UnnecessaryThis_KO, ActionTestFile.UnnecessaryThis_OK); + } + + @Test + void should_finalPrivateMethod_removes_final_on_private_methods() { + storage.setEnabled(activate, true); + storage.setEnabled(finalPrivateMethod, true); + assertSaveAction(ActionTestFile.FinalPrivateMethod_KO, ActionTestFile.FinalPrivateMethod_OK); + } + + @Test + void should_unnecessaryFinalOnLocalVariableOrParameter_removes_final_on_local_varible_and_parameters() { + storage.setEnabled(activate, true); + storage.setEnabled(unnecessaryFinalOnLocalVariableOrParameter, true); + assertSaveAction(ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_KO, ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_OK); + } + + @Test + @Disabled("do not work") + void should_explicitTypeCanBeDiamond_removes_explicit_diamond() { + storage.setEnabled(activate, true); + storage.setEnabled(explicitTypeCanBeDiamond, true); + assertSaveAction(ActionTestFile.ExplicitTypeCanBeDiamond_KO, ActionTestFile.ExplicitTypeCanBeDiamond_OK); + } + + @Test + void should_suppressAnnotation_remove_unnecessary_suppress_warning_annotation() { + storage.setEnabled(activate, true); + storage.setEnabled(suppressAnnotation, true); + assertSaveAction(ActionTestFile.SuppressAnnotation_KO, ActionTestFile.SuppressAnnotation_OK); + } + + @Test + void should_unnecessarySemicolon_remove_unnecessary_semicolon() { + storage.setEnabled(activate, true); + storage.setEnabled(unnecessarySemicolon, true); + assertSaveAction(ActionTestFile.UnnecessarySemicolon_KO, ActionTestFile.UnnecessarySemicolon_OK); + } + + @Test + void should_accessCanBeTightened_remove_unnecessary_semicolon() { + storage.setEnabled(activate, true); + storage.setEnabled(accessCanBeTightened, true); + assertSaveAction(ActionTestFile.AccessCanBeTightened_KO, ActionTestFile.AccessCanBeTightened_OK); + } + + @Test + void should_singleStatementInBlock_remove_braces() { + storage.setEnabled(activate, true); + storage.setEnabled(singleStatementInBlock, true); + assertSaveAction(ActionTestFile.SingleStatementInBlock_KO, ActionTestFile.SingleStatementInBlock_OK); + } + + @Test + void should_inspectionsAll_boogaloo() { + storage.setEnabled(activate, true); + storage.setEnabled(useBlocks, true); + storage.setEnabled(accessCanBeTightened, true); + storage.setEnabled(unnecessarySemicolon, true); + assertSaveAction(ActionTestFile.InspectionsAll_KO, ActionTestFile.InspectionsAll_OK); + } + +} diff --git a/src/test/java/com/dubreuia/junit/JUnit5Utils.java b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java similarity index 98% rename from src/test/java/com/dubreuia/junit/JUnit5Utils.java rename to src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java index 604ddc9..eedecad 100644 --- a/src/test/java/com/dubreuia/junit/JUnit5Utils.java +++ b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.junit; +package software.xdev.saveactions.junit; import com.intellij.rt.execution.junit.FileComparisonFailure; import org.opentest4j.AssertionFailedError; diff --git a/src/test/java/com/dubreuia/model/java/EpfActionTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java similarity index 92% rename from src/test/java/com/dubreuia/model/java/EpfActionTest.java rename to src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java index 877ea38..a7788ed 100644 --- a/src/test/java/com/dubreuia/model/java/EpfActionTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java @@ -23,10 +23,11 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; -import com.dubreuia.model.Action; +import software.xdev.saveactions.model.Action; import org.junit.jupiter.api.Test; +import software.xdev.saveactions.model.java.EpfAction; import java.util.List; @@ -47,4 +48,4 @@ void should_java_processor_have_valid_type_and_inspection() { EpfAction.stream().forEach(epfAction -> assertThat(epfAction.getEpfKeys()).isNotEmpty()); } -} \ No newline at end of file +} diff --git a/src/test/java/com/dubreuia/model/java/EpfKeyTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java similarity index 86% rename from src/test/java/com/dubreuia/model/java/EpfKeyTest.java rename to src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java index 25814d3..5ed15c6 100644 --- a/src/test/java/com/dubreuia/model/java/EpfKeyTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; import org.junit.jupiter.api.Test; @@ -33,9 +33,6 @@ import java.util.Map; import java.util.Properties; -import static com.dubreuia.model.java.EpfTestConstants.EXAMPLE_EPF_0; -import static com.dubreuia.model.java.EpfTestConstants.EXAMPLE_EPF_1; -import static com.dubreuia.model.java.EpfTestConstants.EXAMPLE_EPF_2; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; @@ -43,25 +40,25 @@ class EpfKeyTest { @Test void should_all_example_file_0_keys_be_present_in_epf_key() throws IOException { - Properties properties = readProperties(EXAMPLE_EPF_0.toString()); + Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_0.toString()); assertPropertyPresenceInEpf(properties); } @Test void should_all_example_file_1_keys_be_present_in_epf_key() throws IOException { - Properties properties = readProperties(EXAMPLE_EPF_1.toString()); + Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_1.toString()); assertPropertyPresenceInEpf(properties); } @Test void should_all_example_file_2_keys_be_present_in_epf_key() throws IOException { - Properties properties = readProperties(EXAMPLE_EPF_2.toString()); + Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_2.toString()); assertPropertyPresenceInEpf(properties); } @Test void should_all_epf_key_be_present_in_example_files_2_to_remove_unused_keys() throws IOException { - Properties properties = readProperties(EXAMPLE_EPF_2.toString()); + Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_2.toString()); List epfKeyNames = getEpfKeyNames(); List propertiesKeyNames = getPropertiesKeyNames(properties); epfKeyNames.forEach(epfKeyName -> assertThat(propertiesKeyNames).contains(epfKeyName)); @@ -96,4 +93,4 @@ private Properties readProperties(String configurationPath) throws IOException { return properties; } -} \ No newline at end of file +} diff --git a/src/test/java/com/dubreuia/model/java/EpfStorageTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java similarity index 80% rename from src/test/java/com/dubreuia/model/java/EpfStorageTest.java rename to src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java index 586b7a4..e7b784a 100644 --- a/src/test/java/com/dubreuia/model/java/EpfStorageTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java @@ -23,32 +23,32 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; -import com.dubreuia.model.Action; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.EnumSet; import java.util.HashSet; -import static com.dubreuia.model.Action.activate; -import static com.dubreuia.model.Action.explicitTypeCanBeDiamond; -import static com.dubreuia.model.Action.fieldCanBeFinal; -import static com.dubreuia.model.Action.localCanBeFinal; -import static com.dubreuia.model.Action.missingOverrideAnnotation; -import static com.dubreuia.model.Action.organizeImports; -import static com.dubreuia.model.Action.rearrange; -import static com.dubreuia.model.Action.reformat; -import static com.dubreuia.model.Action.reformatChangedCode; -import static com.dubreuia.model.Action.unnecessarySemicolon; -import static com.dubreuia.model.Action.unqualifiedFieldAccess; -import static com.dubreuia.model.Action.unqualifiedStaticMemberAccess; -import static com.dubreuia.model.Action.useBlocks; -import static com.dubreuia.model.java.EpfTestConstants.EXAMPLE_EPF_0; -import static com.dubreuia.model.java.EpfTestConstants.EXAMPLE_EPF_1; -import static com.dubreuia.model.java.EpfTestConstants.EXAMPLE_EPF_2; +import static software.xdev.saveactions.model.Action.activate; +import static software.xdev.saveactions.model.Action.explicitTypeCanBeDiamond; +import static software.xdev.saveactions.model.Action.fieldCanBeFinal; +import static software.xdev.saveactions.model.Action.localCanBeFinal; +import static software.xdev.saveactions.model.Action.missingOverrideAnnotation; +import static software.xdev.saveactions.model.Action.organizeImports; +import static software.xdev.saveactions.model.Action.rearrange; +import static software.xdev.saveactions.model.Action.reformat; +import static software.xdev.saveactions.model.Action.reformatChangedCode; +import static software.xdev.saveactions.model.Action.unnecessarySemicolon; +import static software.xdev.saveactions.model.Action.unqualifiedFieldAccess; +import static software.xdev.saveactions.model.Action.unqualifiedStaticMemberAccess; +import static software.xdev.saveactions.model.Action.useBlocks; +import static software.xdev.saveactions.model.java.EpfTestConstants.EXAMPLE_EPF_0; +import static software.xdev.saveactions.model.java.EpfTestConstants.EXAMPLE_EPF_1; +import static software.xdev.saveactions.model.java.EpfTestConstants.EXAMPLE_EPF_2; import static org.assertj.core.api.Assertions.assertThat; class EpfStorageTest { diff --git a/src/test/java/com/dubreuia/model/java/EpfTestConstants.java b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java similarity index 97% rename from src/test/java/com/dubreuia/model/java/EpfTestConstants.java rename to src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java index 3e422fd..46f5773 100644 --- a/src/test/java/com/dubreuia/model/java/EpfTestConstants.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java @@ -23,7 +23,7 @@ * */ -package com.dubreuia.model.java; +package software.xdev.saveactions.model.java; import java.io.File; import java.nio.file.Path; diff --git a/src/test/java/com/dubreuia/processors/BuildProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java similarity index 88% rename from src/test/java/com/dubreuia/processors/BuildProcessorTest.java rename to src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java index 860d6e8..e39e485 100644 --- a/src/test/java/com/dubreuia/processors/BuildProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java @@ -23,14 +23,16 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.model.Action; +import software.xdev.saveactions.model.Action; import org.junit.jupiter.api.Test; +import software.xdev.saveactions.processors.BuildProcessor; +import software.xdev.saveactions.processors.Processor; import java.util.List; -import static com.dubreuia.model.ActionType.build; +import static software.xdev.saveactions.model.ActionType.build; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/com/dubreuia/processors/GlobalProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java similarity index 88% rename from src/test/java/com/dubreuia/processors/GlobalProcessorTest.java rename to src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java index 8026b59..4e5563d 100644 --- a/src/test/java/com/dubreuia/processors/GlobalProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java @@ -23,14 +23,16 @@ * */ -package com.dubreuia.processors; +package software.xdev.saveactions.processors; -import com.dubreuia.model.Action; +import software.xdev.saveactions.model.Action; import org.junit.jupiter.api.Test; +import software.xdev.saveactions.processors.GlobalProcessor; +import software.xdev.saveactions.processors.Processor; import java.util.List; -import static com.dubreuia.model.ActionType.global; +import static software.xdev.saveactions.model.ActionType.global; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/com/dubreuia/processors/java/JavaProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java similarity index 88% rename from src/test/java/com/dubreuia/processors/java/JavaProcessorTest.java rename to src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java index f7291fe..8035645 100644 --- a/src/test/java/com/dubreuia/processors/java/JavaProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java @@ -23,15 +23,16 @@ * */ -package com.dubreuia.processors.java; +package software.xdev.saveactions.processors.java; -import com.dubreuia.model.Action; -import com.dubreuia.processors.Processor; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.processors.Processor; import org.junit.jupiter.api.Test; +import software.xdev.saveactions.processors.java.JavaProcessor; import java.util.List; -import static com.dubreuia.model.ActionType.java; +import static software.xdev.saveactions.model.ActionType.java; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; @@ -56,4 +57,4 @@ void should_java_action_have_java_processor() { Action.stream(java).forEach(action -> assertThat(JavaProcessor.getProcessorForAction(action)).isNotEmpty()); } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/AccessCanBeTightened_KO.java b/src/test/resources/software/xdev/saveactions/integration/AccessCanBeTightened_KO.java similarity index 75% rename from src/test/resources/com/dubreuia/integration/AccessCanBeTightened_KO.java rename to src/test/resources/software/xdev/saveactions/integration/AccessCanBeTightened_KO.java index 2c730f9..97e068a 100644 --- a/src/test/resources/com/dubreuia/integration/AccessCanBeTightened_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/AccessCanBeTightened_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { @@ -13,4 +13,4 @@ public void method1() { field = 0; } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/AccessCanBeTightened_OK.java b/src/test/resources/software/xdev/saveactions/integration/AccessCanBeTightened_OK.java similarity index 75% rename from src/test/resources/com/dubreuia/integration/AccessCanBeTightened_OK.java rename to src/test/resources/software/xdev/saveactions/integration/AccessCanBeTightened_OK.java index 6c9428d..d0b3f89 100644 --- a/src/test/resources/com/dubreuia/integration/AccessCanBeTightened_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/AccessCanBeTightened_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { @@ -13,4 +13,4 @@ public void method1() { field = 0; } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/CustomUnqualifiedStaticMemberAccess_KO.java b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java similarity index 90% rename from src/test/resources/com/dubreuia/integration/CustomUnqualifiedStaticMemberAccess_KO.java rename to src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java index abec95b..8ca184f 100644 --- a/src/test/resources/com/dubreuia/integration/CustomUnqualifiedStaticMemberAccess_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 @@ -21,4 +21,4 @@ class World extends Hello { void sayIt() { println(STR + " World!"); // should qualify } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/CustomUnqualifiedStaticMemberAccess_OK.java b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java similarity index 90% rename from src/test/resources/com/dubreuia/integration/CustomUnqualifiedStaticMemberAccess_OK.java rename to src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java index 4e28a04..80fb7df 100644 --- a/src/test/resources/com/dubreuia/integration/CustomUnqualifiedStaticMemberAccess_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 @@ -21,4 +21,4 @@ class World extends Hello { void sayIt() { println(Hello.STR + " World!"); // should qualify } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/ExplicitTypeCanBeDiamond_KO.java b/src/test/resources/software/xdev/saveactions/integration/ExplicitTypeCanBeDiamond_KO.java similarity index 85% rename from src/test/resources/com/dubreuia/integration/ExplicitTypeCanBeDiamond_KO.java rename to src/test/resources/software/xdev/saveactions/integration/ExplicitTypeCanBeDiamond_KO.java index 87ebecf..d29941a 100644 --- a/src/test/resources/com/dubreuia/integration/ExplicitTypeCanBeDiamond_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/ExplicitTypeCanBeDiamond_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/test/resources/com/dubreuia/integration/ExplicitTypeCanBeDiamond_OK.java b/src/test/resources/software/xdev/saveactions/integration/ExplicitTypeCanBeDiamond_OK.java similarity index 84% rename from src/test/resources/com/dubreuia/integration/ExplicitTypeCanBeDiamond_OK.java rename to src/test/resources/software/xdev/saveactions/integration/ExplicitTypeCanBeDiamond_OK.java index 82079b3..9c1e2cf 100644 --- a/src/test/resources/com/dubreuia/integration/ExplicitTypeCanBeDiamond_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/ExplicitTypeCanBeDiamond_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/test/resources/com/dubreuia/integration/FieldCanBeFinal_KO.java b/src/test/resources/software/xdev/saveactions/integration/FieldCanBeFinal_KO.java similarity index 85% rename from src/test/resources/com/dubreuia/integration/FieldCanBeFinal_KO.java rename to src/test/resources/software/xdev/saveactions/integration/FieldCanBeFinal_KO.java index 49da410..e747db2 100644 --- a/src/test/resources/com/dubreuia/integration/FieldCanBeFinal_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/FieldCanBeFinal_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/FieldCanBeFinal_OK.java b/src/test/resources/software/xdev/saveactions/integration/FieldCanBeFinal_OK.java similarity index 86% rename from src/test/resources/com/dubreuia/integration/FieldCanBeFinal_OK.java rename to src/test/resources/software/xdev/saveactions/integration/FieldCanBeFinal_OK.java index 6aaff28..d1e1bf3 100644 --- a/src/test/resources/com/dubreuia/integration/FieldCanBeFinal_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/FieldCanBeFinal_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/FinalPrivateMethod_KO.java b/src/test/resources/software/xdev/saveactions/integration/FinalPrivateMethod_KO.java similarity index 60% rename from src/test/resources/com/dubreuia/integration/FinalPrivateMethod_KO.java rename to src/test/resources/software/xdev/saveactions/integration/FinalPrivateMethod_KO.java index 1f3f98b..c44b0d3 100644 --- a/src/test/resources/com/dubreuia/integration/FinalPrivateMethod_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/FinalPrivateMethod_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/FinalPrivateMethod_OK.java b/src/test/resources/software/xdev/saveactions/integration/FinalPrivateMethod_OK.java similarity index 58% rename from src/test/resources/com/dubreuia/integration/FinalPrivateMethod_OK.java rename to src/test/resources/software/xdev/saveactions/integration/FinalPrivateMethod_OK.java index bbe5b4b..2cc661e 100644 --- a/src/test/resources/com/dubreuia/integration/FinalPrivateMethod_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/FinalPrivateMethod_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/GenerateSerialVersionUID_KO.java b/src/test/resources/software/xdev/saveactions/integration/GenerateSerialVersionUID_KO.java similarity index 62% rename from src/test/resources/com/dubreuia/integration/GenerateSerialVersionUID_KO.java rename to src/test/resources/software/xdev/saveactions/integration/GenerateSerialVersionUID_KO.java index 38dbab3..83696fd 100644 --- a/src/test/resources/com/dubreuia/integration/GenerateSerialVersionUID_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/GenerateSerialVersionUID_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import java.io.Serializable; diff --git a/src/test/resources/com/dubreuia/integration/GenerateSerialVersionUID_OK.java b/src/test/resources/software/xdev/saveactions/integration/GenerateSerialVersionUID_OK.java similarity index 76% rename from src/test/resources/com/dubreuia/integration/GenerateSerialVersionUID_OK.java rename to src/test/resources/software/xdev/saveactions/integration/GenerateSerialVersionUID_OK.java index b600925..833408e 100644 --- a/src/test/resources/com/dubreuia/integration/GenerateSerialVersionUID_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/GenerateSerialVersionUID_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import java.io.Serializable; diff --git a/src/test/resources/com/dubreuia/integration/InspectionsAll_KO.java b/src/test/resources/software/xdev/saveactions/integration/InspectionsAll_KO.java similarity index 81% rename from src/test/resources/com/dubreuia/integration/InspectionsAll_KO.java rename to src/test/resources/software/xdev/saveactions/integration/InspectionsAll_KO.java index 668f39f..8b757db 100644 --- a/src/test/resources/com/dubreuia/integration/InspectionsAll_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/InspectionsAll_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { @@ -15,4 +15,4 @@ public void method1() { ; } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/InspectionsAll_OK.java b/src/test/resources/software/xdev/saveactions/integration/InspectionsAll_OK.java similarity index 82% rename from src/test/resources/com/dubreuia/integration/InspectionsAll_OK.java rename to src/test/resources/software/xdev/saveactions/integration/InspectionsAll_OK.java index 3445d57..4695b52 100644 --- a/src/test/resources/com/dubreuia/integration/InspectionsAll_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/InspectionsAll_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { @@ -15,4 +15,4 @@ public void method1() { field = 0; } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/LocalCanBeFinalExceptImplicit_KO.java b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinalExceptImplicit_KO.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/LocalCanBeFinalExceptImplicit_KO.java rename to src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinalExceptImplicit_KO.java index dd5e1ae..b187b5c 100644 --- a/src/test/resources/com/dubreuia/integration/LocalCanBeFinalExceptImplicit_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinalExceptImplicit_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/LocalCanBeFinalExceptImplicit_OK.java b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinalExceptImplicit_OK.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/LocalCanBeFinalExceptImplicit_OK.java rename to src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinalExceptImplicit_OK.java index f28893d..40d168a 100644 --- a/src/test/resources/com/dubreuia/integration/LocalCanBeFinalExceptImplicit_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinalExceptImplicit_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/LocalCanBeFinal_KO.java b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinal_KO.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/LocalCanBeFinal_KO.java rename to src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinal_KO.java index b6c9b21..5b4b53b 100644 --- a/src/test/resources/com/dubreuia/integration/LocalCanBeFinal_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinal_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/LocalCanBeFinal_OK.java b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinal_OK.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/LocalCanBeFinal_OK.java rename to src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinal_OK.java index 180cf5b..1b81654 100644 --- a/src/test/resources/com/dubreuia/integration/LocalCanBeFinal_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/LocalCanBeFinal_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/MethodMayBeStatic_KO.java b/src/test/resources/software/xdev/saveactions/integration/MethodMayBeStatic_KO.java similarity index 72% rename from src/test/resources/com/dubreuia/integration/MethodMayBeStatic_KO.java rename to src/test/resources/software/xdev/saveactions/integration/MethodMayBeStatic_KO.java index 4e60647..5d9e1d4 100644 --- a/src/test/resources/com/dubreuia/integration/MethodMayBeStatic_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/MethodMayBeStatic_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/MethodMayBeStatic_OK.java b/src/test/resources/software/xdev/saveactions/integration/MethodMayBeStatic_OK.java similarity index 73% rename from src/test/resources/com/dubreuia/integration/MethodMayBeStatic_OK.java rename to src/test/resources/software/xdev/saveactions/integration/MethodMayBeStatic_OK.java index 96d8673..13afb96 100644 --- a/src/test/resources/com/dubreuia/integration/MethodMayBeStatic_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/MethodMayBeStatic_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/MissingOverrideAnnotation_KO.java b/src/test/resources/software/xdev/saveactions/integration/MissingOverrideAnnotation_KO.java similarity index 88% rename from src/test/resources/com/dubreuia/integration/MissingOverrideAnnotation_KO.java rename to src/test/resources/software/xdev/saveactions/integration/MissingOverrideAnnotation_KO.java index ea6619f..1b9de31 100644 --- a/src/test/resources/com/dubreuia/integration/MissingOverrideAnnotation_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/MissingOverrideAnnotation_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/MissingOverrideAnnotation_OK.java b/src/test/resources/software/xdev/saveactions/integration/MissingOverrideAnnotation_OK.java similarity index 89% rename from src/test/resources/com/dubreuia/integration/MissingOverrideAnnotation_OK.java rename to src/test/resources/software/xdev/saveactions/integration/MissingOverrideAnnotation_OK.java index 2e91bac..8862f79 100644 --- a/src/test/resources/com/dubreuia/integration/MissingOverrideAnnotation_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/MissingOverrideAnnotation_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/Reformat_KO_Import_KO.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java similarity index 82% rename from src/test/resources/com/dubreuia/integration/Reformat_KO_Import_KO.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java index fb9403d..a4d66b7 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_KO_Import_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java @@ -1,24 +1,18 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.components.ServiceManager; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; -import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl; import org.junit.jupiter.api.BeforeEach; import java.nio.file.Path; import java.nio.file.Paths; import java.util.function.Consumer; -import java.math.BigDecimal; - -import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; -import static java.math.BigDecimal.ONE public class Class { diff --git a/src/test/resources/com/dubreuia/integration/Reformat_KO_Import_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/Reformat_KO_Import_OK.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java index 3be351a..a4d66b7 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_KO_Import_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java @@ -1,6 +1,6 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; diff --git a/src/test/resources/com/dubreuia/integration/Reformat_KO_Rearrange_KO.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/Reformat_KO_Rearrange_KO.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java index 3be351a..a4d66b7 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_KO_Rearrange_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java @@ -1,6 +1,6 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; diff --git a/src/test/resources/com/dubreuia/integration/Reformat_KO_Rearrange_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java similarity index 94% rename from src/test/resources/com/dubreuia/integration/Reformat_KO_Rearrange_OK.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java index 773d930..04050b7 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_KO_Rearrange_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java @@ -1,6 +1,6 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; diff --git a/src/test/resources/com/dubreuia/integration/Reformat_OK_Import_KO.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java similarity index 84% rename from src/test/resources/com/dubreuia/integration/Reformat_OK_Import_KO.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java index 8bdcf9d..e4d0bd0 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_OK_Import_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java @@ -1,24 +1,18 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.components.ServiceManager; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; -import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl; import org.junit.jupiter.api.BeforeEach; import java.nio.file.Path; import java.nio.file.Paths; import java.util.function.Consumer; -import java.math.BigDecimal; - -import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; -import static java.math.BigDecimal.ONE public class Class { diff --git a/src/test/resources/com/dubreuia/integration/Reformat_OK_Import_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java similarity index 95% rename from src/test/resources/com/dubreuia/integration/Reformat_OK_Import_OK.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java index 8e4b01b..e4d0bd0 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_OK_Import_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java @@ -1,6 +1,6 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; diff --git a/src/test/resources/com/dubreuia/integration/Reformat_OK_Rearrange_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java similarity index 95% rename from src/test/resources/com/dubreuia/integration/Reformat_OK_Rearrange_OK.java rename to src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java index 7f1a5a1..9796108 100644 --- a/src/test/resources/com/dubreuia/integration/Reformat_OK_Rearrange_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java @@ -1,6 +1,6 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; -import com.dubreuia.model.Storage; +import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; diff --git a/src/test/resources/com/dubreuia/integration/SingleStatementInBlock_KO.java b/src/test/resources/software/xdev/saveactions/integration/SingleStatementInBlock_KO.java similarity index 93% rename from src/test/resources/com/dubreuia/integration/SingleStatementInBlock_KO.java rename to src/test/resources/software/xdev/saveactions/integration/SingleStatementInBlock_KO.java index d2df60e..b38e7d0 100644 --- a/src/test/resources/com/dubreuia/integration/SingleStatementInBlock_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/SingleStatementInBlock_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/SingleStatementInBlock_OK.java b/src/test/resources/software/xdev/saveactions/integration/SingleStatementInBlock_OK.java similarity index 90% rename from src/test/resources/com/dubreuia/integration/SingleStatementInBlock_OK.java rename to src/test/resources/software/xdev/saveactions/integration/SingleStatementInBlock_OK.java index 9220bf2..f5b0704 100644 --- a/src/test/resources/com/dubreuia/integration/SingleStatementInBlock_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/SingleStatementInBlock_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/SuppressAnnotation_KO.java b/src/test/resources/software/xdev/saveactions/integration/SuppressAnnotation_KO.java similarity index 80% rename from src/test/resources/com/dubreuia/integration/SuppressAnnotation_KO.java rename to src/test/resources/software/xdev/saveactions/integration/SuppressAnnotation_KO.java index 3db3cb4..2f02b12 100644 --- a/src/test/resources/com/dubreuia/integration/SuppressAnnotation_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/SuppressAnnotation_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import java.util.List; import java.util.ArrayList; diff --git a/src/test/resources/com/dubreuia/integration/SuppressAnnotation_OK.java b/src/test/resources/software/xdev/saveactions/integration/SuppressAnnotation_OK.java similarity index 77% rename from src/test/resources/com/dubreuia/integration/SuppressAnnotation_OK.java rename to src/test/resources/software/xdev/saveactions/integration/SuppressAnnotation_OK.java index c3cc6f5..09e04a0 100644 --- a/src/test/resources/com/dubreuia/integration/SuppressAnnotation_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/SuppressAnnotation_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; import java.util.List; import java.util.ArrayList; diff --git a/src/test/resources/com/dubreuia/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java similarity index 77% rename from src/test/resources/com/dubreuia/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java index 5ec8d38..649a85b 100644 --- a/src/test/resources/com/dubreuia/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java similarity index 75% rename from src/test/resources/com/dubreuia/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java index 74c0fc7..2f7f5ec 100644 --- a/src/test/resources/com/dubreuia/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnnecessarySemicolon_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessarySemicolon_KO.java similarity index 71% rename from src/test/resources/com/dubreuia/integration/UnnecessarySemicolon_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UnnecessarySemicolon_KO.java index 9edd141..fe852df 100644 --- a/src/test/resources/com/dubreuia/integration/UnnecessarySemicolon_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessarySemicolon_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnnecessarySemicolon_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessarySemicolon_OK.java similarity index 69% rename from src/test/resources/com/dubreuia/integration/UnnecessarySemicolon_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UnnecessarySemicolon_OK.java index a4223de..db0442f 100644 --- a/src/test/resources/com/dubreuia/integration/UnnecessarySemicolon_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessarySemicolon_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnnecessaryThis_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryThis_KO.java similarity index 87% rename from src/test/resources/com/dubreuia/integration/UnnecessaryThis_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UnnecessaryThis_KO.java index 6f23390..1cddf43 100644 --- a/src/test/resources/com/dubreuia/integration/UnnecessaryThis_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryThis_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnnecessaryThis_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryThis_OK.java similarity index 87% rename from src/test/resources/com/dubreuia/integration/UnnecessaryThis_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UnnecessaryThis_OK.java index 1fab307..21cc0fd 100644 --- a/src/test/resources/com/dubreuia/integration/UnnecessaryThis_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryThis_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnqualifiedFieldAccess_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedFieldAccess_KO.java similarity index 81% rename from src/test/resources/com/dubreuia/integration/UnqualifiedFieldAccess_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UnqualifiedFieldAccess_KO.java index 704f23e..bb77fdc 100644 --- a/src/test/resources/com/dubreuia/integration/UnqualifiedFieldAccess_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedFieldAccess_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnqualifiedFieldAccess_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedFieldAccess_OK.java similarity index 81% rename from src/test/resources/com/dubreuia/integration/UnqualifiedFieldAccess_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UnqualifiedFieldAccess_OK.java index 1bc86e1..d70fefa 100644 --- a/src/test/resources/com/dubreuia/integration/UnqualifiedFieldAccess_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedFieldAccess_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnqualifiedMethodAccess_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedMethodAccess_KO.java similarity index 81% rename from src/test/resources/com/dubreuia/integration/UnqualifiedMethodAccess_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UnqualifiedMethodAccess_KO.java index 7229b3f..decddbe 100644 --- a/src/test/resources/com/dubreuia/integration/UnqualifiedMethodAccess_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedMethodAccess_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnqualifiedMethodAccess_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedMethodAccess_OK.java similarity index 82% rename from src/test/resources/com/dubreuia/integration/UnqualifiedMethodAccess_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UnqualifiedMethodAccess_OK.java index f36b597..958fb48 100644 --- a/src/test/resources/com/dubreuia/integration/UnqualifiedMethodAccess_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedMethodAccess_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UnqualifiedStaticMemberAccess_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java similarity index 90% rename from src/test/resources/com/dubreuia/integration/UnqualifiedStaticMemberAccess_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java index 73e780b..fd0b7d0 100644 --- a/src/test/resources/com/dubreuia/integration/UnqualifiedStaticMemberAccess_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 @@ -21,4 +21,4 @@ class World extends Hello { void sayIt() { println(STR + " World!"); // should qualify } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/UnqualifiedStaticMemberAccess_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java similarity index 90% rename from src/test/resources/com/dubreuia/integration/UnqualifiedStaticMemberAccess_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java index 77a0b65..a56075d 100644 --- a/src/test/resources/com/dubreuia/integration/UnqualifiedStaticMemberAccess_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 @@ -21,4 +21,4 @@ class World extends Hello { void sayIt() { println(Hello.STR + " World!"); // should qualify } -} \ No newline at end of file +} diff --git a/src/test/resources/com/dubreuia/integration/UseBlocks_KO.java b/src/test/resources/software/xdev/saveactions/integration/UseBlocks_KO.java similarity index 92% rename from src/test/resources/com/dubreuia/integration/UseBlocks_KO.java rename to src/test/resources/software/xdev/saveactions/integration/UseBlocks_KO.java index 2d9195e..424e244 100644 --- a/src/test/resources/com/dubreuia/integration/UseBlocks_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UseBlocks_KO.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/integration/UseBlocks_OK.java b/src/test/resources/software/xdev/saveactions/integration/UseBlocks_OK.java similarity index 93% rename from src/test/resources/com/dubreuia/integration/UseBlocks_OK.java rename to src/test/resources/software/xdev/saveactions/integration/UseBlocks_OK.java index d2df60e..b38e7d0 100644 --- a/src/test/resources/com/dubreuia/integration/UseBlocks_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UseBlocks_OK.java @@ -1,4 +1,4 @@ -package com.dubreuia.integration; +package software.xdev.saveactions.integration; public class Class { diff --git a/src/test/resources/com/dubreuia/model/example0.epf b/src/test/resources/software/xdev/saveactions/model/example0.epf similarity index 100% rename from src/test/resources/com/dubreuia/model/example0.epf rename to src/test/resources/software/xdev/saveactions/model/example0.epf diff --git a/src/test/resources/com/dubreuia/model/example1.epf b/src/test/resources/software/xdev/saveactions/model/example1.epf similarity index 100% rename from src/test/resources/com/dubreuia/model/example1.epf rename to src/test/resources/software/xdev/saveactions/model/example1.epf diff --git a/src/test/resources/com/dubreuia/model/example2.epf b/src/test/resources/software/xdev/saveactions/model/example2.epf similarity index 100% rename from src/test/resources/com/dubreuia/model/example2.epf rename to src/test/resources/software/xdev/saveactions/model/example2.epf From 5b95d753e26fa436bfb430225d8a000ecaa0c8d5 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 11:33:30 +0200 Subject: [PATCH 317/518] Rename --- .idea/saveactions_settings.xml | 4 +- src/main/resources/META-INF/plugin.xml | 56 +++++--------------------- 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/.idea/saveactions_settings.xml b/.idea/saveactions_settings.xml index 1d9abf8..6d1df43 100644 --- a/.idea/saveactions_settings.xml +++ b/.idea/saveactions_settings.xml @@ -25,8 +25,8 @@
- \ No newline at end of file + diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 2333258..5989641 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -3,57 +3,21 @@ software.xdev.saveactions - Save Actions + Save Actions - XDEV Edition 2.6.0 - Alexandre DuBreuil + XDEV Software Supports configurable, Eclipse like, save actions, including "optimize imports", "reformat code", "rearrange code", "compile file" and some quick fixes for Java like "add / remove 'this' qualifier", etc. The plugin executes the configured actions when the file is synchronised (or saved) on disk.

-

Features

+

Fork of the popular but now deprecated Save Actions plugin

-
    -
  • Optimize imports
  • -
  • Run on file save, shortcut, batch (or a combination)
  • -
  • Run on multiple files by choosing a scope
  • -
  • Reformat code (whole file or only changed text)
  • -
  • Rearrange code (reorder methods, fields, etc.)
  • -
  • Include / exclude files with regex support
  • -
  • Works on any file type (Java, Python, XML, etc.)
  • -
  • Uses a settings file per project you can commit
  • -
  • Available keymaps and actions for activation
  • -
  • Launch any editor action using "quick lists"
  • -
  • [Java IDE] Eclipse configuration file `.epf` support
  • -
  • [Java IDE] Automatically fix Java inspections
  • -
  • [Java IDE] Compile project after save
  • -
  • [Java IDE] Reload debugger after save
  • -
- -

Compatibility

- -
    -
  • Intellij IDEA
  • -
  • PyCharm
  • -
  • PHPStorm
  • -
  • AndroidStudio
  • -
  • WebStorm
  • -
  • RubyMine
  • -
  • CLion
  • -
- -

Documentation

- -
+

More information is available on GitHub

]]>
-
  • Release notes: https://github.com/dubreuia/intellij-plugin-save-actions/releases/tag/v2.5.0
  • +
  • Release notes: https://github.com/xdev-software/intellij-plugin-save-actions/releases
  • ]]>
    @@ -64,9 +28,11 @@ com.intellij.modules.java - + - + @@ -89,7 +55,7 @@ @@ -97,7 +63,7 @@ From f4dda1bccd951528445cf2f2490b57b7d852daff Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 11:39:41 +0200 Subject: [PATCH 318/518] Update README.md --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 6438dd5..08700eb 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ If a quick fix adds something that is removed by another quick fix, the removal The plugin will be kept compatible with the latest IDEA version. -Support for other Intellij products should also be automatically available but not guaranteed. +Support for other JetBrains products should also be automatically available but is not guaranteed. ### Eclipse configuration support @@ -216,10 +216,6 @@ Some things to note when using other plugins with the Save Actions plugin: ## Contributions -### Contributors - -Big thanks to all the contributors submitting issues, testing, and especially submitting pull requests. See [contributors graph](https://github.com/dubreuia/intellij-plugin-save-actions/graphs/contributors) :hearts: - ### Contributing See [CONTRIBUTING](CONTRIBUTING.md). From 66572a54d2151b884d2948bfae5b90dc56d6e483 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 11:40:55 +0200 Subject: [PATCH 319/518] Disable jacoco as it's not used --- build.gradle | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build.gradle b/build.gradle index 0a74e46..d990d75 100644 --- a/build.gradle +++ b/build.gradle @@ -6,8 +6,6 @@ plugins { id 'org.sonarqube' version '4.2.1.3168' } -// Add coverage plugin -apply plugin: "jacoco" apply plugin: 'org.jetbrains.intellij' apply plugin: 'java' @@ -69,11 +67,3 @@ test { sourceSets { test.output.resourcesDir = "build/classes/java/resources" } - -// Add jacoco test report for codecov -jacocoTestReport { - reports { - xml.required = true - html.required = false - } -} From f1fa60f1eaceccbc166df29a77555cc84dd804da Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 11:41:05 +0200 Subject: [PATCH 320/518] Reset version --- build.gradle | 2 +- src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d990d75..4974357 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ apply plugin: 'java' // Add plugin group and version group "software.xdev.saveactions" -version "2.6.0" +version "1.0.0-SNAPSHOT" // Add build script repository to maven central repositories { diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5989641..faaa4f9 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -4,7 +4,7 @@ software.xdev.saveactions Save Actions - XDEV Edition - 2.6.0 + 1.0.0-SNAPSHOT XDEV Software Date: Wed, 21 Jun 2023 11:50:00 +0200 Subject: [PATCH 321/518] Update docs --- CONTRIBUTING.md | 35 +++++++++++++++++++++++++++++++++-- README.md | 18 ++---------------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 486b8f7..21c6add 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,26 @@ -# Contributing +## Contributing + +## Developing + +### Software Requirements +You should have the following things installed: +* Git +* Java 17 - should be as unmodified as possible (Recommended: [Eclipse Adoptium](https://adoptium.net/temurin/releases/)) +* Gradle (shipped inside the repo as Gradle Wrapper - also available inside Intellij) + +### Recommended setup +* Install ``IntelliJ`` (Community Edition is sufficient) + * Install the following plugins: + * [Save Actions](https://plugins.jetbrains.com/plugin/7642-save-actions) - Provides save actions, like running the formatter or adding ``final`` to fields + * [SonarLint](https://plugins.jetbrains.com/plugin/7973-sonarlint) - CodeStyle/CodeAnalysis + * [Checkstyle-IDEA](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea) - CodeStyle/CodeAnalysis + * Import the project + * Ensure that everything is encoded in ``UTF-8`` + * Ensure that the JDK/Java-Version is correct ## Development environment -The plugin is built with gradle, but you don't need to install it if you build with the Intellij gradle plugin (check out the [prerequisites](https://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system/prerequisites.html)). If you don't intend to use the Intellij gradle plugin, you can use native gradle (replace `./gradlew` by `gradle`). +The plugin is built with gradle, but you don't need to install it if you build with the Intellij gradle plugin (check out the [prerequisites](https://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system/prerequisites.html)). If you don't intend to use the Intellij gradle plugin, you can use native gradle (replace `./gradlew` by `gradle`). Start idea and import the `build.gradle` file with "File > Open". Then in the "Import Project from Gradle" window, make sure you check "Use gradle 'wrapper' task configuration" before clicking "Finish". You now have a gradle wrapper installed (`gradlew`) that you can use on the command line to generate idea folders: @@ -18,3 +36,16 @@ Intellij should refresh and the project is now configured as a gradle project. Y ./gradlew runIde ``` +Based on the [original documentation](https://github.com/dubreuia/intellij-plugin-save-actions/blob/main/CONTRIBUTING.md) + +## Releasing [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/release.yml?branch=master)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/release.yml) + +Before releasing: +* Consider doing a [test-deployment](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/test-deploy.yml?query=branch%3Adevelop) before actually releasing. +* Check the [changelog](CHANGELOG.md) + +If the ``develop`` is ready for release, create a pull request to the ``master``-Branch and merge the changes + +When the release is finished do the following: +* Merge the auto-generated PR (with the incremented version number) back into the ``develop`` + diff --git a/README.md b/README.md index 08700eb..999a4a2 100644 --- a/README.md +++ b/README.md @@ -214,19 +214,5 @@ Some things to note when using other plugins with the Save Actions plugin: - **idea.log**: The log file the save actions plugin writes in. It contains debug information, prefixed with `software.xdev.saveactions.SaveActionManager`. If you are using default locations, it would be in `~/.IntelliJIdeaVERSION/system/log/idea.log`. - **saveactions_settings.xml**: The settings file is saved by project in the `.idea` folder. That file can be committed in git thus shared in your development team. If you are using the default locations, it would be in `~/IdeaProjects/PROJECT_NAME/.idea/saveactions_settings.xml` -## Contributions - -### Contributing - -See [CONTRIBUTING](CONTRIBUTING.md). - -### Releasing - -See [RELEASING](RELEASING.md). - -## Links - -### JetBrains plugin page - -The plugin is in the [JetBrains plugin repository](https://plugins.jetbrains.com/plugin/7642-save-actions), please take the time to [rate it](https://plugins.jetbrains.com/plugin/7642-save-actions)! - +## Contributing +See the [contributing guide](./CONTRIBUTING.md) for detailed instructions on how to get started with our project. From 2686d81cbf9e23d57064dedeca5c7c4fcddbda09 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 11:52:19 +0200 Subject: [PATCH 322/518] Create CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3252fab --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +## 1.0.0 +Initial release +* Fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) +* Rebrand From 89df4791241c16d534c874ce9fc94c0c3f4ca11f Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 12:54:30 +0200 Subject: [PATCH 323/518] Fix tests --- .../software/xdev/saveactions/model/java/EpfTestConstants.java | 2 +- .../xdev/saveactions/integration/Reformat_KO_Import_KO.java | 2 +- .../xdev/saveactions/integration/Reformat_KO_Import_OK.java | 2 +- .../xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java | 2 +- .../xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java | 2 +- .../xdev/saveactions/integration/Reformat_OK_Import_KO.java | 2 +- .../xdev/saveactions/integration/Reformat_OK_Import_OK.java | 2 +- .../xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java index 46f5773..2d7d42f 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java @@ -33,7 +33,7 @@ public interface EpfTestConstants { Path ROOT = new File(".").toPath().toAbsolutePath().getParent(); Path ROOT_RESOURCES = Paths.get(ROOT.toString(), "src", "test", "resources"); - Path ROOT_EPF = Paths.get(ROOT_RESOURCES.toString(), "com", "dubreuia", "model"); + Path ROOT_EPF = Paths.get(ROOT_RESOURCES.toString(), "software", "xdev", "saveactions", "model"); Path EXAMPLE_EPF_0 = Paths.get(ROOT_EPF.toString(), "example0.epf"); Path EXAMPLE_EPF_1 = Paths.get(ROOT_EPF.toString(), "example1.epf"); diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java index a4d66b7..6e0547c 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_KO.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java index a4d66b7..6e0547c 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Import_OK.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java index a4d66b7..6e0547c 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_KO.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java index 04050b7..a169dc3 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_KO_Rearrange_OK.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java index e4d0bd0..e43b574 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_KO.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java index e4d0bd0..e43b574 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Import_OK.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; diff --git a/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java index 9796108..4af0654 100644 --- a/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/Reformat_OK_Rearrange_OK.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.model.Storage; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import org.junit.jupiter.api.BeforeEach; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; From 456210101ad7466aa8d6a0f25e224d397dbccea6 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 13:05:39 +0200 Subject: [PATCH 324/518] Strip away existing licensing information as it's no longer acurate --- .../CustomAccessCanBeTightenedInspection.java | 24 ------------------ ...ustomUnqualifiedStaticUsageInspection.java | 25 ------------------- .../xdev/saveactions/core/ExecutionMode.java | 25 ------------------- .../saveactions/core/action/BatchAction.java | 24 ------------------ .../core/action/ShortcutAction.java | 25 ------------------- .../core/action/ToggleAnAction.java | 25 ------------------- .../saveactions/core/component/Engine.java | 25 ------------------- .../SaveActionsDocumentManagerListener.java | 25 ------------------- .../core/service/SaveActionsService.java | 25 ------------------- .../service/SaveActionsServiceManager.java | 25 ------------------- .../impl/AbstractSaveActionsService.java | 25 ------------------- .../impl/SaveActionsDefaultService.java | 25 ------------------- .../service/impl/SaveActionsJavaService.java | 25 ------------------- .../xdev/saveactions/model/Action.java | 25 ------------------- .../xdev/saveactions/model/ActionType.java | 25 ------------------- .../xdev/saveactions/model/Storage.java | 25 ------------------- .../saveactions/model/StorageFactory.java | 25 ------------------- .../saveactions/model/java/EpfAction.java | 25 ------------------- .../xdev/saveactions/model/java/EpfKey.java | 25 ------------------- .../saveactions/model/java/EpfStorage.java | 25 ------------------- .../processors/BuildProcessor.java | 25 ------------------- .../processors/GlobalProcessor.java | 25 ------------------- .../saveactions/processors/Processor.java | 25 ------------------- .../xdev/saveactions/processors/Result.java | 25 ------------------- .../saveactions/processors/ResultCode.java | 25 ------------------- .../saveactions/processors/SaveCommand.java | 25 ------------------- .../processors/SaveReadCommand.java | 25 ------------------- .../processors/SaveWriteCommand.java | 25 ------------------- .../processors/java/InspectionRunnable.java | 25 ------------------- .../processors/java/JavaProcessor.java | 25 ------------------- .../inspection/CustomLocalCanBeFinal.java | 25 ------------------- ...erialVersionUIDFieldInspectionWrapper.java | 25 ------------------- .../xdev/saveactions/ui/BuildPanel.java | 25 ------------------- .../xdev/saveactions/ui/Configuration.java | 25 ------------------- .../ui/FileMaskExclusionPanel.java | 25 ------------------- .../ui/FileMaskInclusionPanel.java | 25 ------------------- .../xdev/saveactions/ui/FileMaskPanel.java | 25 ------------------- .../xdev/saveactions/ui/FormattingPanel.java | 25 ------------------- .../xdev/saveactions/ui/GeneralPanel.java | 25 ------------------- .../saveactions/ui/java/IdeSupportPanel.java | 25 ------------------- .../saveactions/ui/java/InspectionPanel.java | 25 ------------------- .../xdev/saveactions/utils/Helper.java | 25 ------------------- .../core/action/BatchActionConstants.java | 25 ------------------- .../core/action/ShortcutActionConstants.java | 25 ------------------- .../core/component/PsiFileTest.java | 25 ------------------- .../component/SaveActionManagerConstants.java | 25 ------------------- .../integration/ActionTestFile.java | 25 ------------------- .../integration/GlobalIntegrationTest.java | 25 ------------------- .../integration/IntegrationTest.java | 25 ------------------- .../integration/JavaIntegrationTest.java | 25 ------------------- .../xdev/saveactions/junit/JUnit5Utils.java | 25 ------------------- .../saveactions/model/java/EpfActionTest.java | 25 ------------------- .../saveactions/model/java/EpfKeyTest.java | 25 ------------------- .../model/java/EpfStorageTest.java | 25 ------------------- .../model/java/EpfTestConstants.java | 25 ------------------- .../processors/BuildProcessorTest.java | 25 ------------------- .../processors/GlobalProcessorTest.java | 25 ------------------- .../processors/java/JavaProcessorTest.java | 25 ------------------- 58 files changed, 1448 deletions(-) diff --git a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java b/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java index 1314c48..46ed202 100644 --- a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java @@ -1,27 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ package com.intellij.codeInspection.visibility; //@formatter:off import com.intellij.codeInsight.daemon.impl.UnusedSymbolUtil; diff --git a/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java b/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java index fad52ab..872571c 100644 --- a/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java +++ b/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package com.siyeh.ig.style; import com.intellij.psi.JavaResolveResult; diff --git a/src/main/java/software/xdev/saveactions/core/ExecutionMode.java b/src/main/java/software/xdev/saveactions/core/ExecutionMode.java index 02bb6f1..b03415c 100644 --- a/src/main/java/software/xdev/saveactions/core/ExecutionMode.java +++ b/src/main/java/software/xdev/saveactions/core/ExecutionMode.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core; import com.intellij.openapi.editor.Document; diff --git a/src/main/java/software/xdev/saveactions/core/action/BatchAction.java b/src/main/java/software/xdev/saveactions/core/action/BatchAction.java index 5bec1f3..7668808 100644 --- a/src/main/java/software/xdev/saveactions/core/action/BatchAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/BatchAction.java @@ -1,27 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ package software.xdev.saveactions.core.action; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java b/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java index 6f7f783..bfd4b4b 100644 --- a/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.action; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java index ecaf895..d086f97 100644 --- a/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.action; import software.xdev.saveactions.model.Storage; diff --git a/src/main/java/software/xdev/saveactions/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java index 522cc11..e73b723 100644 --- a/src/main/java/software/xdev/saveactions/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.component; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java index 2cff54d..86a3b4e 100644 --- a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java +++ b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.listener; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java index 6b7de14..8353b2a 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.service; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java index 4cdbc21..ccf6b2c 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.service; import software.xdev.saveactions.core.service.impl.SaveActionsDefaultService; diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index 3d3777a..0a8538a 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.service.impl; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java index 082d4c4..7413413 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.service.impl; import software.xdev.saveactions.processors.BuildProcessor; diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java index 4110870..b0462b7 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.service.impl; import software.xdev.saveactions.processors.BuildProcessor; diff --git a/src/main/java/software/xdev/saveactions/model/Action.java b/src/main/java/software/xdev/saveactions/model/Action.java index 6f7ae3f..40e9a38 100644 --- a/src/main/java/software/xdev/saveactions/model/Action.java +++ b/src/main/java/software/xdev/saveactions/model/Action.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model; import java.util.Arrays; diff --git a/src/main/java/software/xdev/saveactions/model/ActionType.java b/src/main/java/software/xdev/saveactions/model/ActionType.java index 698e3a9..e956980 100644 --- a/src/main/java/software/xdev/saveactions/model/ActionType.java +++ b/src/main/java/software/xdev/saveactions/model/ActionType.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model; public enum ActionType { diff --git a/src/main/java/software/xdev/saveactions/model/Storage.java b/src/main/java/software/xdev/saveactions/model/Storage.java index 175ea0f..b70c679 100644 --- a/src/main/java/software/xdev/saveactions/model/Storage.java +++ b/src/main/java/software/xdev/saveactions/model/Storage.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model; import com.intellij.openapi.components.PersistentStateComponent; diff --git a/src/main/java/software/xdev/saveactions/model/StorageFactory.java b/src/main/java/software/xdev/saveactions/model/StorageFactory.java index db5e108..e88d76f 100644 --- a/src/main/java/software/xdev/saveactions/model/StorageFactory.java +++ b/src/main/java/software/xdev/saveactions/model/StorageFactory.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model; import software.xdev.saveactions.model.java.EpfStorage; diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfAction.java b/src/main/java/software/xdev/saveactions/model/java/EpfAction.java index 61a203c..f83483c 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfAction.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfAction.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import software.xdev.saveactions.model.Action; diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfKey.java b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java index 13a0d62..15a503c 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfKey.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import java.util.Arrays; diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java b/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java index dcad32d..29d646e 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index 2b18e3d..cd47a19 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java index f89c0e5..51db4c5 100644 --- a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/Processor.java b/src/main/java/software/xdev/saveactions/processors/Processor.java index be63d86..02cc89f 100644 --- a/src/main/java/software/xdev/saveactions/processors/Processor.java +++ b/src/main/java/software/xdev/saveactions/processors/Processor.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/Result.java b/src/main/java/software/xdev/saveactions/processors/Result.java index d47812c..49d3e9f 100644 --- a/src/main/java/software/xdev/saveactions/processors/Result.java +++ b/src/main/java/software/xdev/saveactions/processors/Result.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; /** diff --git a/src/main/java/software/xdev/saveactions/processors/ResultCode.java b/src/main/java/software/xdev/saveactions/processors/ResultCode.java index 830f1e5..a4d062f 100644 --- a/src/main/java/software/xdev/saveactions/processors/ResultCode.java +++ b/src/main/java/software/xdev/saveactions/processors/ResultCode.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; /** diff --git a/src/main/java/software/xdev/saveactions/processors/SaveCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveCommand.java index eba2195..b2314cb 100644 --- a/src/main/java/software/xdev/saveactions/processors/SaveCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveCommand.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java index 68e36fe..c3598d7 100644 --- a/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java index 31f02be..4716298 100644 --- a/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java index 1806e0f..96db99b 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java +++ b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors.java; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java index 3826bf3..f40dafc 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors.java; import software.xdev.saveactions.core.ExecutionMode; diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java index c77e26f..7ed32c5 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors.java.inspection; import com.intellij.codeInspection.InspectionManager; diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java index 1271b42..a69d6d0 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors.java.inspection; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java index d093314..bf09793 100644 --- a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import software.xdev.saveactions.core.service.SaveActionsServiceManager; diff --git a/src/main/java/software/xdev/saveactions/ui/Configuration.java b/src/main/java/software/xdev/saveactions/ui/Configuration.java index 8e67612..a6108bf 100644 --- a/src/main/java/software/xdev/saveactions/ui/Configuration.java +++ b/src/main/java/software/xdev/saveactions/ui/Configuration.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import software.xdev.saveactions.model.Action; diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java index 60f2d6d..0c7b465 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import java.util.Set; diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java index 981b741..b1b7b1f 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import java.util.Set; diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java index 0da6065..b8913c3 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import com.intellij.openapi.ui.InputValidator; diff --git a/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java b/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java index e6f165b..76c7b74 100644 --- a/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import software.xdev.saveactions.model.Action; diff --git a/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java index 41d07f7..575de9d 100644 --- a/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui; import software.xdev.saveactions.model.Action; diff --git a/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java index 6e00a64..599a66b 100644 --- a/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui.java; import software.xdev.saveactions.core.service.SaveActionsServiceManager; diff --git a/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java b/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java index cb2f4f1..5191653 100644 --- a/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.ui.java; import software.xdev.saveactions.core.service.SaveActionsServiceManager; diff --git a/src/main/java/software/xdev/saveactions/utils/Helper.java b/src/main/java/software/xdev/saveactions/utils/Helper.java index c6f2efa..f53814f 100644 --- a/src/main/java/software/xdev/saveactions/utils/Helper.java +++ b/src/main/java/software/xdev/saveactions/utils/Helper.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.utils; import com.intellij.openapi.vfs.VirtualFile; diff --git a/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java index 9e59efa..6905af1 100644 --- a/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.action; import com.intellij.analysis.AnalysisScope; diff --git a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java index ea677e6..bd3868a 100644 --- a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.action; import com.intellij.openapi.actionSystem.ActionManager; diff --git a/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java b/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java index 9efc5ab..f0a6088 100644 --- a/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java +++ b/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.component; diff --git a/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java b/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java index 723f61d..f612006 100644 --- a/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java +++ b/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.core.component; import software.xdev.saveactions.core.service.SaveActionsService; diff --git a/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java b/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java index fb847c7..c67164f 100644 --- a/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java +++ b/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.integration; public enum ActionTestFile { diff --git a/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java index c094916..ae08817 100644 --- a/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.integration; import org.junit.jupiter.api.Test; diff --git a/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java index 667e260..dc9b934 100644 --- a/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.integration; import software.xdev.saveactions.core.action.BatchActionConstants; diff --git a/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java index ffb00ca..32d28a0 100644 --- a/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.integration; import org.junit.jupiter.api.Disabled; diff --git a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java index eedecad..428b7e8 100644 --- a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java +++ b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.junit; import com.intellij.rt.execution.junit.FileComparisonFailure; diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java index a7788ed..0a9ae64 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import software.xdev.saveactions.model.Action; diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java index 5ed15c6..be08355 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import org.junit.jupiter.api.Test; diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java index e7b784a..ed99d32 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import software.xdev.saveactions.model.Action; diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java index 2d7d42f..20fa7bc 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.model.java; import java.io.File; diff --git a/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java index e39e485..b4dc61c 100644 --- a/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.model.Action; diff --git a/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java index 4e5563d..1f183dc 100644 --- a/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors; import software.xdev.saveactions.model.Action; diff --git a/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java index 8035645..c1a6ae6 100644 --- a/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java @@ -1,28 +1,3 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020 Alexandre DuBreuil - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - package software.xdev.saveactions.processors.java; import software.xdev.saveactions.model.Action; From 8987ae0d6d62cb96fa90510a6d4241674a9aef6c Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 13:11:29 +0200 Subject: [PATCH 325/518] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21c6add..81e0276 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,8 @@ You should have the following things installed: ## Development environment +See also [JetBrains Docs for developing IntelliJ Plugins](https://plugins.jetbrains.com/docs/intellij/developing-plugins.html) + The plugin is built with gradle, but you don't need to install it if you build with the Intellij gradle plugin (check out the [prerequisites](https://www.jetbrains.org/intellij/sdk/docs/tutorials/build_system/prerequisites.html)). If you don't intend to use the Intellij gradle plugin, you can use native gradle (replace `./gradlew` by `gradle`). Start idea and import the `build.gradle` file with "File > Open". Then in the "Import Project from Gradle" window, make sure you check "Use gradle 'wrapper' task configuration" before clicking "Finish". You now have a gradle wrapper installed (`gradlew`) that you can use on the command line to generate idea folders: From 1c45087b0fe81b61d85473a4ccb973f8c4e7c2fb Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 14:16:16 +0200 Subject: [PATCH 326/518] Update plugin version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4974357..912d82d 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.13.3' + id 'org.jetbrains.intellij' version '1.14.1' id 'org.sonarqube' version '4.2.1.3168' } From bed94bd799c3ce2a7a50673a26d3c4814af89450 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 14:16:29 +0200 Subject: [PATCH 327/518] Vendor can't contain spaces --- src/main/resources/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index faaa4f9..edbb393 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -5,7 +5,7 @@ software.xdev.saveactions Save Actions - XDEV Edition 1.0.0-SNAPSHOT - XDEV Software + xdev-software Supports configurable, Eclipse like, save actions, including "optimize imports", "reformat code", "rearrange code", "compile file" and some quick fixes for Java like "add / remove 'this' qualifier", etc. The plugin executes the configured actions when the file is synchronised (or saved) on disk.

    From 6af1b488c3c4dca57ec4eadae6d1911e1b529ed3 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 21 Jun 2023 16:57:50 +0200 Subject: [PATCH 328/518] Prepare for CI releases - Copy over template from JetBrains and modifiy --- build.gradle | 51 +++++++++++++++++++++----- gradle.properties | 17 +++++++++ src/main/resources/META-INF/plugin.xml | 7 +--- 3 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 gradle.properties diff --git a/build.gradle b/build.gradle index 912d82d..b5a6b3b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,3 @@ -// Add idea plugin version plugins { id 'java' id 'idea' @@ -6,12 +5,20 @@ plugins { id 'org.sonarqube' version '4.2.1.3168' } +def properties(String key) { + return providers.gradleProperty(key) +} + +def environment(String key) { + return providers.environmentVariable(key) +} + apply plugin: 'org.jetbrains.intellij' apply plugin: 'java' // Add plugin group and version -group "software.xdev.saveactions" -version "1.0.0-SNAPSHOT" +group = properties("pluginGroup").get() +version = properties("pluginVersion").get() // Add build script repository to maven central repositories { @@ -34,12 +41,14 @@ dependencies { // See https://www.jetbrains.com/intellij-repository/snapshots // See https://www.jetbrains.com/intellij-repository/releases intellij { - version = "2023.1" - //version = "LATEST-EAP-SNAPSHOT" - type = "IC" - plugins = ["java"] - pluginName = "Save Actions" - // Do not touch the plugin.xml file + pluginName = properties("pluginName") + + version = properties("platformVersion") + type = properties("platformType") + + // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. + plugins = properties("platformPlugins").map { it.split(",").collect { it.trim() }.findAll { !it.empty } } + updateSinceUntilBuild = false } @@ -67,3 +76,27 @@ test { sourceSets { test.output.resourcesDir = "build/classes/java/resources" } + +tasks { + wrapper { + gradleVersion = properties("gradleVersion").get() + } + + patchPluginXml { + version = properties("pluginVersion") + } + + signPlugin { + certificateChain = environment("JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN") + privateKey = environment("JETBRAINS_MARKETPLACE_PRIVATE_KEY") + password = environment("JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD") + } + + publishPlugin { + token = environment("JETBRAINS_MARKETPLACE_PUBLISH_TOKEN") + // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 + // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: + // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel + channels = properties("pluginVersion").map { (it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase() } + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..b107d89 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html +pluginGroup=software.xdev.saveactions +pluginName=Save Actions - XDEV Edition +# SemVer format -> https://semver.org +pluginVersion=1.0.0-SNAPSHOT +# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension +platformType=IC +platformVersion=2023.1 +# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html +# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 +platformPlugins=java +# Gradle Releases -> https://github.com/gradle/gradle/releases +gradleVersion=8.1.1 +# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html +org.gradle.configuration-cache=true +# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html +org.gradle.caching=true diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index edbb393..e88b497 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1,10 +1,8 @@ - software.xdev.saveactions Save Actions - XDEV Edition - 1.0.0-SNAPSHOT xdev-software -
  • Release notes: https://github.com/xdev-software/intellij-plugin-save-actions/releases
  • - +https://github.com/xdev-software/intellij-plugin-save-actions/releases ]]>
    + From 85295635acb2588b483db8218fd3bd561b390208 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 09:46:44 +0200 Subject: [PATCH 329/518] Create test-deploy.yml --- .github/workflows/test-deploy.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/test-deploy.yml diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml new file mode 100644 index 0000000..50ef04a --- /dev/null +++ b/.github/workflows/test-deploy.yml @@ -0,0 +1,28 @@ +name: Test Deployment + +on: + workflow_dispatch: + +env: + PRIMARY_MAVEN_MODULE: ${{ github.event.repository.name }} + +jobs: + publish_central: # Publish the code to central + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Update/Generify version + run: | + originalVersion=$(grep -Po 'pluginVersion=\K.*' gradle.properties) + newVersion="$(echo $originalVersion | cut -d '-' -f1).$( date -u '+%Y%m%d%H%M%S')-SNAPSHOT" + echo "New version: $newVersion" + sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties + + - name: Publish Plugin + env: + PUBLISH_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_PUBLISH_TOKEN }} + CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN }} + PRIVATE_KEY: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY }} + PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD }} + run: ./gradlew publishPlugin From 0c530f1625ea78164b5d88a04a18962937bb7069 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 09:47:07 +0200 Subject: [PATCH 330/518] Simplify Env vars --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index b5a6b3b..c91de47 100644 --- a/build.gradle +++ b/build.gradle @@ -87,13 +87,13 @@ tasks { } signPlugin { - certificateChain = environment("JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN") - privateKey = environment("JETBRAINS_MARKETPLACE_PRIVATE_KEY") - password = environment("JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD") + certificateChain = environment("CERTIFICATE_CHAIN") + privateKey = environment("PRIVATE_KEY") + password = environment("PRIVATE_KEY_PASSWORD") } publishPlugin { - token = environment("JETBRAINS_MARKETPLACE_PUBLISH_TOKEN") + token = environment("PUBLISH_TOKEN") // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel From dbbeb2517181265220aed8832900dbf1bc9ddd4a Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 09:48:00 +0200 Subject: [PATCH 331/518] Rename --- .github/workflows/test-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 50ef04a..eb841c5 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -7,7 +7,7 @@ env: PRIMARY_MAVEN_MODULE: ${{ github.event.repository.name }} jobs: - publish_central: # Publish the code to central + publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 4cc94147192b32c31cf4af051f1e4241855c8809 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 09:49:54 +0200 Subject: [PATCH 332/518] Run with more info --- .github/workflows/checkBuild.yml | 2 +- .github/workflows/test-deploy.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index b0cd88f..2887624 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -31,7 +31,7 @@ jobs: cache: 'gradle' - name: Build - run: ./gradlew build buildPlugin + run: ./gradlew build buildPlugin --info - name: Check for uncommited changes run: | diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index eb841c5..0849087 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -25,4 +25,4 @@ jobs: CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN }} PRIVATE_KEY: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY }} PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD }} - run: ./gradlew publishPlugin + run: ./gradlew publishPlugin --info From 37aa8d0f0cc28860fcc99e983217b8cf59199a00 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 09:51:26 +0200 Subject: [PATCH 333/518] Update test-deploy.yml --- .github/workflows/test-deploy.yml | 39 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 0849087..89fe98f 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -10,19 +10,26 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - name: Update/Generify version - run: | - originalVersion=$(grep -Po 'pluginVersion=\K.*' gradle.properties) - newVersion="$(echo $originalVersion | cut -d '-' -f1).$( date -u '+%Y%m%d%H%M%S')-SNAPSHOT" - echo "New version: $newVersion" - sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties - - - name: Publish Plugin - env: - PUBLISH_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_PUBLISH_TOKEN }} - CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN }} - PRIVATE_KEY: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY }} - PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD }} - run: ./gradlew publishPlugin --info + - uses: actions/checkout@v3 + + - name: Update/Generify version + run: | + originalVersion=$(grep -Po 'pluginVersion=\K.*' gradle.properties) + newVersion="$(echo $originalVersion | cut -d '-' -f1).$( date -u '+%Y%m%d%H%M%S')-SNAPSHOT" + echo "New version: $newVersion" + sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties + + - name: Publish Plugin + env: + PUBLISH_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_PUBLISH_TOKEN }} + CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN }} + PRIVATE_KEY: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY }} + PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD }} + run: ./gradlew publishPlugin --info + + - name: Upload plugin files + uses: actions/upload-artifact@v3 + with: + name: plugin-files-java-${{ matrix.java }} + path: build/distributions/* + if-no-files-found: error From 114bc517adc1bf622e7de349390ad35cae810492 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 09:54:17 +0200 Subject: [PATCH 334/518] Update test-deploy.yml --- .github/workflows/test-deploy.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 89fe98f..0cdf295 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -11,6 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 17 + cache: 'gradle' - name: Update/Generify version run: | @@ -18,6 +25,9 @@ jobs: newVersion="$(echo $originalVersion | cut -d '-' -f1).$( date -u '+%Y%m%d%H%M%S')-SNAPSHOT" echo "New version: $newVersion" sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties + + echo "Contents of gradle.properties" + cat gradle.properties - name: Publish Plugin env: From a3171afc3180db2ff0eaa8c1ea0ec1d980416d07 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 10:02:11 +0200 Subject: [PATCH 335/518] Display errors --- .github/workflows/test-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 0cdf295..49a93d2 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -35,7 +35,7 @@ jobs: CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN }} PRIVATE_KEY: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY }} PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD }} - run: ./gradlew publishPlugin --info + run: ./gradlew publishPlugin --info --stacktrace - name: Upload plugin files uses: actions/upload-artifact@v3 From 48480e45d819c35c568e8de2377c9eeb82ffa694 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 10:06:07 +0200 Subject: [PATCH 336/518] Create list --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c91de47..0a0f28b 100644 --- a/build.gradle +++ b/build.gradle @@ -97,6 +97,6 @@ tasks { // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel - channels = properties("pluginVersion").map { (it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase() } + channels = [properties("pluginVersion").map { (it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase() }] } } From ef414c8487ead9639c95fafdba42f45712c4a4d4 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 10:55:12 +0200 Subject: [PATCH 337/518] Make plugin releaseable --- build.gradle | 2 +- src/main/resources/META-INF/plugin.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 0a0f28b..d9b58c7 100644 --- a/build.gradle +++ b/build.gradle @@ -97,6 +97,6 @@ tasks { // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel - channels = [properties("pluginVersion").map { (it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase() }] + channels = properties("pluginVersion").map { (it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase() }.collect { it as String } } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index e88b497..6182f2b 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -6,11 +6,11 @@ xdev-software Fork of the popular but now deprecated Save Actions plugin.

    +

    Supports configurable, Eclipse like, save actions, including "optimize imports", "reformat code", "rearrange code", "compile file" and some quick fixes for Java like "add / remove 'this' qualifier", etc. The plugin executes the configured actions when the file is synchronised (or saved) on disk.

    - -

    Fork of the popular but now deprecated Save Actions plugin

    - -

    More information is available on GitHub

    +
    +

    More information is available on GitHub.

    ]]>
    Date: Thu, 22 Jun 2023 11:08:20 +0200 Subject: [PATCH 338/518] Create valid list --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d9b58c7..82c5fd5 100644 --- a/build.gradle +++ b/build.gradle @@ -97,6 +97,7 @@ tasks { // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel - channels = properties("pluginVersion").map { (it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase() }.collect { it as String } + channels = properties("pluginVersion") + .map { [(it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase()] } } } From 0dbcabec405a7a22e581ba03e3bda00911af8f8f Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 11:25:18 +0200 Subject: [PATCH 339/518] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 999a4a2..af3380c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Latest version](https://img.shields.io/jetbrains/plugin/v/22113?logo=jetbrains)](https://plugins.jetbrains.com/plugin/22113-save-actions--xdev-edition) [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/checkBuild.yml?branch=develop)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/checkBuild.yml?query=branch%3Adevelop) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_intellij-plugin-save-actions&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_intellij-plugin-save-actions) From a02ec87cea304b9410e71e5974b51bc57f0e1d48 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 11:44:00 +0200 Subject: [PATCH 340/518] Deduplicate files and modify colors to XDEV scheme --- README.md | 2 +- assets/icon-save-actions-dark.svg | 81 ------ assets/icon-save-actions.grid | 244 ------------------ assets/icon-save-actions.svg | 81 ------ src/main/resources/META-INF/pluginIcon.svg | 4 +- .../resources/META-INF/pluginIcon_dark.svg | 4 +- 6 files changed, 5 insertions(+), 411 deletions(-) delete mode 100644 assets/icon-save-actions-dark.svg delete mode 100644 assets/icon-save-actions.grid delete mode 100644 assets/icon-save-actions.svg diff --git a/README.md b/README.md index 999a4a2..9807ff1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/checkBuild.yml?branch=develop)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/checkBuild.yml?query=branch%3Adevelop) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_intellij-plugin-save-actions&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_intellij-plugin-save-actions) -# Save Actions Plugin icon light Save Actions Plugin - XDEV Edition +# Save Actions Plugin icon light Save Actions Plugin - XDEV Edition > **ℹ️About** > diff --git a/assets/icon-save-actions-dark.svg b/assets/icon-save-actions-dark.svg deleted file mode 100644 index 1bb6b36..0000000 --- a/assets/icon-save-actions-dark.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/assets/icon-save-actions.grid b/assets/icon-save-actions.grid deleted file mode 100644 index eb5646a..0000000 --- a/assets/icon-save-actions.grid +++ /dev/null @@ -1,244 +0,0 @@ -{ - "settings": { - "size": { - "width": 1905, - "height": 945 - }, - "crest": false - }, - "layers": [ - [ - { - "type": "line", - "vertices": [ - { - "x": 660, - "y": 300 - }, - { - "x": 660, - "y": 300 - }, - { - "x": 660, - "y": 300 - }, - { - "x": 660, - "y": 300 - }, - { - "x": 1140, - "y": 300 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 660, - "y": 900 - }, - { - "x": 660, - "y": 300 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 1200, - "y": 900 - }, - { - "x": 660, - "y": 900 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 1140, - "y": 300 - }, - { - "x": 1200, - "y": 360 - }, - { - "x": 1200, - "y": 360 - }, - { - "x": 1200, - "y": 900 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 1080, - "y": 480 - }, - { - "x": 1080, - "y": 300 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 780, - "y": 480 - }, - { - "x": 1080, - "y": 480 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 780, - "y": 480 - }, - { - "x": 780, - "y": 300 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 960, - "y": 360 - }, - { - "x": 1020, - "y": 360 - }, - { - "x": 1020, - "y": 420 - }, - { - "x": 960, - "y": 420 - }, - { - "x": 960, - "y": 360 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 780, - "y": 660 - }, - { - "x": 780, - "y": 900 - }, - { - "x": 1080, - "y": 900 - }, - { - "x": 1080, - "y": 660 - }, - { - "x": 780, - "y": 660 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 840, - "y": 720 - }, - { - "x": 1020, - "y": 720 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 840, - "y": 780 - }, - { - "x": 1020, - "y": 780 - } - ] - }, - { - "type": "line", - "vertices": [ - { - "x": 840, - "y": 840 - }, - { - "x": 1020, - "y": 840 - } - ] - } - ], - [], - [] - ], - "styles": [ - { - "thickness": 43, - "strokeLinecap": "round", - "strokeLinejoin": "round", - "color": "#212121", - "fill": "none", - "mirror_style": 0, - "transform": "rotate(45)" - }, - { - "thickness": 10, - "strokeLinecap": "round", - "strokeLinejoin": "round", - "color": "#999", - "fill": "none", - "mirror_style": 0, - "transform": "rotate(45)" - }, - { - "thickness": 10, - "strokeLinecap": "round", - "strokeLinejoin": "round", - "color": "#ccc", - "fill": "none", - "mirror_style": 0, - "transform": "rotate(45)" - } - ] -} \ No newline at end of file diff --git a/assets/icon-save-actions.svg b/assets/icon-save-actions.svg deleted file mode 100644 index c4866b5..0000000 --- a/assets/icon-save-actions.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/META-INF/pluginIcon.svg b/src/main/resources/META-INF/pluginIcon.svg index c4866b5..66fbca3 100644 --- a/src/main/resources/META-INF/pluginIcon.svg +++ b/src/main/resources/META-INF/pluginIcon.svg @@ -30,11 +30,11 @@ + style="stop-color:#c02222;stop-opacity:1;" /> + style="stop-color:#d71e23;stop-opacity:1;" /> + style="stop-color:#d71e23;stop-opacity:1;" /> + style="stop-color:#c02222;stop-opacity:1;" /> Date: Thu, 22 Jun 2023 13:05:18 +0200 Subject: [PATCH 341/518] Import launch profiles --- .run/Run Plugin.run.xml | 24 ++++++++++++++++++++++++ .run/Run Tests.run.xml | 24 ++++++++++++++++++++++++ .run/Run Verifications.run.xml | 26 ++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 .run/Run Plugin.run.xml create mode 100644 .run/Run Tests.run.xml create mode 100644 .run/Run Verifications.run.xml diff --git a/.run/Run Plugin.run.xml b/.run/Run Plugin.run.xml new file mode 100644 index 0000000..d15ff68 --- /dev/null +++ b/.run/Run Plugin.run.xml @@ -0,0 +1,24 @@ + + + + + + + + true + true + false + + + \ No newline at end of file diff --git a/.run/Run Tests.run.xml b/.run/Run Tests.run.xml new file mode 100644 index 0000000..132d9ad --- /dev/null +++ b/.run/Run Tests.run.xml @@ -0,0 +1,24 @@ + + + + + + + + true + true + false + + + diff --git a/.run/Run Verifications.run.xml b/.run/Run Verifications.run.xml new file mode 100644 index 0000000..3a8d688 --- /dev/null +++ b/.run/Run Verifications.run.xml @@ -0,0 +1,26 @@ + + + + + + + + true + true + false + + + + \ No newline at end of file From dcc88d3df18d215c8c3e350108f21fcfc8e409f8 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 13:10:02 +0200 Subject: [PATCH 342/518] Update class to fix deprecation --- .../CustomAccessCanBeTightenedInspection.java | 655 ++++++++++-------- 1 file changed, 367 insertions(+), 288 deletions(-) diff --git a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java b/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java index 46ed202..eb473fb 100644 --- a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java @@ -1,346 +1,425 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInspection.visibility; + //@formatter:off import com.intellij.codeInsight.daemon.impl.UnusedSymbolUtil; -import com.intellij.codeInspection.InspectionProfile; +import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase; +import com.intellij.codeInspection.inheritance.ImplicitSubclassProvider; +import com.intellij.java.analysis.JavaAnalysisBundle; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; -import com.intellij.profile.codeInspection.InspectionProjectProfileManager; -import com.intellij.psi.JavaDirectoryService; -import com.intellij.psi.JavaElementVisitor; -import com.intellij.psi.JavaRecursiveElementWalkingVisitor; -import com.intellij.psi.LambdaUtil; -import com.intellij.psi.PsiAnonymousClass; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementVisitor; -import com.intellij.psi.PsiEnumConstant; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiJavaCodeReferenceElement; -import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.PsiKeyword; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiModifier; -import com.intellij.psi.PsiModifierList; -import com.intellij.psi.PsiNameIdentifierOwner; -import com.intellij.psi.PsiNewExpression; -import com.intellij.psi.PsiPackage; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiSyntheticClass; -import com.intellij.psi.PsiTypeParameter; -import com.intellij.psi.SyntheticElement; +import com.intellij.openapi.util.Conditions; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.FindSuperElementsHelper; import com.intellij.psi.search.searches.FunctionalExpressionSearch; -import com.intellij.psi.util.ClassUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; -import com.intellij.util.VisibilityUtil; +import com.intellij.psi.util.*; +import com.intellij.util.containers.ComparatorUtil; import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.fixes.ChangeModifierFix; import com.siyeh.ig.psiutils.MethodUtils; -import gnu.trove.TObjectIntHashMap; +import com.siyeh.ig.visibility.ClassEscapesItsScopeInspection; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; /** - * Copy pasting because: cannot extend. Do not reformat (useful for diffs) + * A public version of {@link AccessCanBeTightenedInspection}. + * + * @implNote This is a 1 to 1 copy of {@link AccessCanBeTightenedInspection}. + *

    + * Copy pasting is required because when extending the following error is thrown error: + * class com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection cannot access its superclass + * com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection + * (com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection is in unnamed module of loader + * com.intellij.ide.plugins.cl.PluginClassLoader ...; + * com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection is in unnamed module of loader + * com.intellij.ide.plugins.cl.PluginClassLoader ...) * * @see com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection */ -@SuppressWarnings({"deprecation", "squid:S125", "squid:S3776", "squid:S107"}) -public class CustomAccessCanBeTightenedInspection extends com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool { - private final VisibilityInspection myVisibilityInspection; - - public CustomAccessCanBeTightenedInspection(@NotNull VisibilityInspection visibilityInspection) { - myVisibilityInspection = visibilityInspection; - } - - @Override - public boolean isEnabledByDefault() { - return true; - } - - @Override - @NotNull - public String getGroupDisplayName() { - return InspectionsBundle.message("group.names.visibility.issues"); - } - - @Override - @NotNull - public String getDisplayName() { - return "Member access can be tightened"; - } - - @Override - @NotNull - public String getShortName() { - return VisibilityInspection.SHORT_NAME; - } - - @NotNull - @Override - public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { - return new MyVisitor(holder); - } - - private class MyVisitor extends JavaElementVisitor { - private final ProblemsHolder myHolder; - private final UnusedDeclarationInspectionBase myDeadCodeInspection; - - public MyVisitor(@NotNull ProblemsHolder holder) { - myHolder = holder; - InspectionProfile profile = InspectionProjectProfileManager.getInstance(holder.getProject()).getCurrentProfile(); - UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)profile.getUnwrappedTool(UnusedDeclarationInspectionBase.SHORT_NAME, holder.getFile()); - myDeadCodeInspection = tool == null ? new UnusedDeclarationInspectionBase() : tool; +@SuppressWarnings({"java:S6201", "java:S3776", "java:S125", "java:S3398", "java:S2637", "java:S120", "java:S6541", "java:S135"}) +public class CustomAccessCanBeTightenedInspection extends AbstractBaseJavaLocalInspectionTool { + private static final Logger LOG = Logger.getInstance(CustomAccessCanBeTightenedInspection.class); + private final VisibilityInspection myVisibilityInspection; + + public CustomAccessCanBeTightenedInspection(@NotNull VisibilityInspection visibilityInspection) { + myVisibilityInspection = visibilityInspection; + } + + @Override + public boolean isEnabledByDefault() { + return true; } - private final TObjectIntHashMap maxSuggestedLevelForChildMembers = new TObjectIntHashMap<>(); @Override - public void visitClass(PsiClass aClass) { - checkMember(aClass); + @NotNull + public String getGroupDisplayName() { + return InspectionsBundle.message("group.names.visibility.issues"); } @Override - public void visitMethod(PsiMethod method) { - checkMember(method); + @NotNull + public String getShortName() { + return VisibilityInspection.SHORT_NAME; } + @NotNull @Override - public void visitField(PsiField field) { - checkMember(field); + public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) { + return new MyVisitor(holder); } - private void checkMember(@NotNull PsiMember member) { - PsiClass memberClass = member.getContainingClass(); - PsiModifierList memberModifierList = member.getModifierList(); - if (memberModifierList == null) { - return; - } - int currentLevel = PsiUtil.getAccessLevel(memberModifierList); - int suggestedLevel = suggestLevel(member, memberClass, currentLevel); - if (memberClass != null) { - synchronized (maxSuggestedLevelForChildMembers) { - int prevMax = maxSuggestedLevelForChildMembers.get(memberClass); - maxSuggestedLevelForChildMembers.put(memberClass, Math.max(prevMax, suggestedLevel)); + private class MyVisitor extends JavaElementVisitor { + private final ProblemsHolder myHolder; + private final UnusedDeclarationInspectionBase myDeadCodeInspection; + + MyVisitor(@NotNull ProblemsHolder holder) { + myHolder = holder; + myDeadCodeInspection = UnusedDeclarationInspectionBase.findUnusedDeclarationInspection(holder.getFile()); + } + private final Object2IntMap maxSuggestedLevelForChildMembers = new Object2IntOpenHashMap<>(); + + @Override + public void visitClass(@NotNull PsiClass aClass) { + checkMember(aClass); } - } - - log(member.getName() + ": effective level is '" + PsiUtil.getAccessModifier(suggestedLevel) + "'"); - - if (suggestedLevel < currentLevel) { - if (member instanceof PsiClass) { - int memberMaxLevel; - synchronized (maxSuggestedLevelForChildMembers) { - memberMaxLevel = maxSuggestedLevelForChildMembers.get((PsiClass)member); - } - if (memberMaxLevel > suggestedLevel) { - // a class can't have visibility less than its members - return; - } + + @Override + public void visitMethod(@NotNull PsiMethod method) { + checkMember(method); } - PsiElement toHighlight = currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL ? ((PsiNameIdentifierOwner)member).getNameIdentifier() : ContainerUtil.find( - memberModifierList.getChildren(), - element -> element instanceof PsiKeyword && element.getText().equals(PsiUtil.getAccessModifier(currentLevel))); - assert toHighlight != null : member +" ; " + ((PsiNameIdentifierOwner)member).getNameIdentifier() + "; "+ memberModifierList.getText(); - String suggestedModifier = PsiUtil.getAccessModifier(suggestedLevel); - myHolder.registerProblem(toHighlight, "Access can be " + VisibilityUtil.toPresentableText(suggestedModifier), new ChangeModifierFix(suggestedModifier)); - } - } - @PsiUtil.AccessLevel - private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUtil.AccessLevel int currentLevel) { - if (member.hasModifierProperty(PsiModifier.PRIVATE) || member.hasModifierProperty(PsiModifier.NATIVE)) { - return currentLevel; - } - if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical()) { - return currentLevel; - } - - if (member instanceof PsiMethod) { - PsiMethod method = (PsiMethod)member; - if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) { - log(member.getName() + " overrides"); - return currentLevel; // overrides + @Override + public void visitField(@NotNull PsiField field) { + checkMember(field); } - if (MethodUtils.isOverridden(method)) { - log(member.getName() + " overridden"); - return currentLevel; + + private void checkMember(@NotNull final PsiMember member) { + if (!myVisibilityInspection.SUGGEST_FOR_CONSTANTS && isConstantField(member)) { + return; + } + + final PsiClass memberClass = member.getContainingClass(); + PsiModifierList memberModifierList = member.getModifierList(); + if (memberModifierList == null) return; + int currentLevel = PsiUtil.getAccessLevel(memberModifierList); + int suggestedLevel = suggestLevel(member, memberClass, currentLevel); + if (memberClass != null) { + synchronized (maxSuggestedLevelForChildMembers) { + int prevMax = maxSuggestedLevelForChildMembers.getInt(memberClass); + maxSuggestedLevelForChildMembers.put(memberClass, Math.max(prevMax, suggestedLevel)); + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + ": effective level is '" + PsiUtil.getAccessModifier(suggestedLevel) + "'"); + } + + if (suggestedLevel < currentLevel) { + if (member instanceof PsiClass) { + int memberMaxLevel; + synchronized (maxSuggestedLevelForChildMembers) { + memberMaxLevel = maxSuggestedLevelForChildMembers.getInt(member); + } + if (memberMaxLevel > suggestedLevel) { + // a class can't have visibility less than its members + return; + } + } + PsiElement toHighlight = currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL ? ((PsiNameIdentifierOwner)member).getNameIdentifier() : + ContainerUtil.find(memberModifierList.getChildren(), + element -> element instanceof PsiKeyword && element.getText().equals(PsiUtil.getAccessModifier(currentLevel))); + // can be null in some strange cases of malbuilt PSI, like in EA-95877 + if (toHighlight != null) { + String suggestedModifier = PsiUtil.getAccessModifier(suggestedLevel); + String message = PsiModifier.PACKAGE_LOCAL.equals(suggestedModifier) + ? JavaAnalysisBundle.message("access.can.be.package.private") + : JavaAnalysisBundle.message("access.can.be.0", suggestedModifier); + myHolder.registerProblem(toHighlight, message, new ChangeModifierFix(suggestedModifier)); + } + } + } + + @PsiUtil.AccessLevel + private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUtil.AccessLevel int currentLevel) { + if (member.hasModifierProperty(PsiModifier.PRIVATE) || member.hasModifierProperty(PsiModifier.NATIVE)) return currentLevel; + if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical()) return currentLevel; + + if (member instanceof PsiMethod method) { + if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) { + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + " overrides"); + } + return currentLevel; // overrides + } + if (MethodUtils.isOverridden(method)) { + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + " overridden"); + } + return currentLevel; + } + if (FindSuperElementsHelper.getSiblingInfoInheritedViaSubClass(method) != null || + JavaPsiRecordUtil.getRecordComponentForAccessor(method) != null) { + return currentLevel; + } + } + if (member instanceof PsiEnumConstant) return currentLevel; + if (member instanceof PsiClass && (member instanceof PsiAnonymousClass || + member instanceof PsiTypeParameter || + member instanceof PsiSyntheticClass || + PsiUtil.isLocalClass((PsiClass)member))) { + return currentLevel; + } + if (memberClass != null && (memberClass.isInterface() || PsiUtil.isLocalClass(memberClass) && member instanceof PsiClass)) { + return currentLevel; + } + + if (memberClass != null && member instanceof PsiMethod) { + if (memberClass.isRecord() && ((PsiMethod)member).isConstructor()) { + final PsiModifierList modifierList = memberClass.getModifierList(); + assert modifierList != null; // anonymous records don't exist + return PsiUtil.getAccessLevel(modifierList); + } + // If class will be subclassed by some framework then it could apply some specific requirements for methods visibility + // so we just skip it here (IDEA-182709, IDEA-160602) + for (ImplicitSubclassProvider subclassProvider : ImplicitSubclassProvider.EP_NAME.getExtensions()) { + if (!subclassProvider.isApplicableTo(memberClass)) continue; + ImplicitSubclassProvider.SubclassingInfo info = subclassProvider.getSubclassingInfo(memberClass); + if (info == null) continue; + Map methodsInfo = info.getMethodsInfo(); + if (methodsInfo == null || methodsInfo.containsKey(member)) { + return currentLevel; + } + } + } + + final PsiFile memberFile = member.getContainingFile(); + Project project = memberFile.getProject(); + + int level = myVisibilityInspection.getMinVisibilityLevel(member); + boolean entryPoint = myDeadCodeInspection.isEntryPoint(member) || + member instanceof PsiField && (UnusedSymbolUtil.isImplicitWrite((PsiVariable)member) || UnusedSymbolUtil.isImplicitRead((PsiVariable)member)); + if (entryPoint && level <= 0) { + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + " is entry point"); + } + return currentLevel; + } + + final PsiPackage memberPackage = getPackage(memberFile); + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + ": checking effective level for " + member); + } + + int minLevel = Math.max(PsiUtil.ACCESS_LEVEL_PRIVATE, level); + AtomicInteger maxLevel = new AtomicInteger(minLevel); + AtomicBoolean foundUsage = new AtomicBoolean(); + boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> { + PsiElement element = info.getElement(); + if (element == null) return true; + PsiFile psiFile = info.getFile(); + if (psiFile == null) return true; + + return handleUsage(member, memberClass, maxLevel, memberPackage, element, psiFile, foundUsage); + }); + + if (proceed && member instanceof PsiClass && LambdaUtil.isFunctionalClass((PsiClass)member)) { + // there can be lambda implementing this interface implicitly + FunctionalExpressionSearch.search((PsiClass)member).forEach(functionalExpression -> { + PsiFile psiFile = functionalExpression.getContainingFile(); + return handleUsage(member, memberClass, maxLevel, memberPackage, functionalExpression, psiFile, foundUsage); + }); + } + if (!foundUsage.get() && !entryPoint) { + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + " unused; ignore"); + } + return currentLevel; // do not propose private for unused method + } + + @PsiUtil.AccessLevel + int suggestedLevel = maxLevel.get(); + if (suggestedLevel == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) { + suggestedLevel = suggestPackageLocal(member); + } + + String suggestedModifier = PsiUtil.getAccessModifier(suggestedLevel); + if (LOG.isDebugEnabled()) { + LOG.debug(member.getName() + ": effective level is '" + suggestedModifier + "'"); + } + + return suggestedLevel; } - } - if (member instanceof PsiEnumConstant) { - return currentLevel; - } - if (member instanceof PsiClass && (member instanceof PsiAnonymousClass || - member instanceof PsiTypeParameter || - member instanceof PsiSyntheticClass || - PsiUtil.isLocalClass((PsiClass)member))) { - return currentLevel; - } - if (memberClass != null && (memberClass.isInterface() || memberClass.isEnum() || memberClass.isAnnotationType() || PsiUtil.isLocalClass(memberClass) && member instanceof PsiClass)) { - return currentLevel; - } - PsiFile memberFile = member.getContainingFile(); - Project project = memberFile.getProject(); - - if (myDeadCodeInspection.isEntryPoint(member)) { - log(member.getName() +" is entry point"); - return currentLevel; - } - - PsiDirectory memberDirectory = memberFile.getContainingDirectory(); - PsiPackage memberPackage = memberDirectory == null ? null : JavaDirectoryService.getInstance().getPackage(memberDirectory); - log(member.getName()+ ": checking effective level for "+member); - - AtomicInteger maxLevel = new AtomicInteger(PsiUtil.ACCESS_LEVEL_PRIVATE); - AtomicBoolean foundUsage = new AtomicBoolean(); - boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> { - PsiElement element = info.getElement(); - if (element == null) { - return true; + + private boolean handleUsage(@NotNull PsiMember member, + @Nullable PsiClass memberClass, + @NotNull AtomicInteger maxLevel, + @Nullable PsiPackage memberPackage, + @NotNull PsiElement element, + @NotNull PsiFile psiFile, + @NotNull AtomicBoolean foundUsage) { + foundUsage.set(true); + if (!(psiFile instanceof PsiJavaFile)) { + if (LOG.isDebugEnabled()) { + LOG.debug(" refd from " + psiFile.getName() + "; set to public"); + } + maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC); + return false; // referenced from XML, has to be public + } + @PsiUtil.AccessLevel + int level = getEffectiveLevel(element, psiFile, member, memberClass, memberPackage); + if (LOG.isDebugEnabled()) { + LOG.debug(" ref in file " + psiFile.getName() + "; level = " + PsiUtil.getAccessModifier(level) + "; (" + element + ")"); + } + maxLevel.getAndAccumulate(level, Math::max); + + return level != PsiUtil.ACCESS_LEVEL_PUBLIC; } - PsiFile psiFile = info.getFile(); - if (psiFile == null) { - return true; + + @PsiUtil.AccessLevel + private int getEffectiveLevel(@NotNull PsiElement element, + @NotNull PsiFile file, + @NotNull PsiMember member, + PsiClass memberClass, + PsiPackage memberPackage) { + if (member instanceof PsiClass && element instanceof PsiJavaCodeReferenceElement) { + PsiMember exportingMember = ClassEscapesItsScopeInspection.getExportingMember((PsiJavaCodeReferenceElement)element); + if (exportingMember != null) { + final PsiModifierList modifierList = exportingMember.getModifierList(); + assert modifierList != null; + return PsiUtil.getAccessLevel(modifierList); + } + } + PsiClass innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); + if (memberClass != null && PsiTreeUtil.isAncestor(innerClass, memberClass, false) || + innerClass != null && PsiTreeUtil.isAncestor(memberClass, innerClass, false)) { + // access from the same file can be via private + // except when used in annotation: + // @Ann(value = C.VAL) class C { public static final String VAL = "xx"; } + // or in implements/extends clauses + if (VisibilityInspection.containsReferenceTo(innerClass.getModifierList(), member) || + VisibilityInspection.containsReferenceTo(innerClass.getImplementsList(), member) || + VisibilityInspection.containsReferenceTo(innerClass.getExtendsList(), member)) { + return suggestPackageLocal(member); + } + + return !member.hasModifierProperty(PsiModifier.ABSTRACT) && + (myVisibilityInspection.SUGGEST_PRIVATE_FOR_INNERS || !isInnerClass(memberClass)) && + (member.hasModifierProperty(PsiModifier.STATIC) || !calledOnInheritor(element, memberClass)) + ? PsiUtil.ACCESS_LEVEL_PRIVATE : suggestPackageLocal(member); + } + + PsiExpression qualifier = getQualifier(element); + PsiElement resolvedQualifier = qualifier instanceof PsiReference ? ((PsiReference)qualifier).resolve() : null; + if (resolvedQualifier instanceof PsiVariable) { + resolvedQualifier = PsiUtil.resolveClassInClassTypeOnly(((PsiVariable)resolvedQualifier).getType()); + } + PsiPackage qualifierPackage = resolvedQualifier == null ? null : getPackage(resolvedQualifier); + PsiPackage aPackage = getPackage(file); + + if (samePackage(memberPackage, aPackage) + && (qualifierPackage == null || samePackage(qualifierPackage, aPackage)) + // java 9 will dislike split packages + && sameModule(member.getContainingFile(), file)) { + return suggestPackageLocal(member); + } + + // can't access protected members via "qualifier.protectedMember = 0;" + if (qualifier != null) return PsiUtil.ACCESS_LEVEL_PUBLIC; + + if (innerClass != null && memberClass != null && innerClass.isInheritor(memberClass, true)) { + //access from subclass can be via protected, except for constructors + PsiElement resolved = element instanceof PsiReference ? ((PsiReference)element).resolve() : null; + boolean isConstructor = resolved instanceof PsiClass && element.getParent() instanceof PsiNewExpression + || resolved instanceof PsiMethod && ((PsiMethod)resolved).isConstructor(); + if (!isConstructor) { + return PsiUtil.ACCESS_LEVEL_PROTECTED; + } + } + return PsiUtil.ACCESS_LEVEL_PUBLIC; } - return handleUsage(member, memberClass, memberFile, maxLevel, memberPackage, element, psiFile, foundUsage); - }); - - if (proceed && member instanceof PsiClass && LambdaUtil.isFunctionalClass((PsiClass)member)) { - // there can be lambda implementing this interface implicitly - FunctionalExpressionSearch.search((PsiClass)member).forEach(functionalExpression -> { - PsiFile psiFile = functionalExpression.getContainingFile(); - return handleUsage(member, memberClass, memberFile, maxLevel, memberPackage, functionalExpression, psiFile, foundUsage); - }); - } - if (!foundUsage.get()) { - log(member.getName() + " unused; ignore"); - return currentLevel; // do not propose private for unused method - } - - @PsiUtil.AccessLevel - int suggestedLevel = maxLevel.get(); - if (suggestedLevel == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) { - suggestedLevel = suggestPackageLocal(member); - } - - String suggestedModifier = PsiUtil.getAccessModifier(suggestedLevel); - log(member.getName() + ": effective level is '" + suggestedModifier + "'"); - - return suggestedLevel; + private static boolean calledOnInheritor(@NotNull PsiElement element, PsiClass memberClass) { + PsiExpression qualifier = getQualifier(element); + if (qualifier == null) { + PsiClass enclosingInstance = InheritanceUtil.findEnclosingInstanceInScope(memberClass, element, Conditions.alwaysTrue(), true); + return enclosingInstance != null && enclosingInstance != memberClass; + } + PsiClass qClass = PsiUtil.resolveClassInClassTypeOnly(qualifier.getType()); + return qClass != null && qClass.isInheritor(memberClass, true); + } } + @Nullable + private static PsiPackage getPackage(@NotNull PsiElement element) { + PsiFile file = element.getContainingFile(); + PsiDirectory directory = file == null ? null : file.getContainingDirectory(); + return directory == null ? null : JavaDirectoryService.getInstance().getPackage(directory); + } - private boolean handleUsage(@NotNull PsiMember member, - @Nullable PsiClass memberClass, - @NotNull PsiFile memberFile, - @NotNull AtomicInteger maxLevel, - @Nullable PsiPackage memberPackage, - @NotNull PsiElement element, - @NotNull PsiFile psiFile, - @NotNull AtomicBoolean foundUsage) { - foundUsage.set(true); - if (!(psiFile instanceof PsiJavaFile)) { - log(" refd from " + psiFile.getName() + "; set to public"); - maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC); - return false; // referenced from XML, has to be public - } - @PsiUtil.AccessLevel - int level = getEffectiveLevel(element, psiFile, member, memberFile, memberClass, memberPackage); - log(" ref in file " + psiFile.getName() + "; level = " + PsiUtil.getAccessModifier(level) + "; (" + element + ")"); - maxLevel.getAndAccumulate(level, Math::max); - - return level != PsiUtil.ACCESS_LEVEL_PUBLIC; + private static boolean samePackage(PsiPackage package1, PsiPackage package2) { + return package2 == package1 || + package2 != null && package1 != null && Comparing.strEqual(package2.getQualifiedName(), package1.getQualifiedName()); } - @PsiUtil.AccessLevel - private int getEffectiveLevel(@NotNull PsiElement element, - @NotNull PsiFile file, - @NotNull PsiMember member, - @NotNull PsiFile memberFile, - PsiClass memberClass, - PsiPackage memberPackage) { - PsiClass innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); - boolean isAbstractMember = member.hasModifierProperty(PsiModifier.ABSTRACT); - if (memberClass != null && PsiTreeUtil.isAncestor(innerClass, memberClass, false) || - innerClass != null && PsiTreeUtil.isAncestor(memberClass, innerClass, false) && !innerClass.hasModifierProperty(PsiModifier.STATIC)) { - // access from the same file can be via private - // except when used in annotation: - // @Ann(value = C.VAL) class C { public static final String VAL = "xx"; } - // or in implements/extends clauses - if (isInReferenceList(innerClass.getModifierList(), member) || - isInReferenceList(innerClass.getImplementsList(), member) || - isInReferenceList(innerClass.getExtendsList(), member)) { - return suggestPackageLocal(member); + private static boolean sameModule(PsiFile file1, PsiFile file2) { + if (file1 == file2) return true; + if (file1 == null || file2 == null) return false; + + VirtualFile virtualFile1 = file1.getVirtualFile(); + VirtualFile virtualFile2 = file2.getVirtualFile(); + if (virtualFile1 == null || virtualFile2 == null) { + return ComparatorUtil.equalsNullable(virtualFile1, virtualFile2); } - return !isAbstractMember && (myVisibilityInspection.SUGGEST_PRIVATE_FOR_INNERS || - !isInnerClass(memberClass)) ? PsiUtil.ACCESS_LEVEL_PRIVATE : suggestPackageLocal(member); - } - //if (file == memberFile) { - // return PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL; - //} - PsiDirectory directory = file.getContainingDirectory(); - PsiPackage aPackage = directory == null ? null : JavaDirectoryService.getInstance().getPackage(directory); - if (aPackage == memberPackage || aPackage != null && memberPackage != null && Comparing.strEqual(aPackage.getQualifiedName(), memberPackage.getQualifiedName())) { - return suggestPackageLocal(member); - } - if (innerClass != null && memberClass != null && innerClass.isInheritor(memberClass, true)) { - //access from subclass can be via protected, except for constructors - PsiElement resolved = element instanceof PsiReference ? ((PsiReference)element).resolve() : null; - boolean isConstructor = resolved instanceof PsiClass && element.getParent() instanceof PsiNewExpression - || resolved instanceof PsiMethod && ((PsiMethod)resolved).isConstructor(); - if (!isConstructor) { - return PsiUtil.ACCESS_LEVEL_PROTECTED; + Module module1 = ProjectRootManager.getInstance(file1.getProject()).getFileIndex().getModuleForFile(virtualFile1); + Module module2 = ProjectRootManager.getInstance(file2.getProject()).getFileIndex().getModuleForFile(virtualFile2); + + return module1 == module2; + } + + private static PsiExpression getQualifier(@NotNull PsiElement element) { + PsiExpression qualifier = null; + if (element instanceof PsiReferenceExpression) { + qualifier = ((PsiReferenceExpression)element).getQualifierExpression(); } - } - return PsiUtil.ACCESS_LEVEL_PUBLIC; + else if (element instanceof PsiMethodCallExpression) { + qualifier = ((PsiMethodCallExpression)element).getMethodExpression().getQualifierExpression(); + } + + return qualifier instanceof PsiQualifiedExpression ? null : qualifier; } - } - private static boolean isInnerClass(PsiClass memberClass) { - return memberClass != null && memberClass.getContainingClass() != null || memberClass instanceof PsiAnonymousClass; - } + private static boolean isInnerClass(@NotNull PsiClass memberClass) { + return memberClass.getContainingClass() != null || memberClass instanceof PsiAnonymousClass; + } - private static boolean isInReferenceList(@Nullable PsiElement list, @NotNull PsiMember member) { - if (list == null) { - return false; + private static boolean isConstantField(PsiMember member) { + return member instanceof PsiField && + member.hasModifierProperty(PsiModifier.STATIC) && + member.hasModifierProperty(PsiModifier.FINAL) && + ((PsiField)member).hasInitializer(); } - PsiManager psiManager = member.getManager(); - boolean[] result = new boolean[1]; - list.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { - super.visitReferenceElement(reference); - if (psiManager.areElementsEquivalent(reference.resolve(), member)) { - result[0] = true; - stopWalking(); - } - } - }); - return result[0]; - } - - @PsiUtil.AccessLevel - private int suggestPackageLocal(@NotNull PsiMember member) { - boolean suggestPackageLocal = member instanceof PsiClass && ClassUtil.isTopLevelClass((PsiClass)member) + + @PsiUtil.AccessLevel + private int suggestPackageLocal(@NotNull PsiMember member) { + boolean suggestPackageLocal = member instanceof PsiClass && ClassUtil.isTopLevelClass((PsiClass)member) ? myVisibilityInspection.SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES : myVisibilityInspection.SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS; - return suggestPackageLocal ? PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL : PsiUtil.ACCESS_LEVEL_PUBLIC; - } - - private static void log(String s) { - //System.out.println(s); - } + return suggestPackageLocal ? PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL : PsiUtil.ACCESS_LEVEL_PUBLIC; + } } //@formatter:on From f6baea3c230e4ff36c8807f8b49d95aca3eeab59 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:40:56 +0200 Subject: [PATCH 343/518] Create release.yml --- .github/workflows/release.yml | 165 ++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3f6a18a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,165 @@ +name: Release + +on: + push: + branches: [ master ] + +permissions: + contents: write + pull-requests: write + +jobs: + check_code: # Validates the code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: 'gradle' + + - name: Build + run: ./gradlew build buildPlugin --info + + - name: Check for uncommited changes + run: | + if [[ "$(git status --porcelain)" != "" ]]; then + echo ---------------------------------------- + echo git status + echo ---------------------------------------- + git status + echo ---------------------------------------- + echo git diff + echo ---------------------------------------- + git diff + echo ---------------------------------------- + echo Troubleshooting + echo ---------------------------------------- + echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && mvn -B clean package" + exit 1 + fi + + prepare_release: + runs-on: ubuntu-latest + needs: [check_code] + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + steps: + - uses: actions/checkout@v3 + + - name: Configure Git + run: | + git config --global user.email "actions@github.com" + git config --global user.name "GitHub Actions" + + - name: UN-Snap version and output + run: | + originalVersion=$(grep -Po 'pluginVersion=\K.*' gradle.properties) + newVersion="$(echo $originalVersion | cut -d '-' -f1)" + echo "New version: $newVersion" + sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties + + echo "release=$version" >> $GITHUB_OUTPUT + echo "releasenumber=${version//[!0-9]/}" >> $GITHUB_OUTPUT + + echo "Contents of gradle.properties" + cat gradle.properties + + - name: Commit and Push + run: | + git add -A + git commit -m "Release ${{ steps.version.outputs.release }}" + git push origin + git tag v${{ steps.version.outputs.release }} + git push origin --tags + + - name: Create Release + id: create_release + uses: shogo82148/actions-create-release@v1 + with: + tag_name: v${{ steps.version.outputs.release }} + release_name: v${{ steps.version.outputs.release }} + commitish: master + body: | + ## [Changelog](https://github.com/xdev-software/${{ github.event.repository.name }}/blob/develop/CHANGELOG.md#${{ steps.version.outputs.releasenumber }}) + See [Changelog#v${{ steps.version.outputs.release }}](https://github.com/xdev-software/${{ github.event.repository.name }}/blob/develop/CHANGELOG.md#${{ steps.version.outputs.releasenumber }}) for more information. + + ## Installation + The plugin is listed on the [Marketplace](https://plugins.jetbrains.com/plugin/22113). + + Open the plugin Marketplace in your IDE (``File > Settings > Plugins > Marketplace``), search for the plugin and hit the install button. + + Alternatively you can also download the jar from the marketplace website. + ``` + + publish: + runs-on: ubuntu-latest + needs: [prepare_release] + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 17 + cache: 'gradle' + + - name: Init Git and pull + run: | + git config --global user.email "actions@github.com" + git config --global user.name "GitHub Actions" + git pull + + - name: Publish Plugin + env: + PUBLISH_TOKEN: ${{ secrets.JETBRAINS_MARKETPLACE_PUBLISH_TOKEN }} + CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_MARKETPLACE_CERTIFICATE_CHAIN }} + PRIVATE_KEY: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY }} + PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_MARKETPLACE_PRIVATE_KEY_PASSWORD }} + run: ./gradlew publishPlugin --info --stacktrace + + - name: Upload plugin files + uses: actions/upload-artifact@v3 + with: + name: plugin-files-java-${{ matrix.java }} + path: build/distributions/* + if-no-files-found: error + + after_release: + runs-on: ubuntu-latest + needs: [publish] + steps: + - uses: actions/checkout@v3 + + - name: Init Git and pull + run: | + git config --global user.email "actions@github.com" + git config --global user.name "GitHub Actions" + git pull + + - name: Inc Version and SNAP root + run: | + originalVersion=$(grep -Po 'pluginVersion=\K.*' gradle.properties) + newVersion="$(echo $originalVersion | cut -d '-' -f1 | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{$NF=sprintf("%0*d", length($NF), ($NF+1)); print}')-SNAPSHOT" + echo "New version: $newVersion" + sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties + + echo "Contents of gradle.properties" + cat gradle.properties + + - name: Git Commit and Push + run: | + git add -A + git commit -m "Preparing for next development iteration" + git push origin + + - name: pull-request + uses: repo-sync/pull-request@v2 + with: + destination_branch: "develop" + pr_title: "Sync back" + pr_body: "An automated PR to sync changes back" From 89ce92c95436e8805b6957d9ce9548883c465d7c Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:42:19 +0200 Subject: [PATCH 344/518] Update README.md XDEV standard --- README.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 16e702f..d78e40d 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,7 @@ The code style applied by the save actions plugin is the one configured your set - [Configuration](#configuration) - [Compatibility](#compatibility) - [Files location](#files-location) -- [Contributions](#contributions) -- [Links](#links) -- [Licence](#license) +- [Contributing](#contributing) ## Features @@ -62,18 +60,7 @@ Works in JetBrains IDE with Java support, like Intellij IDEA and AndroidStudio. ![Save actions plugin settings page for Java](./assets/intellij-save-actions-plugin-settings-page-java.png) ## Installation - -### IDE (recommended) - -Install it from your IDE (Intellij IDEA, PyCharm, etc.): - -- "File > Settings > Plugins > Browse repositories... > Search 'Save Actions' > Category 'Code tools'" - -### JetBrains plugin repository - -All versions of the plugin are available from the [JetBrains plugin repository](https://plugins.jetbrains.com/plugin/7642). You can download the jar and add it to your IDE (you won't get updates thought): - -- "File > Settings > Plugins > Install plugin from disk..." +[Installation guide for the latest release](https://github.com/xdev-software/intellij-plugin-save-actions/releases/latest#Installation) ## Usage From 9d9d540778bb973a6e3e68f9ea3451741e171cf3 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:46:03 +0200 Subject: [PATCH 345/518] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d78e40d..549529b 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ The plugin can trigger automatically or manually on IDE actions (standard action ### IDE actions -The plugin will trigger automatically on any of these IDE actions (needs to be activated with "Activate save actions on file save" in [activation](#activation))): +The plugin will trigger automatically on any of these IDE actions (needs to be activated with "Activate save actions on file save" in [activation](#activation)): - **Frame deactivation**, which is when the editor loses focus, configured in "File > Settings > Appearance & Behavior > System Settings > Save files on frame deactivation" . - **Application idle**, which is when the IDE isn't used for a period of time, configured in "File > Settings > Appearance & Behavior > System Settings > Save files automatically if application is idle for x sec". From c3c460089c99fe02d4b02f004540bff69bd6e423 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:48:39 +0200 Subject: [PATCH 346/518] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3252fab..44c56fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,3 +2,4 @@ Initial release * Fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) * Rebrand +* Updated copy pasted classes from IDEA From b38071224651fd865c4cb19fc33e91189f4edbbd Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 13:58:36 +0200 Subject: [PATCH 347/518] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f6a18a..287536f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,6 +62,7 @@ jobs: echo "New version: $newVersion" sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties + version=newVersion echo "release=$version" >> $GITHUB_OUTPUT echo "releasenumber=${version//[!0-9]/}" >> $GITHUB_OUTPUT @@ -127,7 +128,6 @@ jobs: with: name: plugin-files-java-${{ matrix.java }} path: build/distributions/* - if-no-files-found: error after_release: runs-on: ubuntu-latest From f1cbc91a08448b9d3744097011733f821927fe1f Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 14:04:10 +0200 Subject: [PATCH 348/518] Fix NPE in build script --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 82c5fd5..a4cf62d 100644 --- a/build.gradle +++ b/build.gradle @@ -98,6 +98,6 @@ tasks { // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel channels = properties("pluginVersion") - .map { [(it.split('-')[1] ?: "default").split('\\.').find { true }.toLowerCase()] } + .map { [((it.split('-') as List)[1] ?: "default").split('\\.').find { true }.toLowerCase()] } } } From 69733bfa564b2a91fa5c822818af0c1d278b3f79 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 14:19:00 +0200 Subject: [PATCH 349/518] Typo --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 287536f..4ff8532 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,7 +62,7 @@ jobs: echo "New version: $newVersion" sed -i "s/pluginVersion=$originalVersion/pluginVersion=$newVersion/" gradle.properties - version=newVersion + version=$newVersion echo "release=$version" >> $GITHUB_OUTPUT echo "releasenumber=${version//[!0-9]/}" >> $GITHUB_OUTPUT From 6840b312565a2211ba38cb62b7e000e9984980e7 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 14:20:21 +0200 Subject: [PATCH 350/518] Update release.yml --- .github/workflows/release.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4ff8532..21da86d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -94,7 +94,6 @@ jobs: Open the plugin Marketplace in your IDE (``File > Settings > Plugins > Marketplace``), search for the plugin and hit the install button. Alternatively you can also download the jar from the marketplace website. - ``` publish: runs-on: ubuntu-latest From f699b340e5e00c5c5d3d5af8ab26da740f58c7b8 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 14:38:46 +0200 Subject: [PATCH 351/518] Add missing ID --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 21da86d..094ac93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,6 +56,7 @@ jobs: git config --global user.name "GitHub Actions" - name: UN-Snap version and output + id: version run: | originalVersion=$(grep -Po 'pluginVersion=\K.*' gradle.properties) newVersion="$(echo $originalVersion | cut -d '-' -f1)" From 69b70b8cd16e60dc43bbd60448e03aca0c7480b6 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 22 Jun 2023 12:40:22 +0000 Subject: [PATCH 352/518] Release 1.0.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index b107d89..f046b61 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.0-SNAPSHOT +pluginVersion=1.0.0 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From bdb97157745e0f854c97a70951e12f77fa096c41 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 22 Jun 2023 12:42:33 +0000 Subject: [PATCH 353/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f046b61..9f3bf03 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.0 +pluginVersion=1.0.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From f86cc1f43c0fb85fe9ff0411304de0d20d41a2a4 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 22 Jun 2023 15:33:08 +0200 Subject: [PATCH 354/518] Fill in template --- SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index 36d6305..970016c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,4 +2,4 @@ ## Reporting a Vulnerability -Please report a security vulnerability [on GitHub Security Advisories](https://github.com/xdev-software/base-template/security/advisories/new). +Please report a security vulnerability [on GitHub Security Advisories](https://github.com/xdev-software/intellij-plugin-save-actions/security/advisories/new). From a2a90c52276962f84cf913acdfc9ad5ceff8f6a4 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 22 Jun 2023 16:54:10 +0200 Subject: [PATCH 355/518] Add reference for snapshot releases --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 549529b..8490179 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,9 @@ Works in JetBrains IDE with Java support, like Intellij IDEA and AndroidStudio. ## Installation [Installation guide for the latest release](https://github.com/xdev-software/intellij-plugin-save-actions/releases/latest#Installation) +[Development versions](https://plugins.jetbrains.com/docs/intellij/publishing-plugin.html#specifying-a-release-channel) can be installed by [adding the ``snapshot`` release channel as a plugin repository](https://www.jetbrains.com/help/idea/managing-plugins.html#repos):
    +``https://plugins.jetbrains.com/plugins/snapshot/list`` + ## Usage The plugin can trigger automatically or manually on IDE actions (standard actions) or plugin actions. Most actions needs to be enabled individually (see [activation](#activation)). From 8142cdfbe2a623dd2dc73a2ed9e62043a425b12f Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 26 Jun 2023 10:03:48 +0200 Subject: [PATCH 356/518] Replace deprecated save actions plugin with XDEV fork --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 81e0276..2456c17 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ You should have the following things installed: ### Recommended setup * Install ``IntelliJ`` (Community Edition is sufficient) * Install the following plugins: - * [Save Actions](https://plugins.jetbrains.com/plugin/7642-save-actions) - Provides save actions, like running the formatter or adding ``final`` to fields + * [Save Actions](https://plugins.jetbrains.com/plugin/22113) - Provides save actions, like running the formatter or adding ``final`` to fields * [SonarLint](https://plugins.jetbrains.com/plugin/7973-sonarlint) - CodeStyle/CodeAnalysis * [Checkstyle-IDEA](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea) - CodeStyle/CodeAnalysis * Import the project From 60f5d4f0946827575f4cd6e29c6d246868a55976 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:20:52 +0200 Subject: [PATCH 357/518] Add note that it's not compatible with the forked plugin --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44c56fa..9683724 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.0.0 Initial release * Fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) + * ⚠️ This plugin is not compatible with the old/deprecated/forked one.
    Please ensure that the old plugin is uninstalled. * Rebrand * Updated copy pasted classes from IDEA + From 4976be2087e26677421a717a0e5de312eb08699a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 01:08:13 +0000 Subject: [PATCH 358/518] Bump org.jetbrains.intellij from 1.14.1 to 1.14.2 Bumps org.jetbrains.intellij from 1.14.1 to 1.14.2. --- updated-dependencies: - dependency-name: org.jetbrains.intellij dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a4cf62d..0a88bac 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.14.1' + id 'org.jetbrains.intellij' version '1.14.2' id 'org.sonarqube' version '4.2.1.3168' } From c24aef51ba7b76d039b820485ba06dcda0db2388 Mon Sep 17 00:00:00 2001 From: AB Date: Tue, 27 Jun 2023 12:35:28 +0200 Subject: [PATCH 359/518] Fix typo --- src/main/java/software/xdev/saveactions/model/Action.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/software/xdev/saveactions/model/Action.java b/src/main/java/software/xdev/saveactions/model/Action.java index 40e9a38..2804f5d 100644 --- a/src/main/java/software/xdev/saveactions/model/Action.java +++ b/src/main/java/software/xdev/saveactions/model/Action.java @@ -94,7 +94,7 @@ public enum Action { finalPrivateMethod("Remove final from private method", java, false), - unnecessaryFinalOnLocalVariableOrParameter("Remove unnecessary final to local variable or parameter", + unnecessaryFinalOnLocalVariableOrParameter("Remove unnecessary final for local variable or parameter", java, false), explicitTypeCanBeDiamond("Remove explicit generic type for diamond", From 446542c7831c4116c1cdf8df0aac2ac91f738f75 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Tue, 4 Jul 2023 16:59:15 +0200 Subject: [PATCH 360/518] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8490179..72705ba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -[![Latest version](https://img.shields.io/jetbrains/plugin/v/22113?logo=jetbrains)](https://plugins.jetbrains.com/plugin/22113-save-actions--xdev-edition) +[![Latest version](https://img.shields.io/jetbrains/plugin/v/22113?logo=jetbrains)](https://plugins.jetbrains.com/plugin/22113) [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/checkBuild.yml?branch=develop)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/checkBuild.yml?query=branch%3Adevelop) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_intellij-plugin-save-actions&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_intellij-plugin-save-actions) +[![Feel free to leave a rating](https://img.shields.io/jetbrains/plugin/r/rating/22113?style=social&logo=jetbrains&label=Feel%20free%20to%20leave%20a%20rating)](https://plugins.jetbrains.com/plugin/22113/reviews) # Save Actions Plugin icon light Save Actions Plugin - XDEV Edition From 7a3bdd6e7173ce4dd21429eaa36112eaea66729d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 00:33:23 +0000 Subject: [PATCH 361/518] Bump org.sonarqube from 4.2.1.3168 to 4.3.0.3225 Bumps org.sonarqube from 4.2.1.3168 to 4.3.0.3225. --- updated-dependencies: - dependency-name: org.sonarqube dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0a88bac..3c2747a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java' id 'idea' id 'org.jetbrains.intellij' version '1.14.2' - id 'org.sonarqube' version '4.2.1.3168' + id 'org.sonarqube' version '4.3.0.3225' } def properties(String key) { From 17cba4590ea04566b83b884e9d6f3ab084256436 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 00:28:08 +0000 Subject: [PATCH 362/518] Bump org.junit:junit-bom from 5.9.3 to 5.10.0 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.9.3 to 5.10.0. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.9.3...r5.10.0) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0a88bac..08ac6df 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { // Add dependencies to test, junit5 api (annotations) and engine (runtime) dependencies { - testImplementation platform('org.junit:junit-bom:5.9.3'), + testImplementation platform('org.junit:junit-bom:5.10.0'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', 'org.assertj:assertj-core:3.24.2' From 6c78f4dbd4f45d7a272fc52f781a1f0e4282aed7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jul 2023 07:53:09 +0000 Subject: [PATCH 363/518] Bump org.jetbrains.intellij from 1.14.2 to 1.15.0 Bumps org.jetbrains.intellij from 1.14.2 to 1.15.0. --- updated-dependencies: - dependency-name: org.jetbrains.intellij dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 93f0710..10e4b96 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.14.2' + id 'org.jetbrains.intellij' version '1.15.0' id 'org.sonarqube' version '4.3.0.3225' } From 1ae879e8e7419dbce32a346bd81440b6688dfe46 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 2 Aug 2023 11:37:25 +0200 Subject: [PATCH 364/518] Update IntelliJ to latest version --- build.gradle | 2 +- gradle.properties | 2 +- src/main/resources/META-INF/plugin.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 10e4b96..8b8271a 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,7 @@ intellij { listProductsReleases { - sinceBuild = "231.*" + sinceBuild = "232.*" } // JAVA compatibility diff --git a/gradle.properties b/gradle.properties index 9f3bf03..aca0a7b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ pluginName=Save Actions - XDEV Edition pluginVersion=1.0.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC -platformVersion=2023.1 +platformVersion=2023.2 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 platformPlugins=java diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 6182f2b..1d209d0 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,7 +19,7 @@ - + com.intellij.modules.java From d78e2d46cb19a040e32c794064789851a46647ab Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 2 Aug 2023 13:48:25 +0200 Subject: [PATCH 365/518] Moved inspections to custom directory and copied over non invokeable code For further information see #4 #14. --- .idea/saveactions_settings.xml | 4 +- ...ustomUnqualifiedStaticUsageInspection.java | 129 ------------------ .../processors/java/JavaProcessor.java | 4 +- .../AccessibleVisibilityInspection.java | 82 +++++++++++ .../CustomAccessCanBeTightenedInspection.java | 107 +++++++++++---- ...ustomUnqualifiedStaticUsageInspection.java | 107 +++++++++++++++ 6 files changed, 273 insertions(+), 160 deletions(-) delete mode 100644 src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java create mode 100644 src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java rename src/main/java/{com/intellij/codeInspection/visibility => software/xdev/saveactions/processors/java/inspection}/CustomAccessCanBeTightenedInspection.java (85%) create mode 100644 src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java diff --git a/.idea/saveactions_settings.xml b/.idea/saveactions_settings.xml index 6d1df43..6221ab6 100644 --- a/.idea/saveactions_settings.xml +++ b/.idea/saveactions_settings.xml @@ -23,10 +23,8 @@ - + \ No newline at end of file diff --git a/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java b/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java deleted file mode 100644 index 872571c..0000000 --- a/src/main/java/com/siyeh/ig/style/CustomUnqualifiedStaticUsageInspection.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.siyeh.ig.style; - -import com.intellij.psi.JavaResolveResult; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiEnumConstant; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiImportStaticStatement; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiMethodCallExpression; -import com.intellij.psi.PsiModifier; -import com.intellij.psi.PsiReferenceExpression; -import com.intellij.psi.PsiSwitchLabelStatement; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; -import com.siyeh.ig.BaseInspectionVisitor; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; - -/** - * Copy pasting because: cannot extend. Do not reformat (useful for diffs) - * - * @see com.siyeh.ig.style.UnqualifiedStaticUsageInspection.UnqualifiedStaticCallVisitor - */ -public class CustomUnqualifiedStaticUsageInspection extends UnqualifiedStaticUsageInspection { - - @Override - public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { - - return this.getClass().getSimpleName(); - } - - - @Override - public BaseInspectionVisitor buildVisitor() { - - return new CustomUnqualifiedStaticCallVisitor(); - } - - - private class CustomUnqualifiedStaticCallVisitor extends BaseInspectionVisitor { - - @Override - public void visitMethodCallExpression( - @NotNull final PsiMethodCallExpression expression) { - - super.visitMethodCallExpression(expression); - if (m_ignoreStaticMethodCalls) { - return; - } - final PsiReferenceExpression methodExpression = - expression.getMethodExpression(); - if (!isUnqualifiedStaticAccess(methodExpression)) { - return; - } - registerError(methodExpression, expression); - } - - - @Override - public void visitReferenceExpression( - @NotNull final PsiReferenceExpression expression) { - - super.visitReferenceExpression(expression); - if (m_ignoreStaticFieldAccesses) { - return; - } - final PsiElement element = expression.resolve(); - if (!(element instanceof PsiField)) { - return; - } - final PsiField field = (PsiField) element; - if (field.hasModifierProperty(PsiModifier.FINAL) && - PsiUtil.isOnAssignmentLeftHand(expression)) { - return; - } - if (!isUnqualifiedStaticAccess(expression)) { - return; - } - registerError(expression, expression); - } - - - private boolean isUnqualifiedStaticAccess( - final PsiReferenceExpression expression) { - - if (m_ignoreStaticAccessFromStaticContext) { - final PsiMember member = - PsiTreeUtil.getParentOfType(expression, - PsiMember.class); - if (member != null && - member.hasModifierProperty(PsiModifier.STATIC)) { - return false; - } - } - final PsiExpression qualifierExpression = - expression.getQualifierExpression(); - if (qualifierExpression != null) { - return false; - } - final JavaResolveResult resolveResult = - expression.advancedResolve(false); - final PsiElement currentFileResolveScope = - resolveResult.getCurrentFileResolveScope(); - if (currentFileResolveScope instanceof PsiImportStaticStatement) { - return false; - } - final PsiElement element = resolveResult.getElement(); - if (!(element instanceof PsiField) && - !(element instanceof PsiMethod)) { - return false; - } - final PsiMember member = (PsiMember) element; - if (member instanceof PsiEnumConstant && - expression.getParent() instanceof PsiSwitchLabelStatement) { - return false; - } - final PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); - final PsiClass memberClass = member.getContainingClass(); - if (memberClass != null && memberClass.equals(expressionClass)) { - return false; - } - return member.hasModifierProperty(PsiModifier.STATIC); - } - } - -} diff --git a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java index f40dafc..524ffbb 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java @@ -8,7 +8,7 @@ import software.xdev.saveactions.processors.java.inspection.SerializableHasSerialVersionUIDFieldInspectionWrapper; import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection; import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection; +import software.xdev.saveactions.processors.java.inspection.CustomAccessCanBeTightenedInspection; import com.intellij.codeInspection.visibility.VisibilityInspection; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; @@ -17,7 +17,7 @@ import com.siyeh.ig.maturity.SuppressionAnnotationInspection; import com.siyeh.ig.performance.MethodMayBeStaticInspection; import com.siyeh.ig.style.ControlFlowStatementWithoutBracesInspection; -import com.siyeh.ig.style.CustomUnqualifiedStaticUsageInspection; +import software.xdev.saveactions.processors.java.inspection.CustomUnqualifiedStaticUsageInspection; import com.siyeh.ig.style.FieldMayBeFinalInspection; import com.siyeh.ig.style.SingleStatementInBlockInspection; import com.siyeh.ig.style.UnnecessaryFinalOnLocalVariableOrParameterInspection; diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java new file mode 100644 index 0000000..9e80d6f --- /dev/null +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java @@ -0,0 +1,82 @@ +package software.xdev.saveactions.processors.java.inspection; + +import com.intellij.codeInspection.ex.EntryPointsManagerBase; +import com.intellij.codeInspection.visibility.EntryPointWithVisibilityLevel; +import com.intellij.codeInspection.visibility.VisibilityInspection; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiMember; +import com.intellij.psi.SyntaxTraverser; +import one.util.streamex.StreamEx; +import org.jetbrains.annotations.NotNull; +import software.xdev.saveactions.model.Action; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Fork of {@link com.intellij.codeInspection.visibility.VisibilityInspection} but accessible for the plugin. + */ +public final class AccessibleVisibilityInspection { + + private static final Logger LOG = Logger.getInstance(AccessibleVisibilityInspection.class); + + private AccessibleVisibilityInspection() { + } + + public static boolean containsReferenceTo(PsiElement source, PsiElement target) { + return SyntaxTraverser.psiTraverser(source) + .filter(PsiJavaCodeReferenceElement.class) + .filter(ref -> ref.isReferenceTo(target)) + .isNotEmpty(); + } + + @SuppressWarnings("java:S3011") // reflection is needed because VisibilityInspection members are private + public static int getMinVisibilityLevel(VisibilityInspection myVisibilityInspection, @NotNull PsiMember member) { + List exceptions = new ArrayList<>(); + // 1. Try to access getMinVisibilityLevel directly + try { + Method getMinVisibilityLevel = myVisibilityInspection.getClass() + .getDeclaredMethod("getMinVisibilityLevel", PsiMember.class); + + getMinVisibilityLevel.setAccessible(true); + + return (int) getMinVisibilityLevel.invoke(myVisibilityInspection, member); + } catch (Exception e) { + LOG.error("Failed to invoke getMinVisibilityLevel", e); + exceptions.add(e); + } + + // 2. Fallback to isEntryPointEnabled + LOG.warn("getMinVisibilityLevel: Trying fallback method: isEntryPointEnabled"); + try { + Method isEntryPointEnabled = myVisibilityInspection.getClass() + .getDeclaredMethod("isEntryPointEnabled", EntryPointWithVisibilityLevel.class); + isEntryPointEnabled.setAccessible(true); + + return StreamEx.of(EntryPointsManagerBase.DEAD_CODE_EP_NAME.getExtensions()) + .select(EntryPointWithVisibilityLevel.class) + .filter(point -> { + try { + return (boolean) isEntryPointEnabled.invoke(myVisibilityInspection, point); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException("Reflection call failed", e); + } + }) + .mapToInt(point -> point.getMinVisibilityLevel(member)) + .max().orElse(-1); + } catch (Exception e) { + LOG.error("Failed to invoke isEntryPointEnabled", e); + exceptions.add(e); + } + + LOG.error("Execution of getMinVisibilityLevel with reflection failed; " + + "Please report the problem so that I can be fixed. In the meantime consider disabling '" + + Action.accessCanBeTightened.getText() + + "' or downgrade your IDE"); + throw new IllegalStateException(exceptions.get(0)); + } +} diff --git a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java similarity index 85% rename from src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java rename to src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java index eb473fb..43f2939 100644 --- a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java @@ -1,5 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.codeInspection.visibility; +package software.xdev.saveactions.processors.java.inspection; //@formatter:off import com.intellij.codeInsight.daemon.impl.UnusedSymbolUtil; @@ -8,6 +7,7 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase; import com.intellij.codeInspection.inheritance.ImplicitSubclassProvider; +import com.intellij.codeInspection.visibility.VisibilityInspection; import com.intellij.java.analysis.JavaAnalysisBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -17,10 +17,43 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Conditions; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.JavaDirectoryService; +import com.intellij.psi.JavaElementVisitor; +import com.intellij.psi.LambdaUtil; +import com.intellij.psi.PsiAnonymousClass; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiEnumConstant; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaCodeReferenceElement; +import com.intellij.psi.PsiJavaFile; +import com.intellij.psi.PsiKeyword; +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiMethodCallExpression; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiModifierList; +import com.intellij.psi.PsiNameIdentifierOwner; +import com.intellij.psi.PsiNewExpression; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.PsiQualifiedExpression; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiSyntheticClass; +import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.PsiVariable; +import com.intellij.psi.SyntheticElement; import com.intellij.psi.impl.FindSuperElementsHelper; import com.intellij.psi.search.searches.FunctionalExpressionSearch; -import com.intellij.psi.util.*; +import com.intellij.psi.util.ClassUtil; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.JavaPsiRecordUtil; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.ComparatorUtil; import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.fixes.ChangeModifierFix; @@ -78,7 +111,7 @@ public String getShortName() { @NotNull @Override - public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) { + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { return new MyVisitor(holder); } @@ -107,14 +140,16 @@ public void visitField(@NotNull PsiField field) { checkMember(field); } - private void checkMember(@NotNull final PsiMember member) { + private void checkMember(@NotNull PsiMember member) { if (!myVisibilityInspection.SUGGEST_FOR_CONSTANTS && isConstantField(member)) { return; } - final PsiClass memberClass = member.getContainingClass(); + PsiClass memberClass = member.getContainingClass(); PsiModifierList memberModifierList = member.getModifierList(); - if (memberModifierList == null) return; + if (memberModifierList == null) { + return; + } int currentLevel = PsiUtil.getAccessLevel(memberModifierList); int suggestedLevel = suggestLevel(member, memberClass, currentLevel); if (memberClass != null) { @@ -155,8 +190,12 @@ private void checkMember(@NotNull final PsiMember member) { @PsiUtil.AccessLevel private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUtil.AccessLevel int currentLevel) { - if (member.hasModifierProperty(PsiModifier.PRIVATE) || member.hasModifierProperty(PsiModifier.NATIVE)) return currentLevel; - if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical()) return currentLevel; + if (member.hasModifierProperty(PsiModifier.PRIVATE) || member.hasModifierProperty(PsiModifier.NATIVE)) { + return currentLevel; + } + if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical()) { + return currentLevel; + } if (member instanceof PsiMethod method) { if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) { @@ -176,7 +215,9 @@ private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUt return currentLevel; } } - if (member instanceof PsiEnumConstant) return currentLevel; + if (member instanceof PsiEnumConstant) { + return currentLevel; + } if (member instanceof PsiClass && (member instanceof PsiAnonymousClass || member instanceof PsiTypeParameter || member instanceof PsiSyntheticClass || @@ -189,16 +230,20 @@ private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUt if (memberClass != null && member instanceof PsiMethod) { if (memberClass.isRecord() && ((PsiMethod)member).isConstructor()) { - final PsiModifierList modifierList = memberClass.getModifierList(); + PsiModifierList modifierList = memberClass.getModifierList(); assert modifierList != null; // anonymous records don't exist return PsiUtil.getAccessLevel(modifierList); } // If class will be subclassed by some framework then it could apply some specific requirements for methods visibility // so we just skip it here (IDEA-182709, IDEA-160602) for (ImplicitSubclassProvider subclassProvider : ImplicitSubclassProvider.EP_NAME.getExtensions()) { - if (!subclassProvider.isApplicableTo(memberClass)) continue; + if (!subclassProvider.isApplicableTo(memberClass)) { + continue; + } ImplicitSubclassProvider.SubclassingInfo info = subclassProvider.getSubclassingInfo(memberClass); - if (info == null) continue; + if (info == null) { + continue; + } Map methodsInfo = info.getMethodsInfo(); if (methodsInfo == null || methodsInfo.containsKey(member)) { return currentLevel; @@ -206,10 +251,10 @@ private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUt } } - final PsiFile memberFile = member.getContainingFile(); + PsiFile memberFile = member.getContainingFile(); Project project = memberFile.getProject(); - int level = myVisibilityInspection.getMinVisibilityLevel(member); + int level = AccessibleVisibilityInspection.getMinVisibilityLevel(myVisibilityInspection, member); boolean entryPoint = myDeadCodeInspection.isEntryPoint(member) || member instanceof PsiField && (UnusedSymbolUtil.isImplicitWrite((PsiVariable)member) || UnusedSymbolUtil.isImplicitRead((PsiVariable)member)); if (entryPoint && level <= 0) { @@ -219,7 +264,7 @@ private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUt return currentLevel; } - final PsiPackage memberPackage = getPackage(memberFile); + PsiPackage memberPackage = getPackage(memberFile); if (LOG.isDebugEnabled()) { LOG.debug(member.getName() + ": checking effective level for " + member); } @@ -229,9 +274,13 @@ private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUt AtomicBoolean foundUsage = new AtomicBoolean(); boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> { PsiElement element = info.getElement(); - if (element == null) return true; + if (element == null) { + return true; + } PsiFile psiFile = info.getFile(); - if (psiFile == null) return true; + if (psiFile == null) { + return true; + } return handleUsage(member, memberClass, maxLevel, memberPackage, element, psiFile, foundUsage); }); @@ -298,7 +347,7 @@ private int getEffectiveLevel(@NotNull PsiElement element, if (member instanceof PsiClass && element instanceof PsiJavaCodeReferenceElement) { PsiMember exportingMember = ClassEscapesItsScopeInspection.getExportingMember((PsiJavaCodeReferenceElement)element); if (exportingMember != null) { - final PsiModifierList modifierList = exportingMember.getModifierList(); + PsiModifierList modifierList = exportingMember.getModifierList(); assert modifierList != null; return PsiUtil.getAccessLevel(modifierList); } @@ -310,9 +359,9 @@ private int getEffectiveLevel(@NotNull PsiElement element, // except when used in annotation: // @Ann(value = C.VAL) class C { public static final String VAL = "xx"; } // or in implements/extends clauses - if (VisibilityInspection.containsReferenceTo(innerClass.getModifierList(), member) || - VisibilityInspection.containsReferenceTo(innerClass.getImplementsList(), member) || - VisibilityInspection.containsReferenceTo(innerClass.getExtendsList(), member)) { + if (AccessibleVisibilityInspection.containsReferenceTo(innerClass.getModifierList(), member) || + AccessibleVisibilityInspection.containsReferenceTo(innerClass.getImplementsList(), member) || + AccessibleVisibilityInspection.containsReferenceTo(innerClass.getExtendsList(), member)) { return suggestPackageLocal(member); } @@ -338,7 +387,9 @@ && sameModule(member.getContainingFile(), file)) { } // can't access protected members via "qualifier.protectedMember = 0;" - if (qualifier != null) return PsiUtil.ACCESS_LEVEL_PUBLIC; + if (qualifier != null) { + return PsiUtil.ACCESS_LEVEL_PUBLIC; + } if (innerClass != null && memberClass != null && innerClass.isInheritor(memberClass, true)) { //access from subclass can be via protected, except for constructors @@ -376,8 +427,12 @@ private static boolean samePackage(PsiPackage package1, PsiPackage package2) { } private static boolean sameModule(PsiFile file1, PsiFile file2) { - if (file1 == file2) return true; - if (file1 == null || file2 == null) return false; + if (file1 == file2) { + return true; + } + if (file1 == null || file2 == null) { + return false; + } VirtualFile virtualFile1 = file1.getVirtualFile(); VirtualFile virtualFile2 = file2.getVirtualFile(); diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java new file mode 100644 index 0000000..b585d8f --- /dev/null +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java @@ -0,0 +1,107 @@ +package software.xdev.saveactions.processors.java.inspection; + +import com.intellij.psi.JavaResolveResult; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiEnumConstant; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiImportStaticStatement; +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiMethodCallExpression; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiSwitchLabelStatement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.style.UnqualifiedStaticUsageInspection; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +/** + * Copy pasting because: cannot extend. Do not reformat (useful for diffs) + * + * @see com.siyeh.ig.style.UnqualifiedStaticUsageInspection.UnqualifiedStaticCallVisitor + */ +public class CustomUnqualifiedStaticUsageInspection extends UnqualifiedStaticUsageInspection { + + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { + return getClass().getSimpleName(); + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new CustomUnqualifiedStaticCallVisitor(); + } + + private class CustomUnqualifiedStaticCallVisitor extends BaseInspectionVisitor { + @Override + public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + if (m_ignoreStaticMethodCalls) { + return; + } + PsiReferenceExpression methodExpression = expression.getMethodExpression(); + if (!isUnqualifiedStaticAccess(methodExpression)) { + return; + } + registerError(methodExpression, expression); + } + + @Override + public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + if (m_ignoreStaticFieldAccesses) { + return; + } + PsiElement element = expression.resolve(); + if (!(element instanceof PsiField)) { + return; + } + PsiField field = (PsiField) element; + if (field.hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isOnAssignmentLeftHand(expression)) { + return; + } + if (!isUnqualifiedStaticAccess(expression)) { + return; + } + registerError(expression, expression); + } + + private boolean isUnqualifiedStaticAccess(PsiReferenceExpression expression) { + if (m_ignoreStaticAccessFromStaticContext) { + PsiMember member = PsiTreeUtil.getParentOfType(expression, PsiMember.class); + if (member != null && member.hasModifierProperty(PsiModifier.STATIC)) { + return false; + } + } + PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (qualifierExpression != null) { + return false; + } + JavaResolveResult resolveResult = expression.advancedResolve(false); + PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope(); + if (currentFileResolveScope instanceof PsiImportStaticStatement) { + return false; + } + PsiElement element = resolveResult.getElement(); + if (!(element instanceof PsiField) && !(element instanceof PsiMethod)) { + return false; + } + PsiMember member = (PsiMember) element; + if (member instanceof PsiEnumConstant && expression.getParent() instanceof PsiSwitchLabelStatement) { + return false; + } + PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); + PsiClass memberClass = member.getContainingClass(); + if (memberClass != null && memberClass.equals(expressionClass)) { + return false; + } + return member.hasModifierProperty(PsiModifier.STATIC); + } + } + +} From 5c2565cc30c3b6587328738aead087309dae676c Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 2 Aug 2023 13:59:43 +0200 Subject: [PATCH 366/518] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9683724..4f314f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 +* Updated to ``IntelliJ Platform`` ``232`` (2023.2) for compatibility reasons +* Fixed ``Change visibility of field or method to lower access`` not working #14 + ## 1.0.0 Initial release * Fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) From 02ef997be4b68e4737d2fb420d252bc98042f3ac Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 2 Aug 2023 15:46:11 +0200 Subject: [PATCH 367/518] Remove reflection and fallback as IDE validator reports errors --- .../AccessibleVisibilityInspection.java | 43 ++----------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java index 9e80d6f..1d2e2d6 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java @@ -1,21 +1,14 @@ package software.xdev.saveactions.processors.java.inspection; -import com.intellij.codeInspection.ex.EntryPointsManagerBase; -import com.intellij.codeInspection.visibility.EntryPointWithVisibilityLevel; import com.intellij.codeInspection.visibility.VisibilityInspection; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.PsiMember; import com.intellij.psi.SyntaxTraverser; -import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; -import software.xdev.saveactions.model.Action; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; /** * Fork of {@link com.intellij.codeInspection.visibility.VisibilityInspection} but accessible for the plugin. @@ -34,10 +27,9 @@ public static boolean containsReferenceTo(PsiElement source, PsiElement target) .isNotEmpty(); } - @SuppressWarnings("java:S3011") // reflection is needed because VisibilityInspection members are private + // reflection is needed because VisibilityInspection members are private + @SuppressWarnings({"java:S3011"}) public static int getMinVisibilityLevel(VisibilityInspection myVisibilityInspection, @NotNull PsiMember member) { - List exceptions = new ArrayList<>(); - // 1. Try to access getMinVisibilityLevel directly try { Method getMinVisibilityLevel = myVisibilityInspection.getClass() .getDeclaredMethod("getMinVisibilityLevel", PsiMember.class); @@ -47,36 +39,7 @@ public static int getMinVisibilityLevel(VisibilityInspection myVisibilityInspect return (int) getMinVisibilityLevel.invoke(myVisibilityInspection, member); } catch (Exception e) { LOG.error("Failed to invoke getMinVisibilityLevel", e); - exceptions.add(e); + throw new IllegalStateException(e); } - - // 2. Fallback to isEntryPointEnabled - LOG.warn("getMinVisibilityLevel: Trying fallback method: isEntryPointEnabled"); - try { - Method isEntryPointEnabled = myVisibilityInspection.getClass() - .getDeclaredMethod("isEntryPointEnabled", EntryPointWithVisibilityLevel.class); - isEntryPointEnabled.setAccessible(true); - - return StreamEx.of(EntryPointsManagerBase.DEAD_CODE_EP_NAME.getExtensions()) - .select(EntryPointWithVisibilityLevel.class) - .filter(point -> { - try { - return (boolean) isEntryPointEnabled.invoke(myVisibilityInspection, point); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Reflection call failed", e); - } - }) - .mapToInt(point -> point.getMinVisibilityLevel(member)) - .max().orElse(-1); - } catch (Exception e) { - LOG.error("Failed to invoke isEntryPointEnabled", e); - exceptions.add(e); - } - - LOG.error("Execution of getMinVisibilityLevel with reflection failed; " - + "Please report the problem so that I can be fixed. In the meantime consider disabling '" - + Action.accessCanBeTightened.getText() - + "' or downgrade your IDE"); - throw new IllegalStateException(exceptions.get(0)); } } From 2930943c5341d0a400be5d93ec82c5b3361bb0c8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 2 Aug 2023 14:01:21 +0000 Subject: [PATCH 368/518] Release 1.0.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index aca0a7b..ff10039 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.1-SNAPSHOT +pluginVersion=1.0.1 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2 From 469a0a3c9b75cca2ce82da595a11a62577446052 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 2 Aug 2023 14:04:10 +0000 Subject: [PATCH 369/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ff10039..04b191b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.1 +pluginVersion=1.0.2-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2 From 52a0d41c48a9c6009d5c8db2b60c418e4218305e Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 7 Aug 2023 14:34:19 +0200 Subject: [PATCH 370/518] Fix error when using multiple configurable plugins Fix #20 --- src/main/resources/META-INF/plugin.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 1d209d0..8e4c49c 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -28,7 +28,9 @@ - From 5d37c742a25ccec81fbeff555b15b3580f5f09e4 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:15:06 +0200 Subject: [PATCH 371/518] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f314f5..4f7c44f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.2 +* Fixed missing display name which causes an error when multiple configureable plugins are installed #20 + ## 1.0.1 * Updated to ``IntelliJ Platform`` ``232`` (2023.2) for compatibility reasons * Fixed ``Change visibility of field or method to lower access`` not working #14 From 0c6b210654bc34cd66bdab51cd17ae78fc000235 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 7 Aug 2023 13:23:37 +0000 Subject: [PATCH 372/518] Release 1.0.2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 04b191b..6d8daec 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.2-SNAPSHOT +pluginVersion=1.0.2 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2 From 4ffc98f06595c1f896a22e8c22ddbeaacde37ce7 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 7 Aug 2023 13:26:35 +0000 Subject: [PATCH 373/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 6d8daec..185097e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.2 +pluginVersion=1.0.3-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2 From 0c889d338b359a5b3ad460ddcf0713ab7db92426 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 28 Aug 2023 09:50:53 +0200 Subject: [PATCH 374/518] Fix problem in combination with qodana plugin Fixes #25 --- .../inspection/CustomAccessCanBeTightenedInspection.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java index 43f2939..c8030ea 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java @@ -61,6 +61,7 @@ import com.siyeh.ig.visibility.ClassEscapesItsScopeInspection; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -103,6 +104,12 @@ public String getGroupDisplayName() { return InspectionsBundle.message("group.names.visibility.issues"); } + // Required for qodana plugin (in most IDEs built-in); see also #25 + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { + return getClass().getSimpleName(); + } + @Override @NotNull public String getShortName() { From 6a88dab364155de483f6b59578036a707632d781 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 28 Aug 2023 10:22:28 +0200 Subject: [PATCH 375/518] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f7c44f..dd2caaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.3 +* Fixed problem in combination with Qodana plugin #25 + ## 1.0.2 * Fixed missing display name which causes an error when multiple configureable plugins are installed #20 From 06addf903ee16601171e4ce32e2ffdf6b302dbd3 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 28 Aug 2023 13:26:43 +0200 Subject: [PATCH 376/518] Fix inspection problems --- .../saveactions/core/component/Engine.java | 23 +++++++++---------- .../core/service/SaveActionsService.java | 5 ++-- .../xdev/saveactions/model/ActionType.java | 5 +--- .../processors/BuildProcessor.java | 11 ++++----- .../CustomAccessCanBeTightenedInspection.java | 4 ++-- .../xdev/saveactions/ui/BuildPanel.java | 11 ++++----- .../xdev/saveactions/ui/Configuration.java | 11 ++++----- .../integration/IntegrationTest.java | 13 +++++------ .../xdev/saveactions/junit/JUnit5Utils.java | 6 ++--- .../saveactions/model/java/EpfKeyTest.java | 4 +--- 10 files changed, 40 insertions(+), 53 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java index e73b723..0fd7315 100644 --- a/src/main/java/software/xdev/saveactions/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -1,13 +1,5 @@ package software.xdev.saveactions.core.component; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.core.service.SaveActionsService; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.model.Storage; -import software.xdev.saveactions.processors.Processor; -import software.xdev.saveactions.processors.Result; -import software.xdev.saveactions.processors.ResultCode; -import software.xdev.saveactions.processors.SaveCommand; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -17,6 +9,14 @@ import com.intellij.psi.PsiFile; import com.intellij.util.PsiErrorElementUtil; import org.jetbrains.annotations.NotNull; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; +import software.xdev.saveactions.processors.Processor; +import software.xdev.saveactions.processors.Result; +import software.xdev.saveactions.processors.ResultCode; +import software.xdev.saveactions.processors.SaveCommand; import java.util.AbstractMap.SimpleEntry; import java.util.List; @@ -26,7 +26,6 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; /** @@ -83,7 +82,7 @@ private void processPsiFiles(Project project, Set psiFiles, ExecutionMo .map(processor -> processor.getSaveCommand(project, psiFiles)) .filter(command -> storage.isEnabled(command.getAction())) .filter(command -> command.getModes().contains(mode)) - .collect(toList()); + .toList(); LOGGER.info(String.format("Filtered processors %s", processorsEligible)); if (!processorsEligible.isEmpty()) { PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); @@ -93,10 +92,10 @@ private void processPsiFiles(Project project, Set psiFiles, ExecutionMo .filter(Objects::nonNull) .peek(command -> LOGGER.info(String.format("Execute command %s on %d files", command, psiFiles.size()))) .map(command -> new SimpleEntry<>(command.getAction(), command.execute())) - .collect(toList()); + .toList(); LOGGER.info(String.format("Exit engine with results %s", results.stream() .map(entry -> entry.getKey() + ":" + entry.getValue()) - .collect(toList()))); + .toList())); } private boolean isPsiFileEligible(Project project, PsiFile psiFile) { diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java index 8353b2a..7419959 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java @@ -1,11 +1,11 @@ package software.xdev.saveactions.core.service; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.components.Service; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; import java.util.List; import java.util.Set; @@ -14,7 +14,6 @@ * This interface is implemented by all SaveAction ApplicationServices. It is used to be able to override * a concrete implementation. Also, it has to be annotated with {@link Service}. */ -@Service public interface SaveActionsService { void guardedProcessPsiFiles(Project project, Set psiFiles, Action activation, ExecutionMode mode); diff --git a/src/main/java/software/xdev/saveactions/model/ActionType.java b/src/main/java/software/xdev/saveactions/model/ActionType.java index e956980..f7a9c45 100644 --- a/src/main/java/software/xdev/saveactions/model/ActionType.java +++ b/src/main/java/software/xdev/saveactions/model/ActionType.java @@ -8,8 +8,5 @@ public enum ActionType { build, - java, - - ; - + java } diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index cd47a19..56218e8 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -1,8 +1,5 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; -import software.xdev.saveactions.model.Action; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.HotSwapUI; @@ -15,6 +12,9 @@ import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; import java.util.Arrays; import java.util.EnumSet; @@ -24,11 +24,10 @@ import java.util.function.BiFunction; import java.util.stream.Stream; -import static software.xdev.saveactions.utils.Helper.toVirtualFiles; import static com.intellij.openapi.actionSystem.ActionPlaces.UNKNOWN; import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR; import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT; -import static java.util.stream.Collectors.toList; +import static software.xdev.saveactions.utils.Helper.toVirtualFiles; /** * Available processors for build. @@ -61,7 +60,7 @@ public enum BuildProcessor implements Processor { List actionIds = SaveActionsServiceManager.getService().getQuickLists(project).stream() .flatMap(quickList -> Arrays.stream(quickList.getActionIds())) - .collect(toList()); + .toList(); for (String actionId : actionIds) { AnAction anAction = actionManager.getAction(actionId); diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java index c8030ea..8a37960 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java @@ -70,9 +70,9 @@ import java.util.concurrent.atomic.AtomicInteger; /** - * A public version of {@link AccessCanBeTightenedInspection}. + * A public version of {@link com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection}. * - * @implNote This is a 1 to 1 copy of {@link AccessCanBeTightenedInspection}. + * @implNote This is a 1 to 1 copy of {@link com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection}. *

    * Copy pasting is required because when extending the following error is thrown error: * class com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection cannot access its superclass diff --git a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java index bf09793..a2fad2e 100644 --- a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java @@ -1,12 +1,12 @@ package software.xdev.saveactions.ui; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; -import software.xdev.saveactions.model.Action; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; import com.intellij.openapi.ui.ComboBox; import com.intellij.ui.IdeBorderFactory; import org.jdesktop.swingx.combobox.ListComboBoxModel; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; import javax.swing.Box; import javax.swing.BoxLayout; @@ -23,12 +23,11 @@ import java.util.List; import java.util.Map; +import static java.text.MessageFormat.format; +import static java.util.Comparator.comparing; import static software.xdev.saveactions.model.Action.compile; import static software.xdev.saveactions.model.Action.executeAction; import static software.xdev.saveactions.model.Action.reload; -import static java.text.MessageFormat.format; -import static java.util.Comparator.comparing; -import static java.util.stream.Collectors.toList; class BuildPanel { @@ -68,7 +67,7 @@ void update() { .stream(QuickListsManager.getInstance().getAllQuickLists()) .map(QuickListWrapper::new) .sorted(comparing(QuickListWrapper::toString)) - .collect(toList()); + .toList(); quickListElements.clear(); quickListElements.addAll(quickListWrappers); if (!quickLists.isEmpty()) { diff --git a/src/main/java/software/xdev/saveactions/ui/Configuration.java b/src/main/java/software/xdev/saveactions/ui/Configuration.java index a6108bf..6c9d641 100644 --- a/src/main/java/software/xdev/saveactions/ui/Configuration.java +++ b/src/main/java/software/xdev/saveactions/ui/Configuration.java @@ -1,14 +1,14 @@ package software.xdev.saveactions.ui; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; import software.xdev.saveactions.model.Action; import software.xdev.saveactions.model.Storage; import software.xdev.saveactions.model.java.EpfStorage; import software.xdev.saveactions.ui.java.IdeSupportPanel; import software.xdev.saveactions.ui.java.InspectionPanel; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.Nullable; import javax.swing.Box; import javax.swing.BoxLayout; @@ -260,10 +260,9 @@ private void updateCheckboxEnabledIfActiveSelected() { } private void updateCheckboxGroupExclusive(ActionEvent event, Action checkbox1, Action checkbox2) { - if (event == null || !(event.getSource() instanceof JCheckBox)) { + if (event == null || !(event.getSource() instanceof JCheckBox thisCheckbox)) { return; } - JCheckBox thisCheckbox = (JCheckBox) event.getSource(); if (thisCheckbox.isSelected()) { if (thisCheckbox == checkboxes.get(checkbox1)) { checkboxes.get(checkbox2).setSelected(false); diff --git a/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java index dc9b934..0c933d0 100644 --- a/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java @@ -1,11 +1,5 @@ package software.xdev.saveactions.integration; -import software.xdev.saveactions.core.action.BatchActionConstants; -import software.xdev.saveactions.core.action.ShortcutActionConstants; -import software.xdev.saveactions.core.component.SaveActionManagerConstants; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; -import software.xdev.saveactions.junit.JUnit5Utils; -import software.xdev.saveactions.model.Storage; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; @@ -13,11 +7,16 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; +import software.xdev.saveactions.core.action.BatchActionConstants; +import software.xdev.saveactions.core.action.ShortcutActionConstants; +import software.xdev.saveactions.core.component.SaveActionManagerConstants; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.junit.JUnit5Utils; +import software.xdev.saveactions.model.Storage; import java.nio.file.Path; import java.nio.file.Paths; -import static software.xdev.saveactions.junit.JUnit5Utils.rethrowAsJunit5Error; import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; public abstract class IntegrationTest { diff --git a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java index 428b7e8..4b8edb2 100644 --- a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java +++ b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java @@ -12,10 +12,8 @@ private JUnit5Utils() { } public static void rethrowAsJunit5Error(AssertionError error) { - if (error.getCause() instanceof InvocationTargetException) { - InvocationTargetException intellijInternal = (InvocationTargetException) error.getCause(); - if (intellijInternal.getCause() instanceof FileComparisonFailure) { - FileComparisonFailure fileComparisonFailure = ((FileComparisonFailure) intellijInternal.getCause()); + if (error.getCause() instanceof InvocationTargetException intellijInternal) { + if (intellijInternal.getCause() instanceof FileComparisonFailure fileComparisonFailure) { String expected = fileComparisonFailure.getExpected(); String actual = fileComparisonFailure.getActual(); throw new AssertionFailedError("Expected file do not match actual file", expected, actual); diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java index be08355..43388ca 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java @@ -5,7 +5,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.List; -import java.util.Map; import java.util.Properties; import static java.util.stream.Collectors.toList; @@ -46,8 +45,7 @@ private void assertPropertyPresenceInEpf(Properties properties) { } private List getPropertiesKeyNames(Properties properties) { - return properties.entrySet().stream() - .map(Map.Entry::getKey) + return properties.keySet().stream() .map(Object::toString) .filter(key -> EpfKey.getPrefixes().stream().anyMatch(key::startsWith)) .map(key -> key.substring(key.lastIndexOf(".") == -1 ? 0 : key.lastIndexOf(".") + 1)) From 28f7f2c864db61c69ac48b5905788825849d4e1e Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 28 Aug 2023 13:29:38 +0200 Subject: [PATCH 377/518] Set sinceBuild 231 This makes Android Studio (which hangs 1-2 versions behind) compatible with the plugin --- build.gradle | 2 +- gradle.properties | 2 +- src/main/resources/META-INF/plugin.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 8b8271a..10e4b96 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,7 @@ intellij { listProductsReleases { - sinceBuild = "232.*" + sinceBuild = "231.*" } // JAVA compatibility diff --git a/gradle.properties b/gradle.properties index 185097e..2e741b3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ pluginName=Save Actions - XDEV Edition pluginVersion=1.0.3-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC -platformVersion=2023.2 +platformVersion=2023.1 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 platformPlugins=java diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 8e4c49c..8dd3a27 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,7 +19,7 @@ - + com.intellij.modules.java From 295bac584d883fb65cb2e74c77daf7cf594b7764 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 28 Aug 2023 13:30:49 +0200 Subject: [PATCH 378/518] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd2caaa..9d03903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,11 @@ ## 1.0.3 * Fixed problem in combination with Qodana plugin #25 +* Improved compatibility and cleaned up code ## 1.0.2 -* Fixed missing display name which causes an error when multiple configureable plugins are installed #20 +* Fixed missing display name which causes an error when multiple configurable plugins are installed #20 ## 1.0.1 -* Updated to ``IntelliJ Platform`` ``232`` (2023.2) for compatibility reasons * Fixed ``Change visibility of field or method to lower access`` not working #14 ## 1.0.0 From b198f162444c957a2e7ffe72f6d7d7c94023404b Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 28 Aug 2023 12:09:00 +0000 Subject: [PATCH 379/518] Release 1.0.3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2e741b3..19951dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.3-SNAPSHOT +pluginVersion=1.0.3 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From fd6acec59ecc9c961af4e5f058a0a46bc7f3dc05 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 28 Aug 2023 12:11:47 +0000 Subject: [PATCH 380/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 19951dc..4cd9bda 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.3 +pluginVersion=1.0.4-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From 057dd74beeacfc1b1efd0a9cee3609f0e26d0ec7 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 28 Aug 2023 14:15:46 +0200 Subject: [PATCH 381/518] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d03903..75d9be0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.0.3 * Fixed problem in combination with Qodana plugin #25 -* Improved compatibility and cleaned up code +* Improved compatibility and cleaned up code #27 ## 1.0.2 * Fixed missing display name which causes an error when multiple configurable plugins are installed #20 From c67fe6e467962d7c84b73948379b81c0334187f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 01:07:58 +0000 Subject: [PATCH 382/518] Bump org.sonarqube from 4.3.0.3225 to 4.3.1.3277 Bumps org.sonarqube from 4.3.0.3225 to 4.3.1.3277. --- updated-dependencies: - dependency-name: org.sonarqube dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 10e4b96..29068cb 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java' id 'idea' id 'org.jetbrains.intellij' version '1.15.0' - id 'org.sonarqube' version '4.3.0.3225' + id 'org.sonarqube' version '4.3.1.3277' } def properties(String key) { From 2909bf49ccc2c41bd7ac4685b942f3f056ed6d24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 06:50:31 +0000 Subject: [PATCH 383/518] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/checkBuild.yml | 2 +- .github/workflows/release.yml | 8 ++++---- .github/workflows/sonar.yml | 2 +- .github/workflows/test-deploy.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 2887624..38ceec8 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -21,7 +21,7 @@ jobs: distribution: [temurin] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 094ac93..e68b54b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ jobs: check_code: # Validates the code runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v3 @@ -48,7 +48,7 @@ jobs: outputs: upload_url: ${{ steps.create_release.outputs.upload_url }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Configure Git run: | @@ -100,7 +100,7 @@ jobs: runs-on: ubuntu-latest needs: [prepare_release] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v3 @@ -133,7 +133,7 @@ jobs: runs-on: ubuntu-latest needs: [publish] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Init Git and pull run: | diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 23b666f..fbd4290 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -26,7 +26,7 @@ jobs: # Dependabot PRs have no access to secrets (SONAR_TOKEN) -> Ignore them if: ${{ github.event_name != 'pull_request' || !startsWith(github.head_ref, 'dependabot/') }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index 49a93d2..a78e4d6 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -10,7 +10,7 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v3 From 021ea2729a560d4b8297a1b5f081ed8b5372f02b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Sep 2023 00:37:16 +0000 Subject: [PATCH 384/518] Bump org.sonarqube from 4.3.1.3277 to 4.4.0.3356 Bumps org.sonarqube from 4.3.1.3277 to 4.4.0.3356. --- updated-dependencies: - dependency-name: org.sonarqube dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 29068cb..ca81d3f 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java' id 'idea' id 'org.jetbrains.intellij' version '1.15.0' - id 'org.sonarqube' version '4.3.1.3277' + id 'org.sonarqube' version '4.4.0.3356' } def properties(String key) { From 4f38ca11e383defee9543488cbe649df36209c83 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 2 Oct 2023 09:49:20 +0200 Subject: [PATCH 385/518] Fixed plugin Icon being not displayed Fixes #35 Minified with https://jakearchibald.github.io/svgomg/ and added ``viewBox`` --- src/main/resources/META-INF/pluginIcon.svg | 89 +++---------------- .../resources/META-INF/pluginIcon_dark.svg | 89 +++---------------- 2 files changed, 22 insertions(+), 156 deletions(-) diff --git a/src/main/resources/META-INF/pluginIcon.svg b/src/main/resources/META-INF/pluginIcon.svg index 66fbca3..4969ded 100644 --- a/src/main/resources/META-INF/pluginIcon.svg +++ b/src/main/resources/META-INF/pluginIcon.svg @@ -1,81 +1,14 @@ - - - - - - image/svg+xml - - - - - - - - - + + + + + + - - - - - - - - + + + + + diff --git a/src/main/resources/META-INF/pluginIcon_dark.svg b/src/main/resources/META-INF/pluginIcon_dark.svg index 3c393b7..7a6ad1e 100644 --- a/src/main/resources/META-INF/pluginIcon_dark.svg +++ b/src/main/resources/META-INF/pluginIcon_dark.svg @@ -1,81 +1,14 @@ - - - - - - image/svg+xml - - - - - - - - - + + + + + + - - - - - - - - + + + + + From 5ce6e1207fb77069d411f6fb71ad257b3ab99631 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 2 Oct 2023 09:50:16 +0200 Subject: [PATCH 386/518] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75d9be0..be3e1f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.4 +* Fixed pluginIcon being not displayed #35 + ## 1.0.3 * Fixed problem in combination with Qodana plugin #25 * Improved compatibility and cleaned up code #27 From a4cb916c0831f439e4010eade93e6d1dc8c17d9e Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 2 Oct 2023 10:45:13 +0200 Subject: [PATCH 387/518] Improve support of Android studio Fixes #27 --- build.gradle | 2 +- src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ca81d3f..eb13298 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,7 @@ intellij { listProductsReleases { - sinceBuild = "231.*" + sinceBuild = "223.*" } // JAVA compatibility diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 8dd3a27..9119dd3 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,7 +19,7 @@ - + com.intellij.modules.java From 07fb29f37550411179fe89c8cc6455a213dcb42d Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 2 Oct 2023 10:46:39 +0200 Subject: [PATCH 388/518] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be3e1f4..ff1b178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 1.0.4 * Fixed pluginIcon being not displayed #35 +* Improved support of Android Studio (until a 2023 version is released) #27 ## 1.0.3 * Fixed problem in combination with Qodana plugin #25 From e6467df30b09fd3ea69aaba6ca86168cffac8f31 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 2 Oct 2023 08:59:00 +0000 Subject: [PATCH 389/518] Release 1.0.4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 4cd9bda..cc6fe26 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.4-SNAPSHOT +pluginVersion=1.0.4 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From f323327887731c9d5b19deb3e3ad964f11ee662d Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 2 Oct 2023 09:01:13 +0000 Subject: [PATCH 390/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index cc6fe26..89af99d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.4 +pluginVersion=1.0.5-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From 15d8bec0310201539a26e9674fed52109dc7edd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:27:22 +0000 Subject: [PATCH 391/518] Bump org.sonarqube from 4.4.0.3356 to 4.4.1.3373 Bumps org.sonarqube from 4.4.0.3356 to 4.4.1.3373. --- updated-dependencies: - dependency-name: org.sonarqube dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index eb13298..e21a91d 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java' id 'idea' id 'org.jetbrains.intellij' version '1.15.0' - id 'org.sonarqube' version '4.4.0.3356' + id 'org.sonarqube' version '4.4.1.3373' } def properties(String key) { From 805b9ba27a3e4dfc61a0f1ddeeb69ad8536ccbe0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 00:29:01 +0000 Subject: [PATCH 392/518] Bump org.jetbrains.intellij from 1.15.0 to 1.16.0 Bumps org.jetbrains.intellij from 1.15.0 to 1.16.0. --- updated-dependencies: - dependency-name: org.jetbrains.intellij dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e21a91d..4658357 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.15.0' + id 'org.jetbrains.intellij' version '1.16.0' id 'org.sonarqube' version '4.4.1.3373' } From dde875a453778614e1477c7a16e130c8b6cdd940 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:32:48 +0000 Subject: [PATCH 393/518] Bump org.junit:junit-bom from 5.10.0 to 5.10.1 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.10.0 to 5.10.1. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.0...r5.10.1) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4658357..4ae9474 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { // Add dependencies to test, junit5 api (annotations) and engine (runtime) dependencies { - testImplementation platform('org.junit:junit-bom:5.10.0'), + testImplementation platform('org.junit:junit-bom:5.10.1'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', 'org.assertj:assertj-core:3.24.2' From 18f5a597c6d684d2ef9ad4e01c712d3194aeeb28 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 6 Nov 2023 08:29:22 +0100 Subject: [PATCH 394/518] Update gradle wrapper to latest version --- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 62076 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 22 +++++++++++++--------- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/gradle.properties b/gradle.properties index 89af99d..05c84c6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ platformVersion=2023.1 # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 platformPlugins=java # Gradle Releases -> https://github.com/gradle/gradle/releases -gradleVersion=8.1.1 +gradleVersion=8.4 # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html org.gradle.configuration-cache=true # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a79e29d3e0ab67b14947c167a862655af9b..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644 GIT binary patch delta 37652 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 delta 36122 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 Ac-xW1# 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 Q>rd#Eb%7 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37aef8d..744c64d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cb..1aa94a4 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ From bbc28fd803569ed116570ea7d565e77b8e08a981 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 6 Nov 2023 08:38:30 +0100 Subject: [PATCH 395/518] Remove unused inspection code --- ...ableHasSerialVersionUIDFieldInspectionWrapper.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java index a69d6d0..891c572 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java @@ -1,8 +1,8 @@ package software.xdev.saveactions.processors.java.inspection; -import software.xdev.saveactions.core.service.SaveActionsService; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.openapi.diagnostic.Logger; +import software.xdev.saveactions.core.service.SaveActionsService; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; @@ -31,11 +31,7 @@ public static LocalInspectionTool get() { private enum SerializableClass { CLASS_NAME_INTELLIJ_2021_3("com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection", - "software.xdev.saveactions.processors.java.inspection.CustomSerializableHasSerialVersionUidFieldInspection"), - CLASS_NAME_INTELLIJ_2018_3("com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspection", - "com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspection"), - CLASS_NAME_INTELLIJ_2016("com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspectionBase", - "com.siyeh.ig.serialization.SerializableHasSerialVersionUIDFieldInspectionBase"); + "software.xdev.saveactions.processors.java.inspection.CustomSerializableHasSerialVersionUidFieldInspection"); /** * Field className: Inspection class provided by IDE @@ -61,7 +57,8 @@ public LocalInspectionTool getInspectionInstance() { Class.forName(targetClass).asSubclass(LocalInspectionTool.class); LOGGER.info(String.format("Found serial version uid class %s", targetInspectionClass.getName())); return targetInspectionClass.cast(targetInspectionClass.getDeclaredConstructor().newInstance()); - } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException + | InvocationTargetException e) { return null; } } From dc4802331b0408686ee3134702622dc6a38d7103 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 6 Nov 2023 08:54:13 +0100 Subject: [PATCH 396/518] Simplify code --- .../CustomSerializableHasSerialVersionUidFieldInspection.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java index b90630f..72c3e9c 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java @@ -19,10 +19,9 @@ */ public class CustomSerializableHasSerialVersionUidFieldInspection extends USerializableInspectionBase { - @SuppressWarnings("unchecked") public CustomSerializableHasSerialVersionUidFieldInspection() { - super(new Class[]{UClass.class}); + super(UClass.class); } @Override From ee686625f5696108a13ff1f939815341747e855d Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 6 Nov 2023 09:11:41 +0100 Subject: [PATCH 397/518] Moved ``CustomUnqualifiedStaticUsageInspection`` into correct package Fixes #25 --- CHANGELOG.md | 3 +++ .../processors/java/JavaProcessor.java | 16 ++++++++-------- .../CustomUnqualifiedStaticUsageInspection.java | 4 +++- 3 files changed, 14 insertions(+), 9 deletions(-) rename src/main/java/software/xdev/saveactions/processors/java/inspection/{ => style}/CustomUnqualifiedStaticUsageInspection.java (95%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff1b178..70f6f0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.5 +* Fixed ``Add class qualifier to static member access outside declaring class`` not working in combination with Qodana plugin #25 + ## 1.0.4 * Fixed pluginIcon being not displayed #35 * Improved support of Android Studio (until a 2023 version is released) #27 diff --git a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java index 524ffbb..0239901 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java @@ -1,14 +1,7 @@ package software.xdev.saveactions.processors.java; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.processors.Processor; -import software.xdev.saveactions.processors.SaveWriteCommand; -import software.xdev.saveactions.processors.java.inspection.CustomLocalCanBeFinal; -import software.xdev.saveactions.processors.java.inspection.SerializableHasSerialVersionUIDFieldInspectionWrapper; import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection; import com.intellij.codeInspection.LocalInspectionTool; -import software.xdev.saveactions.processors.java.inspection.CustomAccessCanBeTightenedInspection; import com.intellij.codeInspection.visibility.VisibilityInspection; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; @@ -17,7 +10,6 @@ import com.siyeh.ig.maturity.SuppressionAnnotationInspection; import com.siyeh.ig.performance.MethodMayBeStaticInspection; import com.siyeh.ig.style.ControlFlowStatementWithoutBracesInspection; -import software.xdev.saveactions.processors.java.inspection.CustomUnqualifiedStaticUsageInspection; import com.siyeh.ig.style.FieldMayBeFinalInspection; import com.siyeh.ig.style.SingleStatementInBlockInspection; import com.siyeh.ig.style.UnnecessaryFinalOnLocalVariableOrParameterInspection; @@ -26,6 +18,14 @@ import com.siyeh.ig.style.UnqualifiedFieldAccessInspection; import com.siyeh.ig.style.UnqualifiedMethodAccessInspection; import com.siyeh.ig.style.UnqualifiedStaticUsageInspection; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.processors.Processor; +import software.xdev.saveactions.processors.SaveWriteCommand; +import software.xdev.saveactions.processors.java.inspection.CustomAccessCanBeTightenedInspection; +import software.xdev.saveactions.processors.java.inspection.CustomLocalCanBeFinal; +import software.xdev.saveactions.processors.java.inspection.SerializableHasSerialVersionUIDFieldInspectionWrapper; +import software.xdev.saveactions.processors.java.inspection.style.CustomUnqualifiedStaticUsageInspection; import java.util.Arrays; import java.util.EnumSet; diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java similarity index 95% rename from src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java rename to src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java index b585d8f..53ad808 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomUnqualifiedStaticUsageInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java @@ -1,4 +1,4 @@ -package software.xdev.saveactions.processors.java.inspection; +package software.xdev.saveactions.processors.java.inspection.style; import com.intellij.psi.JavaResolveResult; import com.intellij.psi.PsiClass; @@ -23,6 +23,8 @@ /** * Copy pasting because: cannot extend. Do not reformat (useful for diffs) * + * @implNote Class needs to be inside a special package otherwise name resolution fails as seen in + * {@link com.siyeh.ig.GroupDisplayNameUtil} * @see com.siyeh.ig.style.UnqualifiedStaticUsageInspection.UnqualifiedStaticCallVisitor */ public class CustomUnqualifiedStaticUsageInspection extends UnqualifiedStaticUsageInspection { From d0fdbd2a1f38020a6a63128753f8d89a62103242 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 6 Nov 2023 08:30:08 +0000 Subject: [PATCH 398/518] Release 1.0.5 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 05c84c6..ad584ea 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.5-SNAPSHOT +pluginVersion=1.0.5 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From 3371e1cad6e54def85627b62ff24788876098b1a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 6 Nov 2023 08:32:45 +0000 Subject: [PATCH 399/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ad584ea..cbd3817 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.0.5 +pluginVersion=1.0.6-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From bbc739454945f7d19fcdc15ab2023dc0c2be03be Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 6 Nov 2023 09:35:54 +0100 Subject: [PATCH 400/518] Update release.yml Fix naming --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e68b54b..9be8030 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -126,7 +126,7 @@ jobs: - name: Upload plugin files uses: actions/upload-artifact@v3 with: - name: plugin-files-java-${{ matrix.java }} + name: plugin-files path: build/distributions/* after_release: From c0c266ffd07e0b9c54f6664d140c22f8cc37ff3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 00:48:46 +0000 Subject: [PATCH 401/518] Bump actions/setup-java from 3 to 4 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3 to 4. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-java dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/checkBuild.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/sonar.yml | 2 +- .github/workflows/test-deploy.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 38ceec8..e71de1b 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: ${{ matrix.distribution }} java-version: ${{ matrix.java }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9be8030..4514b7e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' @@ -103,7 +103,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 17 diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index fbd4290..9d9d6a2 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -31,7 +31,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 17 diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index a78e4d6..9da9eb5 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: 17 From 89a4e473fe2b78d9fe5b2df8572949bc67046b89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 01:04:37 +0000 Subject: [PATCH 402/518] Bump org.jetbrains.intellij from 1.16.0 to 1.16.1 Bumps org.jetbrains.intellij from 1.16.0 to 1.16.1. --- updated-dependencies: - dependency-name: org.jetbrains.intellij dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4ae9474..d8d174a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.16.0' + id 'org.jetbrains.intellij' version '1.16.1' id 'org.sonarqube' version '4.4.1.3373' } From 2f90407a6b1fff7efffab79b470640846f317416 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:20:00 +0000 Subject: [PATCH 403/518] Bump actions/upload-artifact from 3 to 4 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/checkBuild.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test-deploy.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 38ceec8..bf4bbed 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -52,7 +52,7 @@ jobs: fi - name: Upload plugin files - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: plugin-files-java-${{ matrix.java }} path: build/libs/intellij-plugin-save-actions-*.jar diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9be8030..27fd11a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -124,7 +124,7 @@ jobs: run: ./gradlew publishPlugin --info --stacktrace - name: Upload plugin files - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: plugin-files path: build/distributions/* diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml index a78e4d6..4d82517 100644 --- a/.github/workflows/test-deploy.yml +++ b/.github/workflows/test-deploy.yml @@ -38,7 +38,7 @@ jobs: run: ./gradlew publishPlugin --info --stacktrace - name: Upload plugin files - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: plugin-files-java-${{ matrix.java }} path: build/distributions/* From aad86ea98b735fbaf91283add0928c882ca90bb2 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Fri, 22 Dec 2023 12:53:54 +0100 Subject: [PATCH 404/518] Check if compilation works with Java 21 --- .github/workflows/checkBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 6a0e481..5838c65 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: - java: [17] + java: [17, 21] distribution: [temurin] steps: From 33df169f932c862f0ca041e25bad4cd13da3ccec Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:24:47 +0100 Subject: [PATCH 405/518] Upload test reports --- .github/workflows/checkBuild.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 5838c65..d1539bf 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -32,6 +32,13 @@ jobs: - name: Build run: ./gradlew build buildPlugin --info + + - name: Try upload test reports when failure occurs + uses: actions/upload-artifact@v4 + if: failure() + with: + name: intellij-plugin-save-actions-test-reports + path: intellij-plugin-save-actions/build/reports/tests/test/** - name: Check for uncommited changes run: | From 3e74c37da07a90d8d2459eefcb914ec3d0eb97a2 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:29:35 +0100 Subject: [PATCH 406/518] Fix test reports path --- .github/workflows/checkBuild.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index d1539bf..d07e91d 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -37,8 +37,8 @@ jobs: uses: actions/upload-artifact@v4 if: failure() with: - name: intellij-plugin-save-actions-test-reports - path: intellij-plugin-save-actions/build/reports/tests/test/** + name: test-reports + path: build/reports/tests/test/** - name: Check for uncommited changes run: | From a60c1fd9e29abfabc7d7b3dba4283412ed4e7578 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 11 Jan 2024 08:35:41 +0100 Subject: [PATCH 407/518] Update gradle --- gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 744c64d..3499ded 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From f2f683eeaa8294404e828e987dbc2a7274190970 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:36:03 +0100 Subject: [PATCH 408/518] Include Java Version in test report name --- .github/workflows/checkBuild.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index d07e91d..0cd547b 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -37,7 +37,7 @@ jobs: uses: actions/upload-artifact@v4 if: failure() with: - name: test-reports + name: test-reports-${{ matrix.java }} path: build/reports/tests/test/** - name: Check for uncommited changes From feee51b7ad420663f30f5111df6f0a4c28d2d2f7 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 11 Jan 2024 08:50:13 +0100 Subject: [PATCH 409/518] Java Version needs to be set also for test classes compilation --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d8d174a..c79da92 100644 --- a/build.gradle +++ b/build.gradle @@ -57,8 +57,10 @@ listProductsReleases { sinceBuild = "223.*" } -// JAVA compatibility -compileJava { +// Configure compileJava AND compileTestJava +// https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html +tasks.withType(JavaCompile).configureEach { + // JAVA compatibility sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } From 845a6037c352124b49e8ad535ed5e6879a44e53c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 07:53:11 +0000 Subject: [PATCH 410/518] Bump org.assertj:assertj-core from 3.24.2 to 3.25.1 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.24.2 to 3.25.1. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.24.2...assertj-build-3.25.1) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c79da92..5b9c096 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { testImplementation platform('org.junit:junit-bom:5.10.1'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', - 'org.assertj:assertj-core:3.24.2' + 'org.assertj:assertj-core:3.25.1' testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") } From 826484f1540d16752963748689875d49d222fa8b Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:56:10 +0100 Subject: [PATCH 411/518] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70f6f0d..bb872e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.0.6 +* Allow compilation with Java 21 + ## 1.0.5 * Fixed ``Add class qualifier to static member access outside declaring class`` not working in combination with Qodana plugin #25 From ca8a515c212854aa636227b31eee6ba727dbf215 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 00:18:46 +0000 Subject: [PATCH 412/518] Bump org.assertj:assertj-core from 3.25.1 to 3.25.3 Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.25.1 to 3.25.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.25.1...assertj-build-3.25.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5b9c096..18395b0 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { testImplementation platform('org.junit:junit-bom:5.10.1'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', - 'org.assertj:assertj-core:3.25.1' + 'org.assertj:assertj-core:3.25.3' testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") } From 208c9276fd3ebb039c684ed617c099b47ad62a61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 00:18:49 +0000 Subject: [PATCH 413/518] Bump org.junit:junit-bom from 5.10.1 to 5.10.2 Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.10.1 to 5.10.2. - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.1...r5.10.2) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5b9c096..19e656d 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ repositories { // Add dependencies to test, junit5 api (annotations) and engine (runtime) dependencies { - testImplementation platform('org.junit:junit-bom:5.10.1'), + testImplementation platform('org.junit:junit-bom:5.10.2'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', 'org.assertj:assertj-core:3.25.1' From 19a2198e984d14bdc7fbf813d050671e029c5518 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 00:19:16 +0000 Subject: [PATCH 414/518] Bump org.jetbrains.intellij from 1.16.1 to 1.17.1 Bumps org.jetbrains.intellij from 1.16.1 to 1.17.1. --- updated-dependencies: - dependency-name: org.jetbrains.intellij dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5b9c096..c224b6b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.16.1' + id 'org.jetbrains.intellij' version '1.17.1' id 'org.sonarqube' version '4.4.1.3373' } From 0156c238de618e437902ce06d2bd6b4990bc85ba Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 12:39:40 +0100 Subject: [PATCH 415/518] Removed "suppressAnnotation" * This option never worked #64 * Allows usage of the plugin with IntelliJ Idea 2024+ #63 * Bump version --- CHANGELOG.md | 6 +++++- gradle.properties | 2 +- src/main/java/software/xdev/saveactions/model/Action.java | 5 +---- .../java/software/xdev/saveactions/model/Storage.java | 7 +++++++ .../xdev/saveactions/processors/java/JavaProcessor.java | 4 ---- .../xdev/saveactions/integration/JavaIntegrationTest.java | 8 -------- 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb872e7..f54e897 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -## 1.0.6 +## 1.1.0 +* Removed "Remove unused suppress warning annotation" + * This option never worked #64 + * Allows usage of the plugin with IntelliJ Idea 2024+ #63 + * If you used this option you should remove the line `` - + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 3343d31..21e0aff 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,12 +1,99 @@ - - + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml index 19681fa..79ee123 100644 --- a/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -1,99 +1,5 @@ - - - + + + \ No newline at end of file diff --git a/src/main/java/software/xdev/saveactions/core/ExecutionMode.java b/src/main/java/software/xdev/saveactions/core/ExecutionMode.java index b03415c..360a4d4 100644 --- a/src/main/java/software/xdev/saveactions/core/ExecutionMode.java +++ b/src/main/java/software/xdev/saveactions/core/ExecutionMode.java @@ -3,31 +3,32 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; -public enum ExecutionMode { - - /** - * When the plugin is called normally (the IDE calls the plugin component on frame deactivation or "save all"). The - * {@link #saveSingle} is also called on every document. - * - * @see FileDocumentManager#saveAllDocuments() - */ - saveAll, - - /** - * When the plugin is called only with a single save (some other plugins like ideavim do that). - * - * @see FileDocumentManager#saveDocument(Document) - */ - saveSingle, - - /** - * When the plugin is called in batch mode (the IDE calls the plugin after a file selection popup). - */ - batch, - - /** - * When the plugin is called from a user input shortcut. - */ - shortcut, +public enum ExecutionMode +{ + + /** + * When the plugin is called normally (the IDE calls the plugin component on frame deactivation or "save all"). The + * {@link #saveSingle} is also called on every document. + * + * @see FileDocumentManager#saveAllDocuments() + */ + saveAll, + + /** + * When the plugin is called only with a single save (some other plugins like ideavim do that). + * + * @see FileDocumentManager#saveDocument(Document) + */ + saveSingle, + + /** + * When the plugin is called in batch mode (the IDE calls the plugin after a file selection popup). + */ + batch, + + /** + * When the plugin is called from a user input shortcut. + */ + shortcut, } diff --git a/src/main/java/software/xdev/saveactions/core/action/BatchAction.java b/src/main/java/software/xdev/saveactions/core/action/BatchAction.java index 7668808..d65bec8 100644 --- a/src/main/java/software/xdev/saveactions/core/action/BatchAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/BatchAction.java @@ -1,54 +1,59 @@ package software.xdev.saveactions.core.action; -import software.xdev.saveactions.core.service.SaveActionsService; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import static java.util.Collections.synchronizedSet; +import static software.xdev.saveactions.core.ExecutionMode.batch; +import static software.xdev.saveactions.model.Action.activateOnBatch; + +import java.util.HashSet; +import java.util.Set; + +import org.jetbrains.annotations.NotNull; + import com.intellij.analysis.AnalysisScope; import com.intellij.analysis.BaseAnalysisAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.NotNull; -import software.xdev.saveactions.model.Action; -import java.util.HashSet; -import java.util.Set; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; -import static software.xdev.saveactions.core.ExecutionMode.batch; -import static software.xdev.saveactions.model.Action.activateOnBatch; -import static java.util.Collections.synchronizedSet; /** - * This action runs the save actions on the given scope of files, only if property - * {@link Action#activateOnShortcut} is enabled. The user is asked for the scope using a standard - * IDEA dialog. It delegates to {@link SaveActionsService}. Originally based on - * {@link com.intellij.codeInspection.inferNullity.InferNullityAnnotationsAction}. + * This action runs the save actions on the given scope of files, only if property {@link Action#activateOnShortcut} is + * enabled. The user is asked for the scope using a standard IDEA dialog. It delegates to {@link SaveActionsService}. + * Originally based on {@link com.intellij.codeInspection.inferNullity.InferNullityAnnotationsAction}. * * @author markiewb * @see SaveActionsServiceManager */ -public class BatchAction extends BaseAnalysisAction { - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - private static final String COMPONENT_NAME = "Save Actions"; - - public BatchAction() { - super(COMPONENT_NAME, COMPONENT_NAME); - } - - @Override - protected void analyze(@NotNull Project project, @NotNull AnalysisScope scope) { - LOGGER.info("[+] Start BatchAction#analyze with project " + project + " and scope " + scope); - Set psiFiles = synchronizedSet(new HashSet<>()); - scope.accept(new PsiElementVisitor() { - @Override - public void visitFile(PsiFile psiFile) { - super.visitFile(psiFile); - psiFiles.add(psiFile); - } - }); - SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, activateOnBatch, batch); - LOGGER.info("End BatchAction#analyze processed " + psiFiles.size() + " files"); - } - +public class BatchAction extends BaseAnalysisAction +{ + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + private static final String COMPONENT_NAME = "Save Actions"; + + public BatchAction() + { + super(COMPONENT_NAME, COMPONENT_NAME); + } + + @Override + protected void analyze(@NotNull final Project project, @NotNull final AnalysisScope scope) + { + LOGGER.info("[+] Start BatchAction#analyze with project " + project + " and scope " + scope); + final Set psiFiles = synchronizedSet(new HashSet<>()); + scope.accept(new PsiElementVisitor() + { + @Override + public void visitFile(final PsiFile psiFile) + { + super.visitFile(psiFile); + psiFiles.add(psiFile); + } + }); + SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, activateOnBatch, batch); + LOGGER.info("End BatchAction#analyze processed " + psiFiles.size() + " files"); + } } diff --git a/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java b/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java index bfd4b4b..9fc835c 100644 --- a/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ShortcutAction.java @@ -1,41 +1,44 @@ package software.xdev.saveactions.core.action; -import software.xdev.saveactions.core.service.SaveActionsService; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import static com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE; +import static java.util.Collections.singletonList; +import static software.xdev.saveactions.core.ExecutionMode.shortcut; +import static software.xdev.saveactions.model.Action.activateOnShortcut; + +import java.util.HashSet; +import java.util.Set; + +import org.jetbrains.annotations.NotNull; + import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.NotNull; + +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; import software.xdev.saveactions.model.Action; -import java.util.HashSet; -import java.util.Set; - -import static software.xdev.saveactions.core.ExecutionMode.shortcut; -import static software.xdev.saveactions.model.Action.activateOnShortcut; -import static com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE; -import static java.util.Collections.singletonList; /** - * This action runs the plugin on shortcut, only if property {@link Action#activateOnShortcut} is - * enabled. It delegates to {@link SaveActionsService}. + * This action runs the plugin on shortcut, only if property {@link Action#activateOnShortcut} is enabled. It delegates + * to {@link SaveActionsService}. * * @see SaveActionsServiceManager */ -public class ShortcutAction extends AnAction { - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - - @Override - public void actionPerformed(@NotNull AnActionEvent event) { - LOGGER.info("[+] Start ShortcutAction#actionPerformed with event " + event); - PsiFile psiFile = event.getData(PSI_FILE); - Project project = event.getProject(); - Set psiFiles = new HashSet<>(singletonList(psiFile)); - SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, activateOnShortcut, shortcut); - LOGGER.info("End ShortcutAction#actionPerformed processed " + psiFiles.size() + " files"); - } - +public class ShortcutAction extends AnAction +{ + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + + @Override + public void actionPerformed(@NotNull final AnActionEvent event) + { + LOGGER.info("[+] Start ShortcutAction#actionPerformed with event " + event); + final PsiFile psiFile = event.getData(PSI_FILE); + final Project project = event.getProject(); + final Set psiFiles = new HashSet<>(singletonList(psiFile)); + SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, activateOnShortcut, shortcut); + LOGGER.info("End ShortcutAction#actionPerformed processed " + psiFiles.size() + " files"); + } } diff --git a/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java index d086f97..c14f107 100644 --- a/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java @@ -1,35 +1,40 @@ package software.xdev.saveactions.core.action; -import software.xdev.saveactions.model.Storage; +import static software.xdev.saveactions.model.Action.activate; + import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import static software.xdev.saveactions.model.Action.activate; +import software.xdev.saveactions.model.Storage; + /** * This action toggles on and off the plugin, by modifying the underlying storage. */ -public class ToggleAnAction extends ToggleAction implements DumbAware { - - @Override - public boolean isSelected(AnActionEvent event) { - Project project = event.getProject(); - if (project != null) { - Storage storage = project.getService(Storage.class); - return storage.isEnabled(activate); - } - return false; - } - - @Override - public void setSelected(AnActionEvent event, boolean state) { - Project project = event.getProject(); - if (project != null) { - Storage storage = project.getService(Storage.class); - storage.setEnabled(activate, state); - } - } - +public class ToggleAnAction extends ToggleAction implements DumbAware +{ + @Override + public boolean isSelected(final AnActionEvent event) + { + final Project project = event.getProject(); + if(project != null) + { + final Storage storage = project.getService(Storage.class); + return storage.isEnabled(activate); + } + return false; + } + + @Override + public void setSelected(final AnActionEvent event, final boolean state) + { + final Project project = event.getProject(); + if(project != null) + { + final Storage storage = project.getService(Storage.class); + storage.setEnabled(activate, state); + } + } } diff --git a/src/main/java/software/xdev/saveactions/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java index 0fd7315..0dc9a12 100644 --- a/src/main/java/software/xdev/saveactions/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -1,5 +1,17 @@ package software.xdev.saveactions.core.component; +import static java.util.stream.Collectors.toSet; + +import java.util.AbstractMap.SimpleEntry; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.jetbrains.annotations.NotNull; + import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -8,7 +20,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.util.PsiErrorElementUtil; -import org.jetbrains.annotations.NotNull; + import software.xdev.saveactions.core.ExecutionMode; import software.xdev.saveactions.core.service.SaveActionsService; import software.xdev.saveactions.model.Action; @@ -18,203 +30,231 @@ import software.xdev.saveactions.processors.ResultCode; import software.xdev.saveactions.processors.SaveCommand; -import java.util.AbstractMap.SimpleEntry; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -import static java.util.stream.Collectors.toSet; /** * Implementation of the save action engine. This class will filter, process and log modifications to the files. */ -public class Engine { - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - private static final String REGEX_STARTS_WITH_ANY_STRING = ".*?"; - - private final Storage storage; - private final List processors; - private final Project project; - private final Set psiFiles; - private final Action activation; - private final ExecutionMode mode; - - public Engine(Storage storage, - List processors, - Project project, - Set psiFiles, - Action activation, - ExecutionMode mode) { - this.storage = storage; - this.processors = processors; - this.project = project; - this.psiFiles = psiFiles; - this.activation = activation; - this.mode = mode; - } - - public void processPsiFilesIfNecessary() { - if (psiFiles == null) { - return; - } - if (!storage.isEnabled(activation)) { - LOGGER.info(String.format("Action \"%s\" not enabled on %s", activation.getText(), project)); - return; - } - LOGGER.info(String.format("Processing %s files %s mode %s", project, psiFiles, mode)); - Set psiFilesEligible = psiFiles.stream() - .filter(psiFile -> isPsiFileEligible(project, psiFile)) - .collect(toSet()); - LOGGER.info(String.format("Valid files %s", psiFilesEligible)); - processPsiFiles(project, psiFilesEligible, mode); - } - - private void processPsiFiles(Project project, Set psiFiles, ExecutionMode mode) { - if (psiFiles.isEmpty()) { - return; - } - LOGGER.info(String.format("Start processors (%d)", processors.size())); - List processorsEligible = processors.stream() - .map(processor -> processor.getSaveCommand(project, psiFiles)) - .filter(command -> storage.isEnabled(command.getAction())) - .filter(command -> command.getModes().contains(mode)) - .toList(); - LOGGER.info(String.format("Filtered processors %s", processorsEligible)); - if (!processorsEligible.isEmpty()) { - PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); - psiFiles.forEach(psiFile -> commitDocumentAndSave(psiFile, psiDocumentManager)); - } - List>> results = processorsEligible.stream() - .filter(Objects::nonNull) - .peek(command -> LOGGER.info(String.format("Execute command %s on %d files", command, psiFiles.size()))) - .map(command -> new SimpleEntry<>(command.getAction(), command.execute())) - .toList(); - LOGGER.info(String.format("Exit engine with results %s", results.stream() - .map(entry -> entry.getKey() + ":" + entry.getValue()) - .toList())); - } - - private boolean isPsiFileEligible(Project project, PsiFile psiFile) { - return psiFile != null - && isProjectValid(project) - && isPsiFileValid(psiFile) - && isPsiFileFresh(psiFile) - && isPsiFileInProject(project, psiFile) - && isPsiFileNoError(project, psiFile) - && isPsiFileIncluded(psiFile); - } - - private boolean isProjectValid(Project project) { - boolean valid = project.isInitialized() && !project.isDisposed(); - if (!valid) { - LOGGER.info("Project invalid. Either not initialized or disposed."); - } - return valid; - } - - private boolean isPsiFileInProject(Project project, @NotNull PsiFile psiFile) { - boolean inProject = ProjectRootManager.getInstance(project).getFileIndex().isInContent(psiFile.getVirtualFile()); - if (!inProject) { - LOGGER.info(String.format("File %s not in current project %s. File belongs to %s", - psiFile, - project, - psiFile.getProject())); - } - return inProject; - } - - private boolean isPsiFileNoError(Project project, PsiFile psiFile) { - if (storage.isEnabled(Action.noActionIfCompileErrors)) { - boolean hasErrors = PsiErrorElementUtil.hasErrors(project, psiFile.getVirtualFile()); - if (hasErrors) { - LOGGER.info(String.format("File %s has errors", psiFile)); - } - return !hasErrors; - } - return true; - } - - private boolean isPsiFileIncluded(PsiFile psiFile) { - String canonicalPath = psiFile.getVirtualFile().getCanonicalPath(); - return isIncludedAndNotExcluded(canonicalPath); - } - - private boolean isPsiFileFresh(PsiFile psiFile) { - if (mode == ExecutionMode.batch) { - return true; - } - boolean isFresh = psiFile.getModificationStamp() != 0; - if (!isFresh) { - LOGGER.info(String.format("File %s is not fresh.", psiFile)); - } - return isFresh; - } - - private boolean isPsiFileValid(PsiFile psiFile) { - boolean valid = psiFile.isValid(); - if (!valid) { - LOGGER.info(String.format("File %s is not valid.", psiFile)); - } - return valid; - } - - boolean isIncludedAndNotExcluded(String path) { - return isIncluded(path) && !isExcluded(path); - } - - private boolean isExcluded(String path) { - Set exclusions = storage.getExclusions(); - boolean psiFileExcluded = atLeastOneMatch(path, exclusions); - if (psiFileExcluded) { - LOGGER.info(String.format("File %s excluded in %s", path, exclusions)); - } - return psiFileExcluded; - } - - private boolean isIncluded(String path) { - Set inclusions = storage.getInclusions(); - if (inclusions.isEmpty()) { - // If no inclusion are defined, all files are allowed - return true; - } - boolean psiFileIncluded = atLeastOneMatch(path, inclusions); - if (psiFileIncluded) { - LOGGER.info(String.format("File %s included in %s", path, inclusions)); - } - return psiFileIncluded; - } - - private boolean atLeastOneMatch(String psiFileUrl, Set patterns) { - for (String pattern : patterns) { - try { - Matcher matcher = Pattern.compile(REGEX_STARTS_WITH_ANY_STRING + pattern).matcher(psiFileUrl); - if (matcher.matches()) { - return true; - } - } catch (PatternSyntaxException e) { - // invalid patterns are ignored - return false; - } - } - return false; - } - - /** - * Should properly fix #402 according to @krasa's recommendation in #109. - * - * @param psiFile of type PsiFile - * @param psiDocumentManager - */ - private void commitDocumentAndSave(PsiFile psiFile, PsiDocumentManager psiDocumentManager) { - Document document = psiDocumentManager.getDocument(psiFile); - if (document != null) { - psiDocumentManager.doPostponedOperationsAndUnblockDocument(document); - psiDocumentManager.commitDocument(document); - FileDocumentManager.getInstance().saveDocument(document); - } - } +public class Engine +{ + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + private static final String REGEX_STARTS_WITH_ANY_STRING = ".*?"; + + private final Storage storage; + private final List processors; + private final Project project; + private final Set psiFiles; + private final Action activation; + private final ExecutionMode mode; + + public Engine( + final Storage storage, + final List processors, + final Project project, + final Set psiFiles, + final Action activation, + final ExecutionMode mode) + { + this.storage = storage; + this.processors = processors; + this.project = project; + this.psiFiles = psiFiles; + this.activation = activation; + this.mode = mode; + } + + public void processPsiFilesIfNecessary() + { + if(this.psiFiles == null) + { + return; + } + if(!this.storage.isEnabled(this.activation)) + { + LOGGER.info(String.format("Action \"%s\" not enabled on %s", this.activation.getText(), this.project)); + return; + } + LOGGER.info(String.format("Processing %s files %s mode %s", this.project, this.psiFiles, this.mode)); + final Set psiFilesEligible = this.psiFiles.stream() + .filter(psiFile -> this.isPsiFileEligible(this.project, psiFile)) + .collect(toSet()); + LOGGER.info(String.format("Valid files %s", psiFilesEligible)); + this.processPsiFiles(this.project, psiFilesEligible, this.mode); + } + + private void processPsiFiles(final Project project, final Set psiFiles, final ExecutionMode mode) + { + if(psiFiles.isEmpty()) + { + return; + } + LOGGER.info(String.format("Start processors (%d)", this.processors.size())); + final List processorsEligible = this.processors.stream() + .map(processor -> processor.getSaveCommand(project, psiFiles)) + .filter(command -> this.storage.isEnabled(command.getAction())) + .filter(command -> command.getModes().contains(mode)) + .toList(); + LOGGER.info(String.format("Filtered processors %s", processorsEligible)); + if(!processorsEligible.isEmpty()) + { + final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + psiFiles.forEach(psiFile -> this.commitDocumentAndSave(psiFile, psiDocumentManager)); + } + final List>> results = processorsEligible.stream() + .filter(Objects::nonNull) + .peek(command -> LOGGER.info(String.format("Execute command %s on %d files", command, psiFiles.size()))) + .map(command -> new SimpleEntry<>(command.getAction(), command.execute())) + .toList(); + LOGGER.info(String.format("Exit engine with results %s", results.stream() + .map(entry -> entry.getKey() + ":" + entry.getValue()) + .toList())); + } + + private boolean isPsiFileEligible(final Project project, final PsiFile psiFile) + { + return psiFile != null + && this.isProjectValid(project) + && this.isPsiFileValid(psiFile) + && this.isPsiFileFresh(psiFile) + && this.isPsiFileInProject(project, psiFile) + && this.isPsiFileNoError(project, psiFile) + && this.isPsiFileIncluded(psiFile); + } + + private boolean isProjectValid(final Project project) + { + final boolean valid = project.isInitialized() && !project.isDisposed(); + if(!valid) + { + LOGGER.info("Project invalid. Either not initialized or disposed."); + } + return valid; + } + + private boolean isPsiFileInProject(final Project project, @NotNull final PsiFile psiFile) + { + final boolean inProject = + ProjectRootManager.getInstance(project).getFileIndex().isInContent(psiFile.getVirtualFile()); + if(!inProject) + { + LOGGER.info(String.format( + "File %s not in current project %s. File belongs to %s", + psiFile, + project, + psiFile.getProject())); + } + return inProject; + } + + private boolean isPsiFileNoError(final Project project, final PsiFile psiFile) + { + if(this.storage.isEnabled(Action.noActionIfCompileErrors)) + { + final boolean hasErrors = PsiErrorElementUtil.hasErrors(project, psiFile.getVirtualFile()); + if(hasErrors) + { + LOGGER.info(String.format("File %s has errors", psiFile)); + } + return !hasErrors; + } + return true; + } + + private boolean isPsiFileIncluded(final PsiFile psiFile) + { + final String canonicalPath = psiFile.getVirtualFile().getCanonicalPath(); + return this.isIncludedAndNotExcluded(canonicalPath); + } + + private boolean isPsiFileFresh(final PsiFile psiFile) + { + if(this.mode == ExecutionMode.batch) + { + return true; + } + final boolean isFresh = psiFile.getModificationStamp() != 0; + if(!isFresh) + { + LOGGER.info(String.format("File %s is not fresh.", psiFile)); + } + return isFresh; + } + + private boolean isPsiFileValid(final PsiFile psiFile) + { + final boolean valid = psiFile.isValid(); + if(!valid) + { + LOGGER.info(String.format("File %s is not valid.", psiFile)); + } + return valid; + } + + boolean isIncludedAndNotExcluded(final String path) + { + return this.isIncluded(path) && !this.isExcluded(path); + } + + private boolean isExcluded(final String path) + { + final Set exclusions = this.storage.getExclusions(); + final boolean psiFileExcluded = this.atLeastOneMatch(path, exclusions); + if(psiFileExcluded) + { + LOGGER.info(String.format("File %s excluded in %s", path, exclusions)); + } + return psiFileExcluded; + } + + private boolean isIncluded(final String path) + { + final Set inclusions = this.storage.getInclusions(); + if(inclusions.isEmpty()) + { + // If no inclusion are defined, all files are allowed + return true; + } + final boolean psiFileIncluded = this.atLeastOneMatch(path, inclusions); + if(psiFileIncluded) + { + LOGGER.info(String.format("File %s included in %s", path, inclusions)); + } + return psiFileIncluded; + } + + private boolean atLeastOneMatch(final String psiFileUrl, final Set patterns) + { + for(final String pattern : patterns) + { + try + { + final Matcher matcher = Pattern.compile(REGEX_STARTS_WITH_ANY_STRING + pattern).matcher(psiFileUrl); + if(matcher.matches()) + { + return true; + } + } + catch(final PatternSyntaxException e) + { + // invalid patterns are ignored + return false; + } + } + return false; + } + + /** + * Should properly fix #402 according to @krasa's recommendation in #109. + * + * @param psiFile of type PsiFile + */ + private void commitDocumentAndSave(final PsiFile psiFile, final PsiDocumentManager psiDocumentManager) + { + final Document document = psiDocumentManager.getDocument(psiFile); + if(document != null) + { + psiDocumentManager.doPostponedOperationsAndUnblockDocument(document); + psiDocumentManager.commitDocument(document); + FileDocumentManager.getInstance().saveDocument(document); + } + } } diff --git a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java index 86a3b4e..9a0a790 100644 --- a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java +++ b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java @@ -1,7 +1,11 @@ package software.xdev.saveactions.core.listener; -import software.xdev.saveactions.core.service.SaveActionsService; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -9,56 +13,65 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; + import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; import software.xdev.saveactions.model.Action; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; /** * FileDocumentManagerListener to catch save events. This listener is registered as ExtensionPoint. */ -public final class SaveActionsDocumentManagerListener implements FileDocumentManagerListener { - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - - private final Project project; - private PsiDocumentManager psiDocumentManager = null; - - public SaveActionsDocumentManagerListener(Project project) { - this.project = project; - } - - @Override - public void beforeAllDocumentsSaving() { - LOGGER.debug("[+] Start SaveActionsDocumentManagerListener#beforeAllDocumentsSaving, " + project.getName()); - List unsavedDocuments = Arrays.asList(FileDocumentManager.getInstance().getUnsavedDocuments()); - if (!unsavedDocuments.isEmpty()) { - LOGGER.debug(String.format("Locating psi files for %d documents: %s", unsavedDocuments.size(), unsavedDocuments)); - beforeDocumentsSaving(unsavedDocuments); - } - LOGGER.debug("End SaveActionsDocumentManagerListener#beforeAllDocumentsSaving"); - } - - public void beforeDocumentsSaving(List documents) { - if (project.isDisposed()) { - return; - } - initPsiDocManager(); - Set psiFiles = documents.stream() - .map(psiDocumentManager::getPsiFile) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - SaveActionsServiceManager.getService().guardedProcessPsiFiles(project, psiFiles, Action.activate, ExecutionMode.saveAll); - } - - private synchronized void initPsiDocManager() { - if (psiDocumentManager == null) { - psiDocumentManager = PsiDocumentManager.getInstance(project); - } - } - +public final class SaveActionsDocumentManagerListener implements FileDocumentManagerListener +{ + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + + private final Project project; + private PsiDocumentManager psiDocumentManager; + + public SaveActionsDocumentManagerListener(final Project project) + { + this.project = project; + } + + @Override + public void beforeAllDocumentsSaving() + { + LOGGER.debug( + "[+] Start SaveActionsDocumentManagerListener#beforeAllDocumentsSaving, " + this.project.getName()); + final List unsavedDocuments = Arrays.asList(FileDocumentManager.getInstance().getUnsavedDocuments()); + if(!unsavedDocuments.isEmpty()) + { + LOGGER.debug(String.format( + "Locating psi files for %d documents: %s", + unsavedDocuments.size(), + unsavedDocuments)); + this.beforeDocumentsSaving(unsavedDocuments); + } + LOGGER.debug("End SaveActionsDocumentManagerListener#beforeAllDocumentsSaving"); + } + + public void beforeDocumentsSaving(final List documents) + { + if(this.project.isDisposed()) + { + return; + } + this.initPsiDocManager(); + final Set psiFiles = documents.stream() + .map(this.psiDocumentManager::getPsiFile) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + SaveActionsServiceManager.getService() + .guardedProcessPsiFiles(this.project, psiFiles, Action.activate, ExecutionMode.saveAll); + } + + private synchronized void initPsiDocManager() + { + if(this.psiDocumentManager == null) + { + this.psiDocumentManager = PsiDocumentManager.getInstance(this.project); + } + } } diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java index 7419959..ccfd8da 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java @@ -1,27 +1,29 @@ package software.xdev.saveactions.core.service; +import java.util.List; +import java.util.Set; + import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.components.Service; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; + import software.xdev.saveactions.core.ExecutionMode; import software.xdev.saveactions.model.Action; -import java.util.List; -import java.util.Set; /** - * This interface is implemented by all SaveAction ApplicationServices. It is used to be able to override - * a concrete implementation. Also, it has to be annotated with {@link Service}. + * This interface is implemented by all SaveAction ApplicationServices. It is used to be able to override a concrete + * implementation. Also, it has to be annotated with {@link Service}. */ -public interface SaveActionsService { - - void guardedProcessPsiFiles(Project project, Set psiFiles, Action activation, ExecutionMode mode); - - boolean isJavaAvailable(); - - boolean isCompilingAvailable(); - - List getQuickLists(Project project); - +public interface SaveActionsService +{ + + void guardedProcessPsiFiles(Project project, Set psiFiles, Action activation, ExecutionMode mode); + + boolean isJavaAvailable(); + + boolean isCompilingAvailable(); + + List getQuickLists(Project project); } diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java index ccf6b2c..3ef1e05 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java @@ -1,44 +1,51 @@ package software.xdev.saveactions.core.service; +import com.intellij.openapi.application.ApplicationManager; + import software.xdev.saveactions.core.service.impl.SaveActionsDefaultService; import software.xdev.saveactions.core.service.impl.SaveActionsJavaService; -import com.intellij.openapi.application.ApplicationManager; + /** - * SaveActionsServiceManager is providing the concrete service implementation. - * All actions are handled by the {@link SaveActionsService} implementation. + * SaveActionsServiceManager is providing the concrete service implementation. All actions are handled by the + * {@link SaveActionsService} implementation. * * @see SaveActionsDefaultService * @see SaveActionsJavaService */ -public class SaveActionsServiceManager { - - - private SaveActionsServiceManager() { - } - - public static SaveActionsService getService() { - return ServiceHandler.INSTANCE.getService(); - } - - private enum ServiceHandler { - - INSTANCE; - - private static SaveActionsService service; - - public SaveActionsService getService() { - if (service == null) { - newService(); - } - return service; - } - - private void newService() { - service = ApplicationManager.getApplication().getService(SaveActionsJavaService.class); - if (service == null) { - service = ApplicationManager.getApplication().getService(SaveActionsDefaultService.class); - } - } - } +public final class SaveActionsServiceManager +{ + private SaveActionsServiceManager() + { + } + + public static SaveActionsService getService() + { + return ServiceHandler.INSTANCE.getService(); + } + + private enum ServiceHandler + { + INSTANCE; + + private static SaveActionsService service; + + public SaveActionsService getService() + { + if(service == null) + { + this.newService(); + } + return service; + } + + private void newService() + { + service = ApplicationManager.getApplication().getService(SaveActionsJavaService.class); + if(service == null) + { + service = ApplicationManager.getApplication().getService(SaveActionsDefaultService.class); + } + } + } } diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index 0a8538a..ed02417 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -1,17 +1,9 @@ package software.xdev.saveactions.core.service.impl; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.core.component.Engine; -import software.xdev.saveactions.core.service.SaveActionsService; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.model.StorageFactory; -import software.xdev.saveactions.processors.Processor; -import com.intellij.openapi.actionSystem.ex.QuickList; -import com.intellij.openapi.actionSystem.ex.QuickListsManager; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; +import static java.util.function.Function.identity; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static software.xdev.saveactions.model.StorageFactory.JAVA; import java.util.ArrayList; import java.util.Arrays; @@ -22,14 +14,24 @@ import java.util.Set; import java.util.stream.Stream; -import static software.xdev.saveactions.model.StorageFactory.JAVA; -import static java.util.function.Function.identity; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.actionSystem.ex.QuickListsManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.core.component.Engine; +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.StorageFactory; +import software.xdev.saveactions.processors.Processor; + /** - * Super class for all ApplicationServices. All actions are routed here. - * ApplicationServices are Singleton implementations by default. + * Super class for all ApplicationServices. All actions are routed here. ApplicationServices are Singleton + * implementations by default. *

    * The main method is {@link #guardedProcessPsiFiles(Project, Set, Action, ExecutionMode)} and will delegate to * {@link Engine#processPsiFilesIfNecessary()}. The method will check if the file needs to be processed and uses the @@ -41,70 +43,87 @@ * * @since 2.4.0 */ -abstract class AbstractSaveActionsService implements SaveActionsService { - - protected static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - - private final List processors; - private final StorageFactory storageFactory; - private final boolean javaAvailable; - private final boolean compilingAvailable; - - protected AbstractSaveActionsService(StorageFactory storageFactory) { - LOGGER.info("Save Actions Service \"" + getClass().getSimpleName() + "\" initialized."); - this.storageFactory = storageFactory; - processors = new ArrayList<>(); - javaAvailable = JAVA.equals(storageFactory); - compilingAvailable = initCompilingAvailable(); - } - - @Override - public synchronized void guardedProcessPsiFiles(Project project, Set psiFiles, Action activation, ExecutionMode mode) { - if (ApplicationManager.getApplication().isDisposed()) { - LOGGER.info("Application is closing, stopping invocation"); - return; - } - Engine engine = new Engine(storageFactory.getStorage(project), processors, project, psiFiles, activation, mode); - engine.processPsiFilesIfNecessary(); - } - - @Override - public boolean isJavaAvailable() { - return javaAvailable; - } - - @Override - public boolean isCompilingAvailable() { - return compilingAvailable; - } - - @Override - public List getQuickLists(Project project) { - Map quickListsIds = - Arrays.stream(QuickListsManager.getInstance().getAllQuickLists()) - .collect(toMap(QuickList::hashCode, identity())); - - return Optional.ofNullable(storageFactory.getStorage(project)) - .map(storage -> storage.getQuickLists().stream() - .map(Integer::valueOf) - .map(quickListsIds::get) - .filter(Objects::nonNull) - .collect(toList())) - .orElse(new ArrayList<>()); - } - - protected SaveActionsService addProcessors(Stream processors) { - processors.forEach(this.processors::add); - this.processors.sort(new Processor.OrderComparator()); - return this; - } - - private boolean initCompilingAvailable() { - try { - Class.forName("com.intellij.openapi.compiler.CompilerManager"); - return true; - } catch (Exception e) { - return false; - } - } +abstract class AbstractSaveActionsService implements SaveActionsService +{ + protected static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + + private final List processors; + private final StorageFactory storageFactory; + private final boolean javaAvailable; + private final boolean compilingAvailable; + + protected AbstractSaveActionsService(final StorageFactory storageFactory) + { + LOGGER.info("Save Actions Service \"" + this.getClass().getSimpleName() + "\" initialized."); + this.storageFactory = storageFactory; + this.processors = new ArrayList<>(); + this.javaAvailable = JAVA.equals(storageFactory); + this.compilingAvailable = this.initCompilingAvailable(); + } + + @Override + public synchronized void guardedProcessPsiFiles( + final Project project, + final Set psiFiles, + final Action activation, + final ExecutionMode mode) + { + if(ApplicationManager.getApplication().isDisposed()) + { + LOGGER.info("Application is closing, stopping invocation"); + return; + } + final Engine engine = new Engine( + this.storageFactory.getStorage(project), this.processors, project, psiFiles, activation, + mode); + engine.processPsiFilesIfNecessary(); + } + + @Override + public boolean isJavaAvailable() + { + return this.javaAvailable; + } + + @Override + public boolean isCompilingAvailable() + { + return this.compilingAvailable; + } + + @Override + public List getQuickLists(final Project project) + { + final Map quickListsIds = + Arrays.stream(QuickListsManager.getInstance().getAllQuickLists()) + .collect(toMap(QuickList::hashCode, identity())); + + return Optional.ofNullable(this.storageFactory.getStorage(project)) + .map(storage -> storage.getQuickLists().stream() + .map(Integer::valueOf) + .map(quickListsIds::get) + .filter(Objects::nonNull) + .collect(toList())) + .orElse(new ArrayList<>()); + } + + protected SaveActionsService addProcessors(final Stream processors) + { + processors.forEach(this.processors::add); + this.processors.sort(new Processor.OrderComparator()); + return this; + } + + private boolean initCompilingAvailable() + { + try + { + Class.forName("com.intellij.openapi.compiler.CompilerManager"); + return true; + } + catch(final Exception e) + { + return false; + } + } } diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java index 7413413..a51ac65 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java @@ -1,15 +1,16 @@ package software.xdev.saveactions.core.service.impl; +import static software.xdev.saveactions.model.StorageFactory.DEFAULT; + import software.xdev.saveactions.processors.BuildProcessor; import software.xdev.saveactions.processors.GlobalProcessor; -import static software.xdev.saveactions.model.StorageFactory.DEFAULT; /** * This ApplicationService implementation is used for all IDE flavors that are not handling JAVA. *

    - * It is assigned as ExtensionPoint from inside plugin.xml. In terms of IDEs using Java this service is overridden - * by the extended JAVA based version {@link SaveActionsJavaService}. Hence, it will not be loaded for Intellij IDEA, + * It is assigned as ExtensionPoint from inside plugin.xml. In terms of IDEs using Java this service is overridden by + * the extended JAVA based version {@link SaveActionsJavaService}. Hence, it will not be loaded for Intellij IDEA, * Android Studio a.s.o. *

    * Services must be final classes as per definition. That is the reason to use an abstract class here. @@ -18,11 +19,13 @@ * @see AbstractSaveActionsService * @since 2.4.0 */ -public final class SaveActionsDefaultService extends AbstractSaveActionsService { - - public SaveActionsDefaultService() { - super(DEFAULT); - addProcessors(BuildProcessor.stream()); - addProcessors(GlobalProcessor.stream()); - } +public final class SaveActionsDefaultService extends AbstractSaveActionsService +{ + + public SaveActionsDefaultService() + { + super(DEFAULT); + addProcessors(BuildProcessor.stream()); + addProcessors(GlobalProcessor.stream()); + } } diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java index b0462b7..ae47577 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java @@ -1,17 +1,18 @@ package software.xdev.saveactions.core.service.impl; +import static software.xdev.saveactions.model.StorageFactory.JAVA; + import software.xdev.saveactions.processors.BuildProcessor; import software.xdev.saveactions.processors.GlobalProcessor; import software.xdev.saveactions.processors.java.JavaProcessor; -import static software.xdev.saveactions.model.StorageFactory.JAVA; /** * This ApplicationService implementation is used for all JAVA based IDE flavors. *

    * It is assigned as ExtensionPoint from inside plugin-java.xml and overrides the default implementation - * {@link SaveActionsDefaultService} which is not being loaded for Intellij IDEA, Android Studio a.s.o. - * Instead this implementation will be assigned. Thus, all processors have to be configured by this class as well. + * {@link SaveActionsDefaultService} which is not being loaded for Intellij IDEA, Android Studio a.s.o. Instead this + * implementation will be assigned. Thus, all processors have to be configured by this class as well. *

    * Services must be final classes as per definition. That is the reason to use an abstract class here. *

    @@ -19,12 +20,14 @@ * @see AbstractSaveActionsService * @since 2.4.0 */ -public final class SaveActionsJavaService extends AbstractSaveActionsService { - - public SaveActionsJavaService() { - super(JAVA); - addProcessors(BuildProcessor.stream()); - addProcessors(GlobalProcessor.stream()); - addProcessors(JavaProcessor.stream()); - } +public final class SaveActionsJavaService extends AbstractSaveActionsService +{ + + public SaveActionsJavaService() + { + super(JAVA); + addProcessors(BuildProcessor.stream()); + addProcessors(GlobalProcessor.stream()); + addProcessors(JavaProcessor.stream()); + } } diff --git a/src/main/java/software/xdev/saveactions/model/Action.java b/src/main/java/software/xdev/saveactions/model/Action.java index fa21d28..11bcddc 100644 --- a/src/main/java/software/xdev/saveactions/model/Action.java +++ b/src/main/java/software/xdev/saveactions/model/Action.java @@ -1,150 +1,155 @@ package software.xdev.saveactions.model; -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Stream; - import static java.util.stream.Collectors.toSet; import static software.xdev.saveactions.model.ActionType.activation; import static software.xdev.saveactions.model.ActionType.build; import static software.xdev.saveactions.model.ActionType.global; import static software.xdev.saveactions.model.ActionType.java; -public enum Action { - - // Activation - - activate("Activate save actions on save (before saving each file, performs the configured actions below)", - activation, true), - - activateOnShortcut("Activate save actions on shortcut (default \"CTRL + SHIFT + S\")", - activation, false), - - activateOnBatch("Activate save actions on batch (\"Code > Save Actions > Execute on multiple files\")", - activation, false), - - noActionIfCompileErrors("No action if compile errors (applied per file)", - activation, false), - - // Global - - organizeImports("Optimize imports", - global, true), - - reformat("Reformat file", - global, true), - - reformatChangedCode("Reformat only changed code (only if VCS configured)", - global, false), - - rearrange("Rearrange fields and methods " + - "(configured in \"File > Settings > Editor > Code Style > (...) > Arrangement\")", - global, false), - - // Build - - compile("[experimental] Compile files (using \"Build > Build Project\")", - build, false), - - reload("[experimental] Reload files in running debugger (using \"Run > Reload Changed Classes\")", - build, false), - - executeAction("[experimental] Execute an action (using quick lists at " + - "\"File > Settings > Appearance & Behavior > Quick Lists\")", - build, false), - - // Java fixes - - fieldCanBeFinal("Add final modifier to field", - java, false), - - localCanBeFinal("Add final modifier to local variable or parameter", - java, false), - - localCanBeFinalExceptImplicit("Add final modifier to local variable or parameter except if it is implicit", - java, false), - - methodMayBeStatic("Add static modifier to methods", - java, false), - - unqualifiedFieldAccess("Add this to field access", - java, false), - - unqualifiedMethodAccess("Add this to method access", - java, false), - - unqualifiedStaticMemberAccess("Add class qualifier to static member access", - java, false), - - customUnqualifiedStaticMemberAccess("Add class qualifier to static member access outside declaring class", - java, false), - - missingOverrideAnnotation("Add missing @Override annotations", - java, false), - - useBlocks("Add blocks to if/while/for statements", - java, false), - - generateSerialVersionUID("Add a serialVersionUID field for Serializable classes", - java, false), - - unnecessaryThis("Remove unnecessary this to field and method", - java, false), - - finalPrivateMethod("Remove final from private method", - java, false), - - unnecessaryFinalOnLocalVariableOrParameter("Remove unnecessary final for local variable or parameter", - java, false), - - explicitTypeCanBeDiamond("Remove explicit generic type for diamond", - java, false), - - unnecessarySemicolon("Remove unnecessary semicolon", - java, false), - - singleStatementInBlock("Remove blocks from if/while/for statements", - java, false), - - accessCanBeTightened("Change visibility of field or method to lower access", - java, false), - - ; - - private final String text; - private final ActionType type; - private final boolean defaultValue; - - Action(String text, ActionType type, boolean defaultValue) { - this.text = text; - this.type = type; - this.defaultValue = defaultValue; - } - - public String getText() { - return text; - } - - public ActionType getType() { - return type; - } - - public boolean isDefaultValue() { - return defaultValue; - } - - public static Set getDefaults() { - return Arrays.stream(Action.values()) - .filter(Action::isDefaultValue) - .collect(toSet()); - } - - public static Stream stream() { - return Arrays.stream(values()); - } +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Stream; - public static Stream stream(ActionType type) { - return Arrays.stream(values()).filter(action -> action.type.equals(type)); - } +public enum Action +{ + // Activation + + activate("Activate save actions on save (before saving each file, performs the configured actions below)", + activation, true), + + activateOnShortcut("Activate save actions on shortcut (default \"CTRL + SHIFT + S\")", + activation, false), + + activateOnBatch("Activate save actions on batch (\"Code > Save Actions > Execute on multiple files\")", + activation, false), + + noActionIfCompileErrors("No action if compile errors (applied per file)", + activation, false), + + // Global + + organizeImports("Optimize imports", + global, true), + + reformat("Reformat file", + global, true), + + reformatChangedCode("Reformat only changed code (only if VCS configured)", + global, false), + + rearrange("Rearrange fields and methods " + + "(configured in \"File > Settings > Editor > Code Style > (...) > Arrangement\")", + global, false), + + // Build + + compile("[experimental] Compile files (using \"Build > Build Project\")", + build, false), + + reload("[experimental] Reload files in running debugger (using \"Run > Reload Changed Classes\")", + build, false), + + executeAction("[experimental] Execute an action (using quick lists at " + + "\"File > Settings > Appearance & Behavior > Quick Lists\")", + build, false), + + // Java fixes + + fieldCanBeFinal("Add final modifier to field", + java, false), + + localCanBeFinal("Add final modifier to local variable or parameter", + java, false), + + localCanBeFinalExceptImplicit("Add final modifier to local variable or parameter except if it is implicit", + java, false), + + methodMayBeStatic("Add static modifier to methods", + java, false), + + unqualifiedFieldAccess("Add this to field access", + java, false), + + unqualifiedMethodAccess("Add this to method access", + java, false), + + unqualifiedStaticMemberAccess("Add class qualifier to static member access", + java, false), + + customUnqualifiedStaticMemberAccess("Add class qualifier to static member access outside declaring class", + java, false), + + missingOverrideAnnotation("Add missing @Override annotations", + java, false), + + useBlocks("Add blocks to if/while/for statements", + java, false), + + generateSerialVersionUID("Add a serialVersionUID field for Serializable classes", + java, false), + + unnecessaryThis("Remove unnecessary this to field and method", + java, false), + + finalPrivateMethod("Remove final from private method", + java, false), + + unnecessaryFinalOnLocalVariableOrParameter("Remove unnecessary final for local variable or parameter", + java, false), + + explicitTypeCanBeDiamond("Remove explicit generic type for diamond", + java, false), + + unnecessarySemicolon("Remove unnecessary semicolon", + java, false), + + singleStatementInBlock("Remove blocks from if/while/for statements", + java, false), + + accessCanBeTightened("Change visibility of field or method to lower access", + java, false); + + private final String text; + private final ActionType type; + private final boolean defaultValue; + + Action(final String text, final ActionType type, final boolean defaultValue) + { + this.text = text; + this.type = type; + this.defaultValue = defaultValue; + } + + public String getText() + { + return this.text; + } + + public ActionType getType() + { + return this.type; + } + + public boolean isDefaultValue() + { + return this.defaultValue; + } + + public static Set getDefaults() + { + return Arrays.stream(Action.values()) + .filter(Action::isDefaultValue) + .collect(toSet()); + } + + public static Stream stream() + { + return Arrays.stream(values()); + } + + public static Stream stream(final ActionType type) + { + return Arrays.stream(values()).filter(action -> action.type.equals(type)); + } } diff --git a/src/main/java/software/xdev/saveactions/model/ActionType.java b/src/main/java/software/xdev/saveactions/model/ActionType.java index f7a9c45..1ec5357 100644 --- a/src/main/java/software/xdev/saveactions/model/ActionType.java +++ b/src/main/java/software/xdev/saveactions/model/ActionType.java @@ -1,12 +1,13 @@ package software.xdev.saveactions.model; -public enum ActionType { - - activation, - - global, - - build, - - java +public enum ActionType +{ + + activation, + + global, + + build, + + java } diff --git a/src/main/java/software/xdev/saveactions/model/Storage.java b/src/main/java/software/xdev/saveactions/model/Storage.java index 4b97a90..6efdca5 100644 --- a/src/main/java/software/xdev/saveactions/model/Storage.java +++ b/src/main/java/software/xdev/saveactions/model/Storage.java @@ -1,133 +1,156 @@ package software.xdev.saveactions.model; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.Service; -import com.intellij.openapi.components.State; -import com.intellij.serviceContainer.NonInjectable; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; - import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; -@State(name = "SaveActionSettings", storages = {@com.intellij.openapi.components.Storage("saveactions_settings.xml")}) -@Service(Service.Level.PROJECT) -public final class Storage implements PersistentStateComponent { - - private boolean firstLaunch; - private Set actions; - private Set exclusions; - private Set inclusions; - private String configurationPath; - private List quickLists; - - @NonInjectable - public Storage() { - firstLaunch = true; - actions = new HashSet<>(); - exclusions = new HashSet<>(); - inclusions = new HashSet<>(); - configurationPath = null; - quickLists = new ArrayList<>(); - } - - @NonInjectable - public Storage(Storage storage) { - firstLaunch = storage.firstLaunch; - actions = new HashSet<>(storage.actions); - exclusions = new HashSet<>(storage.exclusions); - inclusions = new HashSet<>(storage.inclusions); - configurationPath = storage.configurationPath; - quickLists = new ArrayList<>(storage.quickLists); - } - - @Override - public Storage getState() { - return this; - } - - @Override - public void loadState(@NotNull Storage state) { - firstLaunch = false; - XmlSerializerUtil.copyBean(state, this); - - // Remove null values that might have been caused by non-parsable values - actions.removeIf(Objects::isNull); - exclusions.removeIf(Objects::isNull); - inclusions.removeIf(Objects::isNull); - quickLists.removeIf(Objects::isNull); - } - - public Set getActions() { - return actions; - } - - public void setActions(Set actions) { - this.actions = actions; - } - - public Set getExclusions() { - return exclusions; - } - - public void setExclusions(Set exclusions) { - this.exclusions = exclusions; - } - - public boolean isEnabled(Action action) { - return actions.contains(action); - } - - public void setEnabled(Action action, boolean enable) { - if (enable) { - actions.add(action); - } else { - actions.remove(action); - } - } - - public Set getInclusions() { - return inclusions; - } - - public void setInclusions(Set inclusions) { - this.inclusions = inclusions; - } - - public boolean isFirstLaunch() { - return firstLaunch; - } - - public void stopFirstLaunch() { - firstLaunch = false; - } - - public String getConfigurationPath() { - return configurationPath; - } - - public void setConfigurationPath(String configurationPath) { - this.configurationPath = configurationPath; - } - - public List getQuickLists() { - return quickLists; - } +import org.jetbrains.annotations.NotNull; - public void setQuickLists(List quickLists) { - this.quickLists = quickLists; - } +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.Service; +import com.intellij.openapi.components.State; +import com.intellij.serviceContainer.NonInjectable; +import com.intellij.util.xmlb.XmlSerializerUtil; - public void clear() { - firstLaunch = true; - actions.clear(); - exclusions.clear(); - inclusions.clear(); - configurationPath = null; - quickLists.clear(); - } +@State(name = "SaveActionSettings", storages = {@com.intellij.openapi.components.Storage("saveactions_settings.xml")}) +@Service(Service.Level.PROJECT) +public final class Storage implements PersistentStateComponent +{ + private boolean firstLaunch; + private Set actions; + private Set exclusions; + private Set inclusions; + private String configurationPath; + private List quickLists; + + @NonInjectable + public Storage() + { + this.firstLaunch = true; + this.actions = new HashSet<>(); + this.exclusions = new HashSet<>(); + this.inclusions = new HashSet<>(); + this.configurationPath = null; + this.quickLists = new ArrayList<>(); + } + + @NonInjectable + public Storage(final Storage storage) + { + this.firstLaunch = storage.firstLaunch; + this.actions = new HashSet<>(storage.actions); + this.exclusions = new HashSet<>(storage.exclusions); + this.inclusions = new HashSet<>(storage.inclusions); + this.configurationPath = storage.configurationPath; + this.quickLists = new ArrayList<>(storage.quickLists); + } + + @Override + public Storage getState() + { + return this; + } + + @Override + public void loadState(@NotNull final Storage state) + { + this.firstLaunch = false; + XmlSerializerUtil.copyBean(state, this); + + // Remove null values that might have been caused by non-parsable values + this.actions.removeIf(Objects::isNull); + this.exclusions.removeIf(Objects::isNull); + this.inclusions.removeIf(Objects::isNull); + this.quickLists.removeIf(Objects::isNull); + } + + public Set getActions() + { + return this.actions; + } + + public void setActions(final Set actions) + { + this.actions = actions; + } + + public Set getExclusions() + { + return this.exclusions; + } + + public void setExclusions(final Set exclusions) + { + this.exclusions = exclusions; + } + + public boolean isEnabled(final Action action) + { + return this.actions.contains(action); + } + + public void setEnabled(final Action action, final boolean enable) + { + if(enable) + { + this.actions.add(action); + } + else + { + this.actions.remove(action); + } + } + + public Set getInclusions() + { + return this.inclusions; + } + + public void setInclusions(final Set inclusions) + { + this.inclusions = inclusions; + } + + public boolean isFirstLaunch() + { + return this.firstLaunch; + } + + public void stopFirstLaunch() + { + this.firstLaunch = false; + } + + public String getConfigurationPath() + { + return this.configurationPath; + } + + public void setConfigurationPath(final String configurationPath) + { + this.configurationPath = configurationPath; + } + + public List getQuickLists() + { + return this.quickLists; + } + + public void setQuickLists(final List quickLists) + { + this.quickLists = quickLists; + } + + public void clear() + { + this.firstLaunch = true; + this.actions.clear(); + this.exclusions.clear(); + this.inclusions.clear(); + this.configurationPath = null; + this.quickLists.clear(); + } } diff --git a/src/main/java/software/xdev/saveactions/model/StorageFactory.java b/src/main/java/software/xdev/saveactions/model/StorageFactory.java index e88d76f..0ce6f04 100644 --- a/src/main/java/software/xdev/saveactions/model/StorageFactory.java +++ b/src/main/java/software/xdev/saveactions/model/StorageFactory.java @@ -1,27 +1,30 @@ package software.xdev.saveactions.model; -import software.xdev.saveactions.model.java.EpfStorage; -import com.intellij.openapi.project.Project; - import java.util.function.Function; -public enum StorageFactory { - - DEFAULT(project -> project.getService(Storage.class)), - - JAVA(project -> { - Storage defaultStorage = DEFAULT.getStorage(project); - return EpfStorage.INSTANCE.getStorageOrDefault(defaultStorage.getConfigurationPath(), defaultStorage); - }); - - private final Function provider; +import com.intellij.openapi.project.Project; - StorageFactory(Function provider) { - this.provider = provider; - } +import software.xdev.saveactions.model.java.EpfStorage; - public Storage getStorage(Project project) { - return provider.apply(project); - } +public enum StorageFactory +{ + DEFAULT(project -> project.getService(Storage.class)), + + JAVA(project -> { + Storage defaultStorage = DEFAULT.getStorage(project); + return EpfStorage.INSTANCE.getStorageOrDefault(defaultStorage.getConfigurationPath(), defaultStorage); + }); + + private final Function provider; + + StorageFactory(final Function provider) + { + this.provider = provider; + } + + public Storage getStorage(final Project project) + { + return this.provider.apply(project); + } } diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfAction.java b/src/main/java/software/xdev/saveactions/model/java/EpfAction.java index f83483c..8ea17b9 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfAction.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfAction.java @@ -1,92 +1,95 @@ package software.xdev.saveactions.model.java; -import software.xdev.saveactions.model.Action; +import static java.util.Collections.unmodifiableList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.stream.Stream; -import static java.util.Collections.unmodifiableList; - -public enum EpfAction { - - organizeImports( - Action.organizeImports, - EpfKey.organize_imports, EpfKey.remove_unused_imports), - - reformat( - Action.reformat, - EpfKey.format_source_code), - - reformatChangedCode( - Action.reformatChangedCode, - EpfKey.format_source_code_changes_only), - - rearrange( - Action.rearrange, - EpfKey.sort_members, EpfKey.sort_members_all), - - fieldCanBeFinal( - Action.fieldCanBeFinal, - EpfKey.make_private_fields_final), - - localCanBeFinal( - Action.localCanBeFinal, - EpfKey.make_local_variable_final), - - unqualifiedFieldAccess( - Action.unqualifiedFieldAccess, - EpfKey.use_this_for_non_static_field_access), - - unqualifiedMethodAccess( - Action.unqualifiedMethodAccess, - EpfKey.always_use_this_for_non_static_method_access), - - unqualifiedStaticMemberAccess( - Action.unqualifiedStaticMemberAccess, - EpfKey.qualify_static_member_accesses_with_declaring_class), - - missingOverrideAnnotation( - Action.missingOverrideAnnotation, - EpfKey.add_missing_override_annotations, EpfKey.add_missing_override_annotations_interface_methods), - - useBlocks( - Action.useBlocks, - EpfKey.use_blocks, EpfKey.always_use_blocks), - - generateSerialVersionUID( - Action.generateSerialVersionUID, - EpfKey.add_serial_version_id, EpfKey.add_default_serial_version_id, EpfKey.add_generated_serial_version_id), - - explicitTypeCanBeDiamond( - Action.explicitTypeCanBeDiamond, - EpfKey.remove_redundant_type_arguments), - - ; - - private final Action action; - private final List epfKeys; - - EpfAction(Action action, EpfKey... epfKeys) { - this.action = action; - this.epfKeys = Arrays.asList(epfKeys); - } - - public Action getAction() { - return action; - } - - public List getEpfKeys() { - return unmodifiableList(epfKeys); - } - - public static Optional getEpfActionForAction(Action action) { - return stream().filter(epfAction -> epfAction.action.equals(action)).findFirst(); - } +import software.xdev.saveactions.model.Action; - public static Stream stream() { - return Arrays.stream(values()); - } +public enum EpfAction +{ + organizeImports( + Action.organizeImports, + EpfKey.organize_imports, EpfKey.remove_unused_imports), + + reformat( + Action.reformat, + EpfKey.format_source_code), + + reformatChangedCode( + Action.reformatChangedCode, + EpfKey.format_source_code_changes_only), + + rearrange( + Action.rearrange, + EpfKey.sort_members, EpfKey.sort_members_all), + + fieldCanBeFinal( + Action.fieldCanBeFinal, + EpfKey.make_private_fields_final), + + localCanBeFinal( + Action.localCanBeFinal, + EpfKey.make_local_variable_final), + + unqualifiedFieldAccess( + Action.unqualifiedFieldAccess, + EpfKey.use_this_for_non_static_field_access), + + unqualifiedMethodAccess( + Action.unqualifiedMethodAccess, + EpfKey.always_use_this_for_non_static_method_access), + + unqualifiedStaticMemberAccess( + Action.unqualifiedStaticMemberAccess, + EpfKey.qualify_static_member_accesses_with_declaring_class), + + missingOverrideAnnotation( + Action.missingOverrideAnnotation, + EpfKey.add_missing_override_annotations, EpfKey.add_missing_override_annotations_interface_methods), + + useBlocks( + Action.useBlocks, + EpfKey.use_blocks, EpfKey.always_use_blocks), + + generateSerialVersionUID( + Action.generateSerialVersionUID, + EpfKey.add_serial_version_id, EpfKey.add_default_serial_version_id, EpfKey.add_generated_serial_version_id), + + explicitTypeCanBeDiamond( + Action.explicitTypeCanBeDiamond, + EpfKey.remove_redundant_type_arguments); + + private final Action action; + private final List epfKeys; + + EpfAction(final Action action, final EpfKey... epfKeys) + { + this.action = action; + this.epfKeys = Arrays.asList(epfKeys); + } + + public Action getAction() + { + return this.action; + } + + public List getEpfKeys() + { + return unmodifiableList(this.epfKeys); + } + + public static Optional getEpfActionForAction(final Action action) + { + return stream().filter(epfAction -> epfAction.action.equals(action)).findFirst(); + } + + public static Stream stream() + { + return Arrays.stream(values()); + } } diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfKey.java b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java index 15a503c..0ba41f6 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfKey.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java @@ -5,78 +5,79 @@ import java.util.List; import java.util.stream.Stream; -public enum EpfKey { - - add_default_serial_version_id, - add_generated_serial_version_id, - add_missing_annotations, - add_missing_deprecated_annotations, - add_missing_methods, - add_missing_nls_tags, - add_missing_override_annotations, - add_missing_override_annotations_interface_methods, - add_serial_version_id, - always_use_blocks, - always_use_parentheses_in_expressions, - always_use_this_for_non_static_field_access, - always_use_this_for_non_static_method_access, - convert_functional_interfaces, - convert_to_enhanced_for_loop, - correct_indentation, - format_source_code, - format_source_code_changes_only, - insert_inferred_type_arguments, - make_local_variable_final, - make_parameters_final, - make_private_fields_final, - make_type_abstract_if_missing_method, - make_variable_declarations_final, - never_use_blocks, - never_use_parentheses_in_expressions, - on_save_use_additional_actions, - organize_imports, - qualify_static_field_accesses_with_declaring_class, - qualify_static_member_accesses_through_instances_with_declaring_class, - qualify_static_member_accesses_through_subtypes_with_declaring_class, - qualify_static_member_accesses_with_declaring_class, - qualify_static_method_accesses_with_declaring_class, - remove_private_constructors, - remove_redundant_type_arguments, - remove_trailing_whitespaces, - remove_trailing_whitespaces_all, - remove_trailing_whitespaces_ignore_empty, - remove_unnecessary_casts, - remove_unnecessary_nls_tags, - remove_unused_imports, - remove_unused_local_variables, - remove_unused_private_fields, - remove_unused_private_members, - remove_unused_private_methods, - remove_unused_private_types, - sort_members, - sort_members_all, - use_anonymous_class_creation, - use_blocks, - use_blocks_only_for_return_and_throw, - use_lambda, - use_parentheses_in_expressions, - use_this_for_non_static_field_access, - use_this_for_non_static_field_access_only_if_necessary, - use_this_for_non_static_method_access, - use_this_for_non_static_method_access_only_if_necessary, - ; - - private static final List PREFIXES = Arrays.asList( - "sp_cleanup", - "/instance/org.eclipse.jdt.ui/sp_cleanup" - ); - - public static List getPrefixes() { - return Collections.unmodifiableList(PREFIXES); - } - - public static Stream stream() { - return Arrays.stream(values()); - } +public enum EpfKey +{ + add_default_serial_version_id, + add_generated_serial_version_id, + add_missing_annotations, + add_missing_deprecated_annotations, + add_missing_methods, + add_missing_nls_tags, + add_missing_override_annotations, + add_missing_override_annotations_interface_methods, + add_serial_version_id, + always_use_blocks, + always_use_parentheses_in_expressions, + always_use_this_for_non_static_field_access, + always_use_this_for_non_static_method_access, + convert_functional_interfaces, + convert_to_enhanced_for_loop, + correct_indentation, + format_source_code, + format_source_code_changes_only, + insert_inferred_type_arguments, + make_local_variable_final, + make_parameters_final, + make_private_fields_final, + make_type_abstract_if_missing_method, + make_variable_declarations_final, + never_use_blocks, + never_use_parentheses_in_expressions, + on_save_use_additional_actions, + organize_imports, + qualify_static_field_accesses_with_declaring_class, + qualify_static_member_accesses_through_instances_with_declaring_class, + qualify_static_member_accesses_through_subtypes_with_declaring_class, + qualify_static_member_accesses_with_declaring_class, + qualify_static_method_accesses_with_declaring_class, + remove_private_constructors, + remove_redundant_type_arguments, + remove_trailing_whitespaces, + remove_trailing_whitespaces_all, + remove_trailing_whitespaces_ignore_empty, + remove_unnecessary_casts, + remove_unnecessary_nls_tags, + remove_unused_imports, + remove_unused_local_variables, + remove_unused_private_fields, + remove_unused_private_members, + remove_unused_private_methods, + remove_unused_private_types, + sort_members, + sort_members_all, + use_anonymous_class_creation, + use_blocks, + use_blocks_only_for_return_and_throw, + use_lambda, + use_parentheses_in_expressions, + use_this_for_non_static_field_access, + use_this_for_non_static_field_access_only_if_necessary, + use_this_for_non_static_method_access, + use_this_for_non_static_method_access_only_if_necessary; + + private static final List PREFIXES = Arrays.asList( + "sp_cleanup", + "/instance/org.eclipse.jdt.ui/sp_cleanup" + ); + + public static List getPrefixes() + { + return Collections.unmodifiableList(PREFIXES); + } + + public static Stream stream() + { + return Arrays.stream(values()); + } } diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java b/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java index 29d646e..63e5957 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfStorage.java @@ -1,9 +1,6 @@ package software.xdev.saveactions.model.java; -import software.xdev.saveactions.core.service.SaveActionsService; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.model.Storage; -import com.intellij.openapi.diagnostic.Logger; +import static java.util.Collections.emptyList; import java.io.FileInputStream; import java.io.IOException; @@ -11,69 +8,89 @@ import java.util.Optional; import java.util.Properties; -import static java.util.Collections.emptyList; +import com.intellij.openapi.diagnostic.Logger; + +import software.xdev.saveactions.core.service.SaveActionsService; +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; + /** * Storage implementation for the Workspace-Mechanic-Format. Only the Java language-specific actions are supported. *

    - * The main method {@link #getStorageOrDefault(String, Storage)} return a configuration based on EPF - * if the path to EPF configuration file is set and valid, or else the default configuration is returned. + * The main method {@link #getStorageOrDefault(String, Storage)} return a configuration based on EPF if the path to EPF + * configuration file is set and valid, or else the default configuration is returned. *

    * The default storage is used to copy the actions, the inclusions and the exclusions, then the actions are taken from * the epf file and overrides the actions precedently set. * * @author markiewb */ -public enum EpfStorage { - - INSTANCE; - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - - public Storage getStorageOrDefault(String configurationPath, Storage defaultStorage) { - try { - return getStorageOrDefault0(configurationPath, defaultStorage); - } catch (IOException e) { - LOGGER.info("Error in configuration file " + defaultStorage.getConfigurationPath(), e); - return defaultStorage; - } - } - - private Storage getStorageOrDefault0(String configurationPath, Storage defaultStorage) throws IOException { - if ("".equals(configurationPath) || configurationPath == null) { - return defaultStorage; - } - Storage storage = new Storage(defaultStorage); - Properties properties = readProperties(configurationPath); - Action.stream().forEach(action -> storage.setEnabled(action, isEnabledInEpf(properties, action) - .orElse(defaultStorage.isEnabled(action)))); - return storage; - } - - private Optional isEnabledInEpf(Properties properties, Action action) { - List epfKeys = EpfAction.getEpfActionForAction(action).map(EpfAction::getEpfKeys).orElse(emptyList()); - for (EpfKey epfKey : epfKeys) { - if (isEnabledInEpf(properties, epfKey, true)) { - return Optional.of(true); - } - if (isEnabledInEpf(properties, epfKey, false)) { - return Optional.of(false); - } - } - return Optional.empty(); - } - - private boolean isEnabledInEpf(Properties properties, EpfKey key, boolean value) { - return EpfKey.getPrefixes().stream() - .anyMatch(prefix -> String.valueOf(value).equals(properties.getProperty(prefix + "." + key))); - } - - private Properties readProperties(String configurationPath) throws IOException { - Properties properties = new Properties(); - try (FileInputStream in = new FileInputStream(configurationPath)) { - properties.load(in); - } - return properties; - } - +public enum EpfStorage +{ + INSTANCE; + + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + + public Storage getStorageOrDefault(final String configurationPath, final Storage defaultStorage) + { + try + { + return this.getStorageOrDefault0(configurationPath, defaultStorage); + } + catch(final IOException e) + { + LOGGER.info("Error in configuration file " + defaultStorage.getConfigurationPath(), e); + return defaultStorage; + } + } + + private Storage getStorageOrDefault0(final String configurationPath, final Storage defaultStorage) + throws IOException + { + if("".equals(configurationPath) || configurationPath == null) + { + return defaultStorage; + } + final Storage storage = new Storage(defaultStorage); + final Properties properties = this.readProperties(configurationPath); + Action.stream().forEach(action -> storage.setEnabled(action, this.isEnabledInEpf(properties, action) + .orElse(defaultStorage.isEnabled(action)))); + return storage; + } + + private Optional isEnabledInEpf(final Properties properties, final Action action) + { + final List epfKeys = EpfAction.getEpfActionForAction(action) + .map(EpfAction::getEpfKeys) + .orElse(emptyList()); + for(final EpfKey epfKey : epfKeys) + { + if(this.isEnabledInEpf(properties, epfKey, true)) + { + return Optional.of(true); + } + if(this.isEnabledInEpf(properties, epfKey, false)) + { + return Optional.of(false); + } + } + return Optional.empty(); + } + + private boolean isEnabledInEpf(final Properties properties, final EpfKey key, final boolean value) + { + return EpfKey.getPrefixes().stream() + .anyMatch(prefix -> String.valueOf(value).equals(properties.getProperty(prefix + "." + key))); + } + + private Properties readProperties(final String configurationPath) throws IOException + { + final Properties properties = new Properties(); + try(final FileInputStream in = new FileInputStream(configurationPath)) + { + properties.load(in); + } + return properties; + } } diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index 56218e8..289bcc7 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -1,5 +1,18 @@ package software.xdev.saveactions.processors; +import static com.intellij.openapi.actionSystem.ActionPlaces.UNKNOWN; +import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR; +import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT; +import static software.xdev.saveactions.utils.Helper.toVirtualFiles; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.stream.Stream; + import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.HotSwapUI; @@ -12,116 +25,120 @@ import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; + import software.xdev.saveactions.core.ExecutionMode; import software.xdev.saveactions.core.service.SaveActionsServiceManager; import software.xdev.saveactions.model.Action; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.stream.Stream; - -import static com.intellij.openapi.actionSystem.ActionPlaces.UNKNOWN; -import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR; -import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT; -import static software.xdev.saveactions.utils.Helper.toVirtualFiles; /** * Available processors for build. */ -public enum BuildProcessor implements Processor { - - compile(Action.compile, - (project, psiFiles) -> () -> { - if (!SaveActionsServiceManager.getService().isCompilingAvailable()) { - return; - } - CompilerManager.getInstance(project).compile(toVirtualFiles(psiFiles), null); - }), - - reload(Action.reload, - (project, psiFiles) -> () -> { - if (!SaveActionsServiceManager.getService().isCompilingAvailable()) { - return; - } - DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project); - DebuggerSession session = debuggerManager.getContext().getDebuggerSession(); - if (session != null && session.isAttached()) { - HotSwapUI.getInstance(project).reloadChangedClasses(session, true); - } - }), - - executeAction(Action.executeAction, - (project, psiFiles) -> () -> { - ActionManager actionManager = ActionManager.getInstance(); - - List actionIds = SaveActionsServiceManager.getService().getQuickLists(project).stream() - .flatMap(quickList -> Arrays.stream(quickList.getActionIds())) - .toList(); - - for (String actionId : actionIds) { - AnAction anAction = actionManager.getAction(actionId); - if (anAction == null) { - continue; - } - DataContext dataContext = SimpleDataContext.builder() - .add(PROJECT, project) - .add(EDITOR, FileEditorManager.getInstance(project).getSelectedTextEditor()) - .setParent(null) - .build(); - AnActionEvent event = AnActionEvent.createFromAnAction(anAction, null, UNKNOWN, dataContext); - anAction.actionPerformed(event); - } - }) { - @Override - public SaveCommand getSaveCommand(Project project, Set psiFiles) { - return new SaveReadCommand(project, psiFiles, getModes(), getAction(), getCommand()); - } - }, - - ; - - private final Action action; - private final BiFunction command; - - BuildProcessor(Action action, BiFunction command) { - this.action = action; - this.command = command; - } - - @Override - public Action getAction() { - return action; - } - - @Override - public Set getModes() { - return EnumSet.allOf(ExecutionMode.class); - } - - @Override - public int getOrder() { - return 2; - } - - @Override - public SaveCommand getSaveCommand(Project project, Set psiFiles) { - return new SaveWriteCommand(project, psiFiles, getModes(), getAction(), getCommand()); - } - - public BiFunction getCommand() { - return command; - } - - public static Optional getProcessorForAction(Action action) { - return stream().filter(processor -> processor.getAction().equals(action)).findFirst(); - } - - public static Stream stream() { - return Arrays.stream(values()); - } - +public enum BuildProcessor implements Processor +{ + compile( + Action.compile, + (project, psiFiles) -> () -> { + if(!SaveActionsServiceManager.getService().isCompilingAvailable()) + { + return; + } + CompilerManager.getInstance(project).compile(toVirtualFiles(psiFiles), null); + }), + + reload( + Action.reload, + (project, psiFiles) -> () -> { + if(!SaveActionsServiceManager.getService().isCompilingAvailable()) + { + return; + } + DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project); + DebuggerSession session = debuggerManager.getContext().getDebuggerSession(); + if(session != null && session.isAttached()) + { + HotSwapUI.getInstance(project).reloadChangedClasses(session, true); + } + }), + + executeAction( + Action.executeAction, + (project, psiFiles) -> () -> { + ActionManager actionManager = ActionManager.getInstance(); + + List actionIds = SaveActionsServiceManager.getService().getQuickLists(project).stream() + .flatMap(quickList -> Arrays.stream(quickList.getActionIds())) + .toList(); + + for(String actionId : actionIds) + { + AnAction anAction = actionManager.getAction(actionId); + if(anAction == null) + { + continue; + } + DataContext dataContext = SimpleDataContext.builder() + .add(PROJECT, project) + .add(EDITOR, FileEditorManager.getInstance(project).getSelectedTextEditor()) + .setParent(null) + .build(); + AnActionEvent event = AnActionEvent.createFromAnAction(anAction, null, UNKNOWN, dataContext); + anAction.actionPerformed(event); + } + }) + { + @Override + public SaveCommand getSaveCommand(final Project project, final Set psiFiles) + { + return new SaveReadCommand(project, psiFiles, this.getModes(), this.getAction(), this.getCommand()); + } + }; + + private final Action action; + private final BiFunction command; + + BuildProcessor(final Action action, final BiFunction command) + { + this.action = action; + this.command = command; + } + + @Override + public Action getAction() + { + return this.action; + } + + @Override + public Set getModes() + { + return EnumSet.allOf(ExecutionMode.class); + } + + @Override + public int getOrder() + { + return 2; + } + + @Override + public SaveCommand getSaveCommand(final Project project, final Set psiFiles) + { + return new SaveWriteCommand(project, psiFiles, this.getModes(), this.getAction(), this.getCommand()); + } + + public BiFunction getCommand() + { + return this.command; + } + + public static Optional getProcessorForAction(final Action action) + { + return stream().filter(processor -> processor.getAction().equals(action)).findFirst(); + } + + public static Stream stream() + { + return Arrays.stream(values()); + } } diff --git a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java index 51db4c5..ee81103 100644 --- a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java @@ -1,93 +1,112 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.stream.Stream; + +import org.jetbrains.annotations.NotNull; + import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.actions.OptimizeImportsProcessor; import com.intellij.codeInsight.actions.RearrangeCodeProcessor; import com.intellij.codeInsight.actions.ReformatCodeProcessor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.NotNull; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.Optional; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.stream.Stream; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; /** * Available processors for global. */ -public enum GlobalProcessor implements Processor { - - organizeImports(Action.organizeImports, GlobalProcessor::optimizeImports), - - reformat(Action.reformat, - (project, psiFiles) -> reformateCode(project, psiFiles, false)), - - reformatChangedCode(Action.reformatChangedCode, - (project, psiFiles) -> reformateCode(project, psiFiles, true)), - - rearrange(Action.rearrange, GlobalProcessor::rearrangeCode), - - ; - - @NotNull - private static Runnable rearrangeCode(Project project, PsiFile[] psiFiles) { - return new RearrangeCodeProcessor(project, psiFiles, CodeInsightBundle.message("command.rearrange.code"), null)::run; - } - - @NotNull - private static Runnable optimizeImports(Project project, PsiFile[] psiFiles) { - return new OptimizeImportsProcessor(project, psiFiles, null)::run; - } - - @NotNull - private static Runnable reformateCode(Project project, PsiFile[] psiFiles, boolean processChangedTextOnly) { - return new ReformatCodeProcessor(project, psiFiles, null, processChangedTextOnly)::run; - } - - private final Action action; - private final BiFunction command; - - GlobalProcessor(Action action, BiFunction command) { - this.action = action; - this.command = command; - } - - @Override - public Action getAction() { - return action; - } - - @Override - public Set getModes() { - return EnumSet.allOf(ExecutionMode.class); - } - - @Override - public int getOrder() { - return 0; - } - - @Override - public SaveWriteCommand getSaveCommand(Project project, Set psiFiles) { - return new SaveWriteCommand(project, psiFiles, getModes(), getAction(), getCommand()); - } - - public BiFunction getCommand() { - return command; - } - - public static Optional getProcessorForAction(Action action) { - return stream().filter(processor -> processor.getAction().equals(action)).findFirst(); - } - - public static Stream stream() { - return Arrays.stream(values()); - } - +public enum GlobalProcessor implements Processor +{ + organizeImports(Action.organizeImports, GlobalProcessor::optimizeImports), + + reformat( + Action.reformat, + (project, psiFiles) -> reformatCode(project, psiFiles, false)), + + reformatChangedCode( + Action.reformatChangedCode, + (project, psiFiles) -> reformatCode(project, psiFiles, true)), + + rearrange(Action.rearrange, GlobalProcessor::rearrangeCode); + + @NotNull + private static Runnable rearrangeCode(final Project project, final PsiFile[] psiFiles) + { + return new RearrangeCodeProcessor( + project, + psiFiles, + CodeInsightBundle.message("command.rearrange.code"), + null)::run; + } + + @NotNull + private static Runnable optimizeImports(final Project project, final PsiFile[] psiFiles) + { + return new OptimizeImportsProcessor(project, psiFiles, null)::run; + } + + @NotNull + private static Runnable reformatCode( + final Project project, + final PsiFile[] psiFiles, + final boolean processChangedTextOnly) + { + return new ReformatCodeProcessor(project, psiFiles, null, processChangedTextOnly)::run; + } + + private final Action action; + private final BiFunction command; + + GlobalProcessor(final Action action, final BiFunction command) + { + this.action = action; + this.command = command; + } + + @Override + public Action getAction() + { + return this.action; + } + + @Override + public Set getModes() + { + return EnumSet.allOf(ExecutionMode.class); + } + + @Override + public int getOrder() + { + return 0; + } + + @Override + public SaveWriteCommand getSaveCommand(final Project project, final Set psiFiles) + { + return new SaveWriteCommand(project, psiFiles, this.getModes(), this.getAction(), this.getCommand()); + } + + public BiFunction getCommand() + { + return this.command; + } + + public static Optional getProcessorForAction(final Action action) + { + return stream().filter(processor -> processor.getAction().equals(action)).findFirst(); + } + + public static Stream stream() + { + return Arrays.stream(values()); + } } diff --git a/src/main/java/software/xdev/saveactions/processors/Processor.java b/src/main/java/software/xdev/saveactions/processors/Processor.java index 02cc89f..41b0b16 100644 --- a/src/main/java/software/xdev/saveactions/processors/Processor.java +++ b/src/main/java/software/xdev/saveactions/processors/Processor.java @@ -1,34 +1,36 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; - import java.util.Comparator; import java.util.Set; -/** - * Processor interface contains the provider method, the action that enables the processors, and the modes for which - * the processor is available. - */ -public interface Processor { - - Action getAction(); - - Set getModes(); - - int getOrder(); - - SaveCommand getSaveCommand(Project project, Set psiFiles); - - class OrderComparator implements Comparator { +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; - @Override - public int compare(Processor o1, Processor o2) { - return Integer.compare(o1.getOrder(), o2.getOrder()); - } +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; - } +/** + * Processor interface contains the provider method, the action that enables the processors, and the modes for which the + * processor is available. + */ +public interface Processor +{ + Action getAction(); + + Set getModes(); + + int getOrder(); + + SaveCommand getSaveCommand(Project project, Set psiFiles); + + class OrderComparator implements Comparator + { + + @Override + public int compare(final Processor o1, final Processor o2) + { + return Integer.compare(o1.getOrder(), o2.getOrder()); + } + } } diff --git a/src/main/java/software/xdev/saveactions/processors/Result.java b/src/main/java/software/xdev/saveactions/processors/Result.java index 49d3e9f..1597ac5 100644 --- a/src/main/java/software/xdev/saveactions/processors/Result.java +++ b/src/main/java/software/xdev/saveactions/processors/Result.java @@ -3,21 +3,23 @@ /** * Composite of {@link com.intellij.openapi.application.Result} and {@link com.intellij.openapi.application.RunResult}. */ -public class Result { - - private final T result; - - Result(T result) { - this.result = result; - } - - public T getResult() { - return result; - } - - @Override - public String toString() { - return result.toString(); - } - +public class Result +{ + private final T result; + + Result(final T result) + { + this.result = result; + } + + public T getResult() + { + return this.result; + } + + @Override + public String toString() + { + return this.result.toString(); + } } diff --git a/src/main/java/software/xdev/saveactions/processors/ResultCode.java b/src/main/java/software/xdev/saveactions/processors/ResultCode.java index a4d062f..ba79956 100644 --- a/src/main/java/software/xdev/saveactions/processors/ResultCode.java +++ b/src/main/java/software/xdev/saveactions/processors/ResultCode.java @@ -3,9 +3,9 @@ /** * The result code for the run of {@link SaveWriteCommand}. */ -public enum ResultCode { - - OK, - FAILED - +public enum ResultCode +{ + + OK, + FAILED } diff --git a/src/main/java/software/xdev/saveactions/processors/SaveCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveCommand.java index b2314cb..499a53b 100644 --- a/src/main/java/software/xdev/saveactions/processors/SaveCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveCommand.java @@ -1,63 +1,73 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; - import java.util.Set; import java.util.function.BiFunction; -/** - * Abstracts a save command with a {@link BiFunction} from pair ({@link Project}, {@link PsiFile}[]) - * to {@link Runnable}. The entry point is {@link #execute()}. - */ -public abstract class SaveCommand { - - private final Project project; - private final Set psiFiles; - private final Set modes; - private final Action action; - private final BiFunction command; - - protected SaveCommand(Project project, Set psiFiles, Set modes, Action action, - BiFunction command) { - this.project = project; - this.psiFiles = psiFiles; - this.modes = modes; - this.action = action; - this.command = command; - } - - public Project getProject() { - return project; - } - - public Set getPsiFiles() { - return psiFiles; - } - - public PsiFile[] getPsiFilesAsArray() { - return psiFiles.toArray(new PsiFile[0]); - } - - public Set getModes() { - return modes; - } - - public Action getAction() { - return action; - } - - public BiFunction getCommand() { - return command; - } +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; - @Override - public String toString() { - return action.toString(); - } +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; - public abstract Result execute(); +/** + * Abstracts a save command with a {@link BiFunction} from pair ({@link Project}, {@link PsiFile}[]) to + * {@link Runnable}. The entry point is {@link #execute()}. + */ +public abstract class SaveCommand +{ + private final Project project; + private final Set psiFiles; + private final Set modes; + private final Action action; + private final BiFunction command; + + protected SaveCommand( + final Project project, final Set psiFiles, final Set modes, final Action action, + final BiFunction command) + { + this.project = project; + this.psiFiles = psiFiles; + this.modes = modes; + this.action = action; + this.command = command; + } + + public Project getProject() + { + return this.project; + } + + public Set getPsiFiles() + { + return this.psiFiles; + } + + public PsiFile[] getPsiFilesAsArray() + { + return this.psiFiles.toArray(new PsiFile[0]); + } + + public Set getModes() + { + return this.modes; + } + + public Action getAction() + { + return this.action; + } + + public BiFunction getCommand() + { + return this.command; + } + + @Override + public String toString() + { + return this.action.toString(); + } + + public abstract Result execute(); } diff --git a/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java index c3598d7..092a094 100644 --- a/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveReadCommand.java @@ -1,33 +1,39 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; +import java.util.Set; +import java.util.function.BiFunction; + import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import java.util.Set; -import java.util.function.BiFunction; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; + /** * Implements a read action that returns a {@link Result}. */ -public class SaveReadCommand extends SaveCommand { - - public SaveReadCommand( - Project project, Set psiFiles, Set modes, Action action, - BiFunction command) { - - super(project, psiFiles, modes, action, command); - } - - @Override - public synchronized Result execute() { - try { - getCommand().apply(getProject(), getPsiFilesAsArray()).run(); - return new Result<>(ResultCode.OK); - } catch (Exception e) { - return new Result<>(ResultCode.FAILED); - } - } - +public class SaveReadCommand extends SaveCommand +{ + public SaveReadCommand( + final Project project, final Set psiFiles, final Set modes, final Action action, + final BiFunction command) + { + + super(project, psiFiles, modes, action, command); + } + + @Override + public synchronized Result execute() + { + try + { + this.getCommand().apply(this.getProject(), this.getPsiFilesAsArray()).run(); + return new Result<>(ResultCode.OK); + } + catch(final Exception e) + { + return new Result<>(ResultCode.FAILED); + } + } } diff --git a/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java b/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java index 4716298..8d21f87 100644 --- a/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java +++ b/src/main/java/software/xdev/saveactions/processors/SaveWriteCommand.java @@ -1,33 +1,41 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.core.ExecutionMode; -import software.xdev.saveactions.model.Action; +import java.util.Set; +import java.util.function.BiFunction; + import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import java.util.Set; -import java.util.function.BiFunction; +import software.xdev.saveactions.core.ExecutionMode; +import software.xdev.saveactions.model.Action; + /** - * Implements a write action that encapsulates {@link com.intellij.openapi.command.WriteCommandAction} that returns - * a {@link Result}. + * Implements a write action that encapsulates {@link com.intellij.openapi.command.WriteCommandAction} that returns a + * {@link Result}. */ -public class SaveWriteCommand extends SaveCommand { - - public SaveWriteCommand(Project project, Set psiFiles, Set modes, Action action, - BiFunction command) { - super(project, psiFiles, modes, action, command); - } - - @Override - public synchronized Result execute() { - try { - WriteCommandAction.writeCommandAction(getProject(), getPsiFilesAsArray()) - .run(() -> getCommand().apply(getProject(), getPsiFilesAsArray()).run()); - return new Result<>(ResultCode.OK); - } catch (Exception e) { - return new Result<>(ResultCode.FAILED); - } - } +public class SaveWriteCommand extends SaveCommand +{ + public SaveWriteCommand( + final Project project, final Set psiFiles, final Set modes, final Action action, + final BiFunction command) + { + super(project, psiFiles, modes, action, command); + } + + @Override + public synchronized Result execute() + { + try + { + WriteCommandAction.writeCommandAction(this.getProject(), this.getPsiFilesAsArray()) + .run(() -> this.getCommand().apply(this.getProject(), this.getPsiFilesAsArray()).run()); + return new Result<>(ResultCode.OK); + } + catch(final Exception e) + { + return new Result<>(ResultCode.FAILED); + } + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java index 96db99b..4ee46a4 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java +++ b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java @@ -1,6 +1,12 @@ package software.xdev.saveactions.processors.java; -import software.xdev.saveactions.core.service.SaveActionsService; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + import com.intellij.codeInspection.GlobalInspectionContext; import com.intellij.codeInspection.InspectionEngine; import com.intellij.codeInspection.InspectionManager; @@ -15,71 +21,79 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; +import software.xdev.saveactions.core.service.SaveActionsService; + /** * Implements a runnable for inspections commands. */ -class InspectionRunnable implements Runnable { - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - - private final Project project; - private final Set psiFiles; - private final InspectionToolWrapper toolWrapper; - - InspectionRunnable(Project project, Set psiFiles, LocalInspectionTool inspectionTool) { - this.project = project; - this.psiFiles = psiFiles; - toolWrapper = new LocalInspectionToolWrapper(inspectionTool); - LOGGER.info(String.format("Running inspection for %s", inspectionTool.getShortName())); - } - - @Override - public void run() { - InspectionManager inspectionManager = InspectionManager.getInstance(project); - GlobalInspectionContext context = inspectionManager.createNewGlobalContext(); - psiFiles.forEach(pf -> getProblemDescriptors(context, pf).forEach(this::writeQuickFixes)); - } - - private List getProblemDescriptors( - GlobalInspectionContext context, - PsiFile psiFile) { - try { - return InspectionEngine.runInspectionOnFile(psiFile, toolWrapper, context); - } catch (IndexNotReadyException exception) { - LOGGER.info(String.format("Cannot inspect file %s: index not ready (%s)", - psiFile.getName(), - exception.getMessage())); - return Collections.emptyList(); - } - } - - @SuppressWarnings({"unchecked", "squid:S1905", "squid:S3740"}) - private void writeQuickFixes(ProblemDescriptor problemDescriptor) { - QuickFix[] fixes = problemDescriptor.getFixes(); - if (fixes == null) { - return; - } - - Set> quickFixes = Arrays.stream(fixes) - .filter(Objects::nonNull) - .map(qf -> (QuickFix) qf) - .collect(Collectors.toSet()); - - for (QuickFix typedFix : quickFixes) { - try { - LOGGER.info(String.format("Applying fix \"%s\"", typedFix.getName())); - typedFix.applyFix(project, problemDescriptor); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - } - } - } - +class InspectionRunnable implements Runnable +{ + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + + private final Project project; + private final Set psiFiles; + private final InspectionToolWrapper toolWrapper; + + InspectionRunnable(final Project project, final Set psiFiles, final LocalInspectionTool inspectionTool) + { + this.project = project; + this.psiFiles = psiFiles; + this.toolWrapper = new LocalInspectionToolWrapper(inspectionTool); + LOGGER.info(String.format("Running inspection for %s", inspectionTool.getShortName())); + } + + @Override + public void run() + { + final InspectionManager inspectionManager = InspectionManager.getInstance(this.project); + final GlobalInspectionContext context = inspectionManager.createNewGlobalContext(); + this.psiFiles.forEach(pf -> this.getProblemDescriptors(context, pf).forEach(this::writeQuickFixes)); + } + + private List getProblemDescriptors( + final GlobalInspectionContext context, + final PsiFile psiFile) + { + try + { + return InspectionEngine.runInspectionOnFile(psiFile, this.toolWrapper, context); + } + catch(final IndexNotReadyException exception) + { + LOGGER.info(String.format( + "Cannot inspect file %s: index not ready (%s)", + psiFile.getName(), + exception.getMessage())); + return Collections.emptyList(); + } + } + + @SuppressWarnings({"unchecked", "squid:S1905", "squid:S3740"}) + private void writeQuickFixes(final ProblemDescriptor problemDescriptor) + { + final QuickFix[] fixes = problemDescriptor.getFixes(); + if(fixes == null) + { + return; + } + + final Set> quickFixes = Arrays.stream(fixes) + .filter(Objects::nonNull) + .map(qf -> (QuickFix)qf) + .collect(Collectors.toSet()); + + for(final QuickFix typedFix : quickFixes) + { + try + { + LOGGER.info(String.format("Applying fix \"%s\"", typedFix.getName())); + typedFix.applyFix(this.project, problemDescriptor); + } + catch(final Exception e) + { + LOGGER.error(e.getMessage(), e); + } + } + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java index 89f0e81..a523d64 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java @@ -1,5 +1,13 @@ package software.xdev.saveactions.processors.java; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import java.util.stream.Stream; + import com.intellij.codeInspection.ExplicitTypeCanBeDiamondInspection; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.visibility.VisibilityInspection; @@ -17,6 +25,7 @@ import com.siyeh.ig.style.UnqualifiedFieldAccessInspection; import com.siyeh.ig.style.UnqualifiedMethodAccessInspection; import com.siyeh.ig.style.UnqualifiedStaticUsageInspection; + import software.xdev.saveactions.core.ExecutionMode; import software.xdev.saveactions.model.Action; import software.xdev.saveactions.processors.Processor; @@ -26,129 +35,146 @@ import software.xdev.saveactions.processors.java.inspection.SerializableHasSerialVersionUIDFieldInspectionWrapper; import software.xdev.saveactions.processors.java.inspection.style.CustomUnqualifiedStaticUsageInspection; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.Optional; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import java.util.stream.Stream; /** * Available processors for java. */ -public enum JavaProcessor implements Processor { - - fieldCanBeFinal(Action.fieldCanBeFinal, - FieldMayBeFinalInspection::new), - - localCanBeFinal(Action.localCanBeFinal, - CustomLocalCanBeFinal::new), - - localCanBeFinalExceptImplicit(Action.localCanBeFinalExceptImplicit, - () -> { - CustomLocalCanBeFinal resultInspection = new CustomLocalCanBeFinal(); - resultInspection.REPORT_IMPLICIT_FINALS = false; - return resultInspection; - }), - - methodMayBeStatic(Action.methodMayBeStatic, - MethodMayBeStaticInspection::new), - - unqualifiedFieldAccess(Action.unqualifiedFieldAccess, - UnqualifiedFieldAccessInspection::new), - - unqualifiedMethodAccess(Action.unqualifiedMethodAccess, - UnqualifiedMethodAccessInspection::new), - - unqualifiedStaticMemberAccess(Action.unqualifiedStaticMemberAccess, - () -> { - UnqualifiedStaticUsageInspection unqualifiedStaticUsageInspection = new UnqualifiedStaticUsageInspection(); - unqualifiedStaticUsageInspection.m_ignoreStaticFieldAccesses = false; - unqualifiedStaticUsageInspection.m_ignoreStaticMethodCalls = false; - unqualifiedStaticUsageInspection.m_ignoreStaticAccessFromStaticContext = false; - return unqualifiedStaticUsageInspection; - }), - - customUnqualifiedStaticMemberAccess(Action.customUnqualifiedStaticMemberAccess, - CustomUnqualifiedStaticUsageInspection::new), - - missingOverrideAnnotation(Action.missingOverrideAnnotation, - () -> { - MissingOverrideAnnotationInspection missingOverrideAnnotationInspection = new MissingOverrideAnnotationInspection(); - missingOverrideAnnotationInspection.ignoreObjectMethods = false; - return missingOverrideAnnotationInspection; - }), - - useBlocks(Action.useBlocks, - ControlFlowStatementWithoutBracesInspection::new), - - generateSerialVersionUID(Action.generateSerialVersionUID, - SerializableHasSerialVersionUIDFieldInspectionWrapper::get), - - unnecessaryThis(Action.unnecessaryThis, - UnnecessaryThisInspection::new), - - finalPrivateMethod(Action.finalPrivateMethod, - FinalPrivateMethodInspection::new), - - unnecessaryFinalOnLocalVariableOrParameter(Action.unnecessaryFinalOnLocalVariableOrParameter, - UnnecessaryFinalOnLocalVariableOrParameterInspection::new), - - explicitTypeCanBeDiamond(Action.explicitTypeCanBeDiamond, - ExplicitTypeCanBeDiamondInspection::new), - - unnecessarySemicolon(Action.unnecessarySemicolon, - UnnecessarySemicolonInspection::new), - - singleStatementInBlock(Action.singleStatementInBlock, - SingleStatementInBlockInspection::new), - - accessCanBeTightened(Action.accessCanBeTightened, - () -> new CustomAccessCanBeTightenedInspection(new VisibilityInspection())), - - ; - - private final Action action; - private final LocalInspectionTool inspection; - - JavaProcessor(Action action, Supplier inspection) { - this.action = action; - this.inspection = inspection.get(); - } - - @Override - public Action getAction() { - return action; - } - - @Override - public Set getModes() { - return EnumSet.allOf(ExecutionMode.class); - } - - @Override - public int getOrder() { - return 1; - } - - @Override - public SaveWriteCommand getSaveCommand(Project project, Set psiFiles) { - BiFunction command = - (p, f) -> new InspectionRunnable(project, psiFiles, getInspection()); - return new SaveWriteCommand(project, psiFiles, getModes(), getAction(), command); - } - - public LocalInspectionTool getInspection() { - return inspection; - } - - public static Optional getProcessorForAction(Action action) { - return stream().filter(processor -> processor.getAction().equals(action)).findFirst(); - } - - public static Stream stream() { - return Arrays.stream(values()); - } - +public enum JavaProcessor implements Processor +{ + fieldCanBeFinal( + Action.fieldCanBeFinal, + FieldMayBeFinalInspection::new), + + localCanBeFinal( + Action.localCanBeFinal, + CustomLocalCanBeFinal::new), + + localCanBeFinalExceptImplicit( + Action.localCanBeFinalExceptImplicit, + () -> { + CustomLocalCanBeFinal resultInspection = new CustomLocalCanBeFinal(); + resultInspection.REPORT_IMPLICIT_FINALS = false; + return resultInspection; + }), + + methodMayBeStatic( + Action.methodMayBeStatic, + MethodMayBeStaticInspection::new), + + unqualifiedFieldAccess( + Action.unqualifiedFieldAccess, + UnqualifiedFieldAccessInspection::new), + + unqualifiedMethodAccess( + Action.unqualifiedMethodAccess, + UnqualifiedMethodAccessInspection::new), + + unqualifiedStaticMemberAccess( + Action.unqualifiedStaticMemberAccess, + () -> { + UnqualifiedStaticUsageInspection unqualifiedStaticUsageInspection = new UnqualifiedStaticUsageInspection(); + unqualifiedStaticUsageInspection.m_ignoreStaticFieldAccesses = false; + unqualifiedStaticUsageInspection.m_ignoreStaticMethodCalls = false; + unqualifiedStaticUsageInspection.m_ignoreStaticAccessFromStaticContext = false; + return unqualifiedStaticUsageInspection; + }), + + customUnqualifiedStaticMemberAccess( + Action.customUnqualifiedStaticMemberAccess, + CustomUnqualifiedStaticUsageInspection::new), + + missingOverrideAnnotation( + Action.missingOverrideAnnotation, + () -> { + MissingOverrideAnnotationInspection missingOverrideAnnotationInspection = + new MissingOverrideAnnotationInspection(); + missingOverrideAnnotationInspection.ignoreObjectMethods = false; + return missingOverrideAnnotationInspection; + }), + + useBlocks( + Action.useBlocks, + ControlFlowStatementWithoutBracesInspection::new), + + generateSerialVersionUID( + Action.generateSerialVersionUID, + SerializableHasSerialVersionUIDFieldInspectionWrapper::get), + + unnecessaryThis( + Action.unnecessaryThis, + UnnecessaryThisInspection::new), + + finalPrivateMethod( + Action.finalPrivateMethod, + FinalPrivateMethodInspection::new), + + unnecessaryFinalOnLocalVariableOrParameter( + Action.unnecessaryFinalOnLocalVariableOrParameter, + UnnecessaryFinalOnLocalVariableOrParameterInspection::new), + + explicitTypeCanBeDiamond( + Action.explicitTypeCanBeDiamond, + ExplicitTypeCanBeDiamondInspection::new), + + unnecessarySemicolon( + Action.unnecessarySemicolon, + UnnecessarySemicolonInspection::new), + + singleStatementInBlock( + Action.singleStatementInBlock, + SingleStatementInBlockInspection::new), + + accessCanBeTightened( + Action.accessCanBeTightened, + () -> new CustomAccessCanBeTightenedInspection(new VisibilityInspection())); + + private final Action action; + private final LocalInspectionTool inspection; + + JavaProcessor(final Action action, final Supplier inspection) + { + this.action = action; + this.inspection = inspection.get(); + } + + @Override + public Action getAction() + { + return this.action; + } + + @Override + public Set getModes() + { + return EnumSet.allOf(ExecutionMode.class); + } + + @Override + public int getOrder() + { + return 1; + } + + @Override + public SaveWriteCommand getSaveCommand(final Project project, final Set psiFiles) + { + final BiFunction command = + (p, f) -> new InspectionRunnable(project, psiFiles, this.getInspection()); + return new SaveWriteCommand(project, psiFiles, this.getModes(), this.getAction(), command); + } + + public LocalInspectionTool getInspection() + { + return this.inspection; + } + + public static Optional getProcessorForAction(final Action action) + { + return stream().filter(processor -> processor.getAction().equals(action)).findFirst(); + } + + public static Stream stream() + { + return Arrays.stream(values()); + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java index 1d2e2d6..cc57dba 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/AccessibleVisibilityInspection.java @@ -1,45 +1,55 @@ package software.xdev.saveactions.processors.java.inspection; +import java.lang.reflect.Method; + +import org.jetbrains.annotations.NotNull; + import com.intellij.codeInspection.visibility.VisibilityInspection; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.PsiMember; import com.intellij.psi.SyntaxTraverser; -import org.jetbrains.annotations.NotNull; -import java.lang.reflect.Method; /** * Fork of {@link com.intellij.codeInspection.visibility.VisibilityInspection} but accessible for the plugin. */ -public final class AccessibleVisibilityInspection { - - private static final Logger LOG = Logger.getInstance(AccessibleVisibilityInspection.class); - - private AccessibleVisibilityInspection() { - } - - public static boolean containsReferenceTo(PsiElement source, PsiElement target) { - return SyntaxTraverser.psiTraverser(source) - .filter(PsiJavaCodeReferenceElement.class) - .filter(ref -> ref.isReferenceTo(target)) - .isNotEmpty(); - } - - // reflection is needed because VisibilityInspection members are private - @SuppressWarnings({"java:S3011"}) - public static int getMinVisibilityLevel(VisibilityInspection myVisibilityInspection, @NotNull PsiMember member) { - try { - Method getMinVisibilityLevel = myVisibilityInspection.getClass() - .getDeclaredMethod("getMinVisibilityLevel", PsiMember.class); - - getMinVisibilityLevel.setAccessible(true); - - return (int) getMinVisibilityLevel.invoke(myVisibilityInspection, member); - } catch (Exception e) { - LOG.error("Failed to invoke getMinVisibilityLevel", e); - throw new IllegalStateException(e); - } - } +public final class AccessibleVisibilityInspection +{ + private static final Logger LOG = Logger.getInstance(AccessibleVisibilityInspection.class); + + private AccessibleVisibilityInspection() + { + } + + public static boolean containsReferenceTo(final PsiElement source, final PsiElement target) + { + return SyntaxTraverser.psiTraverser(source) + .filter(PsiJavaCodeReferenceElement.class) + .filter(ref -> ref.isReferenceTo(target)) + .isNotEmpty(); + } + + // reflection is needed because VisibilityInspection members are private + @SuppressWarnings({"java:S3011"}) + public static int getMinVisibilityLevel( + final VisibilityInspection myVisibilityInspection, + @NotNull final PsiMember member) + { + try + { + final Method getMinVisibilityLevel = myVisibilityInspection.getClass() + .getDeclaredMethod("getMinVisibilityLevel", PsiMember.class); + + getMinVisibilityLevel.setAccessible(true); + + return (int)getMinVisibilityLevel.invoke(myVisibilityInspection, member); + } + catch(final Exception e) + { + LOG.error("Failed to invoke getMinVisibilityLevel", e); + throw new IllegalStateException(e); + } + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java index 8a37960..df01ad3 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java @@ -1,6 +1,14 @@ package software.xdev.saveactions.processors.java.inspection; //@formatter:off +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import com.intellij.codeInsight.daemon.impl.UnusedSymbolUtil; import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool; import com.intellij.codeInspection.InspectionsBundle; @@ -59,15 +67,9 @@ import com.siyeh.ig.fixes.ChangeModifierFix; import com.siyeh.ig.psiutils.MethodUtils; import com.siyeh.ig.visibility.ClassEscapesItsScopeInspection; + import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; /** * A public version of {@link com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection}. diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java index 7ed32c5..d32ba22 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomLocalCanBeFinal.java @@ -1,5 +1,11 @@ package software.xdev.saveactions.processors.java.inspection; +import java.util.Arrays; +import java.util.Optional; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.localCanBeFinal.LocalCanBeFinal; @@ -7,40 +13,41 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiTypeElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.Optional; @SuppressWarnings("InspectionDescriptionNotFoundInspection") -public class CustomLocalCanBeFinal extends LocalCanBeFinal { - - @Override - public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, - @NotNull InspectionManager manager, - boolean isOnTheFly) { - return checkProblemDescriptors(super.checkMethod(method, manager, isOnTheFly)); - } - - @Override - public ProblemDescriptor[] checkClass(@NotNull PsiClass aClass, - @NotNull InspectionManager manager, - boolean isOnTheFly) { - return checkProblemDescriptors(super.checkClass(aClass, manager, isOnTheFly)); - } - - private ProblemDescriptor[] checkProblemDescriptors(@Nullable ProblemDescriptor[] descriptors) { - return Arrays - .stream(Optional.ofNullable(descriptors).orElse(new ProblemDescriptor[0])) - .filter(descriptor -> isNotLombokVal(descriptor.getPsiElement())) - .toArray(ProblemDescriptor[]::new); - } - - private boolean isNotLombokVal(PsiElement element) { - return Arrays - .stream(element.getParent().getChildren()) - .noneMatch(child -> child instanceof PsiTypeElement && child.getText().equals("val")); - } - +public class CustomLocalCanBeFinal extends LocalCanBeFinal +{ + @Override + public ProblemDescriptor[] checkMethod( + @NotNull final PsiMethod method, + @NotNull final InspectionManager manager, + final boolean isOnTheFly) + { + return this.checkProblemDescriptors(super.checkMethod(method, manager, isOnTheFly)); + } + + @Override + public ProblemDescriptor[] checkClass( + @NotNull final PsiClass aClass, + @NotNull final InspectionManager manager, + final boolean isOnTheFly) + { + return this.checkProblemDescriptors(super.checkClass(aClass, manager, isOnTheFly)); + } + + private ProblemDescriptor[] checkProblemDescriptors(@Nullable final ProblemDescriptor[] descriptors) + { + return Arrays + .stream(Optional.ofNullable(descriptors).orElse(new ProblemDescriptor[0])) + .filter(descriptor -> this.isNotLombokVal(descriptor.getPsiElement())) + .toArray(ProblemDescriptor[]::new); + } + + private boolean isNotLombokVal(final PsiElement element) + { + return Arrays + .stream(element.getParent().getChildren()) + .noneMatch(child -> child instanceof PsiTypeElement && child.getText().equals("val")); + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java index 72c3e9c..a8348c4 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java @@ -1,15 +1,17 @@ package software.xdev.saveactions.processors.java.inspection; -import com.intellij.codeInspection.InspectionManager; -import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection; -import com.intellij.codeInspection.USerializableInspectionBase; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.uast.UClass; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection; +import com.intellij.codeInspection.USerializableInspectionBase; + + /** * Wrapper for the SerializableHasSerialVersionUidFieldInspection class. *

    @@ -17,33 +19,42 @@ * * @since IDEA 2021.3 */ -public class CustomSerializableHasSerialVersionUidFieldInspection extends USerializableInspectionBase { - - @SuppressWarnings("unchecked") - public CustomSerializableHasSerialVersionUidFieldInspection() { - super(UClass.class); - } - - @Override - public @NonNls @NotNull String getID() { - return "serial"; - } - - @Override - public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { - - return this.getClass().getSimpleName(); - } - - @Override - public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getGroupDisplayName() { - - return "SaveActionsInternal"; - } - - @Override - public ProblemDescriptor @Nullable [] checkClass(@NotNull UClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) { - SerializableHasSerialVersionUidFieldInspection inspection = new SerializableHasSerialVersionUidFieldInspection(); - return inspection.checkClass(aClass, manager, true); - } +public class CustomSerializableHasSerialVersionUidFieldInspection extends USerializableInspectionBase +{ + @SuppressWarnings("unchecked") + public CustomSerializableHasSerialVersionUidFieldInspection() + { + super(UClass.class); + } + + @Override + public @NonNls @NotNull String getID() + { + return "serial"; + } + + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() + { + + return this.getClass().getSimpleName(); + } + + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getGroupDisplayName() + { + + return "SaveActionsInternal"; + } + + @Override + public ProblemDescriptor @Nullable [] checkClass( + @NotNull final UClass aClass, + @NotNull final InspectionManager manager, + final boolean isOnTheFly) + { + final SerializableHasSerialVersionUidFieldInspection inspection = + new SerializableHasSerialVersionUidFieldInspection(); + return inspection.checkClass(aClass, manager, true); + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java index 891c572..58111b3 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/SerializableHasSerialVersionUIDFieldInspectionWrapper.java @@ -1,66 +1,78 @@ package software.xdev.saveactions.processors.java.inspection; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.Objects; + import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.openapi.diagnostic.Logger; + import software.xdev.saveactions.core.service.SaveActionsService; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.Objects; /** * This class changes package between intellij versions. * * @see com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection */ -public class SerializableHasSerialVersionUIDFieldInspectionWrapper { - - private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); - - private SerializableHasSerialVersionUIDFieldInspectionWrapper() { - } - - public static LocalInspectionTool get() { - return Arrays.stream(SerializableClass.values()) - .map(SerializableClass::getInspectionInstance) - .filter(Objects::nonNull) - .findFirst() - .orElseThrow(() -> new IllegalStateException( - "Cannot find inspection tool SerializableHasSerialVersionUIDFieldInspection")); - } - - private enum SerializableClass { - CLASS_NAME_INTELLIJ_2021_3("com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection", - "software.xdev.saveactions.processors.java.inspection.CustomSerializableHasSerialVersionUidFieldInspection"); - - /** - * Field className: Inspection class provided by IDE - */ - private final String className; - - /** - * Field targetClass: Inspection class to run. Needed to apply wrapper class for Idea 2021.3 and up. - * - * @see CustomSerializableHasSerialVersionUidFieldInspection - */ - private final String targetClass; - - SerializableClass(String className, String targetClass) { - this.className = className; - this.targetClass = targetClass; - } - - public LocalInspectionTool getInspectionInstance() { - try { - Class.forName(className).asSubclass(LocalInspectionTool.class); - Class targetInspectionClass = - Class.forName(targetClass).asSubclass(LocalInspectionTool.class); - LOGGER.info(String.format("Found serial version uid class %s", targetInspectionClass.getName())); - return targetInspectionClass.cast(targetInspectionClass.getDeclaredConstructor().newInstance()); - } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException - | InvocationTargetException e) { - return null; - } - } - } +public final class SerializableHasSerialVersionUIDFieldInspectionWrapper +{ + private static final Logger LOGGER = Logger.getInstance(SaveActionsService.class); + + private SerializableHasSerialVersionUIDFieldInspectionWrapper() + { + } + + public static LocalInspectionTool get() + { + return Arrays.stream(SerializableClass.values()) + .map(SerializableClass::getInspectionInstance) + .filter(Objects::nonNull) + .findFirst() + .orElseThrow(() -> new IllegalStateException( + "Cannot find inspection tool SerializableHasSerialVersionUIDFieldInspection")); + } + + private enum SerializableClass + { + CLASS_NAME_INTELLIJ_2021_3( + "com.intellij.codeInspection.SerializableHasSerialVersionUidFieldInspection", + "software.xdev.saveactions.processors.java.inspection" + + ".CustomSerializableHasSerialVersionUidFieldInspection"); + + /** + * Field className: Inspection class provided by IDE + */ + private final String className; + + /** + * Field targetClass: Inspection class to run. Needed to apply wrapper class for Idea 2021.3 and up. + * + * @see CustomSerializableHasSerialVersionUidFieldInspection + */ + private final String targetClass; + + SerializableClass(final String className, final String targetClass) + { + this.className = className; + this.targetClass = targetClass; + } + + public LocalInspectionTool getInspectionInstance() + { + try + { + Class.forName(this.className).asSubclass(LocalInspectionTool.class); + final Class targetInspectionClass = + Class.forName(this.targetClass).asSubclass(LocalInspectionTool.class); + LOGGER.info(String.format("Found serial version uid class %s", targetInspectionClass.getName())); + return targetInspectionClass.cast(targetInspectionClass.getDeclaredConstructor().newInstance()); + } + catch(final ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException + | InvocationTargetException e) + { + return null; + } + } + } } diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java index 53ad808..2954f56 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java @@ -1,5 +1,8 @@ package software.xdev.saveactions.processors.java.inspection.style; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + import com.intellij.psi.JavaResolveResult; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; @@ -17,8 +20,7 @@ import com.intellij.psi.util.PsiUtil; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.style.UnqualifiedStaticUsageInspection; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; + /** * Copy pasting because: cannot extend. Do not reformat (useful for diffs) @@ -27,83 +29,100 @@ * {@link com.siyeh.ig.GroupDisplayNameUtil} * @see com.siyeh.ig.style.UnqualifiedStaticUsageInspection.UnqualifiedStaticCallVisitor */ -public class CustomUnqualifiedStaticUsageInspection extends UnqualifiedStaticUsageInspection { - - @Override - public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { - return getClass().getSimpleName(); - } - - @Override - public BaseInspectionVisitor buildVisitor() { - return new CustomUnqualifiedStaticCallVisitor(); - } - - private class CustomUnqualifiedStaticCallVisitor extends BaseInspectionVisitor { - @Override - public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { - super.visitMethodCallExpression(expression); - if (m_ignoreStaticMethodCalls) { - return; - } - PsiReferenceExpression methodExpression = expression.getMethodExpression(); - if (!isUnqualifiedStaticAccess(methodExpression)) { - return; - } - registerError(methodExpression, expression); - } - - @Override - public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { - super.visitReferenceExpression(expression); - if (m_ignoreStaticFieldAccesses) { - return; - } - PsiElement element = expression.resolve(); - if (!(element instanceof PsiField)) { - return; - } - PsiField field = (PsiField) element; - if (field.hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isOnAssignmentLeftHand(expression)) { - return; - } - if (!isUnqualifiedStaticAccess(expression)) { - return; - } - registerError(expression, expression); - } - - private boolean isUnqualifiedStaticAccess(PsiReferenceExpression expression) { - if (m_ignoreStaticAccessFromStaticContext) { - PsiMember member = PsiTreeUtil.getParentOfType(expression, PsiMember.class); - if (member != null && member.hasModifierProperty(PsiModifier.STATIC)) { - return false; - } - } - PsiExpression qualifierExpression = expression.getQualifierExpression(); - if (qualifierExpression != null) { - return false; - } - JavaResolveResult resolveResult = expression.advancedResolve(false); - PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope(); - if (currentFileResolveScope instanceof PsiImportStaticStatement) { - return false; - } - PsiElement element = resolveResult.getElement(); - if (!(element instanceof PsiField) && !(element instanceof PsiMethod)) { - return false; - } - PsiMember member = (PsiMember) element; - if (member instanceof PsiEnumConstant && expression.getParent() instanceof PsiSwitchLabelStatement) { - return false; - } - PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); - PsiClass memberClass = member.getContainingClass(); - if (memberClass != null && memberClass.equals(expressionClass)) { - return false; - } - return member.hasModifierProperty(PsiModifier.STATIC); - } - } - +public class CustomUnqualifiedStaticUsageInspection extends UnqualifiedStaticUsageInspection +{ + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() + { + return this.getClass().getSimpleName(); + } + + @Override + public BaseInspectionVisitor buildVisitor() + { + return new CustomUnqualifiedStaticCallVisitor(); + } + + private final class CustomUnqualifiedStaticCallVisitor extends BaseInspectionVisitor + { + @Override + public void visitMethodCallExpression(@NotNull final PsiMethodCallExpression expression) + { + super.visitMethodCallExpression(expression); + if(CustomUnqualifiedStaticUsageInspection.this.m_ignoreStaticMethodCalls) + { + return; + } + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + if(!this.isUnqualifiedStaticAccess(methodExpression)) + { + return; + } + this.registerError(methodExpression, expression); + } + + @Override + public void visitReferenceExpression(@NotNull final PsiReferenceExpression expression) + { + super.visitReferenceExpression(expression); + if(CustomUnqualifiedStaticUsageInspection.this.m_ignoreStaticFieldAccesses) + { + return; + } + final PsiElement element = expression.resolve(); + if(!(element instanceof final PsiField field)) + { + return; + } + if(field.hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isOnAssignmentLeftHand(expression)) + { + return; + } + if(!this.isUnqualifiedStaticAccess(expression)) + { + return; + } + this.registerError(expression, expression); + } + + private boolean isUnqualifiedStaticAccess(final PsiReferenceExpression expression) + { + if(CustomUnqualifiedStaticUsageInspection.this.m_ignoreStaticAccessFromStaticContext) + { + final PsiMember member = PsiTreeUtil.getParentOfType(expression, PsiMember.class); + if(member != null && member.hasModifierProperty(PsiModifier.STATIC)) + { + return false; + } + } + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if(qualifierExpression != null) + { + return false; + } + final JavaResolveResult resolveResult = expression.advancedResolve(false); + final PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope(); + if(currentFileResolveScope instanceof PsiImportStaticStatement) + { + return false; + } + final PsiElement element = resolveResult.getElement(); + if(!(element instanceof PsiField) && !(element instanceof PsiMethod)) + { + return false; + } + final PsiMember member = (PsiMember)element; + if(member instanceof PsiEnumConstant && expression.getParent() instanceof PsiSwitchLabelStatement) + { + return false; + } + final PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); + final PsiClass memberClass = member.getContainingClass(); + if(memberClass != null && memberClass.equals(expressionClass)) + { + return false; + } + return member.hasModifierProperty(PsiModifier.STATIC); + } + } } diff --git a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java index a2fad2e..309d08f 100644 --- a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java @@ -1,12 +1,17 @@ package software.xdev.saveactions.ui; -import com.intellij.openapi.actionSystem.ex.QuickList; -import com.intellij.openapi.actionSystem.ex.QuickListsManager; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.ui.IdeBorderFactory; -import org.jdesktop.swingx.combobox.ListComboBoxModel; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; -import software.xdev.saveactions.model.Action; +import static java.text.MessageFormat.format; +import static java.util.Comparator.comparing; +import static software.xdev.saveactions.model.Action.compile; +import static software.xdev.saveactions.model.Action.executeAction; +import static software.xdev.saveactions.model.Action.reload; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import javax.swing.Box; import javax.swing.BoxLayout; @@ -16,143 +21,159 @@ import javax.swing.JPanel; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import static java.text.MessageFormat.format; -import static java.util.Comparator.comparing; -import static software.xdev.saveactions.model.Action.compile; -import static software.xdev.saveactions.model.Action.executeAction; -import static software.xdev.saveactions.model.Action.reload; - -class BuildPanel { - - private static final String TEXT_TITLE_ACTIONS = "Build Actions"; - private static final int QUICK_LIST_MAX_DESCRIPTION_LENGTH = 100; - - private final List quickLists; - private final List quickListElements; - private final ListComboBoxModel quickListModel; - private final JPanel panel; - - BuildPanel(Map checkboxes, List quickLists) { - this.quickLists = quickLists; - quickListElements = new ArrayList<>(); - quickListModel = new ListComboBoxModel<>(quickListElements); - quickListModel.addListDataListener(getListDataListener(quickLists)); - panel = new JPanel(); - panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); - panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); - if (SaveActionsServiceManager.getService().isCompilingAvailable()) { - panel.add(wrap(checkboxes.get(compile), null)); - panel.add(wrap(checkboxes.get(reload), null)); - } - @SuppressWarnings("unchecked") - JComboBox comboBox = new ComboBox<>(quickListModel); - panel.add(wrap(checkboxes.get(executeAction), comboBox)); - panel.add(Box.createHorizontalGlue()); - panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); - } - - JPanel getPanel() { - return panel; - } - - void update() { - List quickListWrappers = Arrays - .stream(QuickListsManager.getInstance().getAllQuickLists()) - .map(QuickListWrapper::new) - .sorted(comparing(QuickListWrapper::toString)) - .toList(); - quickListElements.clear(); - quickListElements.addAll(quickListWrappers); - if (!quickLists.isEmpty()) { - String selectedItem = quickLists.get(0); - quickListElements.stream() - .filter(wrapper -> wrapper.hasId(selectedItem)) - .findFirst() - .ifPresent(quickListModel::setSelectedItem); - } - } - - private JComponent wrap(JCheckBox checkBox, @SuppressWarnings("rawtypes") JComboBox comboBox) { - JPanel wrapper = new JPanel(); - wrapper.setLayout(new BorderLayout()); - wrapper.add(checkBox, BorderLayout.WEST); - if (comboBox != null) { - checkBox.addChangeListener(e -> { - comboBox.setEnabled(checkBox.isSelected()); - update(); - }); - comboBox.setEnabled(checkBox.isSelected()); - wrapper.add(comboBox, BorderLayout.SOUTH); - } - wrapper.setMaximumSize(new Dimension(3000, 100)); - return wrapper; - } - - private static class QuickListWrapper { - - private final QuickList quickList; - - private QuickListWrapper(QuickList quickList) { - this.quickList = quickList; - } - - private boolean hasId(String id) { - return getId().equals(id); - } - - private String getId() { - return quickList.hashCode() + ""; - } - - @Override - public String toString() { - String name = quickList.getName(); - String description = quickList.getDescription(); - if (description == null) { - return name; - } - if (description.length() > QUICK_LIST_MAX_DESCRIPTION_LENGTH) { - description = description.substring(0, QUICK_LIST_MAX_DESCRIPTION_LENGTH); - description = description + "..."; - } - return format("{0} ({1})", name, description); - } - - } - - private ListDataListener getListDataListener(List quickLists) { - return new ListDataListener() { - - @Override - public void intervalAdded(ListDataEvent ignored) { - //not used. - } +import org.jdesktop.swingx.combobox.ListComboBoxModel; - @Override - public void intervalRemoved(ListDataEvent ignored) { - //not used. - } +import com.intellij.openapi.actionSystem.ex.QuickList; +import com.intellij.openapi.actionSystem.ex.QuickListsManager; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.ui.IdeBorderFactory; - @Override - public void contentsChanged(ListDataEvent e) { - @SuppressWarnings("rawtypes") - ListComboBoxModel source = (ListComboBoxModel) e.getSource(); - QuickListWrapper selectedItem = (QuickListWrapper) source.getSelectedItem(); - if (selectedItem == null) { - return; - } - quickLists.clear(); - quickLists.add(selectedItem.getId()); - } +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; - }; - } +class BuildPanel +{ + private static final String TEXT_TITLE_ACTIONS = "Build Actions"; + private static final int QUICK_LIST_MAX_DESCRIPTION_LENGTH = 100; + + private final List quickLists; + private final List quickListElements; + private final ListComboBoxModel quickListModel; + private final JPanel panel; + + BuildPanel(final Map checkboxes, final List quickLists) + { + this.quickLists = quickLists; + this.quickListElements = new ArrayList<>(); + this.quickListModel = new ListComboBoxModel<>(this.quickListElements); + this.quickListModel.addListDataListener(this.getListDataListener(quickLists)); + this.panel = new JPanel(); + this.panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); + this.panel.setLayout(new BoxLayout(this.panel, BoxLayout.PAGE_AXIS)); + if(SaveActionsServiceManager.getService().isCompilingAvailable()) + { + this.panel.add(this.wrap(checkboxes.get(compile), null)); + this.panel.add(this.wrap(checkboxes.get(reload), null)); + } + @SuppressWarnings("unchecked") + final JComboBox comboBox = new ComboBox<>(this.quickListModel); + this.panel.add(this.wrap(checkboxes.get(executeAction), comboBox)); + this.panel.add(Box.createHorizontalGlue()); + this.panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); + } + + JPanel getPanel() + { + return this.panel; + } + + void update() + { + final List quickListWrappers = Arrays + .stream(QuickListsManager.getInstance().getAllQuickLists()) + .map(QuickListWrapper::new) + .sorted(comparing(QuickListWrapper::toString)) + .toList(); + this.quickListElements.clear(); + this.quickListElements.addAll(quickListWrappers); + if(!this.quickLists.isEmpty()) + { + final String selectedItem = this.quickLists.get(0); + this.quickListElements.stream() + .filter(wrapper -> wrapper.hasId(selectedItem)) + .findFirst() + .ifPresent(this.quickListModel::setSelectedItem); + } + } + + @SuppressWarnings("checkstyle:MagicNumber") + private JComponent wrap(final JCheckBox checkBox, @SuppressWarnings("rawtypes") final JComboBox comboBox) + { + final JPanel wrapper = new JPanel(); + wrapper.setLayout(new BorderLayout()); + wrapper.add(checkBox, BorderLayout.WEST); + if(comboBox != null) + { + checkBox.addChangeListener(e -> { + comboBox.setEnabled(checkBox.isSelected()); + this.update(); + }); + comboBox.setEnabled(checkBox.isSelected()); + wrapper.add(comboBox, BorderLayout.SOUTH); + } + wrapper.setMaximumSize(new Dimension(3000, 100)); + return wrapper; + } + + private static final class QuickListWrapper + { + private final QuickList quickList; + + private QuickListWrapper(final QuickList quickList) + { + this.quickList = quickList; + } + + private boolean hasId(final String id) + { + return this.getId().equals(id); + } + + private String getId() + { + return this.quickList.hashCode() + ""; + } + + @Override + public String toString() + { + final String name = this.quickList.getName(); + String description = this.quickList.getDescription(); + if(description == null) + { + return name; + } + if(description.length() > QUICK_LIST_MAX_DESCRIPTION_LENGTH) + { + description = description.substring(0, QUICK_LIST_MAX_DESCRIPTION_LENGTH); + description = description + "..."; + } + return format("{0} ({1})", name, description); + } + } + + private ListDataListener getListDataListener(final List quickLists) + { + return new ListDataListener() + { + + @Override + public void intervalAdded(final ListDataEvent ignored) + { + // not used. + } + + @Override + public void intervalRemoved(final ListDataEvent ignored) + { + // not used. + } + + @Override + public void contentsChanged(final ListDataEvent e) + { + @SuppressWarnings("rawtypes") + final ListComboBoxModel source = (ListComboBoxModel)e.getSource(); + final QuickListWrapper selectedItem = (QuickListWrapper)source.getSelectedItem(); + if(selectedItem == null) + { + return; + } + quickLists.clear(); + quickLists.add(selectedItem.getId()); + } + }; + } } diff --git a/src/main/java/software/xdev/saveactions/ui/Configuration.java b/src/main/java/software/xdev/saveactions/ui/Configuration.java index 6c9d641..fd02c96 100644 --- a/src/main/java/software/xdev/saveactions/ui/Configuration.java +++ b/src/main/java/software/xdev/saveactions/ui/Configuration.java @@ -1,20 +1,15 @@ package software.xdev.saveactions.ui; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.Nullable; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.model.Storage; -import software.xdev.saveactions.model.java.EpfStorage; -import software.xdev.saveactions.ui.java.IdeSupportPanel; -import software.xdev.saveactions.ui.java.InspectionPanel; +import static software.xdev.saveactions.model.Action.activate; +import static software.xdev.saveactions.model.Action.activateOnBatch; +import static software.xdev.saveactions.model.Action.activateOnShortcut; +import static software.xdev.saveactions.model.Action.compile; +import static software.xdev.saveactions.model.Action.customUnqualifiedStaticMemberAccess; +import static software.xdev.saveactions.model.Action.reformat; +import static software.xdev.saveactions.model.Action.reformatChangedCode; +import static software.xdev.saveactions.model.Action.reload; +import static software.xdev.saveactions.model.Action.unqualifiedStaticMemberAccess; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JCheckBox; -import javax.swing.JComponent; -import javax.swing.JPanel; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -27,255 +22,301 @@ import java.util.Map; import java.util.Set; -import static software.xdev.saveactions.model.Action.activate; -import static software.xdev.saveactions.model.Action.activateOnBatch; -import static software.xdev.saveactions.model.Action.activateOnShortcut; -import static software.xdev.saveactions.model.Action.compile; -import static software.xdev.saveactions.model.Action.customUnqualifiedStaticMemberAccess; -import static software.xdev.saveactions.model.Action.reformat; -import static software.xdev.saveactions.model.Action.reformatChangedCode; -import static software.xdev.saveactions.model.Action.reload; -import static software.xdev.saveactions.model.Action.unqualifiedStaticMemberAccess; - -public class Configuration implements Configurable { - - public static final int BOX_LAYOUT_MAX_WIDTH = 3000; - public static final int BOX_LAYOUT_MAX_HEIGHT = 100; - - private static final String TEXT_DISPLAY_NAME = "Save Actions"; - - private final Storage storage; - - private final Set exclusions = new HashSet<>(); - private final Set inclusions = new HashSet<>(); - private final List quickLists = new ArrayList<>(); - private final Map checkboxes = new EnumMap<>(Action.class); - private final ActionListener checkboxActionListener = this::updateCheckboxEnabled; - - private GeneralPanel generalPanel; - private FormattingPanel formattingPanel; - private BuildPanel buildPanel; - private InspectionPanel inspectionPanel; - private FileMaskPanel fileMasksExclusionPanel; - private FileMaskPanel fileMasksInclusionPanel; - private IdeSupportPanel ideSupport; - - public Configuration(Project project) { - storage = project.getService(Storage.class); - } - - @Nullable - @Override - public JComponent createComponent() { - JPanel panel = initComponent(); - initFirstLaunch(); - initActionListeners(); - return panel; - } - - private void initFirstLaunch() { - if (storage.isFirstLaunch()) { - updateSelectedStateOfCheckboxes(Action.getDefaults()); - storage.stopFirstLaunch(); - } - } - - private void initActionListeners() { - for (Map.Entry checkbox : checkboxes.entrySet()) { - checkbox.getValue().addActionListener(checkboxActionListener); - } - } - - @Override - public boolean isModified() { - for (Map.Entry checkbox : checkboxes.entrySet()) { - if (storage.isEnabled(checkbox.getKey()) != checkbox.getValue().isSelected()) { - return true; - } - } - if (storage.getConfigurationPath() != null - && !storage.getConfigurationPath().equals(ideSupport.getPath())) { - return true; - } - return !storage.getExclusions().equals(exclusions) - || !storage.getInclusions().equals(inclusions) - || !storage.getQuickLists().equals(quickLists); - } - - @Override - public void apply() { - for (Map.Entry checkbox : checkboxes.entrySet()) { - storage.setEnabled(checkbox.getKey(), checkbox.getValue().isSelected()); - } - storage.setExclusions(new HashSet<>(exclusions)); - storage.setInclusions(new HashSet<>(inclusions)); - storage.setQuickLists(new ArrayList<>(quickLists)); - storage.setConfigurationPath(ideSupport.getPath()); - Storage efpStorage = EpfStorage.INSTANCE.getStorageOrDefault(ideSupport.getPath(), storage); - updateSelectedStateOfCheckboxes(efpStorage.getActions()); - updateCheckboxEnabled(null); - } - - @Override - public void reset() { - updateSelectedStateOfCheckboxes(storage.getActions()); - updateCheckboxEnabled(null); - updateExclusions(); - updateInclusions(); - updateQuickLists(); - ideSupport.setPath(storage.getConfigurationPath()); - } - - private void updateSelectedStateOfCheckboxes(Set selectedActions) { - for (Map.Entry checkbox : checkboxes.entrySet()) { - boolean isSelected = selectedActions.contains(checkbox.getKey()); - checkbox.getValue().setSelected(isSelected); - } - } - - @Override - public void disposeUIResources() { - checkboxes.clear(); - exclusions.clear(); - inclusions.clear(); - quickLists.clear(); - generalPanel = null; - formattingPanel = null; - buildPanel = null; - inspectionPanel = null; - fileMasksInclusionPanel = null; - fileMasksExclusionPanel = null; - ideSupport = null; - } - - @Nls - @Override - public String getDisplayName() { - return TEXT_DISPLAY_NAME; - } - - @Nullable - @Override - public String getHelpTopic() { - return null; - } - - private JPanel initComponent() { - for (Action action : Action.values()) { - checkboxes.put(action, new JCheckBox(action.getText())); - } - generalPanel = new GeneralPanel(checkboxes); - formattingPanel = new FormattingPanel(checkboxes); - buildPanel = new BuildPanel(checkboxes, quickLists); - inspectionPanel = new InspectionPanel(checkboxes); - fileMasksInclusionPanel = new FileMaskInclusionPanel(inclusions); - fileMasksExclusionPanel = new FileMaskExclusionPanel(exclusions); - ideSupport = new IdeSupportPanel(); - return initRootPanel( - generalPanel.getPanel(), - formattingPanel.getPanel(), - buildPanel.getPanel(), - inspectionPanel.getPanel(), - fileMasksInclusionPanel.getPanel(), - fileMasksExclusionPanel.getPanel(), - ideSupport.getPanel(storage.getConfigurationPath()) - ); - } - - private JPanel initRootPanel(JPanel general, JPanel actions, JPanel build, JPanel inspections, - JPanel fileMasksInclusions, JPanel fileMasksExclusions, - JPanel ideSupport) { - JPanel panel = new JPanel(); - panel.setLayout(new GridBagLayout()); - GridBagConstraints c = new GridBagConstraints(); - c.anchor = GridBagConstraints.NORTH; - c.fill = GridBagConstraints.HORIZONTAL; - c.weightx = 1; - c.gridx = 0; - - c.gridy = 0; - panel.add(general, c); - c.gridy = 1; - panel.add(actions, c); - c.gridy = 2; - panel.add(build, c); - c.gridy = 3; - panel.add(inspections, c); - - JPanel fileMaskPanel = new JPanel(); - fileMaskPanel.setLayout(new BoxLayout(fileMaskPanel, BoxLayout.LINE_AXIS)); - fileMaskPanel.add(fileMasksInclusions); - fileMaskPanel.add(Box.createRigidArea(new Dimension(10, 0))); - fileMaskPanel.add(fileMasksExclusions); - c.gridy = 4; - panel.add(fileMaskPanel, c); - - c.gridy = 5; - panel.add(ideSupport, c); - - c.gridy = 6; - c.weighty = 1; - c.fill = GridBagConstraints.BOTH; - JPanel filler = new JPanel(); - filler.setOpaque(false); - panel.add(filler, c); - - return panel; - } - - private void updateInclusions() { - inclusions.clear(); - inclusions.addAll(storage.getInclusions()); - fileMasksInclusionPanel.update(inclusions); - } - - private void updateExclusions() { - exclusions.clear(); - exclusions.addAll(storage.getExclusions()); - fileMasksExclusionPanel.update(exclusions); - } +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JPanel; - private void updateQuickLists() { - quickLists.clear(); - quickLists.addAll(storage.getQuickLists()); - buildPanel.update(); - } +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; - private void updateCheckboxEnabled(ActionEvent event) { - updateCheckboxEnabledIfActiveSelected(); - updateCheckboxGroupExclusive(event, reformat, reformatChangedCode); - updateCheckboxGroupExclusive(event, compile, reload); - updateCheckboxGroupExclusive(event, unqualifiedStaticMemberAccess, customUnqualifiedStaticMemberAccess); - } +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.project.Project; - private void updateCheckboxEnabledIfActiveSelected() { - for (Map.Entry checkbox : checkboxes.entrySet()) { - Action currentCheckBoxKey = checkbox.getKey(); - if (!activate.equals(currentCheckBoxKey) - && !activateOnShortcut.equals(currentCheckBoxKey) - && !activateOnBatch.equals(currentCheckBoxKey)) { - checkbox.getValue().setEnabled(isActiveSelected()); - } - } - } +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; +import software.xdev.saveactions.model.java.EpfStorage; +import software.xdev.saveactions.ui.java.IdeSupportPanel; +import software.xdev.saveactions.ui.java.InspectionPanel; - private void updateCheckboxGroupExclusive(ActionEvent event, Action checkbox1, Action checkbox2) { - if (event == null || !(event.getSource() instanceof JCheckBox thisCheckbox)) { - return; - } - if (thisCheckbox.isSelected()) { - if (thisCheckbox == checkboxes.get(checkbox1)) { - checkboxes.get(checkbox2).setSelected(false); - } else if (thisCheckbox == checkboxes.get(checkbox2)) { - checkboxes.get(checkbox1).setSelected(false); - } - } - } - private boolean isActiveSelected() { - boolean activateIsSelected = checkboxes.get(activate).isSelected(); - boolean activateShortcutIsSelected = checkboxes.get(activateOnShortcut).isSelected(); - boolean activateBatchIsSelected = checkboxes.get(activateOnBatch).isSelected(); - return activateIsSelected || activateShortcutIsSelected || activateBatchIsSelected; - } +public class Configuration implements Configurable +{ + public static final int BOX_LAYOUT_MAX_WIDTH = 3000; + public static final int BOX_LAYOUT_MAX_HEIGHT = 100; + + private static final String TEXT_DISPLAY_NAME = "Save Actions"; + + private final Storage storage; + + private final Set exclusions = new HashSet<>(); + private final Set inclusions = new HashSet<>(); + private final List quickLists = new ArrayList<>(); + private final Map checkboxes = new EnumMap<>(Action.class); + private final ActionListener checkboxActionListener = this::updateCheckboxEnabled; + + private GeneralPanel generalPanel; + private FormattingPanel formattingPanel; + private BuildPanel buildPanel; + private InspectionPanel inspectionPanel; + private FileMaskPanel fileMasksExclusionPanel; + private FileMaskPanel fileMasksInclusionPanel; + private IdeSupportPanel ideSupport; + + public Configuration(final Project project) + { + this.storage = project.getService(Storage.class); + } + + @Nullable + @Override + public JComponent createComponent() + { + final JPanel panel = this.initComponent(); + this.initFirstLaunch(); + this.initActionListeners(); + return panel; + } + + private void initFirstLaunch() + { + if(this.storage.isFirstLaunch()) + { + this.updateSelectedStateOfCheckboxes(Action.getDefaults()); + this.storage.stopFirstLaunch(); + } + } + + private void initActionListeners() + { + for(final Map.Entry checkbox : this.checkboxes.entrySet()) + { + checkbox.getValue().addActionListener(this.checkboxActionListener); + } + } + + @Override + public boolean isModified() + { + for(final Map.Entry checkbox : this.checkboxes.entrySet()) + { + if(this.storage.isEnabled(checkbox.getKey()) != checkbox.getValue().isSelected()) + { + return true; + } + } + if(this.storage.getConfigurationPath() != null + && !this.storage.getConfigurationPath().equals(this.ideSupport.getPath())) + { + return true; + } + return !this.storage.getExclusions().equals(this.exclusions) + || !this.storage.getInclusions().equals(this.inclusions) + || !this.storage.getQuickLists().equals(this.quickLists); + } + + @Override + public void apply() + { + for(final Map.Entry checkbox : this.checkboxes.entrySet()) + { + this.storage.setEnabled(checkbox.getKey(), checkbox.getValue().isSelected()); + } + this.storage.setExclusions(new HashSet<>(this.exclusions)); + this.storage.setInclusions(new HashSet<>(this.inclusions)); + this.storage.setQuickLists(new ArrayList<>(this.quickLists)); + this.storage.setConfigurationPath(this.ideSupport.getPath()); + final Storage efpStorage = EpfStorage.INSTANCE.getStorageOrDefault(this.ideSupport.getPath(), this.storage); + this.updateSelectedStateOfCheckboxes(efpStorage.getActions()); + this.updateCheckboxEnabled(null); + } + + @Override + public void reset() + { + this.updateSelectedStateOfCheckboxes(this.storage.getActions()); + this.updateCheckboxEnabled(null); + this.updateExclusions(); + this.updateInclusions(); + this.updateQuickLists(); + this.ideSupport.setPath(this.storage.getConfigurationPath()); + } + + private void updateSelectedStateOfCheckboxes(final Set selectedActions) + { + for(final Map.Entry checkbox : this.checkboxes.entrySet()) + { + final boolean isSelected = selectedActions.contains(checkbox.getKey()); + checkbox.getValue().setSelected(isSelected); + } + } + + @Override + public void disposeUIResources() + { + this.checkboxes.clear(); + this.exclusions.clear(); + this.inclusions.clear(); + this.quickLists.clear(); + this.generalPanel = null; + this.formattingPanel = null; + this.buildPanel = null; + this.inspectionPanel = null; + this.fileMasksInclusionPanel = null; + this.fileMasksExclusionPanel = null; + this.ideSupport = null; + } + + @Nls + @Override + public String getDisplayName() + { + return TEXT_DISPLAY_NAME; + } + + @Nullable + @Override + public String getHelpTopic() + { + return null; + } + + private JPanel initComponent() + { + for(final Action action : Action.values()) + { + this.checkboxes.put(action, new JCheckBox(action.getText())); + } + this.generalPanel = new GeneralPanel(this.checkboxes); + this.formattingPanel = new FormattingPanel(this.checkboxes); + this.buildPanel = new BuildPanel(this.checkboxes, this.quickLists); + this.inspectionPanel = new InspectionPanel(this.checkboxes); + this.fileMasksInclusionPanel = new FileMaskInclusionPanel(this.inclusions); + this.fileMasksExclusionPanel = new FileMaskExclusionPanel(this.exclusions); + this.ideSupport = new IdeSupportPanel(); + return this.initRootPanel( + this.generalPanel.getPanel(), + this.formattingPanel.getPanel(), + this.buildPanel.getPanel(), + this.inspectionPanel.getPanel(), + this.fileMasksInclusionPanel.getPanel(), + this.fileMasksExclusionPanel.getPanel(), + this.ideSupport.getPanel(this.storage.getConfigurationPath()) + ); + } + + @SuppressWarnings("checkstyle:MagicNumber") + private JPanel initRootPanel( + final JPanel general, final JPanel actions, final JPanel build, final JPanel inspections, + final JPanel fileMasksInclusions, final JPanel fileMasksExclusions, + final JPanel ideSupport) + { + final JPanel panel = new JPanel(); + panel.setLayout(new GridBagLayout()); + final GridBagConstraints c = new GridBagConstraints(); + c.anchor = GridBagConstraints.NORTH; + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 1; + c.gridx = 0; + + c.gridy = 0; + panel.add(general, c); + c.gridy = 1; + panel.add(actions, c); + c.gridy = 2; + panel.add(build, c); + c.gridy = 3; + panel.add(inspections, c); + + final JPanel fileMaskPanel = new JPanel(); + fileMaskPanel.setLayout(new BoxLayout(fileMaskPanel, BoxLayout.LINE_AXIS)); + fileMaskPanel.add(fileMasksInclusions); + fileMaskPanel.add(Box.createRigidArea(new Dimension(10, 0))); + fileMaskPanel.add(fileMasksExclusions); + c.gridy = 4; + panel.add(fileMaskPanel, c); + + c.gridy = 5; + panel.add(ideSupport, c); + + c.gridy = 6; + c.weighty = 1; + c.fill = GridBagConstraints.BOTH; + final JPanel filler = new JPanel(); + filler.setOpaque(false); + panel.add(filler, c); + + return panel; + } + + private void updateInclusions() + { + this.inclusions.clear(); + this.inclusions.addAll(this.storage.getInclusions()); + this.fileMasksInclusionPanel.update(this.inclusions); + } + + private void updateExclusions() + { + this.exclusions.clear(); + this.exclusions.addAll(this.storage.getExclusions()); + this.fileMasksExclusionPanel.update(this.exclusions); + } + + private void updateQuickLists() + { + this.quickLists.clear(); + this.quickLists.addAll(this.storage.getQuickLists()); + this.buildPanel.update(); + } + + private void updateCheckboxEnabled(final ActionEvent event) + { + this.updateCheckboxEnabledIfActiveSelected(); + this.updateCheckboxGroupExclusive(event, reformat, reformatChangedCode); + this.updateCheckboxGroupExclusive(event, compile, reload); + this.updateCheckboxGroupExclusive(event, unqualifiedStaticMemberAccess, customUnqualifiedStaticMemberAccess); + } + + private void updateCheckboxEnabledIfActiveSelected() + { + for(final Map.Entry checkbox : this.checkboxes.entrySet()) + { + final Action currentCheckBoxKey = checkbox.getKey(); + if(!activate.equals(currentCheckBoxKey) + && !activateOnShortcut.equals(currentCheckBoxKey) + && !activateOnBatch.equals(currentCheckBoxKey)) + { + checkbox.getValue().setEnabled(this.isActiveSelected()); + } + } + } + + private void updateCheckboxGroupExclusive(final ActionEvent event, final Action checkbox1, final Action checkbox2) + { + if(event == null || !(event.getSource() instanceof final JCheckBox thisCheckbox)) + { + return; + } + if(thisCheckbox.isSelected()) + { + if(thisCheckbox == this.checkboxes.get(checkbox1)) + { + this.checkboxes.get(checkbox2).setSelected(false); + } + else if(thisCheckbox == this.checkboxes.get(checkbox2)) + { + this.checkboxes.get(checkbox1).setSelected(false); + } + } + } + + private boolean isActiveSelected() + { + final boolean activateIsSelected = this.checkboxes.get(activate).isSelected(); + final boolean activateShortcutIsSelected = this.checkboxes.get(activateOnShortcut).isSelected(); + final boolean activateBatchIsSelected = this.checkboxes.get(activateOnBatch).isSelected(); + return activateIsSelected || activateShortcutIsSelected || activateBatchIsSelected; + } } diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java index 0c7b465..ec58ebc 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskExclusionPanel.java @@ -2,33 +2,33 @@ import java.util.Set; -class FileMaskExclusionPanel extends FileMaskPanel { - - private static final String TEXT_TITLE = "File Path Exclusions (exclusions override inclusions)"; - - private static final String TEXT_ADD_OR_EDIT_MESSAGE = "" + - "" + - "

    When you add exclusion expressions, only the files that do not match will be impacted by the save " + - "actions.

    " + - "

    (use case sensitive Java regular expression that matches the end of the full file path)

    " + - "
      " + - "
    • Ignore\\.java (exclude file 'Ignore.java' in all folders)
    • " + - "
    • .*\\.properties (exclude all '.properties' in all folders)
    • " + - "
    • src/Ignore\\.java (exclude file 'Ignore.java' in 'src' folders)
    • " + - "
    • ignore/.* (exclude folder 'ignore' recursively)
    • " + - "
    • myProject/Ignore.md (exclude file 'Ignore.md' in project 'myProject')
    • " + - "
    " + - ""; - - private static final String TEXT_ADD_TITLE = "Add file path exclusion regex"; - - private static final String TEXT_EDIT_TITLE = "Edit file path exclusion regex"; - - private static final String TEXT_EMPTY = "Nothing excluded"; - - FileMaskExclusionPanel(Set exclusions) { - super(exclusions, TEXT_EMPTY, TEXT_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, TEXT_ADD_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, - TEXT_EDIT_TITLE); - } +class FileMaskExclusionPanel extends FileMaskPanel +{ + private static final String TEXT_TITLE = "File Path Exclusions (exclusions override inclusions)"; + + private static final String TEXT_ADD_OR_EDIT_MESSAGE = "" + + "

    When you add exclusion expressions, only the files that do not match will be impacted by the save " + + "actions.

    " + + "

    (use case sensitive Java regular expression that matches the end of the full file path)

    " + + "
      " + + "
    • Ignore\\.java (exclude file 'Ignore.java' in all folders)
    • " + + "
    • .*\\.properties (exclude all '.properties' in all folders)
    • " + + "
    • src/Ignore\\.java (exclude file 'Ignore.java' in 'src' folders)
    • " + + "
    • ignore/.* (exclude folder 'ignore' recursively)
    • " + + "
    • myProject/Ignore.md (exclude file 'Ignore.md' in project 'myProject')
    • " + + "
    " + + ""; + + private static final String TEXT_ADD_TITLE = "Add file path exclusion regex"; + + private static final String TEXT_EDIT_TITLE = "Edit file path exclusion regex"; + + private static final String TEXT_EMPTY = "Nothing excluded"; + + FileMaskExclusionPanel(final Set exclusions) + { + super(exclusions, TEXT_EMPTY, TEXT_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, TEXT_ADD_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, + TEXT_EDIT_TITLE); + } } diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java index b1b7b1f..9a18a99 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskInclusionPanel.java @@ -2,33 +2,33 @@ import java.util.Set; -class FileMaskInclusionPanel extends FileMaskPanel { - - private static final String TEXT_TITLE = "File Path Inclusions (if empty all included)"; - - private static final String TEXT_ADD_OR_EDIT_MESSAGE = "" + - "" + - "

    When this list is empty, all files are included. When you add inclusion expressions, only the files " + - "that match will be impacted by the save actions.

    " + - "

    (use case sensitive Java regular expression that matches the end of the full file path)

    " + - "
      " + - "
    • .*\\.java (include all '.java' in all folders)
    • " + - "
    • Include\\.java (include file 'Include.java' in all folders)
    • " + - "
    • src/Include\\.java (include file 'Include.java' in 'src' folders)
    • " + - "
    • src/.* (include folder 'src' recursively)
    • " + - "
    • myProject/Include.md (include file 'Include.md' in project 'myProject')
    • " + - "
    " + - ""; - - private static final String TEXT_ADD_TITLE = "Add file path inclusion regex"; - - private static final String TEXT_EDIT_TITLE = "Edit file path inclusion regex"; - - private static final String TEXT_EMPTY = "Everything included"; - - FileMaskInclusionPanel(Set inclusions) { - super(inclusions, TEXT_EMPTY, TEXT_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, TEXT_ADD_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, - TEXT_EDIT_TITLE); - } +class FileMaskInclusionPanel extends FileMaskPanel +{ + private static final String TEXT_TITLE = "File Path Inclusions (if empty all included)"; + + private static final String TEXT_ADD_OR_EDIT_MESSAGE = "" + + "

    When this list is empty, all files are included. When you add inclusion expressions, only the files " + + "that match will be impacted by the save actions.

    " + + "

    (use case sensitive Java regular expression that matches the end of the full file path)

    " + + "
      " + + "
    • .*\\.java (include all '.java' in all folders)
    • " + + "
    • Include\\.java (include file 'Include.java' in all folders)
    • " + + "
    • src/Include\\.java (include file 'Include.java' in 'src' folders)
    • " + + "
    • src/.* (include folder 'src' recursively)
    • " + + "
    • myProject/Include.md (include file 'Include.md' in project 'myProject')
    • " + + "
    " + + ""; + + private static final String TEXT_ADD_TITLE = "Add file path inclusion regex"; + + private static final String TEXT_EDIT_TITLE = "Edit file path inclusion regex"; + + private static final String TEXT_EMPTY = "Everything included"; + + FileMaskInclusionPanel(final Set inclusions) + { + super(inclusions, TEXT_EMPTY, TEXT_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, TEXT_ADD_TITLE, TEXT_ADD_OR_EDIT_MESSAGE, + TEXT_EDIT_TITLE); + } } diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java index b8913c3..fbf3374 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java @@ -1,145 +1,170 @@ package software.xdev.saveactions.ui; -import com.intellij.openapi.ui.InputValidator; -import com.intellij.openapi.ui.Messages; -import com.intellij.ui.AnActionButtonRunnable; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.ToolbarDecorator; -import com.intellij.ui.components.JBList; -import org.jetbrains.annotations.NotNull; - -import javax.swing.DefaultListModel; -import javax.swing.JPanel; import java.util.Collection; import java.util.Enumeration; import java.util.Set; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -abstract class FileMaskPanel extends JPanel { - - private final SortedListModel patternModels = new SortedListModel(); - - private final JBList patternList; - - private final JPanel patternPanel; - - private final String textAddMessage; - - private final String textAddTitle; - - private final String textEditMessage; - - private final String textEditTitle; - - FileMaskPanel(Set patterns, String textEmpty, String textTitle, String textAddMessage, - String textAddTitle, String textEditMessage, String textEditTitle) { - this.textAddMessage = textAddMessage; - this.textAddTitle = textAddTitle; - this.textEditMessage = textEditMessage; - this.textEditTitle = textEditTitle; - patternList = new JBList<>(patternModels); - patternList.setEmptyText(textEmpty); - patternPanel = ToolbarDecorator.createDecorator(patternList) - .setAddAction(getAddActionButtonRunnable(patterns)) - .setRemoveAction(getRemoveActionButtonRunnable(patterns)) - .setEditAction(getEditActionButtonRunnable(patterns)) - .disableUpDownActions() - .createPanel(); - patternPanel.setBorder(IdeBorderFactory.createTitledBorder(textTitle)); - } - - private AnActionButtonRunnable getEditActionButtonRunnable(Set patterns) { - return actionButton -> { - String oldValue = patternList.getSelectedValue(); - String pattern = Messages.showInputDialog( - textEditMessage, textEditTitle, null, oldValue, getRegexInputValidator()); - if (pattern != null && !pattern.equals(oldValue)) { - patterns.remove(oldValue); - patternModels.removeElement(oldValue); - if (patterns.add(pattern)) { - patternModels.addElementSorted(pattern); - } - } - }; - } - - JPanel getPanel() { - return patternPanel; - } - - void update(Set patterns) { - patternModels.clear(); - patternModels.addAllSorted(patterns); - } - - @NotNull - private AnActionButtonRunnable getRemoveActionButtonRunnable(Set patterns) { - return actionButton -> { - for (String selectedValue : patternList.getSelectedValuesList()) { - patterns.remove(selectedValue); - patternModels.removeElement(selectedValue); - } - }; - } - - @NotNull - private AnActionButtonRunnable getAddActionButtonRunnable(Set patterns) { - return actionButton -> { - String pattern = Messages.showInputDialog( - textAddMessage, textAddTitle, null, null, getRegexInputValidator()); - if (pattern != null && (patterns.add(pattern))) { - patternModels.addElementSorted(pattern); - } - }; - } - - @NotNull - private InputValidator getRegexInputValidator() { - return new InputValidator() { - @Override - public boolean checkInput(String string) { - if (string == null || string.trim().isEmpty()) { - // do not allow null or blank entries - return false; - } - try { - Pattern.compile(string); - return true; - } catch (PatternSyntaxException e) { - return false; - } - } - - @Override - public boolean canClose(String s) { - return true; - } - }; - } - - private static class SortedListModel extends DefaultListModel { +import javax.swing.DefaultListModel; +import javax.swing.JPanel; - private void addElementSorted(String element) { - Enumeration modelElements = elements(); - int index = 0; - while (modelElements.hasMoreElements()) { - String modelElement = (String) modelElements.nextElement(); - if (0 < modelElement.compareTo(element)) { - add(index, element); - return; - } - index++; - } - addElement(element); - } +import org.jetbrains.annotations.NotNull; - private void addAllSorted(Collection elements) { - for (String element : elements) { - addElementSorted(element); - } - } +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.ui.AnActionButtonRunnable; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ToolbarDecorator; +import com.intellij.ui.components.JBList; - } +abstract class FileMaskPanel extends JPanel +{ + private final SortedListModel patternModels = new SortedListModel(); + + private final JBList patternList; + + private final JPanel patternPanel; + + private final String textAddMessage; + + private final String textAddTitle; + + private final String textEditMessage; + + private final String textEditTitle; + + FileMaskPanel( + final Set patterns, final String textEmpty, final String textTitle, final String textAddMessage, + final String textAddTitle, final String textEditMessage, final String textEditTitle) + { + this.textAddMessage = textAddMessage; + this.textAddTitle = textAddTitle; + this.textEditMessage = textEditMessage; + this.textEditTitle = textEditTitle; + this.patternList = new JBList<>(this.patternModels); + this.patternList.setEmptyText(textEmpty); + this.patternPanel = ToolbarDecorator.createDecorator(this.patternList) + .setAddAction(this.getAddActionButtonRunnable(patterns)) + .setRemoveAction(this.getRemoveActionButtonRunnable(patterns)) + .setEditAction(this.getEditActionButtonRunnable(patterns)) + .disableUpDownActions() + .createPanel(); + this.patternPanel.setBorder(IdeBorderFactory.createTitledBorder(textTitle)); + } + + private AnActionButtonRunnable getEditActionButtonRunnable(final Set patterns) + { + return actionButton -> { + final String oldValue = this.patternList.getSelectedValue(); + final String pattern = Messages.showInputDialog( + this.textEditMessage, this.textEditTitle, null, oldValue, this.getRegexInputValidator()); + if(pattern != null && !pattern.equals(oldValue)) + { + patterns.remove(oldValue); + this.patternModels.removeElement(oldValue); + if(patterns.add(pattern)) + { + this.patternModels.addElementSorted(pattern); + } + } + }; + } + + JPanel getPanel() + { + return this.patternPanel; + } + + void update(final Set patterns) + { + this.patternModels.clear(); + this.patternModels.addAllSorted(patterns); + } + + @NotNull + private AnActionButtonRunnable getRemoveActionButtonRunnable(final Set patterns) + { + return actionButton -> { + for(final String selectedValue : this.patternList.getSelectedValuesList()) + { + patterns.remove(selectedValue); + this.patternModels.removeElement(selectedValue); + } + }; + } + + @NotNull + private AnActionButtonRunnable getAddActionButtonRunnable(final Set patterns) + { + return actionButton -> { + final String pattern = Messages.showInputDialog( + this.textAddMessage, this.textAddTitle, null, null, this.getRegexInputValidator()); + if(pattern != null && (patterns.add(pattern))) + { + this.patternModels.addElementSorted(pattern); + } + }; + } + + @NotNull + private InputValidator getRegexInputValidator() + { + return new InputValidator() + { + @Override + public boolean checkInput(final String string) + { + if(string == null || string.trim().isEmpty()) + { + // do not allow null or blank entries + return false; + } + try + { + Pattern.compile(string); + return true; + } + catch(final PatternSyntaxException e) + { + return false; + } + } + + @Override + public boolean canClose(final String s) + { + return true; + } + }; + } + + private static final class SortedListModel extends DefaultListModel + { + private void addElementSorted(final String element) + { + final Enumeration modelElements = this.elements(); + int index = 0; + while(modelElements.hasMoreElements()) + { + final String modelElement = (String)modelElements.nextElement(); + if(0 < modelElement.compareTo(element)) + { + this.add(index, element); + return; + } + index++; + } + this.addElement(element); + } + + private void addAllSorted(final Collection elements) + { + for(final String element : elements) + { + this.addElementSorted(element); + } + } + } } diff --git a/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java b/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java index 76c7b74..ba45544 100644 --- a/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FormattingPanel.java @@ -1,41 +1,45 @@ package software.xdev.saveactions.ui; -import software.xdev.saveactions.model.Action; -import com.intellij.ui.IdeBorderFactory; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import java.awt.Dimension; -import java.util.Map; - import static software.xdev.saveactions.model.Action.organizeImports; import static software.xdev.saveactions.model.Action.rearrange; import static software.xdev.saveactions.model.Action.reformat; import static software.xdev.saveactions.model.Action.reformatChangedCode; -class FormattingPanel { +import java.awt.Dimension; +import java.util.Map; - private static final String TEXT_TITLE_ACTIONS = "Formatting Actions"; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JCheckBox; +import javax.swing.JPanel; - private final Map checkboxes; +import com.intellij.ui.IdeBorderFactory; - FormattingPanel(Map checkboxes) { - this.checkboxes = checkboxes; - } +import software.xdev.saveactions.model.Action; - JPanel getPanel() { - JPanel panel = new JPanel(); - panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); - panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); - panel.add(checkboxes.get(organizeImports)); - panel.add(checkboxes.get(reformat)); - panel.add(checkboxes.get(reformatChangedCode)); - panel.add(checkboxes.get(rearrange)); - panel.add(Box.createHorizontalGlue()); - panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); - return panel; - } +class FormattingPanel +{ + private static final String TEXT_TITLE_ACTIONS = "Formatting Actions"; + + private final Map checkboxes; + + FormattingPanel(final Map checkboxes) + { + this.checkboxes = checkboxes; + } + + JPanel getPanel() + { + final JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); + panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); + panel.add(this.checkboxes.get(organizeImports)); + panel.add(this.checkboxes.get(reformat)); + panel.add(this.checkboxes.get(reformatChangedCode)); + panel.add(this.checkboxes.get(rearrange)); + panel.add(Box.createHorizontalGlue()); + panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); + return panel; + } } diff --git a/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java index 575de9d..dca4c4c 100644 --- a/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java @@ -1,41 +1,45 @@ package software.xdev.saveactions.ui; -import software.xdev.saveactions.model.Action; -import com.intellij.ui.IdeBorderFactory; - -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import java.awt.Dimension; -import java.util.Map; - import static software.xdev.saveactions.model.Action.activate; import static software.xdev.saveactions.model.Action.activateOnBatch; import static software.xdev.saveactions.model.Action.activateOnShortcut; import static software.xdev.saveactions.model.Action.noActionIfCompileErrors; -class GeneralPanel { +import java.awt.Dimension; +import java.util.Map; - private static final String TEXT_TITLE_ACTIONS = "General"; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JCheckBox; +import javax.swing.JPanel; - private final Map checkboxes; +import com.intellij.ui.IdeBorderFactory; - GeneralPanel(Map checkboxes) { - this.checkboxes = checkboxes; - } +import software.xdev.saveactions.model.Action; - JPanel getPanel() { - JPanel panel = new JPanel(); - panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); - panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); - panel.add(checkboxes.get(activate)); - panel.add(checkboxes.get(activateOnShortcut)); - panel.add(checkboxes.get(activateOnBatch)); - panel.add(checkboxes.get(noActionIfCompileErrors)); - panel.add(Box.createHorizontalGlue()); - panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); - return panel; - } +class GeneralPanel +{ + private static final String TEXT_TITLE_ACTIONS = "General"; + + private final Map checkboxes; + + GeneralPanel(final Map checkboxes) + { + this.checkboxes = checkboxes; + } + + JPanel getPanel() + { + final JPanel panel = new JPanel(); + panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_ACTIONS)); + panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); + panel.add(this.checkboxes.get(activate)); + panel.add(this.checkboxes.get(activateOnShortcut)); + panel.add(this.checkboxes.get(activateOnBatch)); + panel.add(this.checkboxes.get(noActionIfCompileErrors)); + panel.add(Box.createHorizontalGlue()); + panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); + return panel; + } } diff --git a/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java index 599a66b..925234b 100644 --- a/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java @@ -1,6 +1,18 @@ package software.xdev.saveactions.ui.java; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import static com.intellij.openapi.ui.TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT; +import static java.awt.BorderLayout.CENTER; +import static java.awt.BorderLayout.EAST; +import static java.awt.BorderLayout.WEST; + +import java.awt.BorderLayout; +import java.awt.Dimension; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import org.jetbrains.annotations.NotNull; + import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileChooser.FileChooserFactory; @@ -8,87 +20,86 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.components.JBLabel; -import org.jetbrains.annotations.NotNull; -import software.xdev.saveactions.ui.Configuration; -import javax.swing.JButton; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Dimension; +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.ui.Configuration; -import static com.intellij.openapi.ui.TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT; -import static java.awt.BorderLayout.CENTER; -import static java.awt.BorderLayout.EAST; -import static java.awt.BorderLayout.WEST; /** * @author markiewb */ -public class IdeSupportPanel { - - private static final String BUTTON = "Reset"; - private static final String EXTENSION = "epf"; - private static final String LABEL = "Use external Eclipse configuration file (.epf)"; - private static final String TITLE = "Eclipse Support"; - - private TextFieldWithBrowseButton path; - - public JPanel getPanel(String configurationPath) { - JPanel panel = new JPanel(); - if (!SaveActionsServiceManager.getService().isJavaAvailable()) { - return panel; - } - - panel.setBorder(IdeBorderFactory.createTitledBorder(TITLE)); - panel.setLayout(new BorderLayout()); - - JBLabel label = getLabel(); - path = getPath(configurationPath); - JButton reset = getResetButton(path); - - panel.add(label, WEST); - panel.add(path, CENTER); - panel.add(reset, EAST); - - panel.setMaximumSize(new Dimension(Configuration.BOX_LAYOUT_MAX_WIDTH, Configuration.BOX_LAYOUT_MAX_HEIGHT)); - - return panel; - } - - @NotNull - private JBLabel getLabel() { - JBLabel label = new JBLabel(); - label.setText(LABEL); - label.setLabelFor(path); - return label; - } - - @NotNull - private TextFieldWithBrowseButton getPath(String configurationPath) { - FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileDescriptor(EXTENSION); - FileTextField field = FileChooserFactory.getInstance().createFileTextField(descriptor, null); - field.getField().setEnabled(false); - field.getField().setText(configurationPath); - TextFieldWithBrowseButton resultPath = new TextFieldWithBrowseButton(field.getField()); - resultPath.addBrowseFolderListener(null, null, null, descriptor, TEXT_FIELD_WHOLE_TEXT); - return resultPath; - } - - @NotNull - private JButton getResetButton(TextFieldWithBrowseButton path) { - JButton reset = new JButton(BUTTON); - reset.addActionListener(e -> path.setText("")); - return reset; - } - - public String getPath() { - return path == null ? null : path.getText(); - } - - public void setPath(String configurationPath) { - if (path != null) { - path.setText(configurationPath); - } - } - +public class IdeSupportPanel +{ + private static final String BUTTON = "Reset"; + private static final String EXTENSION = "epf"; + private static final String LABEL = "Use external Eclipse configuration file (.epf)"; + private static final String TITLE = "Eclipse Support"; + + private TextFieldWithBrowseButton path; + + public JPanel getPanel(final String configurationPath) + { + final JPanel panel = new JPanel(); + if(!SaveActionsServiceManager.getService().isJavaAvailable()) + { + return panel; + } + + panel.setBorder(IdeBorderFactory.createTitledBorder(TITLE)); + panel.setLayout(new BorderLayout()); + + final JBLabel label = this.getLabel(); + this.path = this.getPath(configurationPath); + final JButton reset = this.getResetButton(this.path); + + panel.add(label, WEST); + panel.add(this.path, CENTER); + panel.add(reset, EAST); + + panel.setMaximumSize(new Dimension(Configuration.BOX_LAYOUT_MAX_WIDTH, Configuration.BOX_LAYOUT_MAX_HEIGHT)); + + return panel; + } + + @NotNull + private JBLabel getLabel() + { + final JBLabel label = new JBLabel(); + label.setText(LABEL); + label.setLabelFor(this.path); + return label; + } + + @NotNull + private TextFieldWithBrowseButton getPath(final String configurationPath) + { + final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileDescriptor(EXTENSION); + final FileTextField field = FileChooserFactory.getInstance().createFileTextField(descriptor, null); + field.getField().setEnabled(false); + field.getField().setText(configurationPath); + final TextFieldWithBrowseButton resultPath = new TextFieldWithBrowseButton(field.getField()); + resultPath.addBrowseFolderListener(null, null, null, descriptor, TEXT_FIELD_WHOLE_TEXT); + return resultPath; + } + + @NotNull + private JButton getResetButton(final TextFieldWithBrowseButton path) + { + final JButton reset = new JButton(BUTTON); + reset.addActionListener(e -> path.setText("")); + return reset; + } + + public String getPath() + { + return this.path == null ? null : this.path.getText(); + } + + public void setPath(final String configurationPath) + { + if(this.path != null) + { + this.path.setText(configurationPath); + } + } } diff --git a/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java b/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java index 5191653..28bc986 100644 --- a/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/InspectionPanel.java @@ -1,39 +1,44 @@ package software.xdev.saveactions.ui.java; -import software.xdev.saveactions.core.service.SaveActionsServiceManager; -import software.xdev.saveactions.model.Action; -import com.intellij.ui.IdeBorderFactory; +import static software.xdev.saveactions.model.ActionType.java; + +import java.awt.Dimension; +import java.util.Map; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JPanel; -import java.awt.Dimension; -import java.util.Map; - -import static software.xdev.saveactions.model.ActionType.java; - -public class InspectionPanel { - private static final String TEXT_TITLE_INSPECTIONS = "Java Inspection and Quick Fix"; - - private final Map checkboxes; +import com.intellij.ui.IdeBorderFactory; - public InspectionPanel(Map checkboxes) { - this.checkboxes = checkboxes; - } +import software.xdev.saveactions.core.service.SaveActionsServiceManager; +import software.xdev.saveactions.model.Action; - public JPanel getPanel() { - JPanel panel = new JPanel(); - if (!SaveActionsServiceManager.getService().isJavaAvailable()) { - return panel; - } - panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_INSPECTIONS)); - panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); - Action.stream(java).map(checkboxes::get).forEach(panel::add); - panel.add(Box.createHorizontalGlue()); - panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); - return panel; - } +public class InspectionPanel +{ + private static final String TEXT_TITLE_INSPECTIONS = "Java Inspection and Quick Fix"; + + private final Map checkboxes; + + public InspectionPanel(final Map checkboxes) + { + this.checkboxes = checkboxes; + } + + public JPanel getPanel() + { + final JPanel panel = new JPanel(); + if(!SaveActionsServiceManager.getService().isJavaAvailable()) + { + return panel; + } + panel.setBorder(IdeBorderFactory.createTitledBorder(TEXT_TITLE_INSPECTIONS)); + panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); + Action.stream(java).map(this.checkboxes::get).forEach(panel::add); + panel.add(Box.createHorizontalGlue()); + panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); + return panel; + } } diff --git a/src/main/java/software/xdev/saveactions/utils/Helper.java b/src/main/java/software/xdev/saveactions/utils/Helper.java index f53814f..3db506a 100644 --- a/src/main/java/software/xdev/saveactions/utils/Helper.java +++ b/src/main/java/software/xdev/saveactions/utils/Helper.java @@ -1,18 +1,19 @@ package software.xdev.saveactions.utils; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; - import java.util.Arrays; -public class Helper { - - private Helper() { - // static - } +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; - public static VirtualFile[] toVirtualFiles(PsiFile[] psiFiles) { - return Arrays.stream(psiFiles).map(PsiFile::getVirtualFile).toArray(VirtualFile[]::new); - } +public final class Helper +{ + private Helper() + { + } + + public static VirtualFile[] toVirtualFiles(final PsiFile[] psiFiles) + { + return Arrays.stream(psiFiles).map(PsiFile::getVirtualFile).toArray(VirtualFile[]::new); + } } diff --git a/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java index 6905af1..66134d9 100644 --- a/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/BatchActionConstants.java @@ -1,22 +1,24 @@ package software.xdev.saveactions.core.action; +import java.util.function.Consumer; + import com.intellij.analysis.AnalysisScope; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; -import software.xdev.saveactions.core.action.BatchAction; - -import java.util.function.Consumer; - -public interface BatchActionConstants { - - Consumer SAVE_ACTION_BATCH_MANAGER = (fixture) -> - WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixure(fixture)); - static void runFixure(CodeInsightTestFixture fixture) { - // set modification timestamp ++ - fixture.getFile().clearCaches(); - // call plugin on document - new BatchAction().analyze(fixture.getProject(), new AnalysisScope(fixture.getProject())); - } +public interface BatchActionConstants +{ + + Consumer SAVE_ACTION_BATCH_MANAGER = (fixture) -> + WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixure(fixture)); + + static void runFixure(CodeInsightTestFixture fixture) + { + // set modification timestamp ++ + fixture.getFile().clearCaches(); + + // call plugin on document + new BatchAction().analyze(fixture.getProject(), new AnalysisScope(fixture.getProject())); + } } diff --git a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java index bd3868a..acd6b61 100644 --- a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java @@ -1,5 +1,10 @@ package software.xdev.saveactions.core.action; +import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT; +import static com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE; + +import java.util.function.Consumer; + import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -7,33 +12,30 @@ import com.intellij.openapi.actionSystem.impl.SimpleDataContext; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.testFramework.fixtures.CodeInsightTestFixture; -import software.xdev.saveactions.core.action.ShortcutAction; - -import java.util.function.Consumer; - -import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT; -import static com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE; - -public interface ShortcutActionConstants { - - Consumer SAVE_ACTION_SHORTCUT_MANAGER = (fixture) -> - WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixure(fixture)); - - static void runFixure(CodeInsightTestFixture fixture) { - // set modification timestamp ++ - fixture.getFile().clearCaches(); - - ActionManager actionManager = ActionManager.getInstance(); - AnAction action = actionManager.getAction(ShortcutAction.class.getName()); - DataContext dataContext = SimpleDataContext.builder() - .add(PROJECT, fixture.getProject()) - .add(PSI_FILE, fixture.getFile()) - .setParent(null) - .build(); - // call plugin on document - AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "save-actions", dataContext); - new ShortcutAction().actionPerformed(event); - } +public interface ShortcutActionConstants +{ + + Consumer SAVE_ACTION_SHORTCUT_MANAGER = (fixture) -> + WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixure(fixture)); + + static void runFixure(CodeInsightTestFixture fixture) + { + // set modification timestamp ++ + fixture.getFile().clearCaches(); + + ActionManager actionManager = ActionManager.getInstance(); + AnAction action = actionManager.getAction(ShortcutAction.class.getName()); + + DataContext dataContext = SimpleDataContext.builder() + .add(PROJECT, fixture.getProject()) + .add(PSI_FILE, fixture.getFile()) + .setParent(null) + .build(); + + // call plugin on document + AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "save-actions", dataContext); + new ShortcutAction().actionPerformed(event); + } } diff --git a/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java b/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java index f0a6088..351a70e 100644 --- a/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java +++ b/src/test/java/software/xdev/saveactions/core/component/PsiFileTest.java @@ -1,79 +1,82 @@ package software.xdev.saveactions.core.component; - -import software.xdev.saveactions.core.component.Engine; -import software.xdev.saveactions.model.Storage; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.Set; -import java.util.stream.Stream; - import static java.util.Collections.emptySet; import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; -class PsiFileTest { - - @ParameterizedTest(name = "[{index}] included={0}, psiFile={1}, inclusion={2}, exclusion={3}") - @MethodSource("parameters") - void test(boolean included, String psiFile, String inclusion, String exclusion) { - Storage storage = new Storage(); - storage.setInclusions(toSet(inclusion)); - storage.setExclusions(toSet(exclusion)); - - Engine engine = new Engine(storage, null, null, null, null, null); - - assertThat(engine.isIncludedAndNotExcluded(psiFile)) - .isEqualTo(included); - } - - static Stream parameters() { - return Stream.of( - // Only excludes - taken from PsiFilesIsUrlIncludedTest - // Default cases and invalid regex - Arguments.of(true, null, "", "*"), - Arguments.of(true, "file", "", ""), - Arguments.of(true, "/home/alex/projects/project1/ignore.java", "", "*"), - - // Base cases - Arguments.of(false, "/project/Ignore.java", "", "Ignore.java"), - Arguments.of(true, "/project/Ignore.java", "", "ignore.java"), - Arguments.of(false, "/project/Ignore.java", "", ".*\\.java"), - - // With different project strings - Arguments.of(true, "/home/alex/projects/project1/ignore.java", "", ".*\\.properties"), - Arguments.of(false, "/home/alex/projects/project1/ignore.properties", "", ".*\\.properties"), - Arguments.of(false, "c://projects/project/ignore.properties", "", ".*\\.properties"), - - // With specific paths - Arguments.of(true, "/home/alex/projects/project1/ignore.properties", "", "src/.*\\.properties"), - Arguments.of(false, "/home/alex/projects/project1/src/ignore.properties", "", "src/.*\\.properties"), - - // With specific folders recursive - Arguments.of(false, "/project1/src/ignore/Ignore.java", "", "ignore/.*"), - Arguments.of(false, "/project1/src/ignore/sub/Ignore.java", "", "ignore/.*"), - Arguments.of(false, "/project1/src/ignore/sub/Ignore.java", "", "ignore/.*\\.java"), - Arguments.of(false, "/project1/src/ignore/sub/Ignore.java", "", "ignore/.*/.*\\.java"), +import java.util.Set; +import java.util.stream.Stream; - // Only includes - Arguments.of(true, "/project/Include.java", "Include.java", ""), - Arguments.of(false, "/project/Include.java", "include.java", ""), - Arguments.of(true, "/project/Include.java", ".*\\.java", ""), +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; - // Includes and excludes - Arguments.of(false, "/project/Include.java", ".*\\.java", ".*\\.java"), - Arguments.of(true, "/project/Include.java", ".*\\.java", ".*\\.xml"), - Arguments.of(false, "/project/Include.xml", ".*\\.java", ".*\\.xml") - ); - } +import software.xdev.saveactions.model.Storage; - private Set toSet(String inclusion) { - if (null == inclusion || inclusion.isEmpty()) { - return emptySet(); - } - return singleton(inclusion); - } +class PsiFileTest +{ + @ParameterizedTest(name = "[{index}] included={0}, psiFile={1}, inclusion={2}, exclusion={3}") + @MethodSource("parameters") + void test(final boolean included, final String psiFile, final String inclusion, final String exclusion) + { + final Storage storage = new Storage(); + storage.setInclusions(this.toSet(inclusion)); + storage.setExclusions(this.toSet(exclusion)); + + final Engine engine = new Engine(storage, null, null, null, null, null); + + assertThat(engine.isIncludedAndNotExcluded(psiFile)) + .isEqualTo(included); + } + + static Stream parameters() + { + return Stream.of( + // Only excludes - taken from PsiFilesIsUrlIncludedTest + // Default cases and invalid regex + Arguments.of(true, null, "", "*"), + Arguments.of(true, "file", "", ""), + Arguments.of(true, "/home/alex/projects/project1/ignore.java", "", "*"), + + // Base cases + Arguments.of(false, "/project/Ignore.java", "", "Ignore.java"), + Arguments.of(true, "/project/Ignore.java", "", "ignore.java"), + Arguments.of(false, "/project/Ignore.java", "", ".*\\.java"), + + // With different project strings + Arguments.of(true, "/home/alex/projects/project1/ignore.java", "", ".*\\.properties"), + Arguments.of(false, "/home/alex/projects/project1/ignore.properties", "", ".*\\.properties"), + Arguments.of(false, "c://projects/project/ignore.properties", "", ".*\\.properties"), + + // With specific paths + Arguments.of(true, "/home/alex/projects/project1/ignore.properties", "", "src/.*\\.properties"), + Arguments.of(false, "/home/alex/projects/project1/src/ignore.properties", "", "src/.*\\.properties"), + + // With specific folders recursive + Arguments.of(false, "/project1/src/ignore/Ignore.java", "", "ignore/.*"), + Arguments.of(false, "/project1/src/ignore/sub/Ignore.java", "", "ignore/.*"), + Arguments.of(false, "/project1/src/ignore/sub/Ignore.java", "", "ignore/.*\\.java"), + Arguments.of(false, "/project1/src/ignore/sub/Ignore.java", "", "ignore/.*/.*\\.java"), + + // Only includes + Arguments.of(true, "/project/Include.java", "Include.java", ""), + Arguments.of(false, "/project/Include.java", "include.java", ""), + Arguments.of(true, "/project/Include.java", ".*\\.java", ""), + + // Includes and excludes + Arguments.of(false, "/project/Include.java", ".*\\.java", ".*\\.java"), + Arguments.of(true, "/project/Include.java", ".*\\.java", ".*\\.xml"), + Arguments.of(false, "/project/Include.xml", ".*\\.java", ".*\\.xml") + ); + } + + private Set toSet(final String inclusion) + { + if(null == inclusion || inclusion.isEmpty()) + { + return emptySet(); + } + return singleton(inclusion); + } } diff --git a/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java b/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java index f612006..b1e5196 100644 --- a/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java +++ b/src/test/java/software/xdev/saveactions/core/component/SaveActionManagerConstants.java @@ -1,29 +1,33 @@ package software.xdev.saveactions.core.component; -import software.xdev.saveactions.core.service.SaveActionsService; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.psi.PsiFile; -import com.intellij.testFramework.fixtures.CodeInsightTestFixture; +import static java.util.Collections.singleton; +import static software.xdev.saveactions.core.ExecutionMode.saveAll; +import static software.xdev.saveactions.model.Action.activate; import java.util.HashSet; import java.util.Set; import java.util.function.BiConsumer; -import static software.xdev.saveactions.core.ExecutionMode.saveAll; -import static software.xdev.saveactions.model.Action.activate; -import static java.util.Collections.singleton; - -public interface SaveActionManagerConstants { +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.fixtures.CodeInsightTestFixture; - BiConsumer SAVE_ACTION_MANAGER = (fixture, saveActionService) -> - WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixture(fixture, saveActionService)); +import software.xdev.saveactions.core.service.SaveActionsService; - static void runFixture(CodeInsightTestFixture fixture, SaveActionsService saveActionService) { - // set modification timestamp ++ - fixture.getFile().clearCaches(); - // call plugin on document - Set psiFiles = new HashSet<>(singleton(fixture.getFile())); - saveActionService.guardedProcessPsiFiles(fixture.getProject(), psiFiles, activate, saveAll); - } +public interface SaveActionManagerConstants +{ + + BiConsumer SAVE_ACTION_MANAGER = (fixture, saveActionService) -> + WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixture(fixture, saveActionService)); + + static void runFixture(CodeInsightTestFixture fixture, SaveActionsService saveActionService) + { + // set modification timestamp ++ + fixture.getFile().clearCaches(); + + // call plugin on document + Set psiFiles = new HashSet<>(singleton(fixture.getFile())); + saveActionService.guardedProcessPsiFiles(fixture.getProject(), psiFiles, activate, saveAll); + } } diff --git a/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java b/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java index c67164f..2d15ac1 100644 --- a/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java +++ b/src/test/java/software/xdev/saveactions/integration/ActionTestFile.java @@ -1,81 +1,78 @@ package software.xdev.saveactions.integration; -public enum ActionTestFile { - - Reformat_KO_Import_KO, - Reformat_KO_Import_OK, - Reformat_OK_Import_KO, - Reformat_OK_Import_OK, - - Reformat_KO_Rearrange_KO, - Reformat_KO_Rearrange_OK, - Reformat_OK_Rearrange_OK, - - FieldCanBeFinal_KO, - FieldCanBeFinal_OK, - - LocalCanBeFinal_KO, - LocalCanBeFinal_OK, - - LocalCanBeFinalExceptImplicit_KO, - LocalCanBeFinalExceptImplicit_OK, - - MethodMayBeStatic_KO, - MethodMayBeStatic_OK, - - UnqualifiedFieldAccess_KO, - UnqualifiedFieldAccess_OK, - - UnqualifiedMethodAccess_KO, - UnqualifiedMethodAccess_OK, - - UnqualifiedStaticMemberAccess_KO, - UnqualifiedStaticMemberAccess_OK, - - CustomUnqualifiedStaticMemberAccess_KO, - CustomUnqualifiedStaticMemberAccess_OK, - - MissingOverrideAnnotation_KO, - MissingOverrideAnnotation_OK, - - UseBlocks_KO, - UseBlocks_OK, - - GenerateSerialVersionUID_KO, - GenerateSerialVersionUID_OK, - - UnnecessaryThis_KO, - UnnecessaryThis_OK, - - FinalPrivateMethod_KO, - FinalPrivateMethod_OK, - - UnnecessaryFinalOnLocalVariableOrParameter_KO, - UnnecessaryFinalOnLocalVariableOrParameter_OK, - - ExplicitTypeCanBeDiamond_KO, - ExplicitTypeCanBeDiamond_OK, - - SuppressAnnotation_KO, - SuppressAnnotation_OK, - - UnnecessarySemicolon_KO, - UnnecessarySemicolon_OK, - - SingleStatementInBlock_KO, - SingleStatementInBlock_OK, - - AccessCanBeTightened_KO, - AccessCanBeTightened_OK, - - InspectionsAll_KO, - InspectionsAll_OK, - - // - ; - - public String getFilename() { - return name() + ".java"; - } - +public enum ActionTestFile +{ + Reformat_KO_Import_KO, + Reformat_KO_Import_OK, + Reformat_OK_Import_KO, + Reformat_OK_Import_OK, + + Reformat_KO_Rearrange_KO, + Reformat_KO_Rearrange_OK, + Reformat_OK_Rearrange_OK, + + FieldCanBeFinal_KO, + FieldCanBeFinal_OK, + + LocalCanBeFinal_KO, + LocalCanBeFinal_OK, + + LocalCanBeFinalExceptImplicit_KO, + LocalCanBeFinalExceptImplicit_OK, + + MethodMayBeStatic_KO, + MethodMayBeStatic_OK, + + UnqualifiedFieldAccess_KO, + UnqualifiedFieldAccess_OK, + + UnqualifiedMethodAccess_KO, + UnqualifiedMethodAccess_OK, + + UnqualifiedStaticMemberAccess_KO, + UnqualifiedStaticMemberAccess_OK, + + CustomUnqualifiedStaticMemberAccess_KO, + CustomUnqualifiedStaticMemberAccess_OK, + + MissingOverrideAnnotation_KO, + MissingOverrideAnnotation_OK, + + UseBlocks_KO, + UseBlocks_OK, + + GenerateSerialVersionUID_KO, + GenerateSerialVersionUID_OK, + + UnnecessaryThis_KO, + UnnecessaryThis_OK, + + FinalPrivateMethod_KO, + FinalPrivateMethod_OK, + + UnnecessaryFinalOnLocalVariableOrParameter_KO, + UnnecessaryFinalOnLocalVariableOrParameter_OK, + + ExplicitTypeCanBeDiamond_KO, + ExplicitTypeCanBeDiamond_OK, + + SuppressAnnotation_KO, + SuppressAnnotation_OK, + + UnnecessarySemicolon_KO, + UnnecessarySemicolon_OK, + + SingleStatementInBlock_KO, + SingleStatementInBlock_OK, + + AccessCanBeTightened_KO, + AccessCanBeTightened_OK, + + InspectionsAll_KO, + InspectionsAll_OK; + + public String getFilename() + { + return this.name() + ".java"; + } } diff --git a/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java index ae08817..5c3726a 100644 --- a/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/GlobalIntegrationTest.java @@ -1,7 +1,5 @@ package software.xdev.saveactions.integration; -import org.junit.jupiter.api.Test; - import static software.xdev.saveactions.model.Action.activate; import static software.xdev.saveactions.model.Action.activateOnBatch; import static software.xdev.saveactions.model.Action.activateOnShortcut; @@ -9,89 +7,103 @@ import static software.xdev.saveactions.model.Action.rearrange; import static software.xdev.saveactions.model.Action.reformat; -class GlobalIntegrationTest extends IntegrationTest { - - @Test - void should_reformat_without_activation_produces_same_file() { - storage.setEnabled(reformat, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); - } - - @Test - void should_reformat_with_activation_produces_indented_file() { - storage.setEnabled(activate, true); - storage.setEnabled(reformat, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); - } - - @Test - void should_reformat_with_shortcut_produces_same_file() { - storage.setEnabled(activateOnShortcut, true); - storage.setEnabled(reformat, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); - } - - @Test - void should_reformat_with_shortcut_produces_indented_file_on_shortcut() { - storage.setEnabled(activateOnShortcut, true); - storage.setEnabled(reformat, true); - assertSaveActionShortcut(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); - } - - @Test - void should_reformat_as_batch_produces_indented_file() { - storage.setEnabled(activateOnBatch, true); - storage.setEnabled(reformat, true); - assertSaveActionBatch(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); - } - - @Test - void should_reformat_as_batch_on_shortcut_produces_same_file() { - storage.setEnabled(activateOnShortcut, true); - storage.setEnabled(reformat, true); - assertSaveActionBatch(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); - } - - @Test - void should_import_without_activation_produces_same_file() { - storage.setEnabled(organizeImports, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); - } - - @Test - void should_import_with_activation_produces_cleaned_import_file() { - storage.setEnabled(activate, true); - storage.setEnabled(organizeImports, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_OK); - } - - @Test - void should_import_and_format_with_activation_produces_cleaned_import_and_formated_file() { - storage.setEnabled(activate, true); - storage.setEnabled(organizeImports, true); - storage.setEnabled(reformat, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_OK); - } - - @Test - void should_rearrange_without_activation_produces_same_file() { - storage.setEnabled(rearrange, true); - assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); - } - - @Test - void should_rearrange_with_activation_produces_ordered_file() { - storage.setEnabled(activate, true); - storage.setEnabled(rearrange, true); - assertSaveAction(ActionTestFile.Reformat_KO_Rearrange_KO, ActionTestFile.Reformat_KO_Rearrange_OK); - } +import org.junit.jupiter.api.Test; - @Test - void should_rearrange_and_format_with_activation_produces_ordered_file_and_formated_file() { - storage.setEnabled(activate, true); - storage.setEnabled(reformat, true); - storage.setEnabled(rearrange, true); - assertSaveAction(ActionTestFile.Reformat_KO_Rearrange_KO, ActionTestFile.Reformat_OK_Rearrange_OK); - } +class GlobalIntegrationTest extends IntegrationTest +{ + @Test + void should_reformat_without_activation_produces_same_file() + { + this.storage.setEnabled(reformat, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); + } + + @Test + void should_reformat_with_activation_produces_indented_file() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(reformat, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); + } + + @Test + void should_reformat_with_shortcut_produces_same_file() + { + this.storage.setEnabled(activateOnShortcut, true); + this.storage.setEnabled(reformat, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); + } + + @Test + void should_reformat_with_shortcut_produces_indented_file_on_shortcut() + { + this.storage.setEnabled(activateOnShortcut, true); + this.storage.setEnabled(reformat, true); + this.assertSaveActionShortcut(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); + } + + @Test + void should_reformat_as_batch_produces_indented_file() + { + this.storage.setEnabled(activateOnBatch, true); + this.storage.setEnabled(reformat, true); + this.assertSaveActionBatch(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_KO); + } + + @Test + void should_reformat_as_batch_on_shortcut_produces_same_file() + { + this.storage.setEnabled(activateOnShortcut, true); + this.storage.setEnabled(reformat, true); + this.assertSaveActionBatch(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); + } + + @Test + void should_import_without_activation_produces_same_file() + { + this.storage.setEnabled(organizeImports, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); + } + + @Test + void should_import_with_activation_produces_cleaned_import_file() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(organizeImports, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_OK); + } + + @Test + void should_import_and_format_with_activation_produces_cleaned_import_and_formated_file() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(organizeImports, true); + this.storage.setEnabled(reformat, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_OK_Import_OK); + } + + @Test + void should_rearrange_without_activation_produces_same_file() + { + this.storage.setEnabled(rearrange, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Import_KO, ActionTestFile.Reformat_KO_Import_KO); + } + + @Test + void should_rearrange_with_activation_produces_ordered_file() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(rearrange, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Rearrange_KO, ActionTestFile.Reformat_KO_Rearrange_OK); + } + + @Test + void should_rearrange_and_format_with_activation_produces_ordered_file_and_formated_file() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(reformat, true); + this.storage.setEnabled(rearrange, true); + this.assertSaveAction(ActionTestFile.Reformat_KO_Rearrange_KO, ActionTestFile.Reformat_OK_Rearrange_OK); + } } diff --git a/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java index 0c933d0..2847023 100644 --- a/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/IntegrationTest.java @@ -1,12 +1,19 @@ package software.xdev.saveactions.integration; +import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; + import com.intellij.testFramework.fixtures.CodeInsightTestFixture; import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.TestInfo; + import software.xdev.saveactions.core.action.BatchActionConstants; import software.xdev.saveactions.core.action.ShortcutActionConstants; import software.xdev.saveactions.core.component.SaveActionManagerConstants; @@ -14,56 +21,58 @@ import software.xdev.saveactions.junit.JUnit5Utils; import software.xdev.saveactions.model.Storage; -import java.nio.file.Path; -import java.nio.file.Paths; - -import static com.intellij.testFramework.LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; - -public abstract class IntegrationTest { - - private CodeInsightTestFixture fixture; - - Storage storage; - - @BeforeEach - public void before(TestInfo testInfo) throws Exception { - IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory(); - IdeaProjectTestFixture testFixture = factory.createLightFixtureBuilder(EMPTY_PROJECT_DESCRIPTOR, testInfo.getDisplayName()).getFixture(); - fixture = factory.createCodeInsightFixture(testFixture, new LightTempDirTestFixtureImpl(true)); - fixture.setUp(); - fixture.setTestDataPath(getTestDataPath()); - storage = testFixture.getProject().getService(Storage.class); - } - - @AfterEach - public void after() throws Exception { - fixture.tearDown(); - storage.clear(); - } - - void assertSaveAction(ActionTestFile before, ActionTestFile after) { - fixture.configureByFile(before.getFilename()); - SaveActionManagerConstants.SAVE_ACTION_MANAGER.accept(fixture, SaveActionsServiceManager.getService()); - JUnit5Utils.rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); - } - - void assertSaveActionShortcut(ActionTestFile before, ActionTestFile after) { - fixture.configureByFile(before.getFilename()); - ShortcutActionConstants.SAVE_ACTION_SHORTCUT_MANAGER.accept(fixture); - JUnit5Utils.rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); - } - - void assertSaveActionBatch(ActionTestFile before, ActionTestFile after) { - fixture.configureByFile(before.getFilename()); - BatchActionConstants.SAVE_ACTION_BATCH_MANAGER.accept(fixture); - JUnit5Utils.rethrowAsJunit5Error(() -> fixture.checkResultByFile(after.getFilename())); - } - - private String getTestDataPath() { - /* See gradle config. Previous implementation not compatible with intellij gradle plugin >= 1.6.0 */ - Path resources = Paths.get("./build/classes/java/resources"); - Path root = Paths.get(resources.toString(), getClass().getPackage().getName().split("[.]")); - return root.toString(); - } +public abstract class IntegrationTest +{ + private CodeInsightTestFixture fixture; + + Storage storage; + + @BeforeEach + public void before(final TestInfo testInfo) throws Exception + { + final IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory(); + final IdeaProjectTestFixture testFixture = + factory.createLightFixtureBuilder(EMPTY_PROJECT_DESCRIPTOR, testInfo.getDisplayName()).getFixture(); + this.fixture = factory.createCodeInsightFixture(testFixture, new LightTempDirTestFixtureImpl(true)); + this.fixture.setUp(); + this.fixture.setTestDataPath(this.getTestDataPath()); + this.storage = testFixture.getProject().getService(Storage.class); + } + + @AfterEach + public void after() throws Exception + { + this.fixture.tearDown(); + this.storage.clear(); + } + + void assertSaveAction(final ActionTestFile before, final ActionTestFile after) + { + this.fixture.configureByFile(before.getFilename()); + SaveActionManagerConstants.SAVE_ACTION_MANAGER.accept(this.fixture, SaveActionsServiceManager.getService()); + JUnit5Utils.rethrowAsJunit5Error(() -> this.fixture.checkResultByFile(after.getFilename())); + } + + void assertSaveActionShortcut(final ActionTestFile before, final ActionTestFile after) + { + this.fixture.configureByFile(before.getFilename()); + ShortcutActionConstants.SAVE_ACTION_SHORTCUT_MANAGER.accept(this.fixture); + JUnit5Utils.rethrowAsJunit5Error(() -> this.fixture.checkResultByFile(after.getFilename())); + } + + void assertSaveActionBatch(final ActionTestFile before, final ActionTestFile after) + { + this.fixture.configureByFile(before.getFilename()); + BatchActionConstants.SAVE_ACTION_BATCH_MANAGER.accept(this.fixture); + JUnit5Utils.rethrowAsJunit5Error(() -> this.fixture.checkResultByFile(after.getFilename())); + } + + private String getTestDataPath() + { + /* See gradle config. Previous implementation not compatible with intellij gradle plugin >= 1.6.0 */ + final Path resources = Paths.get("./build/classes/java/resources"); + final Path root = Paths.get(resources.toString(), this.getClass().getPackage().getName().split("[.]")); + return root.toString(); + } } diff --git a/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java b/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java index 28c75a4..1784b81 100644 --- a/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java +++ b/src/test/java/software/xdev/saveactions/integration/JavaIntegrationTest.java @@ -1,8 +1,5 @@ package software.xdev.saveactions.integration; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - import static software.xdev.saveactions.model.Action.accessCanBeTightened; import static software.xdev.saveactions.model.Action.activate; import static software.xdev.saveactions.model.Action.activateOnBatch; @@ -25,158 +22,190 @@ import static software.xdev.saveactions.model.Action.unqualifiedStaticMemberAccess; import static software.xdev.saveactions.model.Action.useBlocks; -class JavaIntegrationTest extends IntegrationTest { - - @Test - void should_fieldCanBeFinal_add_final_to_field() { - storage.setEnabled(activate, true); - storage.setEnabled(fieldCanBeFinal, true); - assertSaveAction(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); - } - - @Test - void should_fieldCanBeFinal_add_final_to_field_on_shortcut() { - storage.setEnabled(activateOnShortcut, true); - storage.setEnabled(fieldCanBeFinal, true); - assertSaveActionShortcut(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); - } - - @Test - void should_fieldCanBeFinal_add_final_to_field_on_batch() { - storage.setEnabled(activateOnBatch, true); - storage.setEnabled(fieldCanBeFinal, true); - assertSaveActionBatch(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); - } - - @Test - void should_localCanBeFinal_add_final_to_local_variable_and_parameters() { - storage.setEnabled(activate, true); - storage.setEnabled(localCanBeFinal, true); - assertSaveAction(ActionTestFile.LocalCanBeFinal_KO, ActionTestFile.LocalCanBeFinal_OK); - } - - @Test - void should_localCanBeFinalExceptImplicit_add_final_to_variable_but_not_resources() { - storage.setEnabled(activate, true); - storage.setEnabled(localCanBeFinalExceptImplicit, true); - assertSaveAction(ActionTestFile.LocalCanBeFinalExceptImplicit_KO, ActionTestFile.LocalCanBeFinalExceptImplicit_OK); - } - - @Test - @Disabled("do not work") - void should_methodMayBeStatic_add_static_keyword_to_method() { - storage.setEnabled(activate, true); - storage.setEnabled(methodMayBeStatic, true); - assertSaveAction(ActionTestFile.MethodMayBeStatic_KO, ActionTestFile.MethodMayBeStatic_OK); - } - - @Test - void should_unqualifiedFieldAccess_add_this_to_field_access() { - storage.setEnabled(activate, true); - storage.setEnabled(unqualifiedFieldAccess, true); - assertSaveAction(ActionTestFile.UnqualifiedFieldAccess_KO, ActionTestFile.UnqualifiedFieldAccess_OK); - } - - @Test - void should_unqualifiedMethodAccess_add_this_to_method_access() { - storage.setEnabled(activate, true); - storage.setEnabled(unqualifiedMethodAccess, true); - assertSaveAction(ActionTestFile.UnqualifiedMethodAccess_KO, ActionTestFile.UnqualifiedMethodAccess_OK); - } - - @Test - void should_unqualifiedStaticMemberAccess_add_this_to_method_access() { - storage.setEnabled(activate, true); - storage.setEnabled(unqualifiedStaticMemberAccess, true); - assertSaveAction(ActionTestFile.UnqualifiedStaticMemberAccess_KO, ActionTestFile.UnqualifiedStaticMemberAccess_OK); - } - - @Test - void should_customUnqualifiedStaticMemberAccess_add_this_to_method_access() { - storage.setEnabled(activate, true); - storage.setEnabled(customUnqualifiedStaticMemberAccess, true); - assertSaveAction(ActionTestFile.CustomUnqualifiedStaticMemberAccess_KO, ActionTestFile.CustomUnqualifiedStaticMemberAccess_OK); - } - - @Test - void should_missingOverrideAnnotation_add_override_annotation() { - storage.setEnabled(activate, true); - storage.setEnabled(missingOverrideAnnotation, true); - assertSaveAction(ActionTestFile.MissingOverrideAnnotation_KO, ActionTestFile.MissingOverrideAnnotation_OK); - } - - @Test - void should_useBlocks_add_blocks_to_if_else_while_for() { - storage.setEnabled(activate, true); - storage.setEnabled(useBlocks, true); - assertSaveAction(ActionTestFile.UseBlocks_KO, ActionTestFile.UseBlocks_OK); - } - - @Test - @Disabled("do not work") - void should_generateSerialVersionUID_generates_serial_version_uid_for_serializable_class() { - storage.setEnabled(activate, true); - storage.setEnabled(generateSerialVersionUID, true); - assertSaveAction(ActionTestFile.GenerateSerialVersionUID_KO, ActionTestFile.GenerateSerialVersionUID_OK); - } - - @Test - void should_unnecessaryThis_removes_this_on_method_and_field() { - storage.setEnabled(activate, true); - storage.setEnabled(unnecessaryThis, true); - assertSaveAction(ActionTestFile.UnnecessaryThis_KO, ActionTestFile.UnnecessaryThis_OK); - } - - @Test - void should_finalPrivateMethod_removes_final_on_private_methods() { - storage.setEnabled(activate, true); - storage.setEnabled(finalPrivateMethod, true); - assertSaveAction(ActionTestFile.FinalPrivateMethod_KO, ActionTestFile.FinalPrivateMethod_OK); - } - - @Test - void should_unnecessaryFinalOnLocalVariableOrParameter_removes_final_on_local_varible_and_parameters() { - storage.setEnabled(activate, true); - storage.setEnabled(unnecessaryFinalOnLocalVariableOrParameter, true); - assertSaveAction(ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_KO, ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_OK); - } - - @Test - @Disabled("do not work") - void should_explicitTypeCanBeDiamond_removes_explicit_diamond() { - storage.setEnabled(activate, true); - storage.setEnabled(explicitTypeCanBeDiamond, true); - assertSaveAction(ActionTestFile.ExplicitTypeCanBeDiamond_KO, ActionTestFile.ExplicitTypeCanBeDiamond_OK); - } - - @Test - void should_unnecessarySemicolon_remove_unnecessary_semicolon() { - storage.setEnabled(activate, true); - storage.setEnabled(unnecessarySemicolon, true); - assertSaveAction(ActionTestFile.UnnecessarySemicolon_KO, ActionTestFile.UnnecessarySemicolon_OK); - } - - @Test - void should_accessCanBeTightened_remove_unnecessary_semicolon() { - storage.setEnabled(activate, true); - storage.setEnabled(accessCanBeTightened, true); - assertSaveAction(ActionTestFile.AccessCanBeTightened_KO, ActionTestFile.AccessCanBeTightened_OK); - } - - @Test - void should_singleStatementInBlock_remove_braces() { - storage.setEnabled(activate, true); - storage.setEnabled(singleStatementInBlock, true); - assertSaveAction(ActionTestFile.SingleStatementInBlock_KO, ActionTestFile.SingleStatementInBlock_OK); - } +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; - @Test - void should_inspectionsAll_boogaloo() { - storage.setEnabled(activate, true); - storage.setEnabled(useBlocks, true); - storage.setEnabled(accessCanBeTightened, true); - storage.setEnabled(unnecessarySemicolon, true); - assertSaveAction(ActionTestFile.InspectionsAll_KO, ActionTestFile.InspectionsAll_OK); - } +class JavaIntegrationTest extends IntegrationTest +{ + @Test + void should_fieldCanBeFinal_add_final_to_field() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(fieldCanBeFinal, true); + this.assertSaveAction(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); + } + + @Test + void should_fieldCanBeFinal_add_final_to_field_on_shortcut() + { + this.storage.setEnabled(activateOnShortcut, true); + this.storage.setEnabled(fieldCanBeFinal, true); + this.assertSaveActionShortcut(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); + } + + @Test + void should_fieldCanBeFinal_add_final_to_field_on_batch() + { + this.storage.setEnabled(activateOnBatch, true); + this.storage.setEnabled(fieldCanBeFinal, true); + this.assertSaveActionBatch(ActionTestFile.FieldCanBeFinal_KO, ActionTestFile.FieldCanBeFinal_OK); + } + + @Test + void should_localCanBeFinal_add_final_to_local_variable_and_parameters() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(localCanBeFinal, true); + this.assertSaveAction(ActionTestFile.LocalCanBeFinal_KO, ActionTestFile.LocalCanBeFinal_OK); + } + + @Test + void should_localCanBeFinalExceptImplicit_add_final_to_variable_but_not_resources() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(localCanBeFinalExceptImplicit, true); + this.assertSaveAction( + ActionTestFile.LocalCanBeFinalExceptImplicit_KO, + ActionTestFile.LocalCanBeFinalExceptImplicit_OK); + } + + @Test + @Disabled("do not work") + void should_methodMayBeStatic_add_static_keyword_to_method() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(methodMayBeStatic, true); + this.assertSaveAction(ActionTestFile.MethodMayBeStatic_KO, ActionTestFile.MethodMayBeStatic_OK); + } + + @Test + void should_unqualifiedFieldAccess_add_this_to_field_access() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(unqualifiedFieldAccess, true); + this.assertSaveAction(ActionTestFile.UnqualifiedFieldAccess_KO, ActionTestFile.UnqualifiedFieldAccess_OK); + } + + @Test + void should_unqualifiedMethodAccess_add_this_to_method_access() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(unqualifiedMethodAccess, true); + this.assertSaveAction(ActionTestFile.UnqualifiedMethodAccess_KO, ActionTestFile.UnqualifiedMethodAccess_OK); + } + + @Test + void should_unqualifiedStaticMemberAccess_add_this_to_method_access() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(unqualifiedStaticMemberAccess, true); + this.assertSaveAction( + ActionTestFile.UnqualifiedStaticMemberAccess_KO, + ActionTestFile.UnqualifiedStaticMemberAccess_OK); + } + + @Test + void should_customUnqualifiedStaticMemberAccess_add_this_to_method_access() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(customUnqualifiedStaticMemberAccess, true); + this.assertSaveAction( + ActionTestFile.CustomUnqualifiedStaticMemberAccess_KO, + ActionTestFile.CustomUnqualifiedStaticMemberAccess_OK); + } + + @Test + void should_missingOverrideAnnotation_add_override_annotation() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(missingOverrideAnnotation, true); + this.assertSaveAction(ActionTestFile.MissingOverrideAnnotation_KO, ActionTestFile.MissingOverrideAnnotation_OK); + } + + @Test + void should_useBlocks_add_blocks_to_if_else_while_for() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(useBlocks, true); + this.assertSaveAction(ActionTestFile.UseBlocks_KO, ActionTestFile.UseBlocks_OK); + } + + @Test + @Disabled("do not work") + void should_generateSerialVersionUID_generates_serial_version_uid_for_serializable_class() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(generateSerialVersionUID, true); + this.assertSaveAction(ActionTestFile.GenerateSerialVersionUID_KO, ActionTestFile.GenerateSerialVersionUID_OK); + } + + @Test + void should_unnecessaryThis_removes_this_on_method_and_field() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(unnecessaryThis, true); + this.assertSaveAction(ActionTestFile.UnnecessaryThis_KO, ActionTestFile.UnnecessaryThis_OK); + } + + @Test + void should_finalPrivateMethod_removes_final_on_private_methods() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(finalPrivateMethod, true); + this.assertSaveAction(ActionTestFile.FinalPrivateMethod_KO, ActionTestFile.FinalPrivateMethod_OK); + } + + @Test + void should_unnecessaryFinalOnLocalVariableOrParameter_removes_final_on_local_varible_and_parameters() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(unnecessaryFinalOnLocalVariableOrParameter, true); + this.assertSaveAction( + ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_KO, + ActionTestFile.UnnecessaryFinalOnLocalVariableOrParameter_OK); + } + + @Test + @Disabled("do not work") + void should_explicitTypeCanBeDiamond_removes_explicit_diamond() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(explicitTypeCanBeDiamond, true); + this.assertSaveAction(ActionTestFile.ExplicitTypeCanBeDiamond_KO, ActionTestFile.ExplicitTypeCanBeDiamond_OK); + } + + @Test + void should_unnecessarySemicolon_remove_unnecessary_semicolon() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(unnecessarySemicolon, true); + this.assertSaveAction(ActionTestFile.UnnecessarySemicolon_KO, ActionTestFile.UnnecessarySemicolon_OK); + } + + @Test + void should_accessCanBeTightened_remove_unnecessary_semicolon() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(accessCanBeTightened, true); + this.assertSaveAction(ActionTestFile.AccessCanBeTightened_KO, ActionTestFile.AccessCanBeTightened_OK); + } + + @Test + void should_singleStatementInBlock_remove_braces() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(singleStatementInBlock, true); + this.assertSaveAction(ActionTestFile.SingleStatementInBlock_KO, ActionTestFile.SingleStatementInBlock_OK); + } + + @Test + void should_inspectionsAll_boogaloo() + { + this.storage.setEnabled(activate, true); + this.storage.setEnabled(useBlocks, true); + this.storage.setEnabled(accessCanBeTightened, true); + this.storage.setEnabled(unnecessarySemicolon, true); + this.assertSaveAction(ActionTestFile.InspectionsAll_KO, ActionTestFile.InspectionsAll_OK); + } } diff --git a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java index 4b8edb2..6082ffa 100644 --- a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java +++ b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java @@ -1,33 +1,41 @@ package software.xdev.saveactions.junit; -import com.intellij.rt.execution.junit.FileComparisonFailure; -import org.opentest4j.AssertionFailedError; - import java.lang.reflect.InvocationTargetException; -public class JUnit5Utils { - - private JUnit5Utils() { - // static - } +import org.opentest4j.AssertionFailedError; - public static void rethrowAsJunit5Error(AssertionError error) { - if (error.getCause() instanceof InvocationTargetException intellijInternal) { - if (intellijInternal.getCause() instanceof FileComparisonFailure fileComparisonFailure) { - String expected = fileComparisonFailure.getExpected(); - String actual = fileComparisonFailure.getActual(); - throw new AssertionFailedError("Expected file do not match actual file", expected, actual); - } - } - throw error; - } +import com.intellij.rt.execution.junit.FileComparisonFailure; - public static void rethrowAsJunit5Error(Runnable runnable) { - try { - runnable.run(); - } catch (AssertionError error) { - rethrowAsJunit5Error(error); - } - } +public final class JUnit5Utils +{ + private JUnit5Utils() + { + } + + public static void rethrowAsJunit5Error(final AssertionError error) + { + if(error.getCause() instanceof final InvocationTargetException intellijInternal) + { + if(intellijInternal.getCause() instanceof final FileComparisonFailure fileComparisonFailure) + { + final String expected = fileComparisonFailure.getExpected(); + final String actual = fileComparisonFailure.getActual(); + throw new AssertionFailedError("Expected file do not match actual file", expected, actual); + } + } + throw error; + } + + public static void rethrowAsJunit5Error(final Runnable runnable) + { + try + { + runnable.run(); + } + catch(final AssertionError error) + { + rethrowAsJunit5Error(error); + } + } } diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java index 0a9ae64..6d3e833 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfActionTest.java @@ -1,26 +1,28 @@ package software.xdev.saveactions.model.java; -import software.xdev.saveactions.model.Action; -import org.junit.jupiter.api.Test; -import software.xdev.saveactions.model.java.EpfAction; - -import java.util.List; - import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; -class EpfActionTest { +import java.util.List; + +import org.junit.jupiter.api.Test; - @Test - void should_epf_action_have_no_duplicate_action() { - List actions = EpfAction.stream().map(EpfAction::getAction).collect(toList()); - assertThat(actions).doesNotHaveDuplicates(); - } +import software.xdev.saveactions.model.Action; - @Test - void should_java_processor_have_valid_type_and_inspection() { - EpfAction.stream().forEach(epfAction -> assertThat(epfAction.getAction().getType()).isNotNull()); - EpfAction.stream().forEach(epfAction -> assertThat(epfAction.getEpfKeys()).isNotEmpty()); - } +class EpfActionTest +{ + @Test + void should_epf_action_have_no_duplicate_action() + { + final List actions = EpfAction.stream().map(EpfAction::getAction).collect(toList()); + assertThat(actions).doesNotHaveDuplicates(); + } + + @Test + void should_java_processor_have_valid_type_and_inspection() + { + EpfAction.stream().forEach(epfAction -> assertThat(epfAction.getAction().getType()).isNotNull()); + EpfAction.stream().forEach(epfAction -> assertThat(epfAction.getEpfKeys()).isNotEmpty()); + } } diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java index 43388ca..955aaac 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java @@ -1,69 +1,78 @@ package software.xdev.saveactions.model.java; -import org.junit.jupiter.api.Test; +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; import java.io.FileInputStream; import java.io.IOException; import java.util.List; import java.util.Properties; -import static java.util.stream.Collectors.toList; -import static org.assertj.core.api.Assertions.assertThat; - -class EpfKeyTest { - - @Test - void should_all_example_file_0_keys_be_present_in_epf_key() throws IOException { - Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_0.toString()); - assertPropertyPresenceInEpf(properties); - } - - @Test - void should_all_example_file_1_keys_be_present_in_epf_key() throws IOException { - Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_1.toString()); - assertPropertyPresenceInEpf(properties); - } - - @Test - void should_all_example_file_2_keys_be_present_in_epf_key() throws IOException { - Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_2.toString()); - assertPropertyPresenceInEpf(properties); - } - - @Test - void should_all_epf_key_be_present_in_example_files_2_to_remove_unused_keys() throws IOException { - Properties properties = readProperties(EpfTestConstants.EXAMPLE_EPF_2.toString()); - List epfKeyNames = getEpfKeyNames(); - List propertiesKeyNames = getPropertiesKeyNames(properties); - epfKeyNames.forEach(epfKeyName -> assertThat(propertiesKeyNames).contains(epfKeyName)); - } - - private void assertPropertyPresenceInEpf(Properties properties) { - List epfKeyNames = getEpfKeyNames(); - List propertiesKeyNames = getPropertiesKeyNames(properties); - propertiesKeyNames.forEach(propertiesKeyName -> assertThat(epfKeyNames).contains(propertiesKeyName)); - } - - private List getPropertiesKeyNames(Properties properties) { - return properties.keySet().stream() - .map(Object::toString) - .filter(key -> EpfKey.getPrefixes().stream().anyMatch(key::startsWith)) - .map(key -> key.substring(key.lastIndexOf(".") == -1 ? 0 : key.lastIndexOf(".") + 1)) - .collect(toList()); - } - - private List getEpfKeyNames() { - return EpfKey.stream() - .map(EpfKey::name) - .collect(toList()); - } +import org.junit.jupiter.api.Test; - private Properties readProperties(String configurationPath) throws IOException { - Properties properties = new Properties(); - try (FileInputStream in = new FileInputStream(configurationPath)) { - properties.load(in); - } - return properties; - } +class EpfKeyTest +{ + @Test + void should_all_example_file_0_keys_be_present_in_epf_key() throws IOException + { + final Properties properties = this.readProperties(EpfTestConstants.EXAMPLE_EPF_0.toString()); + this.assertPropertyPresenceInEpf(properties); + } + + @Test + void should_all_example_file_1_keys_be_present_in_epf_key() throws IOException + { + final Properties properties = this.readProperties(EpfTestConstants.EXAMPLE_EPF_1.toString()); + this.assertPropertyPresenceInEpf(properties); + } + + @Test + void should_all_example_file_2_keys_be_present_in_epf_key() throws IOException + { + final Properties properties = this.readProperties(EpfTestConstants.EXAMPLE_EPF_2.toString()); + this.assertPropertyPresenceInEpf(properties); + } + + @Test + void should_all_epf_key_be_present_in_example_files_2_to_remove_unused_keys() throws IOException + { + final Properties properties = this.readProperties(EpfTestConstants.EXAMPLE_EPF_2.toString()); + final List epfKeyNames = this.getEpfKeyNames(); + final List propertiesKeyNames = this.getPropertiesKeyNames(properties); + epfKeyNames.forEach(epfKeyName -> assertThat(propertiesKeyNames).contains(epfKeyName)); + } + + private void assertPropertyPresenceInEpf(final Properties properties) + { + final List epfKeyNames = this.getEpfKeyNames(); + final List propertiesKeyNames = this.getPropertiesKeyNames(properties); + propertiesKeyNames.forEach(propertiesKeyName -> assertThat(epfKeyNames).contains(propertiesKeyName)); + } + + private List getPropertiesKeyNames(final Properties properties) + { + return properties.keySet().stream() + .map(Object::toString) + .filter(key -> EpfKey.getPrefixes().stream().anyMatch(key::startsWith)) + .map(key -> key.substring(key.lastIndexOf(".") == -1 ? 0 : key.lastIndexOf(".") + 1)) + .collect(toList()); + } + + private List getEpfKeyNames() + { + return EpfKey.stream() + .map(EpfKey::name) + .collect(toList()); + } + + private Properties readProperties(final String configurationPath) throws IOException + { + final Properties properties = new Properties(); + try(final FileInputStream in = new FileInputStream(configurationPath)) + { + properties.load(in); + } + return properties; + } } diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java index ed99d32..2a98195 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfStorageTest.java @@ -1,13 +1,6 @@ package software.xdev.saveactions.model.java; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.model.Storage; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.EnumSet; -import java.util.HashSet; - +import static org.assertj.core.api.Assertions.assertThat; import static software.xdev.saveactions.model.Action.activate; import static software.xdev.saveactions.model.Action.explicitTypeCanBeDiamond; import static software.xdev.saveactions.model.Action.fieldCanBeFinal; @@ -24,117 +17,131 @@ import static software.xdev.saveactions.model.java.EpfTestConstants.EXAMPLE_EPF_0; import static software.xdev.saveactions.model.java.EpfTestConstants.EXAMPLE_EPF_1; import static software.xdev.saveactions.model.java.EpfTestConstants.EXAMPLE_EPF_2; -import static org.assertj.core.api.Assertions.assertThat; - -class EpfStorageTest { - - private Storage storage; - - @BeforeEach - void before() { - storage = new Storage(); - - storage.setActions(new HashSet<>()); - storage.setInclusions(new HashSet<>()); - storage.setExclusions(new HashSet<>()); - - storage.getActions().add(activate); - storage.getActions().add(reformat); - storage.getActions().add(reformatChangedCode); - storage.getActions().add(fieldCanBeFinal); - storage.getActions().add(missingOverrideAnnotation); - storage.getActions().add(unnecessarySemicolon); - - storage.getInclusions().add("inclusion1"); - storage.getInclusions().add("inclusion2"); - storage.getExclusions().add("exclusion1"); - storage.getExclusions().add("exclusion2"); - } - - @Test - void should_storage_with_bad_configuration_path_returns_default_storage() { - Storage epfStorage; - - epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(storage.getConfigurationPath(), storage); - assertThat(storage).isSameAs(epfStorage); - - storage.setConfigurationPath("bad path"); - epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(storage.getConfigurationPath(), storage); - assertThat(storage).isSameAs(epfStorage); - } - - @Test - void should_default_storage_values_are_copied_to_epf_storage_if_empty_file() { - Storage epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(EXAMPLE_EPF_0.toString(), storage); - assertThat(epfStorage).isNotSameAs(storage); - - assertThat(epfStorage.getActions()).isNotSameAs(storage.getActions()); - assertThat(epfStorage.getInclusions()).isNotSameAs(storage.getInclusions()); - assertThat(epfStorage.getExclusions()).isNotSameAs(storage.getExclusions()); - - assertThat(epfStorage.getActions()).isEqualTo(storage.getActions()); - assertThat(epfStorage.getInclusions()).isEqualTo(storage.getInclusions()); - assertThat(epfStorage.getExclusions()).isEqualTo(storage.getExclusions()); - } - - @Test - void should_storage_values_are_correct_for_file_format_1() { - Storage epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(EXAMPLE_EPF_1.toString(), storage); - assertThat(epfStorage).isNotSameAs(storage); - - EnumSet expected = EnumSet.of( - // from default store (not in java) - activate, - // in both store - reformat, - // added by java - useBlocks, - // added by java - unqualifiedFieldAccess, - // added by java - localCanBeFinal, - // added by java - rearrange, - // added by java - organizeImports, - // added by java - explicitTypeCanBeDiamond, - // added by java - missingOverrideAnnotation, - // from default store (not in java) - unnecessarySemicolon - // removed by java : fieldCanBeFinal - // removed by java : reformatChangedCode - ); - - assertThat(epfStorage.getActions()).isEqualTo(expected); - assertThat(epfStorage.getInclusions()).isEqualTo(storage.getInclusions()); - assertThat(epfStorage.getExclusions()).isEqualTo(storage.getExclusions()); - } +import java.util.EnumSet; +import java.util.HashSet; - @Test - void should_storage_values_are_correct_for_file_format_2() { - Storage epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(EXAMPLE_EPF_2.toString(), storage); - assertThat(epfStorage).isNotSameAs(storage); +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; - EnumSet expected = EnumSet.of( - missingOverrideAnnotation, - unnecessarySemicolon, - rearrange, - unqualifiedStaticMemberAccess, - useBlocks, - activate, - organizeImports, - unqualifiedFieldAccess, - explicitTypeCanBeDiamond, - localCanBeFinal, - fieldCanBeFinal - ); +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; - assertThat(epfStorage.getActions()).isEqualTo(expected); - assertThat(epfStorage.getInclusions()).isEqualTo(storage.getInclusions()); - assertThat(epfStorage.getExclusions()).isEqualTo(storage.getExclusions()); - } +class EpfStorageTest +{ + + private Storage storage; + + @BeforeEach + void before() + { + storage = new Storage(); + + storage.setActions(new HashSet<>()); + storage.setInclusions(new HashSet<>()); + storage.setExclusions(new HashSet<>()); + + storage.getActions().add(activate); + storage.getActions().add(reformat); + storage.getActions().add(reformatChangedCode); + storage.getActions().add(fieldCanBeFinal); + storage.getActions().add(missingOverrideAnnotation); + storage.getActions().add(unnecessarySemicolon); + + storage.getInclusions().add("inclusion1"); + storage.getInclusions().add("inclusion2"); + + storage.getExclusions().add("exclusion1"); + storage.getExclusions().add("exclusion2"); + } + + @Test + void should_storage_with_bad_configuration_path_returns_default_storage() + { + Storage epfStorage; + + epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(storage.getConfigurationPath(), storage); + assertThat(storage).isSameAs(epfStorage); + + storage.setConfigurationPath("bad path"); + epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(storage.getConfigurationPath(), storage); + assertThat(storage).isSameAs(epfStorage); + } + + @Test + void should_default_storage_values_are_copied_to_epf_storage_if_empty_file() + { + Storage epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(EXAMPLE_EPF_0.toString(), storage); + assertThat(epfStorage).isNotSameAs(storage); + + assertThat(epfStorage.getActions()).isNotSameAs(storage.getActions()); + assertThat(epfStorage.getInclusions()).isNotSameAs(storage.getInclusions()); + assertThat(epfStorage.getExclusions()).isNotSameAs(storage.getExclusions()); + + assertThat(epfStorage.getActions()).isEqualTo(storage.getActions()); + assertThat(epfStorage.getInclusions()).isEqualTo(storage.getInclusions()); + assertThat(epfStorage.getExclusions()).isEqualTo(storage.getExclusions()); + } + + @Test + void should_storage_values_are_correct_for_file_format_1() + { + Storage epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(EXAMPLE_EPF_1.toString(), storage); + assertThat(epfStorage).isNotSameAs(storage); + + EnumSet expected = EnumSet.of( + // from default store (not in java) + activate, + // in both store + reformat, + // added by java + useBlocks, + // added by java + unqualifiedFieldAccess, + // added by java + localCanBeFinal, + // added by java + rearrange, + // added by java + organizeImports, + // added by java + explicitTypeCanBeDiamond, + // added by java + missingOverrideAnnotation, + // from default store (not in java) + unnecessarySemicolon + // removed by java : fieldCanBeFinal + // removed by java : reformatChangedCode + ); + + assertThat(epfStorage.getActions()).isEqualTo(expected); + assertThat(epfStorage.getInclusions()).isEqualTo(storage.getInclusions()); + assertThat(epfStorage.getExclusions()).isEqualTo(storage.getExclusions()); + } + + @Test + void should_storage_values_are_correct_for_file_format_2() + { + Storage epfStorage = EpfStorage.INSTANCE.getStorageOrDefault(EXAMPLE_EPF_2.toString(), storage); + assertThat(epfStorage).isNotSameAs(storage); + + EnumSet expected = EnumSet.of( + missingOverrideAnnotation, + unnecessarySemicolon, + rearrange, + unqualifiedStaticMemberAccess, + useBlocks, + activate, + organizeImports, + unqualifiedFieldAccess, + explicitTypeCanBeDiamond, + localCanBeFinal, + fieldCanBeFinal + ); + + assertThat(epfStorage.getActions()).isEqualTo(expected); + assertThat(epfStorage.getInclusions()).isEqualTo(storage.getInclusions()); + assertThat(epfStorage.getExclusions()).isEqualTo(storage.getExclusions()); + } } diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java index 20fa7bc..86bae43 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfTestConstants.java @@ -4,14 +4,18 @@ import java.nio.file.Path; import java.nio.file.Paths; -public interface EpfTestConstants { - - Path ROOT = new File(".").toPath().toAbsolutePath().getParent(); - Path ROOT_RESOURCES = Paths.get(ROOT.toString(), "src", "test", "resources"); - Path ROOT_EPF = Paths.get(ROOT_RESOURCES.toString(), "software", "xdev", "saveactions", "model"); - - Path EXAMPLE_EPF_0 = Paths.get(ROOT_EPF.toString(), "example0.epf"); - Path EXAMPLE_EPF_1 = Paths.get(ROOT_EPF.toString(), "example1.epf"); - Path EXAMPLE_EPF_2 = Paths.get(ROOT_EPF.toString(), "example2.epf"); +public final class EpfTestConstants +{ + static final Path ROOT = new File(".").toPath().toAbsolutePath().getParent(); + static final Path ROOT_RESOURCES = Paths.get(ROOT.toString(), "src", "test", "resources"); + static final Path ROOT_EPF = Paths.get(ROOT_RESOURCES.toString(), "software", "xdev", "saveactions", "model"); + + public static final Path EXAMPLE_EPF_0 = Paths.get(ROOT_EPF.toString(), "example0.epf"); + public static final Path EXAMPLE_EPF_1 = Paths.get(ROOT_EPF.toString(), "example1.epf"); + public static final Path EXAMPLE_EPF_2 = Paths.get(ROOT_EPF.toString(), "example2.epf"); + + private EpfTestConstants() + { + } } diff --git a/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java index b4dc61c..936dd78 100644 --- a/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/BuildProcessorTest.java @@ -1,35 +1,37 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.model.Action; -import org.junit.jupiter.api.Test; -import software.xdev.saveactions.processors.BuildProcessor; -import software.xdev.saveactions.processors.Processor; - -import java.util.List; - -import static software.xdev.saveactions.model.ActionType.build; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import static software.xdev.saveactions.model.ActionType.build; -class BuildProcessorTest { +import java.util.List; - @Test - void should_processor_have_no_duplicate_action() { - List actions = BuildProcessor.stream().map(Processor::getAction).collect(toList()); - assertThat(actions).doesNotHaveDuplicates(); - } +import org.junit.jupiter.api.Test; - @Test - void should_processor_have_valid_type_and_inspection() { - BuildProcessor.stream() - .forEach(processor -> assertThat(processor.getAction().getType()).isEqualTo(build)); - BuildProcessor.stream() - .forEach(processor -> assertThat(((BuildProcessor) processor).getCommand()).isNotNull()); - } +import software.xdev.saveactions.model.Action; - @Test - void should_action_have_java_processor() { - Action.stream(build).forEach(action -> assertThat(BuildProcessor.getProcessorForAction(action)).isNotEmpty()); - } +class BuildProcessorTest +{ + @Test + void should_processor_have_no_duplicate_action() + { + final List actions = BuildProcessor.stream().map(Processor::getAction).collect(toList()); + assertThat(actions).doesNotHaveDuplicates(); + } + + @Test + void should_processor_have_valid_type_and_inspection() + { + BuildProcessor.stream() + .forEach(processor -> assertThat(processor.getAction().getType()).isEqualTo(build)); + BuildProcessor.stream() + .forEach(processor -> assertThat(((BuildProcessor)processor).getCommand()).isNotNull()); + } + + @Test + void should_action_have_java_processor() + { + Action.stream(build).forEach(action -> assertThat(BuildProcessor.getProcessorForAction(action)).isNotEmpty()); + } } diff --git a/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java index 1f183dc..da3cd84 100644 --- a/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/GlobalProcessorTest.java @@ -1,35 +1,37 @@ package software.xdev.saveactions.processors; -import software.xdev.saveactions.model.Action; -import org.junit.jupiter.api.Test; -import software.xdev.saveactions.processors.GlobalProcessor; -import software.xdev.saveactions.processors.Processor; - -import java.util.List; - -import static software.xdev.saveactions.model.ActionType.global; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import static software.xdev.saveactions.model.ActionType.global; -class GlobalProcessorTest { +import java.util.List; - @Test - void should_processor_have_no_duplicate_action() { - List actions = GlobalProcessor.stream().map(Processor::getAction).collect(toList()); - assertThat(actions).doesNotHaveDuplicates(); - } +import org.junit.jupiter.api.Test; - @Test - void should_processor_have_valid_type_and_inspection() { - GlobalProcessor.stream() - .forEach(processor -> assertThat(processor.getAction().getType()).isEqualTo(global)); - GlobalProcessor.stream() - .forEach(processor -> assertThat(((GlobalProcessor) processor).getCommand()).isNotNull()); - } +import software.xdev.saveactions.model.Action; - @Test - void should_action_have_java_processor() { - Action.stream(global).forEach(action -> assertThat(GlobalProcessor.getProcessorForAction(action)).isNotEmpty()); - } +class GlobalProcessorTest +{ + @Test + void should_processor_have_no_duplicate_action() + { + final List actions = GlobalProcessor.stream().map(Processor::getAction).collect(toList()); + assertThat(actions).doesNotHaveDuplicates(); + } + + @Test + void should_processor_have_valid_type_and_inspection() + { + GlobalProcessor.stream() + .forEach(processor -> assertThat(processor.getAction().getType()).isEqualTo(global)); + GlobalProcessor.stream() + .forEach(processor -> assertThat(((GlobalProcessor)processor).getCommand()).isNotNull()); + } + + @Test + void should_action_have_java_processor() + { + Action.stream(global).forEach(action -> assertThat(GlobalProcessor.getProcessorForAction(action)).isNotEmpty()); + } } diff --git a/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java b/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java index c1a6ae6..ae0f2a3 100644 --- a/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java +++ b/src/test/java/software/xdev/saveactions/processors/java/JavaProcessorTest.java @@ -1,35 +1,38 @@ package software.xdev.saveactions.processors.java; -import software.xdev.saveactions.model.Action; -import software.xdev.saveactions.processors.Processor; -import org.junit.jupiter.api.Test; -import software.xdev.saveactions.processors.java.JavaProcessor; - -import java.util.List; - -import static software.xdev.saveactions.model.ActionType.java; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import static software.xdev.saveactions.model.ActionType.java; -class JavaProcessorTest { +import java.util.List; - @Test - void should_java_processor_have_no_duplicate_action() { - List actions = JavaProcessor.stream().map(Processor::getAction).collect(toList()); - assertThat(actions).doesNotHaveDuplicates(); - } +import org.junit.jupiter.api.Test; - @Test - void should_java_processor_have_valid_type_and_inspection() { - JavaProcessor.stream() - .forEach(processor -> assertThat(processor.getAction().getType()).isEqualTo(java)); - JavaProcessor.stream() - .forEach(processor -> assertThat(((JavaProcessor) processor).getInspection()).isNotNull()); - } +import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.processors.Processor; - @Test - void should_java_action_have_java_processor() { - Action.stream(java).forEach(action -> assertThat(JavaProcessor.getProcessorForAction(action)).isNotEmpty()); - } +class JavaProcessorTest +{ + @Test + void should_java_processor_have_no_duplicate_action() + { + final List actions = JavaProcessor.stream().map(Processor::getAction).collect(toList()); + assertThat(actions).doesNotHaveDuplicates(); + } + + @Test + void should_java_processor_have_valid_type_and_inspection() + { + JavaProcessor.stream() + .forEach(processor -> assertThat(processor.getAction().getType()).isEqualTo(java)); + JavaProcessor.stream() + .forEach(processor -> assertThat(((JavaProcessor)processor).getInspection()).isNotNull()); + } + + @Test + void should_java_action_have_java_processor() + { + Action.stream(java).forEach(action -> assertThat(JavaProcessor.getProcessorForAction(action)).isNotEmpty()); + } } diff --git a/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java index 8ca184f..3c40f26 100644 --- a/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_KO.java @@ -2,23 +2,32 @@ // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 -class Hello { - static final String STR = "Hello"; - void sayIt() { - println(STR); // should not qualify it as Hello.STR - } - - class Other { - String method(){ - String s = STR; // should qualify - return s.replace("l", "y"); - } - } +class Hello +{ + static final String STR = "Hello"; + + void sayIt() + { + println(STR); // should not qualify it as Hello.STR + } + + class Other + { + String method() + { + final String s = STR; // should qualify + return s.replace("l", "y"); + } + } } -class World extends Hello { - void sayIt() { - println(STR + " World!"); // should qualify - } + +class World extends Hello +{ + @Override + void sayIt() + { + println(STR + " World!"); // should qualify + } } diff --git a/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java index 80fb7df..76a0138 100644 --- a/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/CustomUnqualifiedStaticMemberAccess_OK.java @@ -2,23 +2,32 @@ // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 -class Hello { - static final String STR = "Hello"; - void sayIt() { - println(STR); // should not qualify it as Hello.STR - } - - class Other { - String method(){ - String s = Hello.STR; // should qualify - return s.replace("l", "y"); - } - } +class Hello +{ + static final String STR = "Hello"; + + void sayIt() + { + println(STR); // should not qualify it as Hello.STR + } + + class Other + { + String method() + { + final String s = Hello.STR; // should qualify + return s.replace("l", "y"); + } + } } -class World extends Hello { - void sayIt() { - println(Hello.STR + " World!"); // should qualify - } + +class World extends Hello +{ + @Override + void sayIt() + { + println(Hello.STR + " World!"); // should qualify + } } diff --git a/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java index 649a85b..335db8a 100644 --- a/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_KO.java @@ -1,11 +1,12 @@ package software.xdev.saveactions.integration; -public class Class { - - private final String field; - - private void method(final String arg1, final String arg2) { - final String localVariable; - } - +public class Class +{ + + private final String field; + + private void method(final String arg1, final String arg2) + { + final String localVariable; + } } diff --git a/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java index 2f7f5ec..a323ad5 100644 --- a/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java @@ -1,11 +1,12 @@ package software.xdev.saveactions.integration; -public class Class { - - private final String field; - - private void method(String arg1, String arg2) { - String localVariable; - } - +public class Class +{ + + private final String field; + + private void method(final String arg1, final String arg2) + { + String localVariable; + } } diff --git a/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java index fd0b7d0..b5f8814 100644 --- a/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_KO.java @@ -2,23 +2,32 @@ // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 -class Hello { - static final String STR = "Hello"; - void sayIt() { - println(STR); // should qualify - } - - class Other { - String method(){ - String s = STR; // should qualify - return s.replace("l", "y"); - } - } +class Hello +{ + static final String STR = "Hello"; + + void sayIt() + { + println(STR); // should qualify + } + + class Other + { + String method() + { + final String s = STR; // should qualify + return s.replace("l", "y"); + } + } } -class World extends Hello { - void sayIt() { - println(STR + " World!"); // should qualify - } + +class World extends Hello +{ + @Override + void sayIt() + { + println(STR + " World!"); // should qualify + } } diff --git a/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java index a56075d..65e5c3b 100644 --- a/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnqualifiedStaticMemberAccess_OK.java @@ -2,23 +2,32 @@ // https://github.com/dubreuia/intellij-plugin-save-actions/issues/155 -class Hello { - static final String STR = "Hello"; - void sayIt() { - println(Hello.STR); // should qualify - } - - class Other { - String method(){ - String s = Hello.STR; // should qualify - return s.replace("l", "y"); - } - } +class Hello +{ + static final String STR = "Hello"; + + void sayIt() + { + println(Hello.STR); // should qualify + } + + class Other + { + String method() + { + final String s = Hello.STR; // should qualify + return s.replace("l", "y"); + } + } } -class World extends Hello { - void sayIt() { - println(Hello.STR + " World!"); // should qualify - } + +class World extends Hello +{ + @Override + void sayIt() + { + println(Hello.STR + " World!"); // should qualify + } } From 71a7cb43d3ed75a652db7cb4b4f42140a5bfcc42 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 14:28:59 +0100 Subject: [PATCH 420/518] Fix tests --- .idea/saveactions_settings.xml | 5 +++++ .../UnnecessaryFinalOnLocalVariableOrParameter_OK.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.idea/saveactions_settings.xml b/.idea/saveactions_settings.xml index 2909df4..8743331 100644 --- a/.idea/saveactions_settings.xml +++ b/.idea/saveactions_settings.xml @@ -17,5 +17,10 @@ diff --git a/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java index a323ad5..d027284 100644 --- a/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java +++ b/src/test/resources/software/xdev/saveactions/integration/UnnecessaryFinalOnLocalVariableOrParameter_OK.java @@ -5,7 +5,7 @@ public class Class private final String field; - private void method(final String arg1, final String arg2) + private void method(String arg1, String arg2) { String localVariable; } From ed294ec8ecc38bb7b48070db4009c03f996f0e2f Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 14:45:40 +0100 Subject: [PATCH 421/518] Run checkstyle checks in workflow --- .config/checkstyle/checkstyle.xml | 2 +- .github/workflows/checkBuild.yml | 21 +++++++++++++++++++++ build.gradle | 25 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/.config/checkstyle/checkstyle.xml b/.config/checkstyle/checkstyle.xml index a0d7f17..13d47b9 100644 --- a/.config/checkstyle/checkstyle.xml +++ b/.config/checkstyle/checkstyle.xml @@ -9,7 +9,7 @@ - + diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 0cd547b..bc8856c 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -64,3 +64,24 @@ jobs: name: plugin-files-java-${{ matrix.java }} path: build/libs/intellij-plugin-save-actions-*.jar if-no-files-found: error + + code-style: + runs-on: ubuntu-latest + + strategy: + matrix: + java: [17] + distribution: [temurin] + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: ${{ matrix.distribution }} + java-version: ${{ matrix.java }} + cache: 'gradle' + + - name: Run Checkstyle + run: ./gradlew checkstyleMain checkstyleTest -PcheckstyleEnabled=true diff --git a/build.gradle b/build.gradle index 6fce440..98f9403 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,15 @@ plugins { id 'java' id 'idea' + id 'checkstyle' id 'org.jetbrains.intellij' version '1.17.1' id 'org.sonarqube' version '4.4.1.3373' } +ext { + checkstyleVersion = '10.13.0' +} + def properties(String key) { return providers.gradleProperty(key) } @@ -15,6 +20,7 @@ def environment(String key) { apply plugin: 'org.jetbrains.intellij' apply plugin: 'java' +apply plugin: 'checkstyle' // Add plugin group and version group = properties("pluginGroup").get() @@ -25,8 +31,16 @@ repositories { mavenCentral() } +// https://github.com/gradle/gradle/issues/27035 +configurations.checkstyle { + resolutionStrategy.capabilitiesResolution.withCapability("com.google.collections:google-collections") { + select("com.google.guava:guava:0") + } +} + // Add dependencies to test, junit5 api (annotations) and engine (runtime) dependencies { + checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}" testImplementation platform('org.junit:junit-bom:5.10.2'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', @@ -57,6 +71,17 @@ listProductsReleases { sinceBuild = "223.*" } +checkstyle { + configDirectory = file("$rootProject.projectDir/.config/checkstyle") + ignoreFailures false + showViolations true + toolVersion = checkstyleVersion +} + +tasks.withType(Checkstyle).configureEach { + enabled = project.hasProperty("checkstyleEnabled"); +} + // Configure compileJava AND compileTestJava // https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html tasks.withType(JavaCompile).configureEach { From 4732b7a7863844f4d550eef848bbcc9625cb7975 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 15:14:49 +0100 Subject: [PATCH 422/518] [Workflow] Create for IDE compatibility check --- .github/workflows/checkIDECompatibility.yml | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/checkIDECompatibility.yml diff --git a/.github/workflows/checkIDECompatibility.yml b/.github/workflows/checkIDECompatibility.yml new file mode 100644 index 0000000..729400e --- /dev/null +++ b/.github/workflows/checkIDECompatibility.yml @@ -0,0 +1,30 @@ +name: Check IDE Compatibility + +on: + schedule: + - cron: '55 2 * * 1' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + java: [17, 21] + distribution: [temurin] + platformType: [IU, IC] + platformVersion: [LATEST-EAP-SNAPSHOT] + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: ${{ matrix.distribution }} + java-version: ${{ matrix.java }} + cache: 'gradle' + + - name: Build + run: ./gradlew runPluginVerifier -PplatformVersion=LATEST-EAP-SNAPSHOT From 293b907e0d9af6ab64854b7cadc44533d5a70bd7 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 15:15:40 +0100 Subject: [PATCH 423/518] One java version should be enough --- .github/workflows/checkIDECompatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkIDECompatibility.yml b/.github/workflows/checkIDECompatibility.yml index 729400e..4fbc40e 100644 --- a/.github/workflows/checkIDECompatibility.yml +++ b/.github/workflows/checkIDECompatibility.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: - java: [17, 21] + java: [17] distribution: [temurin] platformType: [IU, IC] platformVersion: [LATEST-EAP-SNAPSHOT] From 95e4a99bde9a432f40f159c39084d153e50d3841 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 15:16:47 +0100 Subject: [PATCH 424/518] Name correctly --- .github/workflows/checkIDECompatibility.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkIDECompatibility.yml b/.github/workflows/checkIDECompatibility.yml index 4fbc40e..6fd43a8 100644 --- a/.github/workflows/checkIDECompatibility.yml +++ b/.github/workflows/checkIDECompatibility.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: jobs: - build: + check-ide-compatibility: runs-on: ubuntu-latest strategy: From 1d5b64264bdf3798248d30d8c6f35a5aed3b3b25 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 15:21:00 +0100 Subject: [PATCH 425/518] Debug why download fails --- .github/workflows/checkIDECompatibility.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkIDECompatibility.yml b/.github/workflows/checkIDECompatibility.yml index 6fd43a8..ab33eaf 100644 --- a/.github/workflows/checkIDECompatibility.yml +++ b/.github/workflows/checkIDECompatibility.yml @@ -13,7 +13,7 @@ jobs: matrix: java: [17] distribution: [temurin] - platformType: [IU, IC] + platformType: [IC] platformVersion: [LATEST-EAP-SNAPSHOT] steps: @@ -27,4 +27,4 @@ jobs: cache: 'gradle' - name: Build - run: ./gradlew runPluginVerifier -PplatformVersion=LATEST-EAP-SNAPSHOT + run: ./gradlew runPluginVerifier -PplatformVersion=LATEST-EAP-SNAPSHOT --debug From 92881e5de77f35bb80625c161181590431d196fa Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:15:57 +0100 Subject: [PATCH 426/518] Add automatic test for various IDE versions (#66) --- .github/workflows/checkIDECompatibility.yml | 30 ++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checkIDECompatibility.yml b/.github/workflows/checkIDECompatibility.yml index ab33eaf..17683fe 100644 --- a/.github/workflows/checkIDECompatibility.yml +++ b/.github/workflows/checkIDECompatibility.yml @@ -17,6 +17,31 @@ jobs: platformVersion: [LATEST-EAP-SNAPSHOT] steps: + - name: Free up disk space + run: | + sudo df -h + sudo docker system prune -af || true + sudo rm -rf /usr/share/dotnet \ + /usr/local/.ghcup \ + /usr/local/swift \ + /usr/share/swift \ + /usr/lib/jvm \ + /usr/local/lib/android \ + /usr/lib/google-cloud-sdk \ + /usr/local/share/boost \ + /usr/local/share/powershell \ + /usr/local/share/chromium \ + /usr/local/lib/node_modules \ + /usr/lib/mono \ + /usr/lib/heroku \ + /usr/lib/firefox \ + /usr/share/miniconda \ + /opt/microsoft \ + /opt/chrome \ + /opt/pipx \ + "$AGENT_TOOLSDIRECTORY" || true + sudo df -h + - uses: actions/checkout@v4 - name: Set up JDK @@ -24,7 +49,6 @@ jobs: with: distribution: ${{ matrix.distribution }} java-version: ${{ matrix.java }} - cache: 'gradle' - - name: Build - run: ./gradlew runPluginVerifier -PplatformVersion=LATEST-EAP-SNAPSHOT --debug + - name: Check compatibility + run: ./gradlew runPluginVerifier -PplatformVersion=LATEST-EAP-SNAPSHOT --info From e59239be9561ed5a8e3b358f2a28346b6ffa8cb8 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 17:18:06 +0100 Subject: [PATCH 427/518] Sync with https://github.com/xdev-software/standard-maven-template --- .github/workflows/checkBuild.yml | 6 ++++++ .github/workflows/sonar.yml | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index bc8856c..cb7e525 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -6,10 +6,16 @@ on: branches: [ develop ] paths-ignore: - '**.md' + - '.config/**' + - '.idea/**' + - 'assets/**' pull_request: branches: [ develop ] paths-ignore: - '**.md' + - '.config/**' + - '.idea/**' + - 'assets/**' jobs: build: diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index f35d80a..563faa0 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -6,14 +6,16 @@ on: branches: [ develop ] paths-ignore: - '**.md' + - '.config/**' + - '.idea/**' - 'assets/**' - - 'config/**' pull_request: types: [opened, synchronize, reopened] paths-ignore: - '**.md' + - '.config/**' + - '.idea/**' - 'assets/**' - - 'config/**' env: SONARCLOUD_ORG: ${{ github.event.organization.login }} From 45612b953449798e2794ace4f8b47da88c2c3ca3 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 17:31:21 +0100 Subject: [PATCH 428/518] Handle sonar problems --- .../service/SaveActionsServiceManager.java | 37 ++++++++----------- .../xdev/saveactions/model/Action.java | 5 +-- .../xdev/saveactions/model/java/EpfKey.java | 1 + .../processors/BuildProcessor.java | 1 + .../processors/GlobalProcessor.java | 1 + .../processors/java/JavaProcessor.java | 1 + 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java index 3ef1e05..f1c2f04 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsServiceManager.java @@ -15,37 +15,32 @@ */ public final class SaveActionsServiceManager { - private SaveActionsServiceManager() - { - } + static SaveActionsService instance; public static SaveActionsService getService() { - return ServiceHandler.INSTANCE.getService(); + if(instance == null) + { + initService(); + } + return instance; } - private enum ServiceHandler + private static synchronized void initService() { - INSTANCE; - - private static SaveActionsService service; - - public SaveActionsService getService() + if(instance != null) { - if(service == null) - { - this.newService(); - } - return service; + return; } - private void newService() + instance = ApplicationManager.getApplication().getService(SaveActionsJavaService.class); + if(instance == null) { - service = ApplicationManager.getApplication().getService(SaveActionsJavaService.class); - if(service == null) - { - service = ApplicationManager.getApplication().getService(SaveActionsDefaultService.class); - } + instance = ApplicationManager.getApplication().getService(SaveActionsDefaultService.class); } } + + private SaveActionsServiceManager() + { + } } diff --git a/src/main/java/software/xdev/saveactions/model/Action.java b/src/main/java/software/xdev/saveactions/model/Action.java index 11bcddc..f2fde51 100644 --- a/src/main/java/software/xdev/saveactions/model/Action.java +++ b/src/main/java/software/xdev/saveactions/model/Action.java @@ -11,10 +11,10 @@ import java.util.stream.Stream; +@SuppressWarnings("java:S115") public enum Action { // Activation - activate("Activate save actions on save (before saving each file, performs the configured actions below)", activation, true), @@ -28,7 +28,6 @@ public enum Action activation, false), // Global - organizeImports("Optimize imports", global, true), @@ -43,7 +42,6 @@ public enum Action global, false), // Build - compile("[experimental] Compile files (using \"Build > Build Project\")", build, false), @@ -55,7 +53,6 @@ public enum Action build, false), // Java fixes - fieldCanBeFinal("Add final modifier to field", java, false), diff --git a/src/main/java/software/xdev/saveactions/model/java/EpfKey.java b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java index 0ba41f6..a58d6c7 100644 --- a/src/main/java/software/xdev/saveactions/model/java/EpfKey.java +++ b/src/main/java/software/xdev/saveactions/model/java/EpfKey.java @@ -6,6 +6,7 @@ import java.util.stream.Stream; +@SuppressWarnings("java:S115") public enum EpfKey { add_default_serial_version_id, diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index 289bcc7..361713c 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -34,6 +34,7 @@ /** * Available processors for build. */ +@SuppressWarnings("java:S115") public enum BuildProcessor implements Processor { compile( diff --git a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java index ee81103..c161f7a 100644 --- a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java @@ -23,6 +23,7 @@ /** * Available processors for global. */ +@SuppressWarnings("java:S115") public enum GlobalProcessor implements Processor { organizeImports(Action.organizeImports, GlobalProcessor::optimizeImports), diff --git a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java index a523d64..403b2f6 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/java/JavaProcessor.java @@ -39,6 +39,7 @@ /** * Available processors for java. */ +@SuppressWarnings("java:S115") public enum JavaProcessor implements Processor { fieldCanBeFinal( From 39cd9eb88850a8918155b81383902ef8348ae87d Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 12 Feb 2024 16:43:17 +0000 Subject: [PATCH 429/518] Release 1.1.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e5a3e90..cf3a6fb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.1.0-SNAPSHOT +pluginVersion=1.1.0 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From 8ed3062ac90b870bc1123ca5b9b426fa4bb9c137 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 12 Feb 2024 16:45:56 +0000 Subject: [PATCH 430/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index cf3a6fb..4da49cc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions - XDEV Edition # SemVer format -> https://semver.org -pluginVersion=1.1.0 +pluginVersion=1.1.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1 From 3b1dff9c1f8e42b00bfc208394fdfdd572ba6630 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:51:16 +0100 Subject: [PATCH 431/518] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 11d7b88..2890659 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ # Save Actions Plugin icon light Save Actions Plugin - XDEV Edition -> **ℹ️About** -> +> [!NOTE] > This plugin is a fork of [dubreuia/intellij-plugin-save-actions](https://github.com/dubreuia/intellij-plugin-save-actions) and [fishermans/intellij-plugin-save-actions](https://github.com/fishermans/intellij-plugin-save-actions) and is kept in maintenance mode: > * Keep the plugin up-to-date with the latest IDEA versions > * Distribute the plugin on the IDEA marketplace @@ -63,8 +62,9 @@ Works in JetBrains IDE with Java support, like Intellij IDEA and AndroidStudio. ## Installation [Installation guide for the latest release](https://github.com/xdev-software/intellij-plugin-save-actions/releases/latest#Installation) -[Development versions](https://plugins.jetbrains.com/docs/intellij/publishing-plugin.html#specifying-a-release-channel) can be installed by [adding the ``snapshot`` release channel as a plugin repository](https://www.jetbrains.com/help/idea/managing-plugins.html#repos):
    -``https://plugins.jetbrains.com/plugins/snapshot/list`` +> [!TIP] +> [Development versions](https://plugins.jetbrains.com/plugin/22113-save-actions--xdev-edition/versions/snapshot) can be installed by [adding the ``snapshot`` release channel as a plugin repository](https://www.jetbrains.com/help/idea/managing-plugins.html#repos):
    +> ``https://plugins.jetbrains.com/plugins/snapshot/list`` ## Usage From 7e5ea8c5cf23ce2a4c5103a1dbf7d1f63f263b28 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Feb 2024 17:54:30 +0100 Subject: [PATCH 432/518] Trim readme --- README.md | 147 +----------------------------------------------------- USAGE.md | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 146 deletions(-) create mode 100644 USAGE.md diff --git a/README.md b/README.md index 2890659..a3cfe96 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,6 @@ Using the save actions plugin makes your code cleaner and more uniform across yo The code style applied by the save actions plugin is the one configured your settings at "File > Settings > Editor > Code Style". For some languages, custom formatter (Dartfmt, Prettier, etc.) may also be triggered by the save actions plugin. See the [Editor Actions](#editor-actions) configuration for more information. -## Content - -- [Features](#features) -- [Installation](#installation) -- [Usage](#usage) -- [Configuration](#configuration) -- [Compatibility](#compatibility) -- [Files location](#files-location) -- [Contributing](#contributing) - ## Features ### All JetBrains products @@ -68,142 +58,7 @@ Works in JetBrains IDE with Java support, like Intellij IDEA and AndroidStudio. ## Usage -The plugin can trigger automatically or manually on IDE actions (standard actions) or plugin actions. Most actions needs to be enabled individually (see [activation](#activation)). - -### IDE actions - -The plugin will trigger automatically on any of these IDE actions (needs to be activated with "Activate save actions on file save" in [activation](#activation)): - -- **Frame deactivation**, which is when the editor loses focus, configured in "File > Settings > Appearance & Behavior > System Settings > Save files on frame deactivation" . -- **Application idle**, which is when the IDE isn't used for a period of time, configured in "File > Settings > Appearance & Behavior > System Settings > Save files automatically if application is idle for x sec". -- **Save All**, which is bound by default to "CTRL + S". Some IDE might use "CTRL + S" for the single **Save Document** action, on which the plugin will NOT trigger. This is by design, see issue [#222](https://github.com/dubreuia/intellij-plugin-save-actions/issues/222). - -### Plugin actions - -The plugin actions are grouped under the menu "Code > Save Actions". You can associate a keymap to any action in "Settings > Keymap > Search 'save actions'". - -- **Enable Save Actions (default: not binded)** will activate or deactivate the plugin by changing the configuration. -- **Execute Save Actions on shortcut (default: "CTRL + SHIFT + S")** will trigger the plugin manually (needs to be activated with "Activate save actions on shortcut" in [activation](#activation)). -- **Execute Save Actions on multiple files (default: not binded)** will show a popup to select the files (or a scope) on which to trigger the plugin (needs to be activated with "Activate save actions on batch" in [activation](#activation)). - -

    - Save Actions Plugin Action menu -

    - -## Configuration - -The configurations are located in "File > Settings > Other Settings > Save Actions". - -### Activation - -You can quickly toggle the plugin activation by using the "Enable Save Action" action. Use "CTRL + SHIFT + A" then search for it. It will also show if it is currently activated or not. - -| Name | Description -| --- | --- -| Activate save actions on file save | Enable / disable the plugin on file save. Before saving each file, it will perform the configured actions below -| Activate save actions on shortcut | Enable / disable the plugin on shortcut, by default "CTRL + SHIFT + S" (configured in "File > Keymaps > Main menu > Code > Save Actions") -| Activate save actions on batch | Enable / disable the plugin on batch, by using "Code > Save Actions > Execute on multiple files" -| No action if compile errors | Enable / disable no action if there are compile errors. Applied to each file individually - -### Global - -| Name | Description -| --- | --- -| Optimize imports | Enable / disable import organization (configured in "File > Settings > Code Style > Java > Imports") -| Reformat file | Enable / disable formatting (configured in "File > Settings > Code Style"). See "Reformat only changed code" for more options -| Reformat only changed lines | Enable / disable formatting for only changed lines, which will work only if a VCS is configured -| Rearrange fields and methods | Enable / disable re-ordering of fields and methods (configured in "File > Settings > Code Style > Java > Arrangement") - -### Build - -| Name | Description -| --- | --- -| *\[experimental\]* Compile file | Enable / disable compiling of the modified file. The compiler might compile other files as well. **Warning: this feature is experimental, please post feedback in the github issues** -| *\[experimental\]* Reload file | Enable / disable reloading of the files in the running debugger, meaning the files will get compiled first. The compiler might compile other files as well. **Warning: this feature is experimental, please post feedback in the github issues** -| *\[experimental\]* Execute action | Enable / disable executing of an action using quick lists (using quick lists at "File > Settings > Appearance & Behavior > Quick Lists"). See [Editor Actions](#editor-actions) for more information **Warning: this feature is experimental, please post feedback in the github issues** - -#### Editor Actions - -Some languages requires specific actions, such as Dartfmt or Prettier: - -- For Dart developers, enable "Use the dartfmt tool when formatting the whole file" option in "File > Settings > Editor > Code Style > Dart > Dartfmt". -- For [Prettier](https://prettier.io/) users, read below. - -Using the "Execute action" configuration, the plugin can launch arbitrary editor actions. While not all actions will work, it can be used to launch external tools, specific runs, etc. This feature is experimental, you can post your feedback on issue [#118](https://github.com/dubreuia/intellij-plugin-save-actions/issues/118). - -The actions are implemented in the form of "quick lists", an IDE function that is used to define a list of actions that can be then executed. Quick lists can be configured at "File > Settings > Appearance & Behavior > Quick Lists", and once configured, one can be selected and used in the plugin, using the "Execution action" configuration drop down list. - -### File - -| Name | Description -| --- | --- -| File path inclusions | Add / remove file path inclusions (by default, everything included). The Java regular expressions match the whole file name from the project root. Include only Java files: `.*\.java`. -| File path exclusions | Add / remove file path exclusions to ignore files (overrides inclusions). The Java regular expressions match the whole file name from the project root. Exclude 'Main.java' only in root folder: `Main\.java`. Exclude file 'Foo.java' only in folder 'src': `src/Foo\.java`. Exclude all xml files in any folder: `.*/.*\.xml` -| Use external Eclipse configuration | Add external configuration file ".epf" to read settings from. This will update the current settings and use only the ".epf" file content. Use "reset" button to remove - -### Java fixes - -If a quick fix adds something that is removed by another quick fix, the removal wins. - -| Name | Description -| --- | --- -| Add final modifier to field | The field `private int field = 0` becomes `private final int field = 0` -| Add final modifier to local variable or parameter | The local variable `int variable = 0` becomes `final int variable = 0` -| Add final modifier to local variable or parameter except if implicit | The local variable `int variable = 0` becomes `final int variable = 0`, but not if it is implicit like in try with resources `try (Resource r = new Resource())` -| Add static modifier to methods | The method `private void method()` becomes `private static void method()` if the content does not references instance fields -| Add this to field access | The access to instance field `field = 0` becomes `this.field = 0` -| Add this to method access | The access to instance method `method()` becomes `this.method()` -| Add class qualifier to static member access | The access to class field `FIELD = 0` becomes `Class.FIELD` for a class named Class. Exclusive with "Add class qualifier to static member access outside declaring class only". -| Add class qualifier to static member access outside declaring class only | The access to class field `FIELD = 0` becomes `Class.FIELD` for a class named class, but only if the static member is outside declaring class. Exclusive with "Add class qualifier to static member access". -| Add missing @Override annotations | The method `void method()` becomes `@Override void method()` if it overrides a method from the parent class -| Add blocks to if/while/for statements | The statement `if (true) return false` becomes `if (true) { return false; }` (a block), also working for `for` and `while` statements -| Add missing serialVersionUID field for Serializable classes | The class `class Class implements Serializable` will get a new field `private static final long serialVersionUID` with generated serial version uid -| Remove unnecessary this to field and method | The access to instance field `this.field = 0` becomes `field = 0`, also working for methods -| Remove final from private method | The method `private final void method()` becomes `private void method()` -| Remove unnecessary final to local variable or parameter | The local variable `int final variable = 0` becomes `int variable = 0` -| Remove explicit generic type for diamond | The list creation `List list = new ArrayList()` becomes `List list = new ArrayList<>()` -| Remove unnecessary semicolon | The statement `int variable = 0;;` becomes `int variable = 0;` -| Remove blocks from if/while/for statements | The statement `if (true) { return false; }` becomes `if (true) return false;`, also working for `for` and `while` statements -| Change visibility of field or method to lower access | The field `public int field = 0` becomes `private int field = 0` if it is not used outside class, also working for methods - -## Compatibility - -The plugin will be kept compatible with the latest IDEA version. - -Support for other JetBrains products should also be automatically available but is not guaranteed. - -### Eclipse configuration support - -The save-actions plugin supports Eclipse configuration `.epf` files by the [Workspace Mechanic](https://marketplace.eclipse.org/content/workspace-mechanic) Eclipse plugin (Java IDE only). You can specify a path to an Eclipse configuration file in the "Eclipse support" settings section to import it. The plugin will load the content of the file in the plugin configuration, and disable the plugin configuration options (the checkbox will be grayed out). Use the "reset" button to remove the import. - -The plugin will stay in sync with your Eclipse configuration file. Not every features are present on either side, but the ones that are in common are supported. - -You can find an example of [an Eclipse configuration `.epf` file](src/test/resources/com/dubreuia/model) in the test resources. - -```properties -# @title Save Actions -# @description Save Actions -# @task_type LASTMOD -file_export_version=3.0 -/instance/org.eclipse.jdt.ui/editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code=true -/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code_changes_only=false -/instance/org.eclipse.jdt.ui/sp_cleanup.organize_imports=true -/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces=true -... -``` - -### Other plugin compatibility - -Some things to note when using other plugins with the Save Actions plugin: - -- [IdeaVim](https://plugins.jetbrains.com/plugin/164-ideavim): Since the Save Actions plugin do not trigger on the "Save Document" action (see [usage](#usage)), using `:w` to save in IdeaVim won't trigger the plugin, but using `:wa` will, since it calls the "Save All" action. See issue [#222](https://github.com/dubreuia/intellij-plugin-save-actions/issues/222)). -- [detekt](https://plugins.jetbrains.com/plugin/10761-detekt): Using the detekt plugin breaks the Save Actions plugin, see issue [#270](https://github.com/dubreuia/intellij-plugin-save-actions/issues/270). - -## Files location - -- **idea.log**: The log file the save actions plugin writes in. It contains debug information, prefixed with `software.xdev.saveactions.SaveActionManager`. If you are using default locations, it would be in `~/.IntelliJIdeaVERSION/system/log/idea.log`. -- **saveactions_settings.xml**: The settings file is saved by project in the `.idea` folder. That file can be committed in git thus shared in your development team. If you are using the default locations, it would be in `~/IdeaProjects/PROJECT_NAME/.idea/saveactions_settings.xml` +Read the [full usage guide here](./USAGE.md). ## Contributing See the [contributing guide](./CONTRIBUTING.md) for detailed instructions on how to get started with our project. diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..8f7c49e --- /dev/null +++ b/USAGE.md @@ -0,0 +1,138 @@ +## Usage + +The plugin can trigger automatically or manually on IDE actions (standard actions) or plugin actions. Most actions needs to be enabled individually (see [activation](#activation)). + +### IDE actions + +The plugin will trigger automatically on any of these IDE actions (needs to be activated with "Activate save actions on file save" in [activation](#activation)): + +- **Frame deactivation**, which is when the editor loses focus, configured in "File > Settings > Appearance & Behavior > System Settings > Save files on frame deactivation" . +- **Application idle**, which is when the IDE isn't used for a period of time, configured in "File > Settings > Appearance & Behavior > System Settings > Save files automatically if application is idle for x sec". +- **Save All**, which is bound by default to "CTRL + S". Some IDE might use "CTRL + S" for the single **Save Document** action, on which the plugin will NOT trigger. This is by design, see issue [#222](https://github.com/dubreuia/intellij-plugin-save-actions/issues/222). + +### Plugin actions + +The plugin actions are grouped under the menu "Code > Save Actions". You can associate a keymap to any action in "Settings > Keymap > Search 'save actions'". + +- **Enable Save Actions (default: not binded)** will activate or deactivate the plugin by changing the configuration. +- **Execute Save Actions on shortcut (default: "CTRL + SHIFT + S")** will trigger the plugin manually (needs to be activated with "Activate save actions on shortcut" in [activation](#activation)). +- **Execute Save Actions on multiple files (default: not binded)** will show a popup to select the files (or a scope) on which to trigger the plugin (needs to be activated with "Activate save actions on batch" in [activation](#activation)). + +

    + Save Actions Plugin Action menu +

    + +## Configuration + +The configurations are located in "File > Settings > Other Settings > Save Actions". + +### Activation + +You can quickly toggle the plugin activation by using the "Enable Save Action" action. Use "CTRL + SHIFT + A" then search for it. It will also show if it is currently activated or not. + +| Name | Description +| --- | --- +| Activate save actions on file save | Enable / disable the plugin on file save. Before saving each file, it will perform the configured actions below +| Activate save actions on shortcut | Enable / disable the plugin on shortcut, by default "CTRL + SHIFT + S" (configured in "File > Keymaps > Main menu > Code > Save Actions") +| Activate save actions on batch | Enable / disable the plugin on batch, by using "Code > Save Actions > Execute on multiple files" +| No action if compile errors | Enable / disable no action if there are compile errors. Applied to each file individually + +### Global + +| Name | Description +| --- | --- +| Optimize imports | Enable / disable import organization (configured in "File > Settings > Code Style > Java > Imports") +| Reformat file | Enable / disable formatting (configured in "File > Settings > Code Style"). See "Reformat only changed code" for more options +| Reformat only changed lines | Enable / disable formatting for only changed lines, which will work only if a VCS is configured +| Rearrange fields and methods | Enable / disable re-ordering of fields and methods (configured in "File > Settings > Code Style > Java > Arrangement") + +### Build + +| Name | Description +| --- | --- +| *\[experimental\]* Compile file | Enable / disable compiling of the modified file. The compiler might compile other files as well. **Warning: this feature is experimental, please post feedback in the github issues** +| *\[experimental\]* Reload file | Enable / disable reloading of the files in the running debugger, meaning the files will get compiled first. The compiler might compile other files as well. **Warning: this feature is experimental, please post feedback in the github issues** +| *\[experimental\]* Execute action | Enable / disable executing of an action using quick lists (using quick lists at "File > Settings > Appearance & Behavior > Quick Lists"). See [Editor Actions](#editor-actions) for more information **Warning: this feature is experimental, please post feedback in the github issues** + +#### Editor Actions + +Some languages requires specific actions, such as Dartfmt or Prettier: + +- For Dart developers, enable "Use the dartfmt tool when formatting the whole file" option in "File > Settings > Editor > Code Style > Dart > Dartfmt". +- For [Prettier](https://prettier.io/) users, read below. + +Using the "Execute action" configuration, the plugin can launch arbitrary editor actions. While not all actions will work, it can be used to launch external tools, specific runs, etc. This feature is experimental, you can post your feedback on issue [#118](https://github.com/dubreuia/intellij-plugin-save-actions/issues/118). + +The actions are implemented in the form of "quick lists", an IDE function that is used to define a list of actions that can be then executed. Quick lists can be configured at "File > Settings > Appearance & Behavior > Quick Lists", and once configured, one can be selected and used in the plugin, using the "Execution action" configuration drop down list. + +### File + +| Name | Description +| --- | --- +| File path inclusions | Add / remove file path inclusions (by default, everything included). The Java regular expressions match the whole file name from the project root. Include only Java files: `.*\.java`. +| File path exclusions | Add / remove file path exclusions to ignore files (overrides inclusions). The Java regular expressions match the whole file name from the project root. Exclude 'Main.java' only in root folder: `Main\.java`. Exclude file 'Foo.java' only in folder 'src': `src/Foo\.java`. Exclude all xml files in any folder: `.*/.*\.xml` +| Use external Eclipse configuration | Add external configuration file ".epf" to read settings from. This will update the current settings and use only the ".epf" file content. Use "reset" button to remove + +### Java fixes + +If a quick fix adds something that is removed by another quick fix, the removal wins. + +| Name | Description +| --- | --- +| Add final modifier to field | The field `private int field = 0` becomes `private final int field = 0` +| Add final modifier to local variable or parameter | The local variable `int variable = 0` becomes `final int variable = 0` +| Add final modifier to local variable or parameter except if implicit | The local variable `int variable = 0` becomes `final int variable = 0`, but not if it is implicit like in try with resources `try (Resource r = new Resource())` +| Add static modifier to methods | The method `private void method()` becomes `private static void method()` if the content does not references instance fields +| Add this to field access | The access to instance field `field = 0` becomes `this.field = 0` +| Add this to method access | The access to instance method `method()` becomes `this.method()` +| Add class qualifier to static member access | The access to class field `FIELD = 0` becomes `Class.FIELD` for a class named Class. Exclusive with "Add class qualifier to static member access outside declaring class only". +| Add class qualifier to static member access outside declaring class only | The access to class field `FIELD = 0` becomes `Class.FIELD` for a class named class, but only if the static member is outside declaring class. Exclusive with "Add class qualifier to static member access". +| Add missing @Override annotations | The method `void method()` becomes `@Override void method()` if it overrides a method from the parent class +| Add blocks to if/while/for statements | The statement `if (true) return false` becomes `if (true) { return false; }` (a block), also working for `for` and `while` statements +| Add missing serialVersionUID field for Serializable classes | The class `class Class implements Serializable` will get a new field `private static final long serialVersionUID` with generated serial version uid +| Remove unnecessary this to field and method | The access to instance field `this.field = 0` becomes `field = 0`, also working for methods +| Remove final from private method | The method `private final void method()` becomes `private void method()` +| Remove unnecessary final to local variable or parameter | The local variable `int final variable = 0` becomes `int variable = 0` +| Remove explicit generic type for diamond | The list creation `List list = new ArrayList()` becomes `List list = new ArrayList<>()` +| Remove unnecessary semicolon | The statement `int variable = 0;;` becomes `int variable = 0;` +| Remove blocks from if/while/for statements | The statement `if (true) { return false; }` becomes `if (true) return false;`, also working for `for` and `while` statements +| Change visibility of field or method to lower access | The field `public int field = 0` becomes `private int field = 0` if it is not used outside class, also working for methods + +## Compatibility + +The plugin will be kept compatible with the latest IDEA version. + +Support for other JetBrains products should also be automatically available but is not guaranteed. + +### Eclipse configuration support + +The save-actions plugin supports Eclipse configuration `.epf` files by the [Workspace Mechanic](https://marketplace.eclipse.org/content/workspace-mechanic) Eclipse plugin (Java IDE only). You can specify a path to an Eclipse configuration file in the "Eclipse support" settings section to import it. The plugin will load the content of the file in the plugin configuration, and disable the plugin configuration options (the checkbox will be grayed out). Use the "reset" button to remove the import. + +The plugin will stay in sync with your Eclipse configuration file. Not every features are present on either side, but the ones that are in common are supported. + +You can find an example of [an Eclipse configuration `.epf` file](src/test/resources/com/dubreuia/model) in the test resources. + +```properties +# @title Save Actions +# @description Save Actions +# @task_type LASTMOD +file_export_version=3.0 +/instance/org.eclipse.jdt.ui/editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code=true +/instance/org.eclipse.jdt.ui/sp_cleanup.format_source_code_changes_only=false +/instance/org.eclipse.jdt.ui/sp_cleanup.organize_imports=true +/instance/org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces=true +... +``` + +### Other plugin compatibility + +Some things to note when using other plugins with the Save Actions plugin: + +- [IdeaVim](https://plugins.jetbrains.com/plugin/164-ideavim): Since the Save Actions plugin do not trigger on the "Save Document" action (see [usage](#usage)), using `:w` to save in IdeaVim won't trigger the plugin, but using `:wa` will, since it calls the "Save All" action. See issue [#222](https://github.com/dubreuia/intellij-plugin-save-actions/issues/222)). +- [detekt](https://plugins.jetbrains.com/plugin/10761-detekt): Using the detekt plugin breaks the Save Actions plugin, see issue [#270](https://github.com/dubreuia/intellij-plugin-save-actions/issues/270). + +## Files location + +- **idea.log**: The log file the save actions plugin writes in. It contains debug information, prefixed with `software.xdev.saveactions.SaveActionManager`. If you are using default locations, it would be in `~/.IntelliJIdeaVERSION/system/log/idea.log`. +- **saveactions_settings.xml**: The settings file is saved by project in the `.idea` folder. That file can be committed in git thus shared in your development team. If you are using the default locations, it would be in `~/IdeaProjects/PROJECT_NAME/.idea/saveactions_settings.xml` From 0d3574e9df031c854626c84f49b6630203c05da0 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Tue, 13 Feb 2024 08:21:30 +0100 Subject: [PATCH 433/518] Spelling --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f54e897..8f15a7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## 1.1.0 * Removed "Remove unused suppress warning annotation" * This option never worked #64 - * Allows usage of the plugin with IntelliJ Idea 2024+ #63 + * Allows usage of the plugin with IntelliJ IDEA 2024+ #63 * If you used this option you should remove the line ``
    - + com.intellij.modules.java From 4061662098918dd1f2865bdcbc034efe5f19180c Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 8 Apr 2024 08:51:36 +0200 Subject: [PATCH 453/518] Run GlobalProcessors (e.g. Reformat) last so that code is formatted correctly Fixes #90 --- .../software/xdev/saveactions/processors/GlobalProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java index c161f7a..9560df0 100644 --- a/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/GlobalProcessor.java @@ -87,7 +87,7 @@ public Set getModes() @Override public int getOrder() { - return 0; + return 3; } @Override From d8173748ef68dde071f607e068fa87d5576bbc22 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 8 Apr 2024 08:51:43 +0200 Subject: [PATCH 454/518] Bump version --- CHANGELOG.md | 3 ++- gradle.properties | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 838fb45..7c15423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ -## 1.1.2 +## 1.2.0 +* Run GlobalProcessors (e.g. Reformat) last so that code is formatted correctly #90 * Dropped support for IntelliJ versions < 2023 ## 1.1.1 diff --git a/gradle.properties b/gradle.properties index 5261378..9aefd63 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.1.2-SNAPSHOT +pluginVersion=1.2.0-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1.6 From e18aa87c1e93402699e2151e098cc153ef41aef3 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 8 Apr 2024 06:56:25 +0000 Subject: [PATCH 455/518] Release 1.2.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9aefd63..29448f3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.0-SNAPSHOT +pluginVersion=1.2.0 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1.6 From 68bba69b4a324b2750daffce079eb997742b7ccb Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 8 Apr 2024 06:57:46 +0000 Subject: [PATCH 456/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 29448f3..32fc602 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.0 +pluginVersion=1.2.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.1.6 From 471997a626b54d3fdb7a22c251bf437c986baeee Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 18 Apr 2024 10:11:03 +0200 Subject: [PATCH 457/518] Use correct ``ActionUpdateThread`` for ``ToggleAnAction`` Fixes #95 --- CHANGELOG.md | 3 +++ .../xdev/saveactions/core/action/ToggleAnAction.java | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c15423..04d3703 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.1 +* Fixed ``ToggleAnAction must override getActionUpdateThread`` warning inside IntelliJ 2024+ + ## 1.2.0 * Run GlobalProcessors (e.g. Reformat) last so that code is formatted correctly #90 * Dropped support for IntelliJ versions < 2023 diff --git a/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java index c14f107..5da4446 100644 --- a/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java +++ b/src/main/java/software/xdev/saveactions/core/action/ToggleAnAction.java @@ -2,6 +2,9 @@ import static software.xdev.saveactions.model.Action.activate; +import org.jetbrains.annotations.NotNull; + +import com.intellij.openapi.actionSystem.ActionUpdateThread; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.project.DumbAware; @@ -37,4 +40,10 @@ public void setSelected(final AnActionEvent event, final boolean state) storage.setEnabled(activate, state); } } + + @Override + public @NotNull ActionUpdateThread getActionUpdateThread() + { + return ActionUpdateThread.BGT; + } } From b1d99290f946cdc134dc26f3dbb6695c3b7cb4bb Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 18 Apr 2024 10:11:18 +0200 Subject: [PATCH 458/518] Drop support for < 232 --- CHANGELOG.md | 1 + src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04d3703..24b985a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 1.2.1 * Fixed ``ToggleAnAction must override getActionUpdateThread`` warning inside IntelliJ 2024+ +* Dropped support for IntelliJ versions < 2023.2 ## 1.2.0 * Run GlobalProcessors (e.g. Reformat) last so that code is formatted correctly #90 diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index daa3304..a37424b 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,7 +19,7 @@ - + com.intellij.modules.java From 72e1c3fb222953ceb57108a6bb94b581b724709e Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 18 Apr 2024 08:17:00 +0000 Subject: [PATCH 459/518] Release 1.2.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ee7e0fa..c049567 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.1-SNAPSHOT +pluginVersion=1.2.1 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2.6 From 73ac2e0639584c22e8209c9e960186072ed5d43f Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 18 Apr 2024 08:19:19 +0000 Subject: [PATCH 460/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index c049567..a4f9f87 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.1 +pluginVersion=1.2.2-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2.6 From 49e60bef2c51a53210ecf03b29c7f504d4099862 Mon Sep 17 00:00:00 2001 From: AB Date: Tue, 23 Apr 2024 10:38:42 +0200 Subject: [PATCH 461/518] Rename I --- .github/workflows/checkBuild.yml | 2 +- CONTRIBUTING.md | 6 +++--- README.md | 8 ++++---- SECURITY.md | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/checkBuild.yml b/.github/workflows/checkBuild.yml index 9a0b81a..1b229cc 100644 --- a/.github/workflows/checkBuild.yml +++ b/.github/workflows/checkBuild.yml @@ -70,7 +70,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: plugin-files-java-${{ matrix.java }} - path: build/libs/template-placeholder-*.jar + path: build/libs/intellij-plugin-save-actions-*.jar if-no-files-found: error code-style: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe5e226..95d4eb7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,17 +46,17 @@ Start idea and import the `build.gradle` file with "File > Open". Then in the "I ./gradlew cleanIdea idea ``` -IntelliJ should refresh and the project is now configured as a gradle project. You can find IntelliJ gradle tasks in "Gradle > Gradle projects > template-placeholder > Tasks > intellij". To run the plugin, use the `runIde` task: +IntelliJ should refresh and the project is now configured as a gradle project. You can find IntelliJ gradle tasks in "Gradle > Gradle projects > intellij-plugin-save-actions > Tasks > intellij". To run the plugin, use the `runIde` task: ```bash # Run the plugin (starts new idea) ./gradlew runIde ``` -## Releasing [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/template-placeholder/release.yml?branch=master)](https://github.com/xdev-software/template-placeholder/actions/workflows/release.yml) +## Releasing [![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/release.yml?branch=master)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/release.yml) Before releasing: -* Consider doing a [test-deployment](https://github.com/xdev-software/template-placeholder/actions/workflows/test-deploy.yml?query=branch%3Adevelop) before actually releasing. +* Consider doing a [test-deployment](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/test-deploy.yml?query=branch%3Adevelop) before actually releasing. * Check the [changelog](CHANGELOG.md) If the ``develop`` is ready for release, create a pull request to the ``master``-Branch and merge the changes diff --git a/README.md b/README.md index 12482f8..68d893a 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ [![Latest version](https://img.shields.io/jetbrains/plugin/v/pluginId?logo=jetbrains)](https://plugins.jetbrains.com/plugin/pluginId) -[![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/template-placeholder/checkBuild.yml?branch=develop)](https://github.com/xdev-software/template-placeholder/actions/workflows/checkBuild.yml?query=branch%3Adevelop) -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_template-placeholder&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_template-placeholder) +[![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/intellij-plugin-save-actions/checkBuild.yml?branch=develop)](https://github.com/xdev-software/intellij-plugin-save-actions/actions/workflows/checkBuild.yml?query=branch%3Adevelop) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_intellij-plugin-save-actions&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_intellij-plugin-save-actions) [![Feel free to leave a rating](https://img.shields.io/jetbrains/plugin/r/rating/pluginId?style=social&logo=jetbrains&label=Feel%20free%20to%20leave%20a%20rating)](https://plugins.jetbrains.com/plugin/pluginId/reviews) -# Plugin icon template-placeholder +# Plugin icon intellij-plugin-save-actions ## Installation -[Installation guide for the latest release](https://github.com/xdev-software/template-placeholder/releases/latest#Installation) +[Installation guide for the latest release](https://github.com/xdev-software/intellij-plugin-save-actions/releases/latest#Installation) > [!TIP] > [Development versions](https://plugins.jetbrains.com/plugin/pluginId/versions/snapshot) can be installed by [adding the ``snapshot`` release channel as a plugin repository](https://www.jetbrains.com/help/idea/managing-plugins.html#repos):
    diff --git a/SECURITY.md b/SECURITY.md index 34b9514..970016c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,4 +2,4 @@ ## Reporting a Vulnerability -Please report a security vulnerability [on GitHub Security Advisories](https://github.com/xdev-software/template-placeholder/security/advisories/new). +Please report a security vulnerability [on GitHub Security Advisories](https://github.com/xdev-software/intellij-plugin-save-actions/security/advisories/new). From 5d556a441073736504b2ee748d04b1a3560827ef Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 13 May 2024 14:53:07 +0200 Subject: [PATCH 462/518] Fill in template --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 ++-- .github/ISSUE_TEMPLATE/enhancement.yml | 2 +- .github/ISSUE_TEMPLATE/question.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 68299d5..f1ef194 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -14,9 +14,9 @@ body: attributes: label: "Checklist" options: - - label: "I am able to reproduce the bug with the [latest version](https://github.com/xdev-software/template-placeholder/releases/latest)" + - label: "I am able to reproduce the bug with the [latest version](https://github.com/xdev-software/intellij-plugin-save-actions/releases/latest)" required: true - - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/template-placeholder/issues) or [closed](https://github.com/xdev-software/template-placeholder/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." + - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/intellij-plugin-save-actions/issues) or [closed](https://github.com/xdev-software/intellij-plugin-save-actions/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." required: true - label: "I have taken the time to fill in all the required details. I understand that the bug report will be dismissed otherwise." required: true diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 7523129..d2a5f93 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -12,7 +12,7 @@ body: attributes: label: "Checklist" options: - - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/template-placeholder/issues) or [closed](https://github.com/xdev-software/template-placeholder/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." + - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/intellij-plugin-save-actions/issues) or [closed](https://github.com/xdev-software/intellij-plugin-save-actions/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." required: true - label: "I have taken the time to fill in all the required details. I understand that the feature request will be dismissed otherwise." required: true diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index 6ecd6ad..173a4a4 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -12,7 +12,7 @@ body: attributes: label: "Checklist" options: - - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/template-placeholder/issues) or [closed](https://github.com/xdev-software/template-placeholder/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." + - label: "I made sure that there are *no existing issues* - [open](https://github.com/xdev-software/intellij-plugin-save-actions/issues) or [closed](https://github.com/xdev-software/intellij-plugin-save-actions/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to." required: true - label: "I have taken the time to fill in all the required details. I understand that the question will be dismissed otherwise." required: true From 4efe255c6caa97ffcee6bc97c900190a6d296b10 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 13 May 2024 14:59:44 +0200 Subject: [PATCH 463/518] Update USAGE.md Fix broken link #104 --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 65ac74d..b4f9dfd 100644 --- a/USAGE.md +++ b/USAGE.md @@ -106,7 +106,7 @@ The save-actions plugin supports Eclipse configuration `.epf` files by the [Work The plugin will stay in sync with your Eclipse configuration file. Not every features are present on either side, but the ones that are in common are supported. -You can find an example of [an Eclipse configuration `.epf` file](src/test/resources/com/dubreuia/model) in the test resources. +You can find an example of [an Eclipse configuration `.epf` file](src/test/resources/software/xdev/saveactions/model) in the test resources. ```properties # @title Save Actions From 56c2bedbfc27dcfe0fcbe1c8ed11b0e9b21ddf8a Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 29 May 2024 15:59:45 +0200 Subject: [PATCH 464/518] Do not format copy pasted class --- .idea/saveactions_settings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.idea/saveactions_settings.xml b/.idea/saveactions_settings.xml index 8743331..80d7226 100644 --- a/.idea/saveactions_settings.xml +++ b/.idea/saveactions_settings.xml @@ -19,8 +19,9 @@ - + \ No newline at end of file From 4dc1a046c86a56409dd3a66cb974d007d7dd14db Mon Sep 17 00:00:00 2001 From: AB Date: Tue, 4 Jun 2024 11:57:14 +0200 Subject: [PATCH 465/518] Fix scaling problem on "New UI" Works around https://github.com/xdev-software/intellij-plugin-template/issues/26 Underlying problem https://youtrack.jetbrains.com/issue/IDEA-354465 --- CHANGELOG.md | 3 +++ src/main/resources/META-INF/pluginIcon.svg | 2 +- src/main/resources/META-INF/pluginIcon_dark.svg | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24b985a..14dfd4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.2 +* Workaround scaling problem on "New UI" [#26](https://github.com/xdev-software/intellij-plugin-template/issues/26) + ## 1.2.1 * Fixed ``ToggleAnAction must override getActionUpdateThread`` warning inside IntelliJ 2024+ * Dropped support for IntelliJ versions < 2023.2 diff --git a/src/main/resources/META-INF/pluginIcon.svg b/src/main/resources/META-INF/pluginIcon.svg index e3981dc..0e07f15 100644 --- a/src/main/resources/META-INF/pluginIcon.svg +++ b/src/main/resources/META-INF/pluginIcon.svg @@ -1,4 +1,4 @@ - + diff --git a/src/main/resources/META-INF/pluginIcon_dark.svg b/src/main/resources/META-INF/pluginIcon_dark.svg index dbe597c..49a81b3 100644 --- a/src/main/resources/META-INF/pluginIcon_dark.svg +++ b/src/main/resources/META-INF/pluginIcon_dark.svg @@ -1,4 +1,4 @@ - + From 4b8e53c47b3abfe93ead5028c9bc5464c328e087 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 4 Jun 2024 10:02:17 +0000 Subject: [PATCH 466/518] Release 1.2.2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a4f9f87..9670ef3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.2-SNAPSHOT +pluginVersion=1.2.2 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2.6 From 29dd3e2958fdc6b0efb6f23151a1d67086214dac Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 4 Jun 2024 10:03:37 +0000 Subject: [PATCH 467/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9670ef3..5ab56e6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.2 +pluginVersion=1.2.3-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2.6 From de04036366cb3962c868cc82aefd9d574ce8ca46 Mon Sep 17 00:00:00 2001 From: AB Date: Wed, 19 Jun 2024 13:35:49 +0200 Subject: [PATCH 468/518] Fix pmd problems --- .../CustomAccessCanBeTightenedInspection.java | 2 +- .../CustomUnqualifiedStaticUsageInspection.java | 1 + .../software/xdev/saveactions/ui/BuildPanel.java | 2 +- .../software/xdev/saveactions/ui/FileMaskPanel.java | 2 +- .../xdev/saveactions/junit/JUnit5Utils.java | 13 ++++++------- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java index df01ad3..fd840d3 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java @@ -86,7 +86,7 @@ * * @see com.intellij.codeInspection.visibility.AccessCanBeTightenedInspection */ -@SuppressWarnings({"java:S6201", "java:S3776", "java:S125", "java:S3398", "java:S2637", "java:S120", "java:S6541", "java:S135"}) +@SuppressWarnings({"java:S6201", "java:S3776", "java:S125", "java:S3398", "java:S2637", "java:S120", "java:S6541", "java:S135", "PMD"}) public class CustomAccessCanBeTightenedInspection extends AbstractBaseJavaLocalInspectionTool { private static final Logger LOG = Logger.getInstance(CustomAccessCanBeTightenedInspection.class); private final VisibilityInspection myVisibilityInspection; diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java index 2954f56..a859bed 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/style/CustomUnqualifiedStaticUsageInspection.java @@ -85,6 +85,7 @@ public void visitReferenceExpression(@NotNull final PsiReferenceExpression expre this.registerError(expression, expression); } + @SuppressWarnings("PMD.NPathComplexity") private boolean isUnqualifiedStaticAccess(final PsiReferenceExpression expression) { if(CustomUnqualifiedStaticUsageInspection.this.m_ignoreStaticAccessFromStaticContext) diff --git a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java index 309d08f..1aab14e 100644 --- a/src/main/java/software/xdev/saveactions/ui/BuildPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/BuildPanel.java @@ -123,7 +123,7 @@ private boolean hasId(final String id) private String getId() { - return this.quickList.hashCode() + ""; + return String.valueOf(this.quickList.hashCode()); } @Override diff --git a/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java index fbf3374..22a6955 100644 --- a/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/FileMaskPanel.java @@ -116,7 +116,7 @@ private InputValidator getRegexInputValidator() @Override public boolean checkInput(final String string) { - if(string == null || string.trim().isEmpty()) + if(string == null || string.isBlank()) { // do not allow null or blank entries return false; diff --git a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java index 6082ffa..ab33e91 100644 --- a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java +++ b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java @@ -15,15 +15,14 @@ private JUnit5Utils() public static void rethrowAsJunit5Error(final AssertionError error) { - if(error.getCause() instanceof final InvocationTargetException intellijInternal) + if(error.getCause() instanceof final InvocationTargetException intellijInternal + && intellijInternal.getCause() instanceof final FileComparisonFailure fileComparisonFailure) { - if(intellijInternal.getCause() instanceof final FileComparisonFailure fileComparisonFailure) - { - final String expected = fileComparisonFailure.getExpected(); - final String actual = fileComparisonFailure.getActual(); - throw new AssertionFailedError("Expected file do not match actual file", expected, actual); - } + final String expected = fileComparisonFailure.getExpected(); + final String actual = fileComparisonFailure.getActual(); + throw new AssertionFailedError("Expected file do not match actual file", expected, actual); } + throw error; } From 45747e11c489a1bf1ebee3ab9e4eac8effaff229 Mon Sep 17 00:00:00 2001 From: XDEV Renovate Bot Date: Wed, 10 Jul 2024 02:23:41 +0000 Subject: [PATCH 469/518] Update dependency org.assertj:assertj-core to v3.26.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f7214b7..c939dc5 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ dependencies { testImplementation platform('org.junit:junit-bom:5.10.3'), 'org.junit.jupiter:junit-jupiter', 'org.junit.jupiter:junit-jupiter-engine', - 'org.assertj:assertj-core:3.26.0' + 'org.assertj:assertj-core:3.26.3' testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("Only needed to run tests in a version of IntelliJ IDEA that bundles older versions") } From 043b373b9a625fa9604674416a654695c3eda957 Mon Sep 17 00:00:00 2001 From: Alex B <45384811+AB-xdev@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:06:07 +0200 Subject: [PATCH 470/518] Update README.md Fix broken links --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3a800df..78636b8 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ Supports configurable, Eclipse like, save actions, including "optimize imports", "reformat code", "rearrange code", "compile file" and some quick fixes like "add / remove 'this' qualifier", etc. The plugin executes the configured actions when the file is synchronized (or saved) on disk. -Using the save actions plugin makes your code cleaner and more uniform across your code base by enforcing your code style and code rules every time you save. The settings file (see [files location](#files-location)) can be shared in your development team so that every developer has the same configuration. +Using the save actions plugin makes your code cleaner and more uniform across your code base by enforcing your code style and code rules every time you save. The settings file (see [files location](./USAGE.md#files-location)) can be shared in your development team so that every developer has the same configuration. -The code style applied by the save actions plugin is the one configured your settings at "File > Settings > Editor > Code Style". For some languages, custom formatter (Dartfmt, Prettier, etc.) may also be triggered by the save actions plugin. See the [Editor Actions](#editor-actions) configuration for more information. +The code style applied by the save actions plugin is the one configured your settings at "File > Settings > Editor > Code Style". For some languages, custom formatter (Dartfmt, Prettier, etc.) may also be triggered by the save actions plugin. See the [Editor Actions](./USAGE.md#editor-actions) configuration for more information. ## Features @@ -33,8 +33,8 @@ The code style applied by the save actions plugin is the one configured your set - Include / exclude files with regex support - Works on any file type (Java, Python, XML, etc.) - Launch any editor action using "quick lists" -- Uses a settings file per project you can commit (see [Files location](#files-location)) -- Available keymaps and actions for activation (see [Keymap and actions](#keymap-and-actions)) +- Uses a settings file per project you can commit (see [Files location](./USAGE.md#files-location)) +- Available keymaps and actions for activation (see [Keymap and actions](./USAGE.md#keymap-and-actions)) Save actions plugin settings page @@ -44,8 +44,8 @@ Works in JetBrains IDE with Java support, like Intellij IDEA and AndroidStudio. - Compile project after save (if compiling is available) - Reload debugger after save (if compiling is available) -- Eclipse configuration file `.epf` support (see [Eclipse support](#eclipse-support)) -- Automatically fix Java inspections (see [Java quick fixes](#java-fixes)) +- Eclipse configuration file `.epf` support (see [Eclipse support](./USAGE.md#eclipse-support)) +- Automatically fix Java inspections (see [Java quick fixes](./USAGE.md#java-fixes)) Save actions plugin settings page for Java From 5d4aadaed738a85e6ecb835b4c1a21744167af70 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 12 Aug 2024 16:56:25 +0200 Subject: [PATCH 471/518] Fix "run on multiple files" not working when the file is not a text file Fixes #129 --- CHANGELOG.md | 3 +++ .../xdev/saveactions/core/component/Engine.java | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14dfd4a..0d9d3ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.3 +* Fix "run on multiple files" not working when the file is not a text file #129 + ## 1.2.2 * Workaround scaling problem on "New UI" [#26](https://github.com/xdev-software/intellij-plugin-template/issues/26) diff --git a/src/main/java/software/xdev/saveactions/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java index 0dc9a12..b41930a 100644 --- a/src/main/java/software/xdev/saveactions/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -114,6 +114,7 @@ private boolean isPsiFileEligible(final Project project, final PsiFile psiFile) return psiFile != null && this.isProjectValid(project) && this.isPsiFileValid(psiFile) + && this.hasPsiFileText(psiFile) && this.isPsiFileFresh(psiFile) && this.isPsiFileInProject(project, psiFile) && this.isPsiFileNoError(project, psiFile) @@ -189,6 +190,16 @@ private boolean isPsiFileValid(final PsiFile psiFile) return valid; } + private boolean hasPsiFileText(final PsiFile psiFile) + { + final boolean valid = psiFile.getTextRange() != null; + if(!valid) + { + LOGGER.info(String.format("File %s has no text.", psiFile)); + } + return valid; + } + boolean isIncludedAndNotExcluded(final String path) { return this.isIncluded(path) && !this.isExcluded(path); From 16e1761134ba81121c6c5563659628b8895a0579 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 12 Aug 2024 15:07:26 +0000 Subject: [PATCH 472/518] Release 1.2.3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5ab56e6..90ef8d0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.3-SNAPSHOT +pluginVersion=1.2.3 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2.6 From c675fa90739a22b892e43d2dcbba3daa8d22cb47 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 12 Aug 2024 15:08:56 +0000 Subject: [PATCH 473/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 90ef8d0..f73f5c8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.3 +pluginVersion=1.2.4-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2023.2.6 From 96a43c1fbabfb5277d68f92549d7376c233cc5dd Mon Sep 17 00:00:00 2001 From: AB Date: Tue, 13 Aug 2024 11:20:22 +0200 Subject: [PATCH 474/518] Drop support for IntelliJ < 2024 --- CHANGELOG.md | 3 +++ src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d9d3ba..7909d00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.4 +* Dropped support for IntelliJ versions < 2024 + ## 1.2.3 * Fix "run on multiple files" not working when the file is not a text file #129 diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index a37424b..6cb28c5 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,7 +19,7 @@ - + com.intellij.modules.java From 0dee2f8cfeb0c54f3dca9e5e87168c0794a147fc Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 14:19:07 +0200 Subject: [PATCH 475/518] PluginId has been changed --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5465ad6..a62821b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ platformVersion=2024.2.2 platformSinceBuild=242 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformBundledPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 -platformBundledPlugins=java +platformBundledPlugins=com.intellij.java platformPlugins= # Gradle Releases -> https://github.com/gradle/gradle/releases gradleVersion=8.10.1 From a94f216d1e2aec46888ffcdd1fea23d478ec4776 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 14:22:58 +0200 Subject: [PATCH 476/518] Remove plugin.xml entries that are generated by gradle --- src/main/resources/META-INF/plugin.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 6cb28c5..80dacea 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1,8 +1,6 @@ - software.xdev.saveactions - Save Actions X xdev-software - - - com.intellij.modules.java From 65f85b4bd6a783c52813dfd6d233ba920539241a Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 14:24:57 +0200 Subject: [PATCH 477/518] Remove deprecation Fixes https://github.com/xdev-software/intellij-plugin-save-actions/issues/108 --- .../java/inspection/CustomAccessCanBeTightenedInspection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java index fd840d3..992f8e3 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomAccessCanBeTightenedInspection.java @@ -281,7 +281,7 @@ private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, @PsiUt int minLevel = Math.max(PsiUtil.ACCESS_LEVEL_PRIVATE, level); AtomicInteger maxLevel = new AtomicInteger(minLevel); AtomicBoolean foundUsage = new AtomicBoolean(); - boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> { + boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, null, info -> { PsiElement element = info.getElement(); if (element == null) { return true; From 3374aeac62a25b8a87d1b5f3164668b7b7fb97b2 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 14:36:38 +0200 Subject: [PATCH 478/518] Fix compile error Class was moved --- .../java/software/xdev/saveactions/junit/JUnit5Utils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java index ab33e91..a6f1e26 100644 --- a/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java +++ b/src/test/java/software/xdev/saveactions/junit/JUnit5Utils.java @@ -4,7 +4,7 @@ import org.opentest4j.AssertionFailedError; -import com.intellij.rt.execution.junit.FileComparisonFailure; +import com.intellij.platform.testFramework.core.FileComparisonFailedError; public final class JUnit5Utils @@ -16,10 +16,10 @@ private JUnit5Utils() public static void rethrowAsJunit5Error(final AssertionError error) { if(error.getCause() instanceof final InvocationTargetException intellijInternal - && intellijInternal.getCause() instanceof final FileComparisonFailure fileComparisonFailure) + && intellijInternal.getCause() instanceof final FileComparisonFailedError fileComparisonFailure) { - final String expected = fileComparisonFailure.getExpected(); - final String actual = fileComparisonFailure.getActual(); + final String expected = fileComparisonFailure.getExpected().getStringRepresentation(); + final String actual = fileComparisonFailure.getActual().getStringRepresentation(); throw new AssertionFailedError("Expected file do not match actual file", expected, actual); } From 5ead5e8ba101d012348efc3c0f6233676dde2540 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 16:15:55 +0200 Subject: [PATCH 479/518] Implement IDE test framework --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ac3adb4..c2f4207 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ configurations.checkstyle { } } -// Add dependencies to test, junit5 api (annotations) and engine (runtime) +import org.jetbrains.intellij.platform.gradle.TestFrameworkType dependencies { intellijPlatform { create(properties("platformType"), properties("platformVersion")) @@ -53,6 +53,7 @@ dependencies { pluginVerifier() zipSigner() instrumentationTools() + testFramework TestFrameworkType.Platform.INSTANCE } checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}" pmd "net.sourceforge.pmd:pmd-ant:${pmdVersion}", From 0adf4253c4dbf0356dfb2ee8d7d9207b85df72f2 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 16:22:38 +0200 Subject: [PATCH 480/518] Install compatibility layer for JUnit 4 Yes IntelliJ test are still written in JUnit 4... JUnit 5 is exists since 7 YEARS! Installed compatibility layer in favor of importing the JUnit4 library as this usually leads to incorrect imports. See also https://youtrack.jetbrains.com/issue/IJPL-159134 --- .../junit/framework/AssertionFailedError.java | 10 + src/test/java/junit/framework/TestCase.java | 13 ++ src/test/java/org/junit/Assert.java | 191 ++++++++++++++++++ .../junit/AssumptionViolatedException.java | 10 + .../java/org/junit/ComparisonFailure.java | 10 + .../org/junit/rules/ExternalResource.java | 10 + src/test/java/org/junit/rules/TestRule.java | 10 + .../org/junit/runners/model/Statement.java | 10 + 8 files changed, 264 insertions(+) create mode 100644 src/test/java/junit/framework/AssertionFailedError.java create mode 100644 src/test/java/junit/framework/TestCase.java create mode 100644 src/test/java/org/junit/Assert.java create mode 100644 src/test/java/org/junit/AssumptionViolatedException.java create mode 100644 src/test/java/org/junit/ComparisonFailure.java create mode 100644 src/test/java/org/junit/rules/ExternalResource.java create mode 100644 src/test/java/org/junit/rules/TestRule.java create mode 100644 src/test/java/org/junit/runners/model/Statement.java diff --git a/src/test/java/junit/framework/AssertionFailedError.java b/src/test/java/junit/framework/AssertionFailedError.java new file mode 100644 index 0000000..c4f7629 --- /dev/null +++ b/src/test/java/junit/framework/AssertionFailedError.java @@ -0,0 +1,10 @@ +package junit.framework; + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public class AssertionFailedError extends AssertionError +{ +} diff --git a/src/test/java/junit/framework/TestCase.java b/src/test/java/junit/framework/TestCase.java new file mode 100644 index 0000000..b15fa44 --- /dev/null +++ b/src/test/java/junit/framework/TestCase.java @@ -0,0 +1,13 @@ +package junit.framework; + +import org.junit.Assert; + + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public abstract class TestCase extends Assert +{ +} diff --git a/src/test/java/org/junit/Assert.java b/src/test/java/org/junit/Assert.java new file mode 100644 index 0000000..b954f48 --- /dev/null +++ b/src/test/java/org/junit/Assert.java @@ -0,0 +1,191 @@ +package org.junit; + +import org.junit.jupiter.api.Assertions; + + +/** + * @see Source + * @deprecated Compat for com.intellij.testFramework.fixtures.impl.BaseFixture + */ +@SuppressWarnings("all") +@Deprecated +public class Assert +{ + protected Assert() + { + } + + public static void assertTrue(final String message, final boolean condition) + { + Assertions.assertTrue(condition, message); + } + + public static void assertTrue(final boolean condition) + { + Assertions.assertTrue(condition); + } + + public static void assertFalse(final String message, final boolean condition) + { + Assertions.assertFalse(condition, message); + } + + public static void assertFalse(final boolean condition) + { + Assertions.assertFalse(condition); + } + + public static void fail(final String message) + { + Assertions.fail(message); + } + + public static void fail() + { + Assertions.fail(); + } + + public static void assertEquals(final String message, final Object expected, final Object actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final Object expected, final Object actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals(final String message, final String expected, final String actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final String expected, final String actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals( + final String message, + final double expected, + final double actual, + final double delta) + { + Assertions.assertEquals(expected, actual, delta, message); + } + + public static void assertEquals(final double expected, final double actual, final double delta) + { + Assertions.assertEquals(expected, actual, delta); + } + + public static void assertEquals(final String message, final float expected, final float actual, final float delta) + { + Assertions.assertEquals(expected, actual, delta, message); + } + + public static void assertEquals(final float expected, final float actual, final float delta) + { + Assertions.assertEquals(expected, actual, delta); + } + + public static void assertEquals(final String message, final long expected, final long actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final long expected, final long actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals(final String message, final boolean expected, final boolean actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final boolean expected, final boolean actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals(final String message, final byte expected, final byte actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final byte expected, final byte actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals(final String message, final char expected, final char actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final char expected, final char actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals(final String message, final short expected, final short actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final short expected, final short actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertEquals(final String message, final int expected, final int actual) + { + Assertions.assertEquals(expected, actual, message); + } + + public static void assertEquals(final int expected, final int actual) + { + Assertions.assertEquals(expected, actual); + } + + public static void assertNotNull(final Object object) + { + Assertions.assertNotNull(object); + } + + public static void assertNotNull(final String message, final Object object) + { + Assertions.assertNotNull(object, message); + } + + public static void assertNull(final Object object) + { + Assertions.assertNull(object); + } + + public static void assertNull(final String message, final Object object) + { + Assertions.assertNull(object, message); + } + + public static void assertSame(final String message, final Object expected, final Object actual) + { + Assertions.assertSame(expected, actual, message); + } + + public static void assertSame(final Object expected, final Object actual) + { + Assertions.assertSame(expected, actual); + } + + public static void assertNotSame(final String message, final Object expected, final Object actual) + { + Assertions.assertNotSame(expected, actual, message); + } + + public static void assertNotSame(final Object expected, final Object actual) + { + Assertions.assertNotSame(expected, actual); + } +} diff --git a/src/test/java/org/junit/AssumptionViolatedException.java b/src/test/java/org/junit/AssumptionViolatedException.java new file mode 100644 index 0000000..a5f66d3 --- /dev/null +++ b/src/test/java/org/junit/AssumptionViolatedException.java @@ -0,0 +1,10 @@ +package org.junit; + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public class AssumptionViolatedException extends RuntimeException +{ +} diff --git a/src/test/java/org/junit/ComparisonFailure.java b/src/test/java/org/junit/ComparisonFailure.java new file mode 100644 index 0000000..6c08255 --- /dev/null +++ b/src/test/java/org/junit/ComparisonFailure.java @@ -0,0 +1,10 @@ +package org.junit; + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public class ComparisonFailure extends AssertionError +{ +} diff --git a/src/test/java/org/junit/rules/ExternalResource.java b/src/test/java/org/junit/rules/ExternalResource.java new file mode 100644 index 0000000..1532e41 --- /dev/null +++ b/src/test/java/org/junit/rules/ExternalResource.java @@ -0,0 +1,10 @@ +package org.junit.rules; + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public abstract class ExternalResource implements TestRule +{ +} diff --git a/src/test/java/org/junit/rules/TestRule.java b/src/test/java/org/junit/rules/TestRule.java new file mode 100644 index 0000000..8139989 --- /dev/null +++ b/src/test/java/org/junit/rules/TestRule.java @@ -0,0 +1,10 @@ +package org.junit.rules; + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public interface TestRule +{ +} diff --git a/src/test/java/org/junit/runners/model/Statement.java b/src/test/java/org/junit/runners/model/Statement.java new file mode 100644 index 0000000..3cae110 --- /dev/null +++ b/src/test/java/org/junit/runners/model/Statement.java @@ -0,0 +1,10 @@ +package org.junit.runners.model; + +/** + * @deprecated Compat for IJPL-159134 + */ +@SuppressWarnings("all") +@Deprecated +public class Statement +{ +} From ab480545f78fd256c19bca53322ab3645c7fd0a5 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 16:30:33 +0200 Subject: [PATCH 481/518] PMD: Speed up tests --- .../java/software/xdev/saveactions/model/java/EpfKeyTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java index 955aaac..1e5977f 100644 --- a/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java +++ b/src/test/java/software/xdev/saveactions/model/java/EpfKeyTest.java @@ -55,7 +55,7 @@ private List getPropertiesKeyNames(final Properties properties) return properties.keySet().stream() .map(Object::toString) .filter(key -> EpfKey.getPrefixes().stream().anyMatch(key::startsWith)) - .map(key -> key.substring(key.lastIndexOf(".") == -1 ? 0 : key.lastIndexOf(".") + 1)) + .map(key -> key.substring(key.lastIndexOf('.') == -1 ? 0 : key.lastIndexOf('.') + 1)) .collect(toList()); } From 46180ee26dcfc5996e213f0355a9186bf70a1e36 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 16:30:57 +0200 Subject: [PATCH 482/518] PMD: Inline field --- .../xdev/saveactions/ui/Configuration.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/ui/Configuration.java b/src/main/java/software/xdev/saveactions/ui/Configuration.java index fd02c96..0a6053b 100644 --- a/src/main/java/software/xdev/saveactions/ui/Configuration.java +++ b/src/main/java/software/xdev/saveactions/ui/Configuration.java @@ -56,10 +56,7 @@ public class Configuration implements Configurable private final Map checkboxes = new EnumMap<>(Action.class); private final ActionListener checkboxActionListener = this::updateCheckboxEnabled; - private GeneralPanel generalPanel; - private FormattingPanel formattingPanel; private BuildPanel buildPanel; - private InspectionPanel inspectionPanel; private FileMaskPanel fileMasksExclusionPanel; private FileMaskPanel fileMasksInclusionPanel; private IdeSupportPanel ideSupport; @@ -159,10 +156,7 @@ public void disposeUIResources() this.exclusions.clear(); this.inclusions.clear(); this.quickLists.clear(); - this.generalPanel = null; - this.formattingPanel = null; this.buildPanel = null; - this.inspectionPanel = null; this.fileMasksInclusionPanel = null; this.fileMasksExclusionPanel = null; this.ideSupport = null; @@ -188,18 +182,18 @@ private JPanel initComponent() { this.checkboxes.put(action, new JCheckBox(action.getText())); } - this.generalPanel = new GeneralPanel(this.checkboxes); - this.formattingPanel = new FormattingPanel(this.checkboxes); + final GeneralPanel generalPanel = new GeneralPanel(this.checkboxes); + final FormattingPanel formattingPanel = new FormattingPanel(this.checkboxes); this.buildPanel = new BuildPanel(this.checkboxes, this.quickLists); - this.inspectionPanel = new InspectionPanel(this.checkboxes); + final InspectionPanel inspectionPanel = new InspectionPanel(this.checkboxes); this.fileMasksInclusionPanel = new FileMaskInclusionPanel(this.inclusions); this.fileMasksExclusionPanel = new FileMaskExclusionPanel(this.exclusions); this.ideSupport = new IdeSupportPanel(); return this.initRootPanel( - this.generalPanel.getPanel(), - this.formattingPanel.getPanel(), + generalPanel.getPanel(), + formattingPanel.getPanel(), this.buildPanel.getPanel(), - this.inspectionPanel.getPanel(), + inspectionPanel.getPanel(), this.fileMasksInclusionPanel.getPanel(), this.fileMasksExclusionPanel.getPanel(), this.ideSupport.getPanel(this.storage.getConfigurationPath()) @@ -208,8 +202,12 @@ private JPanel initComponent() @SuppressWarnings("checkstyle:MagicNumber") private JPanel initRootPanel( - final JPanel general, final JPanel actions, final JPanel build, final JPanel inspections, - final JPanel fileMasksInclusions, final JPanel fileMasksExclusions, + final JPanel general, + final JPanel actions, + final JPanel build, + final JPanel inspections, + final JPanel fileMasksInclusions, + final JPanel fileMasksExclusions, final JPanel ideSupport) { final JPanel panel = new JPanel(); From 208e137c7fc28f2f11cd1c1cfab8d6cd729abbc2 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 19 Sep 2024 16:44:16 +0200 Subject: [PATCH 483/518] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7909d00..57bd76c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 1.2.4 -* Dropped support for IntelliJ versions < 2024 +* Dropped support for IntelliJ versions < 2024.2 +* Removed deprecated code that was only required for older IDE versions ## 1.2.3 * Fix "run on multiple files" not working when the file is not a text file #129 From b663afaa6172d9b0ff521d5d7903728460765e2e Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 19 Sep 2024 15:05:22 +0000 Subject: [PATCH 484/518] Release 1.2.4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a62821b..df13631 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.4-SNAPSHOT +pluginVersion=1.2.4 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From 40bac66afb972485484079cfe2e1f1746b8a8feb Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 19 Sep 2024 15:07:06 +0000 Subject: [PATCH 485/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index df13631..d3e2afa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.4 +pluginVersion=1.2.5-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From 929f3a973703ac6c764bc8b587c006615d26ef1b Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 20 Sep 2024 11:48:06 +0200 Subject: [PATCH 486/518] Workaround that the plugin is always executed during project load [<2024.3] ``ProjectSettingsTracker#submitSettingsFilesRefresh`` saves all open files during project load. The fix is to ignore this on the affect IntelliJ versions (< 2024.3) Related: * https://github.com/xdev-software/intellij-plugin-save-actions/issues/145 * https://github.com/JetBrains/intellij-community/commit/765caa71175d0a67a54836cf840fae829da590d9 --- .../SaveActionsDocumentManagerListener.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java index 9a0a790..a380f80 100644 --- a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java +++ b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java @@ -5,7 +5,9 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; +import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -40,6 +42,13 @@ public void beforeAllDocumentsSaving() { LOGGER.debug( "[+] Start SaveActionsDocumentManagerListener#beforeAllDocumentsSaving, " + this.project.getName()); + + if(REQUIRES_PROJECT_LOAD_IGNORE_WORKAROUND && isInvokedFromProjectLoadBefore243()) + { + LOGGER.debug("Ignoring due to PROJECT_LOAD_IGNORE_WORKAROUND"); + return; + } + final List unsavedDocuments = Arrays.asList(FileDocumentManager.getInstance().getUnsavedDocuments()); if(!unsavedDocuments.isEmpty()) { @@ -74,4 +83,38 @@ private synchronized void initPsiDocManager() this.psiDocumentManager = PsiDocumentManager.getInstance(this.project); } } + + // region PROJECT_LOAD_IGNORE_WORKAROUND + // https://github.com/xdev-software/intellij-plugin-save-actions/issues/145 + private static final boolean REQUIRES_PROJECT_LOAD_IGNORE_WORKAROUND = + determineIfRequiresProjectLoadIgnoreWorkaround(); + + @SuppressWarnings("checkstyle:MagicNumber") + static boolean determineIfRequiresProjectLoadIgnoreWorkaround() + { + try + { + // Problem was fixed in 2024.3 + return ApplicationInfo.getInstance().getBuild().getBaselineVersion() < 243; + } + catch(final Exception ex) + { + LOGGER.warn("Failed to determine IDE version", ex); + return false; + } + } + + @SuppressWarnings("checkstyle:MagicNumber") + static boolean isInvokedFromProjectLoadBefore243() + { + // The invoking method is ProjectSettingsTracker$submitSettingsFilesRefresh is usually at index 17 and 18 + return Stream.of(Thread.currentThread().getStackTrace()) + .map(StackTraceElement::getClassName) + .skip(16) + .limit(5) + .anyMatch(s -> s.startsWith( + "com.intellij.openapi.externalSystem.autoimport.ProjectSettingsTracker$submitSettingsFilesRefresh")); + } + + // endregion } From 3bb59f02cde7661723e14217797bf711eebbe4e6 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 20 Sep 2024 13:51:39 +0200 Subject: [PATCH 487/518] Add basic support for async processing of files Should improve #130 --- .../saveactions/core/component/Engine.java | 121 +++++++++++++++--- .../core/service/SaveActionsService.java | 1 - .../impl/AbstractSaveActionsService.java | 58 ++++++++- .../xdev/saveactions/model/Action.java | 4 + .../xdev/saveactions/ui/GeneralPanel.java | 2 + 5 files changed, 162 insertions(+), 24 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java index b41930a..f7afbad 100644 --- a/src/main/java/software/xdev/saveactions/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -6,20 +6,27 @@ import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.ThrowableComputable; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; +import com.intellij.util.ApplicationKt; import com.intellij.util.PsiErrorElementUtil; +import com.intellij.util.ThrowableRunnable; import software.xdev.saveactions.core.ExecutionMode; import software.xdev.saveactions.core.service.SaveActionsService; @@ -62,7 +69,9 @@ public Engine( this.mode = mode; } - public void processPsiFilesIfNecessary() + public void processPsiFilesIfNecessary( + @NotNull final ProgressIndicator indicator, + final boolean async) { if(this.psiFiles == null) { @@ -73,36 +82,112 @@ public void processPsiFilesIfNecessary() LOGGER.info(String.format("Action \"%s\" not enabled on %s", this.activation.getText(), this.project)); return; } + + indicator.setIndeterminate(true); + final Set psiFilesEligible = this.getEligiblePsiFiles(indicator, async); + if(psiFilesEligible.isEmpty()) + { + LOGGER.info("No files are eligible"); + return; + } + + final List processorsEligible = this.getEligibleProcessors(indicator, psiFilesEligible); + if(processorsEligible.isEmpty()) + { + LOGGER.info("No processors are eligible"); + return; + } + + this.flushPsiFiles(indicator, async, psiFilesEligible); + + this.execute(indicator, processorsEligible, psiFilesEligible); + } + + private Set getEligiblePsiFiles(final @NotNull ProgressIndicator indicator, final boolean async) + { LOGGER.info(String.format("Processing %s files %s mode %s", this.project, this.psiFiles, this.mode)); - final Set psiFilesEligible = this.psiFiles.stream() - .filter(psiFile -> this.isPsiFileEligible(this.project, psiFile)) - .collect(toSet()); + indicator.checkCanceled(); + indicator.setText2("Collecting files to process"); + + final ThrowableComputable, RuntimeException> psiFilesEligibleFunc = + () -> this.psiFiles.stream() + .filter(psiFile -> this.isPsiFileEligible(this.project, psiFile)) + .collect(toSet()); + final Set psiFilesEligible = async + ? ReadAction.compute(psiFilesEligibleFunc) + : psiFilesEligibleFunc.compute(); LOGGER.info(String.format("Valid files %s", psiFilesEligible)); - this.processPsiFiles(this.project, psiFilesEligible, this.mode); + return psiFilesEligible; } - private void processPsiFiles(final Project project, final Set psiFiles, final ExecutionMode mode) + private @NotNull List getEligibleProcessors( + final @NotNull ProgressIndicator indicator, + final Set psiFilesEligible) { - if(psiFiles.isEmpty()) - { - return; - } LOGGER.info(String.format("Start processors (%d)", this.processors.size())); + indicator.checkCanceled(); + indicator.setText2("Collecting processors"); + final List processorsEligible = this.processors.stream() - .map(processor -> processor.getSaveCommand(project, psiFiles)) + .map(processor -> processor.getSaveCommand(this.project, psiFilesEligible)) .filter(command -> this.storage.isEnabled(command.getAction())) - .filter(command -> command.getModes().contains(mode)) + .filter(command -> command.getModes().contains(this.mode)) .toList(); LOGGER.info(String.format("Filtered processors %s", processorsEligible)); - if(!processorsEligible.isEmpty()) + return processorsEligible; + } + + private void flushPsiFiles( + final @NotNull ProgressIndicator indicator, + final boolean async, + final Set psiFilesEligible) + { + LOGGER.info(String.format("Flushing files (%d)", psiFilesEligible.size())); + indicator.checkCanceled(); + indicator.setText2("Flushing files"); + + final ThrowableRunnable flushFilesFunc = () -> { + final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(this.project); + psiFilesEligible.forEach(psiFile -> this.commitDocumentAndSave(psiFile, psiDocumentManager)); + }; + if(async) + { + ApplicationKt.getApplication().invokeAndWait(() -> WriteAction.run(flushFilesFunc)); + } + else { - final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); - psiFiles.forEach(psiFile -> this.commitDocumentAndSave(psiFile, psiDocumentManager)); + flushFilesFunc.run(); } - final List>> results = processorsEligible.stream() + } + + private void execute( + final @NotNull ProgressIndicator indicator, + final List processorsEligible, + final Set psiFilesEligible) + { + indicator.checkCanceled(); + indicator.setIndeterminate(false); + indicator.setFraction(0d); + + final List saveCommands = processorsEligible.stream() .filter(Objects::nonNull) - .peek(command -> LOGGER.info(String.format("Execute command %s on %d files", command, psiFiles.size()))) - .map(command -> new SimpleEntry<>(command.getAction(), command.execute())) + .toList(); + + final AtomicInteger executedCount = new AtomicInteger(); + final List>> results = saveCommands.stream() + .map(command -> { + LOGGER.info(String.format("Execute command %s on %d files", command, psiFilesEligible.size())); + + indicator.checkCanceled(); + indicator.setText2("Executing '" + command.getAction().getText() + "'"); + + final SimpleEntry> entry = + new SimpleEntry<>(command.getAction(), command.execute()); + + indicator.setFraction((double)executedCount.incrementAndGet() / saveCommands.size()); + + return entry; + }) .toList(); LOGGER.info(String.format("Exit engine with results %s", results.stream() .map(entry -> entry.getKey() + ":" + entry.getValue()) diff --git a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java index ccfd8da..e151c78 100644 --- a/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/SaveActionsService.java @@ -18,7 +18,6 @@ */ public interface SaveActionsService { - void guardedProcessPsiFiles(Project project, Set psiFiles, Action activation, ExecutionMode mode); boolean isJavaAvailable(); diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index ed02417..cb510cd 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -12,12 +12,18 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Stream; +import org.jetbrains.annotations.NotNull; + import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.EmptyProgressIndicator; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; @@ -25,6 +31,7 @@ import software.xdev.saveactions.core.component.Engine; import software.xdev.saveactions.core.service.SaveActionsService; import software.xdev.saveactions.model.Action; +import software.xdev.saveactions.model.Storage; import software.xdev.saveactions.model.StorageFactory; import software.xdev.saveactions.processors.Processor; @@ -34,8 +41,8 @@ * implementations by default. *

    * The main method is {@link #guardedProcessPsiFiles(Project, Set, Action, ExecutionMode)} and will delegate to - * {@link Engine#processPsiFilesIfNecessary()}. The method will check if the file needs to be processed and uses the - * processors to apply the modifications. + * {@link Engine#processPsiFilesIfNecessary(ProgressIndicator, boolean)} ()}. + * The method will check if the file needs to be processed and uses the processors to apply the modifications. *

    * The psi files are ide wide, that means they are shared between projects (and editor windows), so we need to check if * the file is physically in that project before reformatting, or else the file is formatted twice and intellij will ask @@ -52,6 +59,8 @@ abstract class AbstractSaveActionsService implements SaveActionsService private final boolean javaAvailable; private final boolean compilingAvailable; + private final ReentrantLock guardedProcessPsiFilesLock = new ReentrantLock(); + protected AbstractSaveActionsService(final StorageFactory storageFactory) { LOGGER.info("Save Actions Service \"" + this.getClass().getSimpleName() + "\" initialized."); @@ -62,7 +71,7 @@ protected AbstractSaveActionsService(final StorageFactory storageFactory) } @Override - public synchronized void guardedProcessPsiFiles( + public void guardedProcessPsiFiles( final Project project, final Set psiFiles, final Action activation, @@ -73,10 +82,49 @@ public synchronized void guardedProcessPsiFiles( LOGGER.info("Application is closing, stopping invocation"); return; } + + final Storage storage = this.storageFactory.getStorage(project); final Engine engine = new Engine( - this.storageFactory.getStorage(project), this.processors, project, psiFiles, activation, + storage, + this.processors, + project, + psiFiles, + activation, mode); - engine.processPsiFilesIfNecessary(); + + final boolean applyAsync = storage.getActions().contains(Action.processAsync); + if(applyAsync) + { + new Task.Backgroundable(project, "Applying Save Actions", true) + { + @Override + public void run(@NotNull final ProgressIndicator indicator) + { + AbstractSaveActionsService.this.processPsiFilesIfNecessaryWithLock(engine, indicator); + } + }.queue(); + return; + } + + this.processPsiFilesIfNecessaryWithLock(engine, null); + } + + private void processPsiFilesIfNecessaryWithLock(final Engine engine, final ProgressIndicator indicator) + { + LOGGER.trace("Getting lock"); + this.guardedProcessPsiFilesLock.lock(); + LOGGER.trace("Got lock"); + try + { + engine.processPsiFilesIfNecessary( + indicator != null ? indicator : new EmptyProgressIndicator(), + indicator != null); + } + finally + { + this.guardedProcessPsiFilesLock.unlock(); + LOGGER.trace("Released lock"); + } } @Override diff --git a/src/main/java/software/xdev/saveactions/model/Action.java b/src/main/java/software/xdev/saveactions/model/Action.java index f2fde51..f3cfd08 100644 --- a/src/main/java/software/xdev/saveactions/model/Action.java +++ b/src/main/java/software/xdev/saveactions/model/Action.java @@ -27,6 +27,10 @@ public enum Action noActionIfCompileErrors("No action if compile errors (applied per file)", activation, false), + processAsync("Process files asynchronously " + + "(will result in less UI hangs but may break if a processor needs the UI)", + activation, false), + // Global organizeImports("Optimize imports", global, true), diff --git a/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java index dca4c4c..9bfa390 100644 --- a/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/GeneralPanel.java @@ -4,6 +4,7 @@ import static software.xdev.saveactions.model.Action.activateOnBatch; import static software.xdev.saveactions.model.Action.activateOnShortcut; import static software.xdev.saveactions.model.Action.noActionIfCompileErrors; +import static software.xdev.saveactions.model.Action.processAsync; import java.awt.Dimension; import java.util.Map; @@ -38,6 +39,7 @@ JPanel getPanel() panel.add(this.checkboxes.get(activateOnShortcut)); panel.add(this.checkboxes.get(activateOnBatch)); panel.add(this.checkboxes.get(noActionIfCompileErrors)); + panel.add(this.checkboxes.get(processAsync)); panel.add(Box.createHorizontalGlue()); panel.setMinimumSize(new Dimension(Short.MAX_VALUE, 0)); return panel; From 0b195e13b7220e284927b62197e44580bc100ffa Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 20 Sep 2024 13:52:00 +0200 Subject: [PATCH 488/518] Prepare for 1.3.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d3e2afa..26b39c2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.2.5-SNAPSHOT +pluginVersion=1.3.0-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From f454fc1717ce48783d69857a7528afd86b7b5a98 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 20 Sep 2024 13:56:33 +0200 Subject: [PATCH 489/518] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57bd76c..e2c2c63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.3.0 +* Make it possible to run processors asynchronously #130 + * This way the UI should be more responsive when processing a lot of files + * May break processors that interact with the UI e.g. when showing dialogs +* Don't run during startup #145 + * This should cause less race conditions due to partial initialization + * Only active on IntelliJ < 2024.3 as [the underlying problem was fixed in IntelliJ 2024.3](https://github.com/JetBrains/intellij-community/commit/765caa71175d0a67a54836cf840fae829da590d9) + ## 1.2.4 * Dropped support for IntelliJ versions < 2024.2 * Removed deprecated code that was only required for older IDE versions From 26f4565516ffa9a1e1492e053837b5481c1c87f7 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 20 Sep 2024 14:11:14 +0200 Subject: [PATCH 490/518] Update CHANGELOG.md Reword --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2c2c63..2a92efd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ * Make it possible to run processors asynchronously #130 * This way the UI should be more responsive when processing a lot of files * May break processors that interact with the UI e.g. when showing dialogs -* Don't run during startup #145 - * This should cause less race conditions due to partial initialization +* Don't process files during project load #145 + * This should cause less race conditions due to partial project initialization * Only active on IntelliJ < 2024.3 as [the underlying problem was fixed in IntelliJ 2024.3](https://github.com/JetBrains/intellij-community/commit/765caa71175d0a67a54836cf840fae829da590d9) ## 1.2.4 From f945d32082f19ac1685e827d1e4d3580ed7c0675 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 20 Sep 2024 14:17:05 +0200 Subject: [PATCH 491/518] Fix typo --- .../core/listener/SaveActionsDocumentManagerListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java index a380f80..9f1008a 100644 --- a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java +++ b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java @@ -107,7 +107,7 @@ static boolean determineIfRequiresProjectLoadIgnoreWorkaround() @SuppressWarnings("checkstyle:MagicNumber") static boolean isInvokedFromProjectLoadBefore243() { - // The invoking method is ProjectSettingsTracker$submitSettingsFilesRefresh is usually at index 17 and 18 + // The invoking method ProjectSettingsTracker$submitSettingsFilesRefresh is usually at index 17 and 18 return Stream.of(Thread.currentThread().getStackTrace()) .map(StackTraceElement::getClassName) .skip(16) From bb8c8a65056d1fd9320b8b409a5476f4ee685609 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 23 Sep 2024 08:46:51 +0200 Subject: [PATCH 492/518] Update USAGE.md Add "Troubleshooting of common problems" section --- USAGE.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/USAGE.md b/USAGE.md index b4f9dfd..65c7949 100644 --- a/USAGE.md +++ b/USAGE.md @@ -132,3 +132,21 @@ Some things to note when using other plugins with the Save Actions plugin: - **idea.log**: The log file the save actions plugin writes in. It contains debug information, prefixed with `software.xdev.saveactions.SaveActionManager`. If you are using default locations, it would be in `~/.IntelliJIdeaVERSION/system/log/idea.log`. - **saveactions_settings.xml**: The settings file is saved by project in the `.idea` folder. That file can be committed in git thus shared in your development team. If you are using the default locations, it would be in `~/IdeaProjects/PROJECT_NAME/.idea/saveactions_settings.xml` + +## Troubleshooting of common problems + +### "Conflicting component name 'SaveActionSettings': class ``com.dubreuia.model.Storage`` and class ``software.xdev.saveactions.model.Storage``" + +The problem only happens when the [old/deprecated/forked plugin](https://github.com/dubreuia/intellij-plugin-save-actions) plugin is also installed. + +You can fix this by uninstalling the deprecated plugin. + +### "AWT events are not allowed inside write action" occurs when applying Save Actions + +This usually indicates that some action causes a UI dialog to show up.
    However as the actions are run in the background the dialog can't be shown and the crash occurs. + +You can work around this problem by finding out what causes the dialog (e.g. by trying to temporarily disabling Save Actions and saving the files normally) and stop it from being displayed. + +### "Execute Save Actions on multiple files" is not working + +Make sure that you enabled "Activate save actions on batch" in the settings. From 47f24502e31c15d1186acef96779a140f1c7c687 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 23 Sep 2024 08:48:21 +0200 Subject: [PATCH 493/518] Update USAGE.md --- USAGE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USAGE.md b/USAGE.md index 65c7949..01e9203 100644 --- a/USAGE.md +++ b/USAGE.md @@ -32,6 +32,7 @@ You can quickly toggle the plugin activation by using the "Enable Save Action" a | Activate save actions on shortcut | Enable / disable the plugin on shortcut, by default "CTRL + SHIFT + S" (configured in "File > Keymaps > Main menu > Code > Save Actions") | Activate save actions on batch | Enable / disable the plugin on batch, by using "Code > Save Actions > Execute on multiple files" | No action if compile errors | Enable / disable no action if there are compile errors. Applied to each file individually +| Process files asynchronously | Enable / disable if files should be processed asynchronously. Enabling it will result in less UI hangs but may break if a processor needs the UI. ### Global From be48a3ae8ad8b5b02e459477d162abd469f4ba05 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 23 Sep 2024 06:51:55 +0000 Subject: [PATCH 494/518] Release 1.3.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 26b39c2..3303945 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.3.0-SNAPSHOT +pluginVersion=1.3.0 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From 4f28d384ac30a432b2cd63c906b1861d4c9596d8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 23 Sep 2024 06:53:27 +0000 Subject: [PATCH 495/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 3303945..6cb9ce8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.3.0 +pluginVersion=1.3.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From 4a2bc598513969a356b04e815d00bc7eff968f85 Mon Sep 17 00:00:00 2001 From: AB Date: Tue, 24 Sep 2024 14:42:39 +0200 Subject: [PATCH 496/518] Code style improvement --- .../CustomSerializableHasSerialVersionUidFieldInspection.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java index a8348c4..ab6bb0a 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java +++ b/src/main/java/software/xdev/saveactions/processors/java/inspection/CustomSerializableHasSerialVersionUidFieldInspection.java @@ -36,14 +36,12 @@ public CustomSerializableHasSerialVersionUidFieldInspection() @Override public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { - return this.getClass().getSimpleName(); } @Override public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getGroupDisplayName() { - return "SaveActionsInternal"; } From 4ba1d845bcf07ea01c39d0111e6db69605c4ff87 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 26 Sep 2024 17:29:09 +0200 Subject: [PATCH 497/518] Fix IDE hang when projects with different "Process files asynchronously" are open Fixes #160 This problem only happens when at least 2 projects with different "Process files asynchronously" are open and a save is executed. If a save (Ctrl + S) is performed it saves both projects in parallel, causing a lock failure as one project locks the UI while the other one (which has the lock / runs async) tries to acquire the UI thread, thus causing a deadlock. --- .../impl/AbstractSaveActionsService.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index cb510cd..52c20fb 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -7,11 +7,13 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Stream; @@ -59,7 +61,8 @@ abstract class AbstractSaveActionsService implements SaveActionsService private final boolean javaAvailable; private final boolean compilingAvailable; - private final ReentrantLock guardedProcessPsiFilesLock = new ReentrantLock(); + private final Map guardedProcessPsiFilesLocks = + Collections.synchronizedMap(new WeakHashMap<>()); protected AbstractSaveActionsService(final StorageFactory storageFactory) { @@ -100,20 +103,31 @@ public void guardedProcessPsiFiles( @Override public void run(@NotNull final ProgressIndicator indicator) { - AbstractSaveActionsService.this.processPsiFilesIfNecessaryWithLock(engine, indicator); + AbstractSaveActionsService.this.processPsiFilesIfNecessaryWithLock(project, engine, indicator); } }.queue(); return; } - this.processPsiFilesIfNecessaryWithLock(engine, null); + this.processPsiFilesIfNecessaryWithLock(project, engine, null); } - private void processPsiFilesIfNecessaryWithLock(final Engine engine, final ProgressIndicator indicator) + private void processPsiFilesIfNecessaryWithLock( + final Project project, + final Engine engine, + final ProgressIndicator indicator) { - LOGGER.trace("Getting lock"); - this.guardedProcessPsiFilesLock.lock(); - LOGGER.trace("Got lock"); + if(LOGGER.isTraceEnabled()) + { + LOGGER.trace("Getting lock - " + project.getName()); + } + final ReentrantLock lock = + this.guardedProcessPsiFilesLocks.computeIfAbsent(project, ignored -> new ReentrantLock()); + lock.lock(); + if(LOGGER.isTraceEnabled()) + { + LOGGER.trace("Got lock - " + project.getName()); + } try { engine.processPsiFilesIfNecessary( @@ -122,8 +136,11 @@ private void processPsiFilesIfNecessaryWithLock(final Engine engine, final Progr } finally { - this.guardedProcessPsiFilesLock.unlock(); - LOGGER.trace("Released lock"); + lock.unlock(); + if(LOGGER.isTraceEnabled()) + { + LOGGER.trace("Released lock - " + project.getName()); + } } } From d8ddb02d2fcbad4041115276bd04f5912316193e Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 26 Sep 2024 17:29:17 +0200 Subject: [PATCH 498/518] Improve logging --- .../saveactions/core/component/Engine.java | 38 ++++++++++++------- .../processors/java/InspectionRunnable.java | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/component/Engine.java b/src/main/java/software/xdev/saveactions/core/component/Engine.java index f7afbad..5687fc9 100644 --- a/src/main/java/software/xdev/saveactions/core/component/Engine.java +++ b/src/main/java/software/xdev/saveactions/core/component/Engine.java @@ -79,7 +79,10 @@ public void processPsiFilesIfNecessary( } if(!this.storage.isEnabled(this.activation)) { - LOGGER.info(String.format("Action \"%s\" not enabled on %s", this.activation.getText(), this.project)); + LOGGER.info(String.format( + "Action \"%s\" not enabled on %s", + this.activation.getText(), + this.project.getName())); return; } @@ -87,14 +90,14 @@ public void processPsiFilesIfNecessary( final Set psiFilesEligible = this.getEligiblePsiFiles(indicator, async); if(psiFilesEligible.isEmpty()) { - LOGGER.info("No files are eligible"); + LOGGER.info("No files are eligible - " + this.project.getName()); return; } final List processorsEligible = this.getEligibleProcessors(indicator, psiFilesEligible); if(processorsEligible.isEmpty()) { - LOGGER.info("No processors are eligible"); + LOGGER.info("No processors are eligible - " + this.project.getName()); return; } @@ -105,7 +108,7 @@ public void processPsiFilesIfNecessary( private Set getEligiblePsiFiles(final @NotNull ProgressIndicator indicator, final boolean async) { - LOGGER.info(String.format("Processing %s files %s mode %s", this.project, this.psiFiles, this.mode)); + LOGGER.info(String.format("Processing %s files %s mode %s", this.project.getName(), this.psiFiles, this.mode)); indicator.checkCanceled(); indicator.setText2("Collecting files to process"); @@ -124,7 +127,7 @@ private Set getEligiblePsiFiles(final @NotNull ProgressIndicator indica final @NotNull ProgressIndicator indicator, final Set psiFilesEligible) { - LOGGER.info(String.format("Start processors (%d)", this.processors.size())); + LOGGER.info(String.format("Start processors (%d) - %s", this.processors.size(), this.project.getName())); indicator.checkCanceled(); indicator.setText2("Collecting processors"); @@ -142,7 +145,7 @@ private void flushPsiFiles( final boolean async, final Set psiFilesEligible) { - LOGGER.info(String.format("Flushing files (%d)", psiFilesEligible.size())); + LOGGER.info(String.format("Flushing files (%d) - %s", psiFilesEligible.size(), this.project.getName())); indicator.checkCanceled(); indicator.setText2("Flushing files"); @@ -176,7 +179,11 @@ private void execute( final AtomicInteger executedCount = new AtomicInteger(); final List>> results = saveCommands.stream() .map(command -> { - LOGGER.info(String.format("Execute command %s on %d files", command, psiFilesEligible.size())); + LOGGER.info(String.format( + "Execute command %s on %d files - %s", + command, + psiFilesEligible.size(), + this.project.getName())); indicator.checkCanceled(); indicator.setText2("Executing '" + command.getAction().getText() + "'"); @@ -189,9 +196,12 @@ private void execute( return entry; }) .toList(); - LOGGER.info(String.format("Exit engine with results %s", results.stream() - .map(entry -> entry.getKey() + ":" + entry.getValue()) - .toList())); + LOGGER.info(String.format( + "Exit engine with results %s - %s", + results.stream() + .map(entry -> entry.getKey() + ":" + entry.getValue()) + .toList(), + this.project.getName())); } private boolean isPsiFileEligible(final Project project, final PsiFile psiFile) @@ -211,7 +221,7 @@ private boolean isProjectValid(final Project project) final boolean valid = project.isInitialized() && !project.isDisposed(); if(!valid) { - LOGGER.info("Project invalid. Either not initialized or disposed."); + LOGGER.info(String.format("Project %s invalid. Either not initialized or disposed", project.getName())); } return valid; } @@ -260,7 +270,7 @@ private boolean isPsiFileFresh(final PsiFile psiFile) final boolean isFresh = psiFile.getModificationStamp() != 0; if(!isFresh) { - LOGGER.info(String.format("File %s is not fresh.", psiFile)); + LOGGER.info(String.format("File %s is not fresh", psiFile)); } return isFresh; } @@ -270,7 +280,7 @@ private boolean isPsiFileValid(final PsiFile psiFile) final boolean valid = psiFile.isValid(); if(!valid) { - LOGGER.info(String.format("File %s is not valid.", psiFile)); + LOGGER.info(String.format("File %s is not valid", psiFile)); } return valid; } @@ -280,7 +290,7 @@ private boolean hasPsiFileText(final PsiFile psiFile) final boolean valid = psiFile.getTextRange() != null; if(!valid) { - LOGGER.info(String.format("File %s has no text.", psiFile)); + LOGGER.info(String.format("File %s has no text", psiFile)); } return valid; } diff --git a/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java index 4ee46a4..50d0074 100644 --- a/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java +++ b/src/main/java/software/xdev/saveactions/processors/java/InspectionRunnable.java @@ -40,7 +40,7 @@ class InspectionRunnable implements Runnable this.project = project; this.psiFiles = psiFiles; this.toolWrapper = new LocalInspectionToolWrapper(inspectionTool); - LOGGER.info(String.format("Running inspection for %s", inspectionTool.getShortName())); + LOGGER.info(String.format("Running inspection for %s - %s", inspectionTool.getShortName(), project.getName())); } @Override From 00eacb164af977e8ffd2a40b0891b0817256567a Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 26 Sep 2024 17:31:20 +0200 Subject: [PATCH 499/518] Code cleanup --- .../core/service/impl/AbstractSaveActionsService.java | 5 ++--- .../core/service/impl/SaveActionsDefaultService.java | 5 ++--- .../core/service/impl/SaveActionsJavaService.java | 7 +++---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index 52c20fb..d22234f 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -1,7 +1,6 @@ package software.xdev.saveactions.core.service.impl; import static java.util.function.Function.identity; -import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; import static software.xdev.saveactions.model.StorageFactory.JAVA; @@ -168,8 +167,8 @@ public List getQuickLists(final Project project) .map(Integer::valueOf) .map(quickListsIds::get) .filter(Objects::nonNull) - .collect(toList())) - .orElse(new ArrayList<>()); + .toList()) + .orElseGet(List::of); } protected SaveActionsService addProcessors(final Stream processors) diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java index a51ac65..75a1d14 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java @@ -21,11 +21,10 @@ */ public final class SaveActionsDefaultService extends AbstractSaveActionsService { - public SaveActionsDefaultService() { super(DEFAULT); - addProcessors(BuildProcessor.stream()); - addProcessors(GlobalProcessor.stream()); + this.addProcessors(BuildProcessor.stream()); + this.addProcessors(GlobalProcessor.stream()); } } diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java index ae47577..94cff5d 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java @@ -22,12 +22,11 @@ */ public final class SaveActionsJavaService extends AbstractSaveActionsService { - public SaveActionsJavaService() { super(JAVA); - addProcessors(BuildProcessor.stream()); - addProcessors(GlobalProcessor.stream()); - addProcessors(JavaProcessor.stream()); + this.addProcessors(BuildProcessor.stream()); + this.addProcessors(GlobalProcessor.stream()); + this.addProcessors(JavaProcessor.stream()); } } From a8ea0a713029d0324a741989fcc3fcc25c541f8d Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 26 Sep 2024 17:40:59 +0200 Subject: [PATCH 500/518] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a92efd..6730e57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.3.1 +* Fix IDE hang when projects with different "Process files asynchronously" are open #160 + ## 1.3.0 * Make it possible to run processors asynchronously #130 * This way the UI should be more responsive when processing a lot of files From db29fd049727e232551f66c67aa670ea9934cf54 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 26 Sep 2024 15:48:51 +0000 Subject: [PATCH 501/518] Release 1.3.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 6cb9ce8..ad3f52f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.3.1-SNAPSHOT +pluginVersion=1.3.1 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From e2570be66e16db040a625e69807a5223ccb8e4cb Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 26 Sep 2024 15:50:42 +0000 Subject: [PATCH 502/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ad3f52f..e51dd23 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.3.1 +pluginVersion=1.3.2-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.2 From 8e548b7027a67b20cffd3eb7741683435b403cc6 Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 26 Sep 2024 17:51:35 +0200 Subject: [PATCH 503/518] Remove outdated doc --- .../core/service/impl/AbstractSaveActionsService.java | 2 -- .../core/service/impl/SaveActionsDefaultService.java | 1 - .../saveactions/core/service/impl/SaveActionsJavaService.java | 1 - 3 files changed, 4 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java index d22234f..a05245e 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/AbstractSaveActionsService.java @@ -48,8 +48,6 @@ * The psi files are ide wide, that means they are shared between projects (and editor windows), so we need to check if * the file is physically in that project before reformatting, or else the file is formatted twice and intellij will ask * to confirm unlocking of non-project file in the other project, see {@link Engine} for more details. - * - * @since 2.4.0 */ abstract class AbstractSaveActionsService implements SaveActionsService { diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java index 75a1d14..7fbe7aa 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsDefaultService.java @@ -17,7 +17,6 @@ *

    * * @see AbstractSaveActionsService - * @since 2.4.0 */ public final class SaveActionsDefaultService extends AbstractSaveActionsService { diff --git a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java index 94cff5d..600d3bb 100644 --- a/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java +++ b/src/main/java/software/xdev/saveactions/core/service/impl/SaveActionsJavaService.java @@ -18,7 +18,6 @@ *

    * * @see AbstractSaveActionsService - * @since 2.4.0 */ public final class SaveActionsJavaService extends AbstractSaveActionsService { From 8e07ea8aa13178877b80a1ac34381832ee55281c Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 11 Oct 2024 08:37:35 +0200 Subject: [PATCH 504/518] Bump version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a289275..3d23510 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.3.2-SNAPSHOT +pluginVersion=1.4.0-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=2024.2.3 From 6ff9372108555e4a38a3e08729d5ab71d391c92e Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 11 Oct 2024 08:37:48 +0200 Subject: [PATCH 505/518] Switch to 243 EAP --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3d23510..964a0a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,8 +5,8 @@ pluginName=Save Actions X pluginVersion=1.4.0-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC -platformVersion=2024.2.3 -platformSinceBuild=242 +platformVersion=243.19420.21 +platformSinceBuild=243 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformBundledPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 platformBundledPlugins=com.intellij.java From 0daa31c0f147111a7518b18412b474d379cd0479 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 11 Oct 2024 09:05:35 +0200 Subject: [PATCH 506/518] Fix deprecation of ``AnActionEvent.createFromAnAction`` See #148 --- .../processors/BuildProcessor.java | 9 ++++++++- .../core/action/ShortcutActionConstants.java | 20 ++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index 361713c..71b55b1 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -17,6 +17,7 @@ import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.HotSwapUI; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionUiKind; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; @@ -83,7 +84,13 @@ public enum BuildProcessor implements Processor .add(EDITOR, FileEditorManager.getInstance(project).getSelectedTextEditor()) .setParent(null) .build(); - AnActionEvent event = AnActionEvent.createFromAnAction(anAction, null, UNKNOWN, dataContext); + AnActionEvent event = AnActionEvent.createEvent( + dataContext, + anAction.getTemplatePresentation(), + UNKNOWN, + ActionUiKind.NONE, + null); + anAction.actionPerformed(event); } }) diff --git a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java index acd6b61..1248ebd 100644 --- a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java @@ -6,6 +6,7 @@ import java.util.function.Consumer; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionUiKind; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; @@ -16,26 +17,31 @@ public interface ShortcutActionConstants { - - Consumer SAVE_ACTION_SHORTCUT_MANAGER = (fixture) -> + Consumer SAVE_ACTION_SHORTCUT_MANAGER = fixture -> WriteCommandAction.writeCommandAction(fixture.getProject()).run(() -> runFixure(fixture)); - static void runFixure(CodeInsightTestFixture fixture) + static void runFixure(final CodeInsightTestFixture fixture) { // set modification timestamp ++ fixture.getFile().clearCaches(); - ActionManager actionManager = ActionManager.getInstance(); - AnAction action = actionManager.getAction(ShortcutAction.class.getName()); + final ActionManager actionManager = ActionManager.getInstance(); + final AnAction action = actionManager.getAction(ShortcutAction.class.getName()); - DataContext dataContext = SimpleDataContext.builder() + final DataContext dataContext = SimpleDataContext.builder() .add(PROJECT, fixture.getProject()) .add(PSI_FILE, fixture.getFile()) .setParent(null) .build(); // call plugin on document - AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "save-actions", dataContext); + final AnActionEvent event = AnActionEvent.createEvent( + dataContext, + action.getTemplatePresentation(), + "save-actions", + ActionUiKind.NONE, + null); + new ShortcutAction().actionPerformed(event); } } From 2058cccacc1c1c2cd4a22ccbd1f419b5d8fde51b Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 11 Oct 2024 09:06:30 +0200 Subject: [PATCH 507/518] Remove workaround for project load See #152 --- .../SaveActionsDocumentManagerListener.java | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java index 9f1008a..2b7071d 100644 --- a/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java +++ b/src/main/java/software/xdev/saveactions/core/listener/SaveActionsDocumentManagerListener.java @@ -5,9 +5,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; -import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -43,12 +41,6 @@ public void beforeAllDocumentsSaving() LOGGER.debug( "[+] Start SaveActionsDocumentManagerListener#beforeAllDocumentsSaving, " + this.project.getName()); - if(REQUIRES_PROJECT_LOAD_IGNORE_WORKAROUND && isInvokedFromProjectLoadBefore243()) - { - LOGGER.debug("Ignoring due to PROJECT_LOAD_IGNORE_WORKAROUND"); - return; - } - final List unsavedDocuments = Arrays.asList(FileDocumentManager.getInstance().getUnsavedDocuments()); if(!unsavedDocuments.isEmpty()) { @@ -83,38 +75,4 @@ private synchronized void initPsiDocManager() this.psiDocumentManager = PsiDocumentManager.getInstance(this.project); } } - - // region PROJECT_LOAD_IGNORE_WORKAROUND - // https://github.com/xdev-software/intellij-plugin-save-actions/issues/145 - private static final boolean REQUIRES_PROJECT_LOAD_IGNORE_WORKAROUND = - determineIfRequiresProjectLoadIgnoreWorkaround(); - - @SuppressWarnings("checkstyle:MagicNumber") - static boolean determineIfRequiresProjectLoadIgnoreWorkaround() - { - try - { - // Problem was fixed in 2024.3 - return ApplicationInfo.getInstance().getBuild().getBaselineVersion() < 243; - } - catch(final Exception ex) - { - LOGGER.warn("Failed to determine IDE version", ex); - return false; - } - } - - @SuppressWarnings("checkstyle:MagicNumber") - static boolean isInvokedFromProjectLoadBefore243() - { - // The invoking method ProjectSettingsTracker$submitSettingsFilesRefresh is usually at index 17 and 18 - return Stream.of(Thread.currentThread().getStackTrace()) - .map(StackTraceElement::getClassName) - .skip(16) - .limit(5) - .anyMatch(s -> s.startsWith( - "com.intellij.openapi.externalSystem.autoimport.ProjectSettingsTracker$submitSettingsFilesRefresh")); - } - - // endregion } From 75f9a67c13335309c480ea4267c06b4afefe4d15 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 11 Oct 2024 09:08:41 +0200 Subject: [PATCH 508/518] Fix deprecation of ``ComponentWithBrowseButton.addBrowseFolderListener`` See #153 --- .../java/software/xdev/saveactions/ui/java/IdeSupportPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java index 925234b..742087a 100644 --- a/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java +++ b/src/main/java/software/xdev/saveactions/ui/java/IdeSupportPanel.java @@ -78,7 +78,7 @@ private TextFieldWithBrowseButton getPath(final String configurationPath) field.getField().setEnabled(false); field.getField().setText(configurationPath); final TextFieldWithBrowseButton resultPath = new TextFieldWithBrowseButton(field.getField()); - resultPath.addBrowseFolderListener(null, null, null, descriptor, TEXT_FIELD_WHOLE_TEXT); + resultPath.addBrowseFolderListener(null, descriptor, TEXT_FIELD_WHOLE_TEXT); return resultPath; } From 8b12a4eae27a9c424fcc33cfaa273faf53ad1dfc Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 11 Oct 2024 09:22:49 +0200 Subject: [PATCH 509/518] Add missing clone --- .../software/xdev/saveactions/processors/BuildProcessor.java | 2 +- .../xdev/saveactions/core/action/ShortcutActionConstants.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index 71b55b1..013710a 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -86,7 +86,7 @@ public enum BuildProcessor implements Processor .build(); AnActionEvent event = AnActionEvent.createEvent( dataContext, - anAction.getTemplatePresentation(), + anAction.getTemplatePresentation().clone(), UNKNOWN, ActionUiKind.NONE, null); diff --git a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java index 1248ebd..1133ca6 100644 --- a/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java +++ b/src/test/java/software/xdev/saveactions/core/action/ShortcutActionConstants.java @@ -37,7 +37,7 @@ static void runFixure(final CodeInsightTestFixture fixture) // call plugin on document final AnActionEvent event = AnActionEvent.createEvent( dataContext, - action.getTemplatePresentation(), + action.getTemplatePresentation().clone(), "save-actions", ActionUiKind.NONE, null); From 460605ed84c43ad7873eafb7a762a9a33e7fb07d Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 31 Oct 2024 12:36:13 +0100 Subject: [PATCH 510/518] Update to latest EAP --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 964a0a5..2d81635 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ pluginName=Save Actions X pluginVersion=1.4.0-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC -platformVersion=243.19420.21 +platformVersion=243.21565.23 platformSinceBuild=243 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformBundledPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 From c211a45cf5cc6fc47c734247c7940832d4d82bed Mon Sep 17 00:00:00 2001 From: AB Date: Thu, 31 Oct 2024 12:36:05 +0100 Subject: [PATCH 511/518] Fix override-only violation: ``AnAction.actionPerformed(AnActionEvent)`` See #178 --- .../xdev/saveactions/processors/BuildProcessor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java index 013710a..de90cd2 100644 --- a/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java +++ b/src/main/java/software/xdev/saveactions/processors/BuildProcessor.java @@ -21,7 +21,9 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.actionSystem.impl.SimpleDataContext; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompilerManager; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; @@ -91,7 +93,9 @@ public enum BuildProcessor implements Processor ActionUiKind.NONE, null); - anAction.actionPerformed(event); + // Run Action on EDT thread + ApplicationManager.getApplication().invokeLater(() -> + ActionUtil.performActionDumbAwareWithCallbacks(anAction, event)); } }) { From 0cee715c35d64d6a869a474aca116b335556bce7 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 11 Nov 2024 08:12:25 +0000 Subject: [PATCH 512/518] Release 1.4.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2d81635..7527c6f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.4.0-SNAPSHOT +pluginVersion=1.4.0 # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=243.21565.23 From 7be86ac609de20f415ca6a9e0d1753500318c486 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 11 Nov 2024 08:15:08 +0000 Subject: [PATCH 513/518] Preparing for next development iteration --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 7527c6f..27ed25c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ pluginGroup=software.xdev.saveactions pluginName=Save Actions X # SemVer format -> https://semver.org -pluginVersion=1.4.0 +pluginVersion=1.4.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC platformVersion=243.21565.23 From 0eabbe654cc5ba2365234dc835fa8964d4548882 Mon Sep 17 00:00:00 2001 From: AB Date: Tue, 12 Nov 2024 09:36:49 +0100 Subject: [PATCH 514/518] Update changelog Fixes #186 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6730e57..619fc11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.0 +* Dropped support for IntelliJ versions < 2024.3 + * This is required to fix a few deprecations and remove some workarounds #171 + ## 1.3.1 * Fix IDE hang when projects with different "Process files asynchronously" are open #160 From c37e735ab9a486e2ad3252e75ec3c22f74804ba2 Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 18 Nov 2024 14:11:38 +0100 Subject: [PATCH 515/518] Update to stable IntelliJ version Fix #182 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 27ed25c..9b41416 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ pluginName=Save Actions X pluginVersion=1.4.1-SNAPSHOT # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType=IC -platformVersion=243.21565.23 +platformVersion=2024.3 platformSinceBuild=243 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformBundledPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 From 28fbb78aaaf60d5291048723cabb2cc9eed88843 Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 6 Dec 2024 10:56:34 +0100 Subject: [PATCH 516/518] Clarify EPF file in docs Fixes #194 --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 01e9203..e1dda6c 100644 --- a/USAGE.md +++ b/USAGE.md @@ -68,7 +68,7 @@ The actions are implemented in the form of "quick lists", an IDE function that i | --- | --- | File path inclusions | Add / remove file path inclusions (by default, everything included). The Java regular expressions match the whole file name from the project root. Include only Java files: `.*\.java`. | File path exclusions | Add / remove file path exclusions to ignore files (overrides inclusions). The Java regular expressions match the whole file name from the project root. Exclude 'Main.java' only in root folder: `Main\.java`. Exclude file 'Foo.java' only in folder 'src': `src/Foo\.java`. Exclude all xml files in any folder: `.*/.*\.xml` -| Use external Eclipse configuration | Add external configuration file ".epf" to read settings from. This will update the current settings and use only the ".epf" file content. Use "reset" button to remove +| Use external Eclipse configuration | Add external configuration file ".epf" to read/overwrite settings from. This will overwrite the current settings with the ".epf" file content - if the corresponding setting is present (Please note that the checkboxes in the settings UI are not updated and used as "fallback" values!). Use "reset" button to remove ### Java fixes From f3e2f3087e38fb40334751d110f424ae1f3b92ab Mon Sep 17 00:00:00 2001 From: AB Date: Fri, 6 Dec 2024 11:00:39 +0100 Subject: [PATCH 517/518] Revert "Clarify EPF file in docs" This reverts commit 28fbb78aaaf60d5291048723cabb2cc9eed88843. --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index e1dda6c..01e9203 100644 --- a/USAGE.md +++ b/USAGE.md @@ -68,7 +68,7 @@ The actions are implemented in the form of "quick lists", an IDE function that i | --- | --- | File path inclusions | Add / remove file path inclusions (by default, everything included). The Java regular expressions match the whole file name from the project root. Include only Java files: `.*\.java`. | File path exclusions | Add / remove file path exclusions to ignore files (overrides inclusions). The Java regular expressions match the whole file name from the project root. Exclude 'Main.java' only in root folder: `Main\.java`. Exclude file 'Foo.java' only in folder 'src': `src/Foo\.java`. Exclude all xml files in any folder: `.*/.*\.xml` -| Use external Eclipse configuration | Add external configuration file ".epf" to read/overwrite settings from. This will overwrite the current settings with the ".epf" file content - if the corresponding setting is present (Please note that the checkboxes in the settings UI are not updated and used as "fallback" values!). Use "reset" button to remove +| Use external Eclipse configuration | Add external configuration file ".epf" to read settings from. This will update the current settings and use only the ".epf" file content. Use "reset" button to remove ### Java fixes From bf6e49511b23ca392e73555717924560a61e232b Mon Sep 17 00:00:00 2001 From: AB Date: Mon, 9 Dec 2024 08:35:02 +0100 Subject: [PATCH 518/518] Update docs to better describe how EPF file is handled See #194 --- USAGE.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 01e9203..06a60f6 100644 --- a/USAGE.md +++ b/USAGE.md @@ -103,7 +103,11 @@ Support for other JetBrains products should also be automatically available but ### Eclipse configuration support -The save-actions plugin supports Eclipse configuration `.epf` files by the [Workspace Mechanic](https://marketplace.eclipse.org/content/workspace-mechanic) Eclipse plugin (Java IDE only). You can specify a path to an Eclipse configuration file in the "Eclipse support" settings section to import it. The plugin will load the content of the file in the plugin configuration, and disable the plugin configuration options (the checkbox will be grayed out). Use the "reset" button to remove the import. +The save-actions plugin supports Eclipse configuration `.epf` files by the [Workspace Mechanic](https://marketplace.eclipse.org/content/workspace-mechanic) Eclipse plugin (Java IDE only). +You can specify a path to an Eclipse configuration file in the "Eclipse support" settings section to import it. +The plugin will load the content of the file and configure the corresponding options. +Please note that not all plugin options have corresponding ``.epf`` options and therefore might not be configured. +Use the "reset" button to remove the import. The plugin will stay in sync with your Eclipse configuration file. Not every features are present on either side, but the ones that are in common are supported.