Refactored the actions API

This commit is contained in:
Akash Yadav
2022-10-16 19:23:33 +05:30
parent b183049b96
commit 7b15d3e1ca
40 changed files with 319 additions and 153 deletions
+2 -1
View File
@@ -32,10 +32,11 @@ android {
dependencies {
implementation project (':common')
implementation common.editor
implementation common.kotlin
implementation common.utilcode
implementation androidx.ktx
implementation common.kotlin
implementation google.material
}
repositories {
@@ -64,27 +64,6 @@ interface ActionItem {
*/
fun getShowAsActionFlags(data: ActionData): Int = -1
/**
* Checks if the given [ActionData] has instances of the given [types].
*
* @param data The data to check.
* @param types The type of objects to look for.
* @return `true` if the [data] has the given [types], `false` otherwise.
*/
fun hasRequiredData(data: ActionData, vararg types: Class<*>): Boolean {
for (type in types) {
data.get(type) ?: return false
}
return true
}
/** Marks this action item as invisible. */
fun markInvisible() {
visible = false
enabled = false
}
/**
* Create custom action view for this action item.
*
@@ -29,6 +29,15 @@ interface ActionMenu : ActionItem {
fun removeAction(action: ActionItem) = children.remove(action)
/**
* Find the action item with the given action ID.
*
* @return The action item or `null` if not found.
*/
fun findAction(id: String): ActionItem? {
return children.find { it.id == id }
}
/** Action menus are not supposed to perform any action */
override fun execAction(data: ActionData): Boolean {
return false
@@ -0,0 +1,69 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions
import android.content.Context
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.github.rosemoe.sora.widget.CodeEditor
import java.io.File
import java.nio.file.Path
fun ActionItem.requireContext(data: ActionData): Context {
return data.get(Context::class.java)
?: throw IllegalArgumentException("No context instance provided")
}
fun ActionItem.requireFile(data: ActionData): File {
return data.get(File::class.java) ?: throw IllegalArgumentException("No file instance provided")
}
fun ActionItem.requirePath(data: ActionData): Path {
return requireFile(data).toPath()
}
fun ActionItem.requireEditor(data: ActionData): CodeEditor {
return data.get(CodeEditor::class.java)
?: throw IllegalArgumentException("An editor instance is required but none was provided")
}
fun ActionItem.newDialogBuilder(data: ActionData): MaterialAlertDialogBuilder {
val klass = Class.forName("com.itsaky.androidide.utils.DialogUtils")
val method = klass.getDeclaredMethod("newMaterialDialogBuilder", Context::class.java)
return method.invoke(null, data.get(Context::class.java)!!) as MaterialAlertDialogBuilder
}
/**
* Checks if the given [ActionData] has instances of the given [types].
*
* @param data The data to check.
* @param types The type of objects to look for.
* @return `true` if the [data] has the given [types], `false` otherwise.
*/
fun ActionItem.hasRequiredData(data: ActionData, vararg types: Class<*>): Boolean {
for (type in types) {
data.get(type) ?: return false
}
return true
}
/** Marks this action item as invisible. */
fun ActionItem.markInvisible() {
visible = false
enabled = false
}
@@ -23,6 +23,7 @@ import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.ActionMenu
import com.itsaky.androidide.actions.ActionsRegistry
import com.itsaky.androidide.actions.locations.CodeActionsMenu
import com.itsaky.androidide.utils.ILogger
import java.util.concurrent.*
@@ -36,6 +37,10 @@ class DefaultActionsRegistry : ActionsRegistry() {
private val log = ILogger.newInstance("DefaultActionsRegistry")
private val actions: MutableMap<String, MutableMap<String, ActionItem>> = mutableMapOf()
private val listeners = mutableSetOf<ActionExecListener>()
init {
registerAction(CodeActionsMenu)
}
override fun getActions(location: ActionItem.Location): MutableMap<String, ActionItem> {
if (actions[location.id] == null) {
@@ -15,7 +15,7 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.lsp.actions
package com.itsaky.androidide.actions.locations
import android.content.Context
import android.graphics.drawable.Drawable
@@ -25,11 +25,9 @@ import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.ActionMenu
/** @author Akash Yadav */
open class CodeActionsMenu : ActionMenu {
companion object {
const val ID = "editor_text_codeActions"
}
object CodeActionsMenu : ActionMenu {
const val ID = "editor_text_codeActions"
override val children: MutableSet<ActionItem> = mutableSetOf()
override val id: String = ID
+2 -1
View File
@@ -70,4 +70,5 @@
}
# Used in preferences
-keep enum com.itsaky.androidide.lsp.xml.models.EmptyElements { *; }
-keep enum com.itsaky.androidide.lsp.xml.models.EmptyElements { *; }
-keep enum com.itsaky.androidide.xml.permissions.Permission { *; }
@@ -22,6 +22,7 @@ import androidx.core.content.ContextCompat
import com.itsaky.androidide.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.EditorActivityAction
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.lookup.Lookup
import com.itsaky.androidide.projects.builder.BuildService
import com.itsaky.androidide.utils.ILogger
@@ -22,6 +22,7 @@ import androidx.core.content.ContextCompat
import com.itsaky.androidide.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.EditorActivityAction
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.projects.ProjectManager
/** @author Akash Yadav */
View File
@@ -0,0 +1,31 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.lsp.actions
import com.itsaky.androidide.actions.ActionItem
/**
* Provides code actions for the language implementation.
*
* @author Akash Yadav
*/
interface IActionsMenuProvider {
/** Get the action items. */
val actions: List<ActionItem>
}
@@ -20,9 +20,11 @@ package com.itsaky.androidide.lsp.util;
import static com.itsaky.androidide.utils.ILogger.newInstance;
import com.itsaky.androidide.actions.ActionItem;
import com.itsaky.androidide.actions.ActionMenu;
import com.itsaky.androidide.actions.ActionsRegistry;
import com.itsaky.androidide.actions.locations.CodeActionsMenu;
import com.itsaky.androidide.lsp.actions.IActionsMenuProvider;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.lsp.actions.CodeActionsMenu;
/**
* @author Akash Yadav
@@ -31,19 +33,22 @@ public class LSPEditorActions {
private static final ILogger LOG = newInstance("LSPEditorActions");
public static void ensureActionsMenuRegistered(Class<? extends CodeActionsMenu> klass) {
public static void ensureActionsMenuRegistered(IActionsMenuProvider provider) {
final var registry = ActionsRegistry.getInstance();
final var action =
registry.findAction(ActionItem.Location.EDITOR_TEXT_ACTIONS, CodeActionsMenu.ID);
if (action == null) {
try {
final var constructor = klass.getDeclaredConstructor();
final var instance = constructor.newInstance();
registry.registerAction(instance);
} catch (Throwable throwable) {
LOG.error("Unable to register code actions item to editor text actions");
LOG.error("Cannot find registered editor actions menu");
return;
}
final var editorActions = (ActionMenu) action;
for (final var item : provider.getActions()) {
if (editorActions.findAction(item.getId()) != null) {
continue;
}
editorActions.addAction(item);
}
}
}
@@ -141,7 +141,7 @@ public class JavaLanguageServer implements ILanguageServer {
@Override
public void setupWithProject(@NonNull final Project project) {
LSPEditorActions.ensureActionsMenuRegistered(JavaCodeActionsMenu.class);
LSPEditorActions.ensureActionsMenuRegistered(JavaCodeActionsMenu.INSTANCE);
// Once we have project initialized
// Destory the NO_MODULE_COMPILER instance
@@ -19,9 +19,11 @@ package com.itsaky.androidide.lsp.java.actions
import android.content.Context
import android.graphics.drawable.Drawable
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.lsp.api.ILanguageServerRegistry
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.JavaLanguageServer
@@ -29,15 +31,13 @@ import com.itsaky.androidide.lsp.java.rewrite.Rewrite
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.DocumentUtils
import com.itsaky.androidide.utils.ILogger
import io.github.rosemoe.sora.widget.CodeEditor
import java.io.File
import java.nio.file.Path
/**
* Base class for java code actions
* @author Akash Yadav
*/
abstract class BaseCodeAction : ActionItem {
abstract class BaseJavaCodeAction : ActionItem {
override var visible: Boolean = true
override var enabled: Boolean = true
override var icon: Drawable? = null
@@ -45,9 +45,7 @@ abstract class BaseCodeAction : ActionItem {
override var location: ActionItem.Location = ActionItem.Location.EDITOR_CODE_ACTIONS
protected abstract val titleTextRes: Int
private val log = ILogger.newInstance(javaClass.simpleName)
override fun prepare(data: ActionData) {
if (
@@ -66,25 +64,6 @@ abstract class BaseCodeAction : ActionItem {
enabled = visible
}
fun requireFile(data: ActionData): File {
return data.get(File::class.java) ?: throw IllegalArgumentException("No file instance provided")
}
fun requirePath(data: ActionData): Path {
return requireFile(data).toPath()
}
fun requireEditor(data: ActionData): CodeEditor {
return data.get(CodeEditor::class.java)
?: throw IllegalArgumentException("An editor instance is required but none was provided")
}
fun newDialogBuilder(data: ActionData): MaterialAlertDialogBuilder {
val klass = Class.forName("com.itsaky.androidide.utils.DialogUtils")
val method = klass.getDeclaredMethod("newMaterialDialogBuilder", Context::class.java)
return method.invoke(null, data.get(Context::class.java)!!) as MaterialAlertDialogBuilder
}
fun performCodeAction(data: ActionData, result: Rewrite) {
val server = ILanguageServerRegistry.getDefault().getServer(JavaLanguageServer.SERVER_ID)!!
val compiler =
@@ -19,6 +19,10 @@ package com.itsaky.androidide.lsp.java.actions
import android.content.Context
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.newDialogBuilder
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.compiler.CompileTask
@@ -41,7 +45,7 @@ import javax.lang.model.element.Modifier.STATIC
*
* @author Akash Yadav
*/
abstract class FieldBasedAction : BaseCodeAction() {
abstract class FieldBasedAction : BaseJavaCodeAction() {
private val log = ILogger.newInstance(javaClass.simpleName)
@@ -17,7 +17,8 @@
package com.itsaky.androidide.lsp.java.actions
import com.itsaky.androidide.lsp.actions.CodeActionsMenu
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.lsp.actions.IActionsMenuProvider
import com.itsaky.androidide.lsp.java.actions.common.CommentAction
import com.itsaky.androidide.lsp.java.actions.common.FindReferencesAction
import com.itsaky.androidide.lsp.java.actions.common.GoToDefinitionAction
@@ -40,29 +41,34 @@ import com.itsaky.androidide.lsp.java.actions.generators.GenerateSettersAndGette
import com.itsaky.androidide.lsp.java.actions.generators.GenerateToStringMethodAction
import com.itsaky.androidide.lsp.java.actions.generators.OverrideSuperclassMethodsAction
/** @author Akash Yadav */
class JavaCodeActionsMenu : CodeActionsMenu() {
init {
addAction(CommentAction())
addAction(UncommentAction())
addAction(GoToDefinitionAction())
addAction(FindReferencesAction())
addAction(AddImportAction())
addAction(ImplementAbstractMethodsAction())
addAction(VariableToStatementAction())
addAction(FieldToBlockAction())
addAction(RemoveClassAction())
addAction(RemoveMethodAction())
addAction(RemoveUnusedThrowsAction())
addAction(CreateMissingMethodAction())
addAction(SuppressUncheckedWarningAction())
addAction(AddThrowsAction())
addAction(GenerateSettersAndGettersAction())
addAction(OverrideSuperclassMethodsAction())
addAction(GenerateMissingConstructorAction())
addAction(GenerateConstructorAction())
addAction(GenerateToStringMethodAction())
addAction(RemoveUnusedImportsAction())
addAction(OrganizeImportsAction())
}
/**
* Java code actions.
* @author Akash Yadav
*/
object JavaCodeActionsMenu : IActionsMenuProvider {
override val actions: List<ActionItem> =
listOf(
CommentAction(),
UncommentAction(),
GoToDefinitionAction(),
FindReferencesAction(),
AddImportAction(),
ImplementAbstractMethodsAction(),
VariableToStatementAction(),
FieldToBlockAction(),
RemoveClassAction(),
RemoveMethodAction(),
RemoveUnusedThrowsAction(),
CreateMissingMethodAction(),
SuppressUncheckedWarningAction(),
AddThrowsAction(),
GenerateSettersAndGettersAction(),
OverrideSuperclassMethodsAction(),
GenerateMissingConstructorAction(),
GenerateConstructorAction(),
GenerateToStringMethodAction(),
RemoveUnusedImportsAction(),
OrganizeImportsAction()
)
}
@@ -17,11 +17,12 @@
package com.itsaky.androidide.lsp.java.actions.common
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
/** @author Akash Yadav */
class CommentAction : BaseCodeAction() {
class CommentAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_commentLine"
override var label: String = ""
@@ -17,9 +17,11 @@
package com.itsaky.androidide.lsp.java.actions.common
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.utils.ILogger
import io.github.rosemoe.sora.widget.CodeEditor
import java.io.File
@@ -28,7 +30,7 @@ import java.io.File
*
* @author Akash Yadav
*/
class FindReferencesAction : BaseCodeAction() {
class FindReferencesAction : BaseJavaCodeAction() {
override val titleTextRes: Int = R.string.action_find_references
override val id: String = "lsp_java_findReferences"
override var label: String = ""
@@ -17,9 +17,11 @@
package com.itsaky.androidide.lsp.java.actions.common
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.utils.ILogger
import io.github.rosemoe.sora.widget.CodeEditor
import java.io.File
@@ -29,7 +31,7 @@ import java.io.File
*
* @author Akash Yadav
*/
class GoToDefinitionAction : BaseCodeAction() {
class GoToDefinitionAction : BaseJavaCodeAction() {
override val titleTextRes: Int = R.string.action_goto_definition
override val id: String = "lsp_java_gotoDefinition"
override var label: String = ""
@@ -3,14 +3,17 @@ package com.itsaky.androidide.lsp.java.actions.common
import com.google.googlejavaformat.java.FormatterException
import com.google.googlejavaformat.java.ImportOrderer
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.lsp.java.JavaLanguageServer
import com.itsaky.androidide.lsp.java.R.string
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.JavaServerSettings
import com.itsaky.androidide.utils.ILogger
import io.github.rosemoe.sora.widget.CodeEditor
class OrganizeImportsAction : BaseCodeAction() {
class OrganizeImportsAction : BaseJavaCodeAction() {
private val log = ILogger.newInstance(javaClass.simpleName)
override val id: String = "lsp_java_organizeImports"
override var label: String = ""
@@ -3,12 +3,15 @@ package com.itsaky.androidide.lsp.java.actions.common
import com.google.googlejavaformat.java.FormatterException
import com.google.googlejavaformat.java.RemoveUnusedImports
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.lsp.java.R.string
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.utils.ILogger
import io.github.rosemoe.sora.widget.CodeEditor
class RemoveUnusedImportsAction : BaseCodeAction() {
class RemoveUnusedImportsAction : BaseJavaCodeAction() {
private val log = ILogger.newInstance(javaClass.simpleName)
override val id: String = "lsp_java_remove_unused_imports"
@@ -17,11 +17,12 @@
package com.itsaky.androidide.lsp.java.actions.common
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.requireEditor
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
/** @author Akash Yadav */
class UncommentAction : BaseCodeAction() {
class UncommentAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_uncommentLine"
override var label: String = ""
@@ -18,12 +18,17 @@ package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.google.common.collect.Iterables.toArray
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.newDialogBuilder
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.javac.services.util.JavaDiagnosticUtils
import com.itsaky.androidide.lsp.api.ILanguageServerRegistry
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.JavaLanguageServer
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.AddImport
import com.itsaky.androidide.lsp.java.rewrite.Rewrite
@@ -35,7 +40,7 @@ import javax.tools.Diagnostic
import javax.tools.JavaFileObject
/** @author Akash Yadav */
class AddImportAction : BaseCodeAction() {
class AddImportAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_addImport"
override var label: String = ""
@@ -17,9 +17,13 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.AddException
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils
@@ -27,7 +31,7 @@ import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class AddThrowsAction : BaseCodeAction() {
class AddThrowsAction : BaseJavaCodeAction() {
override val id = "lsp_java_addThrows"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.NOT_THROWN.id
@@ -38,7 +42,10 @@ class AddThrowsAction : BaseCodeAction() {
override fun prepare(data: ActionData) {
super.prepare(data)
if (!visible || !hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)) {
if (
!visible ||
!hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)
) {
markInvisible()
return
}
@@ -17,9 +17,13 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.CreateMissingMethod
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils.findPosition
@@ -27,7 +31,7 @@ import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class CreateMissingMethodAction : BaseCodeAction() {
class CreateMissingMethodAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_createMissingMethod"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.MISSING_METHOD.id
@@ -38,7 +42,10 @@ class CreateMissingMethodAction : BaseCodeAction() {
override fun prepare(data: ActionData) {
super.prepare(data)
if (!visible || !hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)) {
if (
!visible ||
!hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)
) {
markInvisible()
return
}
@@ -17,17 +17,22 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.ConvertFieldToBlock
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils.findPosition
import com.itsaky.androidide.lsp.models.DiagnosticItem
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class FieldToBlockAction : BaseCodeAction() {
class FieldToBlockAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_fieldToBlock"
override var label: String = ""
@@ -43,12 +48,12 @@ class FieldToBlockAction : BaseCodeAction() {
return
}
if (!hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)) {
if (!hasRequiredData(data, DiagnosticItem::class.java)) {
markInvisible()
return
}
val diagnostic = data.get(com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)!!
val diagnostic = data.get(DiagnosticItem::class.java)!!
if (diagnosticCode != diagnostic.code) {
markInvisible()
return
@@ -58,7 +63,7 @@ class FieldToBlockAction : BaseCodeAction() {
override fun execAction(data: ActionData): Any {
val compiler =
JavaCompilerProvider.get(ProjectManager.findModuleForFile(requireFile(data)) ?: return Any())
val diagnostic = data[com.itsaky.androidide.lsp.models.DiagnosticItem::class.java]!!
val diagnostic = data[DiagnosticItem::class.java]!!
val file = requirePath(data)
return compiler.compile(file).get {
@@ -17,9 +17,11 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.javac.services.util.JavaDiagnosticUtils
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.ImplementAbstractMethods
import com.itsaky.androidide.utils.ILogger
@@ -27,7 +29,7 @@ import javax.tools.Diagnostic
import javax.tools.JavaFileObject
/** @author Akash Yadav */
class ImplementAbstractMethodsAction : BaseCodeAction() {
class ImplementAbstractMethodsAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_implementAbstractMethods"
override var label: String = ""
private var diagnosticCode = DiagnosticCode.DOES_NOT_OVERRIDE_ABSTRACT.id
@@ -17,9 +17,13 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.RemoveClass
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils.findPosition
@@ -27,7 +31,7 @@ import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class RemoveClassAction : BaseCodeAction() {
class RemoveClassAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_removeClass"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.UNUSED_CLASS.id
@@ -17,9 +17,13 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.RemoveMethod
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils.findMethod
@@ -27,7 +31,7 @@ import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class RemoveMethodAction : BaseCodeAction() {
class RemoveMethodAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_removeMethod"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.UNUSED_METHOD.id
@@ -17,9 +17,13 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.RemoveException
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils
@@ -27,7 +31,7 @@ import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class RemoveUnusedThrowsAction : BaseCodeAction() {
class RemoveUnusedThrowsAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_removeUnusedThrows"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.UNUSED_THROWS.id
@@ -38,7 +42,10 @@ class RemoveUnusedThrowsAction : BaseCodeAction() {
override fun prepare(data: ActionData) {
super.prepare(data)
if (!visible || !hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)) {
if (
!visible ||
!hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)
) {
markInvisible()
return
}
@@ -17,9 +17,13 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.AddSuppressWarningAnnotation
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils
@@ -27,7 +31,7 @@ import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class SuppressUncheckedWarningAction : BaseCodeAction() {
class SuppressUncheckedWarningAction : BaseJavaCodeAction() {
override val id = "lsp_java_suppressUncheckedWarning"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.UNCHECKED.id
@@ -17,17 +17,21 @@
package com.itsaky.androidide.lsp.java.actions.diagnostics
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.ConvertVariableToStatement
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils.findPosition
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class VariableToStatementAction : BaseCodeAction() {
class VariableToStatementAction : BaseJavaCodeAction() {
override val id: String = "lsp_java_variableToStatement"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.UNUSED_LOCAL.id
@@ -23,14 +23,15 @@ import com.github.javaparser.StaticJavaParser
import com.github.javaparser.ast.Modifier
import com.github.javaparser.ast.body.ConstructorDeclaration
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.lsp.java.R.string
import com.itsaky.androidide.lsp.java.actions.FieldBasedAction
import com.itsaky.androidide.lsp.java.compiler.CompileTask
import com.itsaky.androidide.lsp.java.utils.EditHelper
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
import com.itsaky.toaster.Toaster.Type.ERROR
import com.itsaky.toaster.toast
import com.itsaky.toaster.toastLong
@@ -45,7 +46,7 @@ import com.sun.tools.javac.tree.JCTree
import com.sun.tools.javac.tree.TreeInfo
import com.sun.tools.javac.util.ListBuffer
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.concurrent.*
import java.util.concurrent.CompletableFuture
/**
* Allows the user to select fields and generate a constructor which has parameters same as the
@@ -105,7 +106,7 @@ class GenerateConstructorAction : FieldBasedAction() {
log.warn(
"A constructor with same parameter types is already available in class ${type.simpleName}"
)
toastLong(data[Context::class.java]!!.getString(string.msg_constructor_available), ERROR)
toastLong(data[Context::class.java]!!.getString(string.msg_constructor_available), ERROR)
return
}
@@ -17,17 +17,21 @@
package com.itsaky.androidide.lsp.java.actions.generators
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.models.DiagnosticCode
import com.itsaky.androidide.lsp.java.rewrite.GenerateRecordConstructor
import com.itsaky.androidide.lsp.java.utils.CodeActionUtils
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
class GenerateMissingConstructorAction : BaseCodeAction() {
class GenerateMissingConstructorAction : BaseJavaCodeAction() {
override val id = "lsp_java_generateMissingConstructor"
override var label: String = ""
private val diagnosticCode = DiagnosticCode.MISSING_CONSTRUCTOR.id
@@ -37,7 +41,10 @@ class GenerateMissingConstructorAction : BaseCodeAction() {
override fun prepare(data: ActionData) {
super.prepare(data)
if (!visible || !hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)) {
if (
!visible ||
!hasRequiredData(data, com.itsaky.androidide.lsp.models.DiagnosticItem::class.java)
) {
markInvisible()
return
}
@@ -23,9 +23,9 @@ import com.github.javaparser.ast.body.MethodDeclaration
import com.github.javaparser.ast.expr.SimpleName
import com.github.javaparser.ast.type.VoidType
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.FieldBasedAction
import com.itsaky.androidide.lsp.java.compiler.CompileTask
@@ -33,13 +33,14 @@ import com.itsaky.androidide.lsp.java.utils.EditHelper
import com.itsaky.androidide.lsp.java.utils.JavaParserUtils
import com.itsaky.androidide.lsp.java.utils.TypeUtils.toType
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.utils.ILogger
import com.itsaky.toaster.Toaster
import com.itsaky.toaster.toast
import com.sun.source.tree.ClassTree
import com.sun.source.util.TreePath
import com.sun.source.util.Trees
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.concurrent.*
import java.util.concurrent.CompletableFuture
import javax.lang.model.element.Modifier
import javax.lang.model.element.VariableElement
@@ -65,11 +66,10 @@ class GenerateSettersAndGettersAction : FieldBasedAction() {
if (error != null) {
log.error("Unable to generate setters and getters", error)
ThreadUtils.runOnUiThread {
toast(data[Context::class.java]!!.getString(
R.string.msg_cannot_generate_setters_getters
),
Toaster.Type.ERROR
)
toast(
data[Context::class.java]!!.getString(R.string.msg_cannot_generate_setters_getters),
Toaster.Type.ERROR
)
}
return@whenComplete
}
@@ -23,6 +23,8 @@ import com.github.javaparser.ast.Modifier
import com.github.javaparser.ast.body.MethodDeclaration
import com.github.javaparser.ast.stmt.ReturnStmt
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.R.string
@@ -19,9 +19,14 @@ package com.itsaky.androidide.lsp.java.actions.generators
import android.content.Context
import com.blankj.utilcode.util.ThreadUtils
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
import com.itsaky.androidide.actions.newDialogBuilder
import com.itsaky.androidide.actions.requireFile
import com.itsaky.androidide.actions.requirePath
import com.itsaky.androidide.lsp.java.JavaCompilerProvider
import com.itsaky.androidide.lsp.java.R
import com.itsaky.androidide.lsp.java.actions.BaseCodeAction
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.compiler.CompileTask
import com.itsaky.androidide.lsp.java.compiler.CompilerProvider
import com.itsaky.androidide.lsp.java.parser.ParseTask
@@ -54,7 +59,7 @@ import javax.tools.JavaFileObject
*
* @author Akash Yadav
*/
class OverrideSuperclassMethodsAction : BaseCodeAction() {
class OverrideSuperclassMethodsAction : BaseJavaCodeAction() {
override val titleTextRes: Int = R.string.action_override_superclass_methods
override val id: String = "lsp_java_overrideSuperclassMethods"
override var label: String = ""
+2
View File
@@ -66,6 +66,7 @@ dependencies {
implementation common.editor
implementation common.utilcode
implementation project (':actions')
implementation project (':lsp:api')
implementation project (':lexers')
implementation project (':build-tools:xml-dom')
@@ -75,6 +76,7 @@ dependencies {
implementation androidx.ktx
implementation common.kotlin
implementation google.material
testImplementation project (':build-tools:projects')
testImplementation project (':build-tools:tooling-api')
@@ -93,7 +93,6 @@ public class XMLFormatterDocument {
public List<? extends TextEdit> format() throws BadLocationException {
this.fullDomDocument =
DOMParser.getInstance().parse(textDocument.getText(), textDocument.getUri(), null, false);
if (isRangeFormatting()) {
setupRangeFormatting(range);
} else {
Binary file not shown.