diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index aa9d22bc2..5d93c95d8 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -4,6 +4,7 @@
+
diff --git a/actions/src/main/java/com/itsaky/androidide/actions/ActionItem.kt b/actions/src/main/java/com/itsaky/androidide/actions/ActionItem.kt
index 6dc4aa1b3..c4e53a23a 100644
--- a/actions/src/main/java/com/itsaky/androidide/actions/ActionItem.kt
+++ b/actions/src/main/java/com/itsaky/androidide/actions/ActionItem.kt
@@ -54,7 +54,9 @@ interface ActionItem {
*
* @param data The data containing various information about the event.
*/
- fun postExec(data: ActionData, result: Any) = Unit
+ fun postExec(data: ActionData, result: Any) = Any()
+
+ fun getShowAsActionFlags(data: ActionData): Int = -1
/** Location where an action item will be shown. */
enum class Location(val id: String) {
diff --git a/actions/src/main/java/com/itsaky/androidide/actions/internal/DefaultActionsRegistry.kt b/actions/src/main/java/com/itsaky/androidide/actions/internal/DefaultActionsRegistry.kt
index 3bc9ab8e0..8dd4f573b 100644
--- a/actions/src/main/java/com/itsaky/androidide/actions/internal/DefaultActionsRegistry.kt
+++ b/actions/src/main/java/com/itsaky/androidide/actions/internal/DefaultActionsRegistry.kt
@@ -125,6 +125,10 @@ class DefaultActionsRegistry : ActionsRegistry() {
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
}
+ if (action.getShowAsActionFlags(data) != -1) {
+ item.setShowAsAction(action.getShowAsActionFlags(data))
+ }
+
if (action !is ActionMenu) {
item.setOnMenuItemClickListener {
if (action.requiresUIThread) {
@@ -154,8 +158,8 @@ class DefaultActionsRegistry : ActionsRegistry() {
}
ThreadUtils.runOnUiThread {
- action.postExec(data, result)
- notifyActionExec(action, result)
+ action.postExec(data, result ?: false)
+ notifyActionExec(action, result ?: false)
}
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/EditorActivity.java b/app/src/main/java/com/itsaky/androidide/EditorActivity.java
index b72994686..53ecbe1d2 100755
--- a/app/src/main/java/com/itsaky/androidide/EditorActivity.java
+++ b/app/src/main/java/com/itsaky/androidide/EditorActivity.java
@@ -83,7 +83,6 @@ import com.itsaky.androidide.fragments.sheets.OptionsListFragment;
import com.itsaky.androidide.fragments.sheets.ProgressSheet;
import com.itsaky.androidide.fragments.sheets.TextSheetFragment;
import com.itsaky.androidide.handlers.BuildServiceHandler;
-import com.itsaky.androidide.utils.EditorActivityActions;
import com.itsaky.androidide.handlers.FileOptionsHandler;
import com.itsaky.androidide.handlers.IDEHandler;
import com.itsaky.androidide.interfaces.DiagnosticClickListener;
@@ -103,6 +102,7 @@ import com.itsaky.androidide.services.builder.IDEService;
import com.itsaky.androidide.shell.ShellServer;
import com.itsaky.androidide.tasks.TaskExecutor;
import com.itsaky.androidide.utils.DialogUtils;
+import com.itsaky.androidide.utils.EditorActivityActions;
import com.itsaky.androidide.utils.EditorBottomSheetBehavior;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.LSPUtils;
@@ -113,6 +113,7 @@ import com.itsaky.androidide.viewmodel.EditorViewModel;
import com.itsaky.androidide.views.MaterialBanner;
import com.itsaky.androidide.views.SymbolInputView;
import com.itsaky.androidide.views.editor.CodeEditorView;
+import com.itsaky.androidide.views.editor.IDEEditor;
import com.itsaky.inflater.values.ValuesTableFactory;
import com.itsaky.lsp.java.models.JavaServerConfiguration;
import com.itsaky.lsp.java.models.JavaServerSettings;
@@ -223,7 +224,6 @@ public class EditorActivity extends StudioActivity
this::onGetUIDesignerResult);
EditorActivityActions.register(this);
- ensureToolbarMenu();
}
private void setupDrawerToggle() {
@@ -354,7 +354,6 @@ public class EditorActivity extends StudioActivity
super.onResume();
EditorActivityActions.register(this);
- ensureToolbarMenu();
try {
checkForCompilerModule();
@@ -377,91 +376,6 @@ public class EditorActivity extends StudioActivity
super.onDestroy();
}
- // @Override
- // @SuppressLint("AlwaysShowAction")
- // public boolean onPrepareOptionsMenu(Menu menu) {
- // for (int id : BUILD_IDS) {
- // MenuItem item = menu.findItem(id);
- // if (item != null) {
- // boolean enabled = getBuildService() != null &&
- // !getBuildService().isBuilding();
- // item.setEnabled(enabled);
- // item.getIcon().setAlpha(enabled ? 255 : 76);
- // }
- // }
- //
- // MenuItem run1 = menu.findItem(R.id.menuEditor_quickRun);
- // MenuItem run2 = menu.findItem(R.id.menuEditor_run);
- // MenuItem undo = menu.findItem(R.id.menuEditor_undo);
- // MenuItem redo = menu.findItem(R.id.menuEditor_redo);
- // MenuItem save = menu.findItem(R.id.menuEditor_save);
- // MenuItem def = menu.findItem(R.id.menuEditor_gotoDefinition);
- // MenuItem ref = menu.findItem(R.id.menuEditor_findReferences);
- // MenuItem comment = menu.findItem(R.id.menuEditor_commentLine);
- // MenuItem uncomment = menu.findItem(R.id.menuEditor_uncommentLine);
- // MenuItem findFile = menu.findItem(R.id.menuEditor_findFile);
- // MenuItem viewLayout = menu.findItem(R.id.menuEditor_viewLayout);
- //
- // if (KeyboardUtils.isSoftInputVisible(this)) {
- // run1.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- // run2.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- // undo.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- // redo.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- //
- // viewLayout.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- // } else {
- // run1.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- // run2.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- // undo.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- // redo.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- //
- // viewLayout.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- // }
- //
- // final var editor = getCurrentEditor();
- // final var file = editor != null ? editor.getFile() : null;
- // final var notNull = editor != null && file != null;
- // final var isJava = notNull && file.getName().endsWith(".java");
- // final var isXml = notNull && file.getName().endsWith(".xml");
- // final var filesModified = notNull && mViewModel != null &&
- // mViewModel.areFilesModified();
- // final var isLayout =
- // isXml
- // && file.getParentFile() != null
- // && Pattern.compile(FileOptionsHandler.LAYOUT_RES_PATH_REGEX)
- // .matcher(file.getParentFile().getAbsolutePath())
- // .matches();
- // final var nullableAlpha = notNull ? 255 : 76;
- // final var javaFileAlpha = isJava ? 255 : 76;
- // final var layoutFileAlpha = isLayout ? 255 : 76;
- // final var saveAlpha = filesModified ? 255 : 76;
- //
- // undo.setEnabled(notNull);
- // redo.setEnabled(notNull);
- // save.setEnabled(filesModified);
- // comment.setEnabled(notNull);
- // uncomment.setEnabled(notNull);
- // findFile.setEnabled(notNull);
- // def.setEnabled(isJava);
- // ref.setEnabled(isJava);
- //
- // undo.getIcon().setAlpha(nullableAlpha);
- // redo.getIcon().setAlpha(nullableAlpha);
- // save.getIcon().setAlpha(saveAlpha);
- // comment.getIcon().setAlpha(nullableAlpha);
- // uncomment.getIcon().setAlpha(nullableAlpha);
- // findFile.getIcon().setAlpha(nullableAlpha);
- // def.getIcon().setAlpha(javaFileAlpha);
- // ref.getIcon().setAlpha(javaFileAlpha);
- //
- // viewLayout.setEnabled(isLayout);
- // viewLayout.getIcon().setAlpha(layoutFileAlpha);
- // viewLayout.setShowAsActionFlags(
- // isLayout ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
- //
- // return true;
- // }
-
@SuppressLint("RestrictedApi")
@Override
public boolean onCreateOptionsMenu(Menu menu) {
@@ -473,13 +387,25 @@ public class EditorActivity extends StudioActivity
return true;
}
- public void ensureToolbarMenu() {
- final var menu = mBinding.editorToolbar.getMenu();
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ ensureToolbarMenu(menu);
+ return true;
+ }
+
+ public void ensureToolbarMenu(@NonNull Menu menu) {
menu.clear();
final var data = new ActionData();
+ final var currentEditor = getCurrentEditor();
data.put(Context.class, EditorActivity.this);
- data.put(CodeEditorView.class, getCurrentEditor());
+ data.put(CodeEditorView.class, currentEditor);
+
+ if (currentEditor != null) {
+ data.put(IDEEditor.class, currentEditor.getEditor());
+ data.put(File.class, currentEditor.getEditor().getFile());
+ }
+
ActionsRegistry.getInstance()
.fillMenu(
data,
@@ -668,7 +594,6 @@ public class EditorActivity extends StudioActivity
editorView.onEditorSelected();
mViewModel.setCurrentFile(position, editorView.getFile());
refreshSymbolInput(editorView);
- ensureToolbarMenu();
}
@Override
@@ -681,10 +606,6 @@ public class EditorActivity extends StudioActivity
editor.ensureWindowsDismissed();
}
}
-
- if (mViewModel.getOpenedFileCount() <= 0) {
- ensureToolbarMenu();
- }
}
@Override
@@ -929,7 +850,6 @@ public class EditorActivity extends StudioActivity
mBinding.editorContainer.setDisplayedChild(index);
- ensureToolbarMenu();
try {
return getEditorAtIndex(index);
} catch (Throwable th) {
@@ -994,7 +914,6 @@ public class EditorActivity extends StudioActivity
}
mBinding.tabs.requestLayout();
- ensureToolbarMenu();
}
public void closeAll() {
@@ -1031,8 +950,6 @@ public class EditorActivity extends StudioActivity
mBinding.tabs.requestLayout();
mBinding.editorContainer.removeAllViews();
- ensureToolbarMenu();
-
if (onSaved != null) {
onSaved.run();
}
@@ -1457,7 +1374,7 @@ public class EditorActivity extends StudioActivity
}
private void onSoftInputChanged() {
- ensureToolbarMenu();
+ invalidateOptionsMenu();
if (KeyboardUtils.isSoftInputVisible(this)) {
TransitionManager.beginDelayedTransition(mBinding.getRoot(), new Slide(Gravity.TOP));
symbolInput.setVisibility(View.VISIBLE);
diff --git a/app/src/main/java/com/itsaky/androidide/actions/BaseBuildAction.kt b/app/src/main/java/com/itsaky/androidide/actions/BaseBuildAction.kt
index 3a69a5648..5d2e7b7fe 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/BaseBuildAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/BaseBuildAction.kt
@@ -45,7 +45,7 @@ abstract class BaseBuildAction : EditorActivityAction() {
override fun postExec(data: ActionData, result: Any) {
val context = getActivity(data) ?: return
- context.ensureToolbarMenu()
+ context.invalidateOptionsMenu()
}
fun shouldPrepare() = visible && enabled
diff --git a/app/src/main/java/com/itsaky/androidide/actions/EditorRelatedAction.kt b/app/src/main/java/com/itsaky/androidide/actions/EditorRelatedAction.kt
index 928e99dd0..534f32b8f 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/EditorRelatedAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/EditorRelatedAction.kt
@@ -18,17 +18,29 @@
package com.itsaky.androidide.actions
import com.itsaky.androidide.views.editor.CodeEditorView
-import java.io.File
+import com.itsaky.androidide.views.editor.IDEEditor
/** @author Akash Yadav */
abstract class EditorRelatedAction : EditorActivityAction() {
- override fun prepare(data: ActionData) {
- val editor = getEditor(data)
- val file = data.get(File::class.java)
- visible = editor != null && file != null
+ override var requiresUIThread: Boolean = true
+
+ override fun prepare(data: ActionData) {
+ val editor =
+ getEditor(data)
+ ?: run {
+ visible = false
+ enabled = false
+ return
+ }
+
+ val file = editor.file
+
+ visible = file != null
enabled = visible
}
- fun getEditor(data: ActionData): CodeEditorView? = data.get(CodeEditorView::class.java)
+ fun getEditor(data: ActionData): IDEEditor? = data.get(IDEEditor::class.java)
+
+ fun getEditorView(data: ActionData): CodeEditorView? = data[CodeEditorView::class.java]
}
diff --git a/app/src/main/java/com/itsaky/androidide/actions/etc/FindInFileAction.kt b/app/src/main/java/com/itsaky/androidide/actions/etc/FindInFileAction.kt
index a5f7d8f3b..64bcbf903 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/etc/FindInFileAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/etc/FindInFileAction.kt
@@ -35,7 +35,7 @@ class FindInFileAction() : EditorRelatedAction() {
}
override fun execAction(data: ActionData): Boolean {
- val editor = getEditor(data) ?: return false
+ val editor = getEditorView(data) ?: return false
editor.beginSearch()
return true
}
diff --git a/app/src/main/java/com/itsaky/androidide/actions/etc/FindInProjectAction.kt b/app/src/main/java/com/itsaky/androidide/actions/etc/FindInProjectAction.kt
index 5246f5c86..8639cc89e 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/etc/FindInProjectAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/etc/FindInProjectAction.kt
@@ -26,6 +26,8 @@ import com.itsaky.androidide.actions.EditorActivityAction
/** @author Akash Yadav */
class FindInProjectAction() : EditorActivityAction() {
+ override var requiresUIThread: Boolean = true
+
constructor(context: Context) : this() {
label = context.getString(R.string.menu_find_project)
icon = ContextCompat.getDrawable(context, R.drawable.ic_search_project)
diff --git a/app/src/main/java/com/itsaky/androidide/actions/text/RedoAction.kt b/app/src/main/java/com/itsaky/androidide/actions/text/RedoAction.kt
index e5840683e..1f28ecd60 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/text/RedoAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/text/RedoAction.kt
@@ -17,12 +17,14 @@
package com.itsaky.androidide.actions.text
+import android.app.Activity
import android.content.Context
+import android.view.MenuItem
import androidx.core.content.ContextCompat
+import com.blankj.utilcode.util.KeyboardUtils
import com.itsaky.androidide.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.EditorRelatedAction
-import com.itsaky.androidide.views.editor.CodeEditorView
/** @author Akash Yadav */
class RedoAction() : EditorRelatedAction() {
@@ -34,14 +36,28 @@ class RedoAction() : EditorRelatedAction() {
override val id: String = "editor_redo"
- override fun execAction(data: ActionData): Boolean {
- val editor = data.get(CodeEditorView::class.java)
+ override fun prepare(data: ActionData) {
+ super.prepare(data)
- return if (editor != null) {
- editor.redo()
- true
+ if (!visible) {
+ return
+ }
+
+ val editor = getEditor(data)!!
+ enabled = editor.canRedo()
+ }
+
+ override fun execAction(data: ActionData): Boolean {
+ val editor = getEditor(data)!!
+ editor.redo()
+ return true
+ }
+
+ override fun getShowAsActionFlags(data: ActionData): Int {
+ return if (KeyboardUtils.isSoftInputVisible(data.get(Context::class.java) as Activity)) {
+ MenuItem.SHOW_AS_ACTION_IF_ROOM
} else {
- false
+ MenuItem.SHOW_AS_ACTION_NEVER
}
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/actions/text/UndoAction.kt b/app/src/main/java/com/itsaky/androidide/actions/text/UndoAction.kt
index a4fa3f9f9..5a28ae91a 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/text/UndoAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/text/UndoAction.kt
@@ -22,7 +22,6 @@ import androidx.core.content.ContextCompat
import com.itsaky.androidide.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.EditorRelatedAction
-import com.itsaky.androidide.views.editor.CodeEditorView
/** @author Akash Yadav */
class UndoAction() : EditorRelatedAction() {
@@ -34,8 +33,19 @@ class UndoAction() : EditorRelatedAction() {
icon = ContextCompat.getDrawable(context, R.drawable.ic_undo)
}
- override fun execAction(data: ActionData): Boolean {
- val editor = data.get(CodeEditorView::class.java)
+ override fun prepare(data: ActionData) {
+ super.prepare(data)
+
+ if (!visible) {
+ return
+ }
+
+ val editor = getEditor(data)!!
+ enabled = editor.canUndo()
+ }
+
+ override fun execAction(data: ActionData): Any {
+ val editor = getEditor(data)
return if (editor != null) {
editor.undo()
true
diff --git a/app/src/main/java/com/itsaky/androidide/handlers/BuildServiceHandler.java b/app/src/main/java/com/itsaky/androidide/handlers/BuildServiceHandler.java
index 07e27305d..0db3dc539 100755
--- a/app/src/main/java/com/itsaky/androidide/handlers/BuildServiceHandler.java
+++ b/app/src/main/java/com/itsaky/androidide/handlers/BuildServiceHandler.java
@@ -154,7 +154,6 @@ public class BuildServiceHandler extends IDEHandler implements BuildListener {
.getApp()
.getPrefManager()
.putBoolean(PreferenceManager.KEY_IS_FIRST_PROJECT_BUILD, false);
- activity().ensureToolbarMenu();
activity().getBinding().buildProgressIndicator.setVisibility(View.GONE);
}
@@ -173,7 +172,6 @@ public class BuildServiceHandler extends IDEHandler implements BuildListener {
.getApp()
.getPrefManager()
.putBoolean(PreferenceManager.KEY_IS_FIRST_PROJECT_BUILD, false);
- activity().ensureToolbarMenu();
activity().getBinding().buildProgressIndicator.setVisibility(View.GONE);
}
diff --git a/app/src/main/java/com/itsaky/androidide/views/editor/CodeEditorView.java b/app/src/main/java/com/itsaky/androidide/views/editor/CodeEditorView.java
index 3f3800165..45cb54978 100644
--- a/app/src/main/java/com/itsaky/androidide/views/editor/CodeEditorView.java
+++ b/app/src/main/java/com/itsaky/androidide/views/editor/CodeEditorView.java
@@ -34,6 +34,7 @@
package com.itsaky.androidide.views.editor;
import android.annotation.SuppressLint;
+import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -291,6 +292,10 @@ public class CodeEditorView extends FrameLayout {
// File must be set only after setting the language server
// This will make sure that textDocument/didOpen is sent
binding.editor.setFile(getFile());
+
+ if (getContext() instanceof Activity) {
+ ((Activity) getContext()).invalidateOptionsMenu();
+ }
}
private void configureEditorIfNeeded() {
diff --git a/app/src/main/java/com/itsaky/androidide/views/editor/IDEEditor.java b/app/src/main/java/com/itsaky/androidide/views/editor/IDEEditor.java
index ec2fc814d..bc8e781c2 100644
--- a/app/src/main/java/com/itsaky/androidide/views/editor/IDEEditor.java
+++ b/app/src/main/java/com/itsaky/androidide/views/editor/IDEEditor.java
@@ -16,6 +16,7 @@
*/
package com.itsaky.androidide.views.editor;
+import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
@@ -869,6 +870,10 @@ public class IDEEditor extends CodeEditor {
* @param event The content change event.
*/
private void handleContentChange(ContentChangeEvent event, Unsubscribe unsubscribe) {
+ if (getContext() instanceof Activity) {
+ ((Activity) getContext()).invalidateOptionsMenu();
+ }
+
if (getFile() == null || mLanguageServer == null) {
return;
}
diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/DiagnosticsCodeActionProvider.java b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/DiagnosticsCodeActionProvider.java
index 0d6cc7b9b..b5c16f6e4 100644
--- a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/DiagnosticsCodeActionProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/DiagnosticsCodeActionProvider.java
@@ -24,7 +24,6 @@ import static com.itsaky.lsp.java.utils.CodeActionUtils.extractRange;
import static com.itsaky.lsp.java.utils.CodeActionUtils.findClassNeedingConstructor;
import static com.itsaky.lsp.java.utils.CodeActionUtils.findMethod;
import static com.itsaky.lsp.java.utils.CodeActionUtils.findPosition;
-import static com.itsaky.lsp.java.utils.CodeActionUtils.unwrapJCDiagnostic;
import android.text.TextUtils;
import android.util.Pair;
@@ -36,13 +35,11 @@ import com.itsaky.lsp.java.compiler.CompileTask;
import com.itsaky.lsp.java.compiler.CompilerProvider;
import com.itsaky.lsp.java.compiler.SynchronizedTask;
import com.itsaky.lsp.java.rewrite.AddException;
-import com.itsaky.lsp.java.rewrite.AddImport;
import com.itsaky.lsp.java.rewrite.AddSuppressWarningAnnotation;
import com.itsaky.lsp.java.rewrite.ConvertFieldToBlock;
import com.itsaky.lsp.java.rewrite.ConvertVariableToStatement;
import com.itsaky.lsp.java.rewrite.CreateMissingMethod;
import com.itsaky.lsp.java.rewrite.GenerateRecordConstructor;
-import com.itsaky.lsp.java.rewrite.ImplementAbstractMethods;
import com.itsaky.lsp.java.rewrite.RemoveClass;
import com.itsaky.lsp.java.rewrite.RemoveException;
import com.itsaky.lsp.java.rewrite.RemoveMethod;
@@ -51,7 +48,6 @@ import com.itsaky.lsp.java.utils.MethodPtr;
import com.itsaky.lsp.models.CodeActionItem;
import com.itsaky.lsp.models.DiagnosticItem;
import com.itsaky.lsp.models.Range;
-import com.sun.tools.javac.util.JCDiagnostic;
import java.nio.file.Path;
import java.time.Instant;
@@ -61,9 +57,6 @@ import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
-
/**
* Provides code actions for diagnostics.
*
@@ -149,8 +142,6 @@ public class DiagnosticsCodeActionProvider implements ActionProvider {
return handleUnreportedException(task, d);
case "compiler.err.var.not.initialized.in.default.constructor":
return handleVarNotInitialized(task, d);
- case "compiler.err.does.not.override.abstract":
- return handleDoesNotOverrideAbstract(d);
case "compiler.err.cant.resolve.location.args":
return handleMissingMethod(task, file, d);
default:
@@ -168,23 +159,6 @@ public class DiagnosticsCodeActionProvider implements ActionProvider {
return Collections.singletonList(Pair.create(title, rewrite));
}
- @NonNull
- private List> handleDoesNotOverrideAbstract(@NonNull DiagnosticItem d) {
- Rewrite rewrite;
- String title;
- //noinspection unchecked
- final Diagnostic extends JavaFileObject> diagnostic =
- (Diagnostic extends JavaFileObject>) d.getExtra();
- JCDiagnostic jcDiagnostic = unwrapJCDiagnostic(diagnostic);
- if (jcDiagnostic == null) {
- return Collections.singletonList(Pair.create("", null));
- }
-
- rewrite = new ImplementAbstractMethods(jcDiagnostic);
- title = "Implement abstract methods";
- return Collections.singletonList(Pair.create(title, rewrite));
- }
-
@NonNull
private List> handleVarNotInitialized(
CompileTask task, @NonNull DiagnosticItem d) {
@@ -199,7 +173,7 @@ public class DiagnosticsCodeActionProvider implements ActionProvider {
title = "Generate constructor";
return Collections.singletonList(Pair.create(title, rewrite));
}
-
+
@NonNull
private List> handleUnreportedException(
CompileTask task, @NonNull DiagnosticItem d) {
diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/ImplementAbstractMethodsAction.kt b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/ImplementAbstractMethodsAction.kt
index f3320c9a4..5b88df7d4 100644
--- a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/ImplementAbstractMethodsAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/ImplementAbstractMethodsAction.kt
@@ -31,8 +31,8 @@ import javax.tools.JavaFileObject
class ImplementAbstractMethodsAction : BaseCodeAction() {
override val id: String = "lsp_java_implementAbstractMethods"
override var label: String = "Implement abstract method(s)"
- private val log = Logger.newInstance(javaClass.simpleName)
private var diagnosticCode = "compiler.err.does.not.override.abstract"
+ private val log = Logger.newInstance(javaClass.simpleName)
@Suppress("UNCHECKED_CAST")
override fun prepare(data: ActionData) {
diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt
index 8730c2eeb..e37b58f45 100644
--- a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/JavaCodeActionsMenu.kt
@@ -26,5 +26,6 @@ class JavaCodeActionsMenu : CodeActionsMenu() {
addAction(UncommentAction())
addAction(AddImportAction())
addAction(ImplementAbstractMethodsAction())
+ addAction(VariableToStatementAction())
}
}
diff --git a/lsp/java/src/main/java/com/itsaky/lsp/java/actions/VariableToStatementAction.kt b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/VariableToStatementAction.kt
new file mode 100644
index 000000000..e955d11fb
--- /dev/null
+++ b/lsp/java/src/main/java/com/itsaky/lsp/java/actions/VariableToStatementAction.kt
@@ -0,0 +1,81 @@
+/*
+ * This file is part of AndroidIDE.
+ *
+ * AndroidIDE is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AndroidIDE is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
+
+package com.itsaky.lsp.java.actions
+
+import com.itsaky.androidide.actions.ActionData
+import com.itsaky.androidide.utils.Logger
+import com.itsaky.lsp.java.JavaLanguageServer
+import com.itsaky.lsp.java.rewrite.ConvertVariableToStatement
+import com.itsaky.lsp.java.utils.CodeActionUtils.findPosition
+import com.itsaky.lsp.models.DiagnosticItem
+import java.io.File
+
+/** @author Akash Yadav */
+class VariableToStatementAction : BaseCodeAction() {
+ override val id: String = "lsp_java_variableToStatement"
+ override var label: String = "Convert to statement"
+ private val diagnosticCode = "unused_local"
+ private val log = Logger.newInstance(javaClass.simpleName)
+
+ @Suppress("UNCHECKED_CAST")
+ override fun prepare(data: ActionData) {
+ super.prepare(data)
+
+ if (!visible) {
+ return
+ }
+
+ if (!hasRequiredData(
+ data, JavaLanguageServer::class.java, DiagnosticItem::class.java, File::class.java)) {
+ markInvisible()
+ return
+ }
+
+ val diagnostic = data.get(DiagnosticItem::class.java)!!
+ if (diagnosticCode != diagnostic.code) {
+ markInvisible()
+ return
+ }
+
+ visible = true
+ enabled = true
+ }
+
+ override fun execAction(data: ActionData): Any {
+ val diagnostic = data[DiagnosticItem::class.java]!!
+ val server = data[JavaLanguageServer::class.java]!!
+ val compiler = server.compiler!!
+ val path = requirePath(data)
+
+ return compiler.compile(path).get {
+ ConvertVariableToStatement(path, findPosition(it, diagnostic.range.start))
+ }
+ }
+
+ override fun postExec(data: ActionData, result: Any) {
+ if (result !is ConvertVariableToStatement) {
+ log.warn("Unable to convert variable to statement")
+ return
+ }
+
+ val file = data[File::class.java]
+ val server = data[JavaLanguageServer::class.java]!!
+ val client = server.client!!
+ client.performCodeAction(file, result.asCodeActions(server.compiler, label))
+ }
+}