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 92a194f227..19b6580f75 100644
--- a/actions/src/main/java/com/itsaky/androidide/actions/ActionItem.kt
+++ b/actions/src/main/java/com/itsaky/androidide/actions/ActionItem.kt
@@ -23,6 +23,7 @@ import android.view.View
/**
* An action that can be registered using the [ActionsRegistry]
* [com.itsaky.androidide.actions.ActionsRegistry]
+ *
* @author Akash Yadav
*/
interface ActionItem {
@@ -37,6 +38,7 @@ interface ActionItem {
/**
* Prepare the action. Subclasses can modify the visual properties of this action here.
+ *
* @param data The data containing various information about the event.
*/
fun prepare(data: ActionData)
@@ -57,6 +59,12 @@ interface ActionItem {
*/
fun postExec(data: ActionData, result: Any) = Unit
+ /**
+ * Called when the action item is to be destroyed. Any resource references must be released if
+ * held.
+ */
+ fun destroy() = Unit
+
/**
* Return the show as action flags for the menu item.
*
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 c1fa8c027d..d49d5ffb3c 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
@@ -66,6 +66,7 @@ class DefaultActionsRegistry : ActionsRegistry() {
val actions = getActions(action.location)
val older = actions.remove(action.id)
if (older != null) {
+ older.destroy()
return true
}
@@ -76,6 +77,7 @@ class DefaultActionsRegistry : ActionsRegistry() {
for (locations in this.actions.values) {
val older = locations.remove(id)
if (older != null) {
+ older.destroy()
return true
}
}
@@ -86,7 +88,13 @@ class DefaultActionsRegistry : ActionsRegistry() {
override fun findAction(location: ActionItem.Location, id: String): ActionItem? =
getActions(location)[id]
- override fun clearActions(location: ActionItem.Location) = getActions(location).clear()
+ override fun clearActions(location: ActionItem.Location) {
+ val actions = getActions(location)
+ actions.forEach {
+ it.value.destroy()
+ }
+ actions.clear()
+ }
override fun registerActionExecListener(listener: ActionExecListener) {
listeners.add(listener)
diff --git a/annotation-ksp/build.gradle.kts b/annotation-ksp/build.gradle.kts
index b9fc837ac3..11cd8d2578 100644
--- a/annotation-ksp/build.gradle.kts
+++ b/annotation-ksp/build.gradle.kts
@@ -27,6 +27,7 @@ dependencies {
implementation(projects.annotations)
+ implementation(libs.androidx.annotation)
implementation(libs.common.javapoet)
implementation(libs.common.ksp)
}
diff --git a/annotation-ksp/src/main/kotlin/com/itsaky/androidide/annotations/ksp/inflater/ViewAdapterIndexGenerator.kt b/annotation-ksp/src/main/kotlin/com/itsaky/androidide/annotations/ksp/inflater/ViewAdapterIndexGenerator.kt
index 78d8d3bb9b..261a8b9084 100644
--- a/annotation-ksp/src/main/kotlin/com/itsaky/androidide/annotations/ksp/inflater/ViewAdapterIndexGenerator.kt
+++ b/annotation-ksp/src/main/kotlin/com/itsaky/androidide/annotations/ksp/inflater/ViewAdapterIndexGenerator.kt
@@ -17,6 +17,7 @@
package com.itsaky.androidide.annotations.ksp.inflater
+import androidx.annotation.RequiresApi
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.isAnnotationPresent
@@ -187,6 +188,11 @@ class ViewAdapterIndexGenerator(private val logger: KSPLogger) {
result
}
} else null
+
+ val requiresApi =
+ if (sym.isAnnotationPresent(RequiresApi::class))
+ sym.getAnnotationsByType(RequiresApi::class).iterator().next()
+ else null
val viewName = getViewName(viewAdapter)
val moduleNs = getModuleNs(viewAdapter)
@@ -195,6 +201,12 @@ class ViewAdapterIndexGenerator(private val logger: KSPLogger) {
val viewTypeName =
ClassName.get(viewName.substringBeforeLast('.'), viewName.substringAfterLast('.'))
+ requiresApi?.let { annotation ->
+ val api = if (annotation.value == 1) annotation.api else annotation.value
+ val androidBuild = ClassName.get("android.os", "Build")
+ block.beginControlFlow("if(\$T.VERSION.SDK_INT >= \$L)", androidBuild, api)
+ }
+
block.addStatement(
"final var adapter = new \$T()",
ParameterizedTypeName.get(adapterTypeName, viewTypeName)
@@ -213,6 +225,8 @@ class ViewAdapterIndexGenerator(private val logger: KSPLogger) {
)
}
+ requiresApi?.let { block.endControlFlow() }
+
indexAddStatements.add("{\n")
indexAddStatements.indent()
indexAddStatements.add(block.build())
@@ -238,7 +252,7 @@ class ViewAdapterIndexGenerator(private val logger: KSPLogger) {
)
indexClassBuilder.addStaticBlock(indexAddStatements.build())
-
+
OutputStreamWriter(out).use {
val file = JavaFile.builder(INDEX_PACKAGE_NAME, indexClassBuilder.build())
file.build().writeTo(it)
@@ -256,11 +270,11 @@ class ViewAdapterIndexGenerator(private val logger: KSPLogger) {
}
private fun getViewType(viewAdapter: KSAnnotation) =
- (getViewAdapterArg(viewAdapter, "forView") as KSType)
+ (getAnnotationArg(viewAdapter, "forView") as KSType)
private fun getModuleNs(viewAdapter: KSAnnotation) =
- (getViewAdapterArg(viewAdapter, "moduleNamespace") as String)
+ (getAnnotationArg(viewAdapter, "moduleNamespace") as String)
- private fun getViewAdapterArg(viewAdapter: KSAnnotation, arg: String) =
+ private fun getAnnotationArg(viewAdapter: KSAnnotation, arg: String) =
viewAdapter.arguments.first { it.name!!.asString() == arg }.value
}
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c95951b714..eaf36c5113 100755
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -73,6 +73,8 @@ android {
kapt { arguments { arg("eventBusIndex", "com.itsaky.androidide.events.AppEventsIndex") } }
dependencies {
+
+ debugImplementation(libs.common.leakcanary)
// Annotation processors
kapt(libs.common.glide.ap)
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 86669aa664..7f20d4147e 100755
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -5,9 +5,10 @@
-dontobfuscate
-keep class javax.** { *; }
+-keep class jdkx.** { *; }
# keep javac classes
--keep class com.sun.** { *; }
+-keep class openjdk.** { *; }
# Android builder model interfaces
-keep class com.android.** { *; }
@@ -55,7 +56,7 @@
-keep class * extends com.itsaky.androidide.lsp.java.providers.completion.IJavaCompletionProvider {
(...);
}
--keep class com.itsaky.androidide.editor.IEditor { *; }
+-keep class com.itsaky.androidide.editor.api.IEditor { *; }
-keep class * extends com.itsaky.androidide.inflater.IViewAdapter { *; }
-keep class * extends com.itsaky.androidide.inflater.drawable.IDrawableParser {
(...);
@@ -83,4 +84,4 @@
-keepclasseswithmembers class ** {
native ;
}
--keep class com.itsaky.androidide.treesitter.** { *; }
\ No newline at end of file
+-keep class com.itsaky.androidide.treesitter.** { *; }
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b812d14fde..acdd297d96 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -61,7 +61,7 @@
android:windowSoftInputMode="adjustResize" />
.
- */
-
-package com.itsaky.androidide.actions.etc
-
-import android.content.Context
-import androidx.core.content.ContextCompat
-import com.itsaky.androidide.resources.R
-import com.itsaky.androidide.actions.ActionData
-import com.itsaky.androidide.actions.EditorActivityAction
-
-/** @author Akash Yadav */
-class DaemonStatusAction() : EditorActivityAction() {
- override val id: String = "editor_daemonStatus"
- override var requiresUIThread: Boolean = true
-
- constructor(context: Context) : this() {
- label = context.getString(R.string.gradle_daemon_status)
- icon = ContextCompat.getDrawable(context, R.drawable.ic_info)
- }
-
- override fun prepare(data: ActionData) {
- visible = true
- enabled = true
- }
-
- override fun execAction(data: ActionData): Boolean {
- val context = getActivity(data) ?: return false
- context.showDaemonStatus()
- 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 8a8728d2b6..9f75427a44 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
@@ -58,11 +58,9 @@ class FindInProjectAction() : EditorActivityAction() {
val context = getActivity(data) ?: return false
val dialog = context.findInProjectDialog
- return if (dialog != null) {
+ return run {
dialog.show()
true
- } else {
- false
}
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/actions/file/SaveFileAction.kt b/app/src/main/java/com/itsaky/androidide/actions/file/SaveFileAction.kt
index 55aa7bdb09..bf4ddeeac2 100644
--- a/app/src/main/java/com/itsaky/androidide/actions/file/SaveFileAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/actions/file/SaveFileAction.kt
@@ -19,13 +19,12 @@ package com.itsaky.androidide.actions.file
import android.content.Context
import androidx.core.content.ContextCompat
-import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.EditorRelatedAction
import com.itsaky.androidide.projects.ProjectManager
+import com.itsaky.androidide.resources.R
import com.itsaky.androidide.utils.ILogger
-import com.itsaky.toaster.Toaster
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashSuccess
/** @author Akash Yadav */
class SaveFileAction() : EditorRelatedAction() {
@@ -77,7 +76,7 @@ class SaveFileAction() : EditorRelatedAction() {
override fun postExec(data: ActionData, result: Any) {
if (result is Boolean && result) {
- toast(R.string.all_saved, Toaster.Type.SUCCESS)
+ flashSuccess(R.string.all_saved)
} else {
log.error("Failed to save file")
TODO("Create message in strings.xml")
diff --git a/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt
index 58346845cd..1a363a8eda 100755
--- a/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt
+++ b/app/src/main/java/com/itsaky/androidide/activities/MainActivity.kt
@@ -26,11 +26,11 @@ import android.widget.TextView
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.text.HtmlCompat
import com.blankj.utilcode.util.SizeUtils
-import com.itsaky.androidide.activities.editor.EditorActivityKt
+import com.google.android.material.color.DynamicColors
import com.itsaky.androidide.R.id
+import com.itsaky.androidide.activities.editor.EditorActivityKt
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.app.IDEActivity
-import com.itsaky.androidide.app.IDEApplication
import com.itsaky.androidide.databinding.ActivityMainBinding
import com.itsaky.androidide.fragments.MainFragment
import com.itsaky.androidide.preferences.internal.NO_OPENED_PROJECT
@@ -41,9 +41,8 @@ import com.itsaky.androidide.projects.ProjectManager.projectPath
import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.utils.DialogUtils
import com.itsaky.androidide.utils.Environment
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.Toaster.Type.INFO
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashError
+import com.itsaky.androidide.utils.flashInfo
import java.io.File
class MainActivity : IDEActivity() {
@@ -67,12 +66,15 @@ class MainActivity : IDEActivity() {
override fun onStorageGranted() {}
override fun onStorageDenied() {
- toast(string.msg_storage_denied, ERROR)
+ flashError(string.msg_storage_denied)
finishAffinity()
}
override fun preSetContentLayout() {
- installSplashScreen()
+ installSplashScreen().setOnExitAnimationListener {
+ it.remove()
+ DynamicColors.applyToActivityIfAvailable(this)
+ }
}
override fun bindLayout(): View {
@@ -127,12 +129,12 @@ class MainActivity : IDEActivity() {
}
if (TextUtils.isEmpty(openedProject)) {
app
- toast(string.msg_opened_project_does_not_exist, INFO)
+ flashInfo(string.msg_opened_project_does_not_exist)
return
}
val project = File(openedProject)
if (!project.exists()) {
- toast(string.msg_opened_project_does_not_exist, INFO)
+ flashInfo(string.msg_opened_project_does_not_exist)
return
}
if (confirmProjectOpen) {
diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
index 2f9bca3be1..c44686ecc3 100644
--- a/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
+++ b/app/src/main/java/com/itsaky/androidide/activities/editor/BaseEditorActivity.kt
@@ -22,6 +22,7 @@ import android.content.IntentFilter
import android.content.pm.PackageInstaller.SessionCallback
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
+import android.os.StrictMode
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextUtils
@@ -49,6 +50,7 @@ import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.Tab
+import com.itsaky.androidide.BuildConfig
import com.itsaky.androidide.R.attr
import com.itsaky.androidide.R.drawable
import com.itsaky.androidide.R.id
@@ -64,7 +66,6 @@ import com.itsaky.androidide.databinding.LayoutDiagnosticInfoBinding
import com.itsaky.androidide.events.InstallationResultEvent
import com.itsaky.androidide.fragments.FileTreeFragment
import com.itsaky.androidide.fragments.SearchResultFragment
-import com.itsaky.androidide.fragments.sheets.TextSheetFragment
import com.itsaky.androidide.handlers.EditorActivityLifecyclerObserver
import com.itsaky.androidide.handlers.LspHandler.registerLanguageServers
import com.itsaky.androidide.interfaces.DiagnosticClickListener
@@ -79,27 +80,24 @@ import com.itsaky.androidide.projects.ProjectManager.getProjectDirPath
import com.itsaky.androidide.projects.ProjectManager.projectPath
import com.itsaky.androidide.projects.builder.BuildService
import com.itsaky.androidide.services.LogReceiver
-import com.itsaky.androidide.ui.EditorBottomSheet
import com.itsaky.androidide.ui.MaterialBanner
import com.itsaky.androidide.ui.editor.CodeEditorView
import com.itsaky.androidide.uidesigner.UIDesignerActivity
import com.itsaky.androidide.utils.ActionMenuUtils.createMenu
+import com.itsaky.androidide.utils.ApkInstallationSessionCallback
import com.itsaky.androidide.utils.DialogUtils.newMaterialDialogBuilder
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.InstallationResultHandler.onResult
-import com.itsaky.androidide.utils.SingleSessionCallback
+import com.itsaky.androidide.utils.flashError
import com.itsaky.androidide.utils.resolveAttr
import com.itsaky.androidide.viewmodel.EditorViewModel
import com.itsaky.androidide.xml.resources.ResourceTableRegistry
import com.itsaky.androidide.xml.versions.ApiVersionsRegistry
import com.itsaky.androidide.xml.widgets.WidgetTableRegistry
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
-import java.io.File
-import java.util.Objects
-import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode.MAIN
+import java.io.File
+import java.util.Objects
/**
* Base class for EditorActivity which handles most of the view related things.
@@ -115,7 +113,6 @@ abstract class BaseEditorActivity :
protected val mLifecycleObserver = EditorActivityLifecyclerObserver()
protected var diagnosticInfoBinding: LayoutDiagnosticInfoBinding? = null
- protected var dmonStatusFragment: TextSheetFragment? = null
protected var filesTreeFragment: FileTreeFragment? = null
protected var editorBottomSheet: BottomSheetBehavior? = null
protected var isDestroying = false
@@ -123,6 +120,8 @@ abstract class BaseEditorActivity :
protected val log: ILogger = ILogger.newInstance("EditorActivity")
protected val logReceiver: LogReceiver = LogReceiver().setLogListener(::appendApkLog)
+ internal var installationCallback: ApkInstallationSessionCallback? = null
+
var uiDesignerResultLauncher: ActivityResultLauncher? = null
val viewModel by viewModels()
lateinit var binding: ActivityEditorBinding
@@ -135,8 +134,6 @@ abstract class BaseEditorActivity :
binding.root.closeDrawer(GravityCompat.END)
} else if (binding.root.isDrawerOpen(GravityCompat.START)) {
binding.root.closeDrawer(GravityCompat.START)
- } else if (getDaemonStatusFragment().isShowing) {
- getDaemonStatusFragment().dismiss()
} else if (editorBottomSheet?.state != BottomSheetBehavior.STATE_COLLAPSED) {
editorBottomSheet?.setState(BottomSheetBehavior.STATE_COLLAPSED)
} else {
@@ -160,6 +157,8 @@ abstract class BaseEditorActivity :
protected abstract fun getOpenedFiles(): List
protected open fun preDestroy() {
+ installationCallback?.destroy()
+ installationCallback = null
try {
unregisterReceiver(logReceiver)
} catch (th: Throwable) {
@@ -193,16 +192,21 @@ abstract class BaseEditorActivity :
if (packageName != null) {
Snackbar.make(binding.realContainer, string.msg_action_open_application, Snackbar.LENGTH_LONG)
.setAction(string.yes) {
- val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
- launchIntent?.let { startActivity(it) }
+ tryLaunchApp(packageName)
}
.show()
}
}
-
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ if (BuildConfig.DEBUG) {
+ StrictMode.setVmPolicy(
+ StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()).detectLeakedClosableObjects().build()
+ )
+ }
+
registerLanguageServers()
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_PROJECT_PATH)) {
@@ -214,8 +218,6 @@ abstract class BaseEditorActivity :
setSupportActionBar(binding.editorToolbar)
- dmonStatusFragment = getDaemonStatusFragment()
-
setupDrawerToggle()
binding.tabs.addOnTabSelectedListener(this)
@@ -244,11 +246,18 @@ abstract class BaseEditorActivity :
getFileTreeFragment()?.listProjectFiles()
} catch (th: Throwable) {
log.error("Failed to update files list", th)
- toast(string.msg_failed_list_files, ERROR)
+ flashError(string.msg_failed_list_files)
}
}
+ override fun onStop() {
+ super.onStop()
+
+ checkIsDestroying()
+ }
+
override fun onDestroy() {
+ checkIsDestroying()
preDestroy()
super.onDestroy()
postDestroy()
@@ -337,27 +346,6 @@ abstract class BaseEditorActivity :
binding.bottomSheet.setDiagnosticsAdapter(adapter)
}
- open fun showDaemonStatus() {
- val shell = app.newShell { t -> getDaemonStatusFragment().append(t) }
- shell.bgAppend(String.format("echo '%s'", getString(string.msg_getting_daemom_status)))
- shell.bgAppend(
- String.format("cd '%s' && sh gradlew --status", Objects.requireNonNull(getProjectDirPath()))
- )
-
- if (!getDaemonStatusFragment().isShowing) {
- getDaemonStatusFragment().show(supportFragmentManager, "daemon_status")
- }
- }
-
- open fun getDaemonStatusFragment(): TextSheetFragment {
- return dmonStatusFragment
- ?: TextSheetFragment().also {
- it.setTextSelectable(true)
- it.setTitleText(string.gradle_daemon_status)
- dmonStatusFragment = it
- }
- }
-
open fun hideBottomSheet() {
if (editorBottomSheet?.state != BottomSheetBehavior.STATE_COLLAPSED) {
editorBottomSheet?.state = BottomSheetBehavior.STATE_COLLAPSED
@@ -418,6 +406,24 @@ abstract class BaseEditorActivity :
viewModel.statusText = text
viewModel.statusGravity = gravity
}
+
+ private fun tryLaunchApp(packageName: String) {
+ val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
+ launchIntent?.let {
+ try {
+ startActivity(it)
+ } catch (e: Throwable) {
+ flashError(string.msg_app_launch_failed)
+ log.error("Failed to launch application with package name '$packageName'", e)
+ }
+ }
+ }
+
+ private fun checkIsDestroying() {
+ if (!isDestroying && isFinishing) {
+ isDestroying = true
+ }
+ }
private fun handleUiDesignerResult(result: ActivityResult) {
if (result.resultCode != RESULT_OK || result.data == null) {
@@ -468,7 +474,7 @@ abstract class BaseEditorActivity :
viewModel.observeFiles(this) { files ->
binding.apply {
- if (files == null || files.isEmpty()) {
+ if (files.isNullOrEmpty()) {
tabs.visibility = View.GONE
viewContainer.displayedChild = 1
} else {
@@ -635,30 +641,6 @@ abstract class BaseEditorActivity :
}
open fun installationSessionCallback(): SessionCallback {
- return object : SingleSessionCallback() {
- override fun onCreated(sessionId: Int) {
- log.debug("on session created:", sessionId)
- binding.apply {
- bottomSheet.setActionText(getString(string.msg_installing_apk))
- bottomSheet.setActionProgress(0)
- bottomSheet.showChild(EditorBottomSheet.CHILD_ACTION)
- }
- }
-
- override fun onProgressChanged(sessionId: Int, progress: Float) {
- binding.bottomSheet.setActionProgress((progress * 100f).toInt())
- }
-
- override fun onFinished(sessionId: Int, success: Boolean) {
- binding.apply {
- bottomSheet.showChild(EditorBottomSheet.CHILD_HEADER)
- bottomSheet.setActionProgress(0)
- if (!success) {
- Snackbar.make(realContainer, string.title_installation_failed, Snackbar.LENGTH_LONG)
- .show()
- }
- }
- }
- }
+ return ApkInstallationSessionCallback(this).also { installationCallback = it }
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
index 3b6a32965a..5d67c68dc5 100644
--- a/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
+++ b/app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
@@ -43,9 +43,7 @@ import com.itsaky.androidide.tasks.executeAsync
import com.itsaky.androidide.ui.editor.CodeEditorView
import com.itsaky.androidide.utils.DialogUtils.newYesNoDialog
import com.itsaky.androidide.utils.IntentUtils.openImage
-import com.itsaky.androidide.utils.LSPUtils
-import com.itsaky.toaster.Toaster.Type.SUCCESS
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashSuccess
import io.github.rosemoe.sora.event.ContentChangeEvent
import java.io.File
@@ -107,7 +105,7 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
viewModel.openedFilesCache = cache
}
}
-
+
executeAsync { IDEColorSchemeProvider.initIfNeeded() }
}
@@ -184,7 +182,7 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
editor.setSelection(0, 0)
return@post
}
-
+
editor.validateRange(selection)
editor.setSelection(selection)
}
@@ -275,7 +273,7 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
val result = saveAllResult()
if (notify) {
- toast(string.all_saved, SUCCESS)
+ flashSuccess(string.all_saved)
}
if (result.gradleSaved) {
diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt
index d6a76433d9..122bc208e5 100644
--- a/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt
+++ b/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt
@@ -46,13 +46,12 @@ import com.itsaky.androidide.projects.ProjectManager.rootProject
import com.itsaky.androidide.projects.ProjectManager.setupProject
import com.itsaky.androidide.projects.api.Project
import com.itsaky.androidide.projects.builder.BuildService
-import com.itsaky.androidide.services.GradleBuildService
-import com.itsaky.androidide.services.GradleBuildServiceConnnection
+import com.itsaky.androidide.services.builder.GradleBuildService
+import com.itsaky.androidide.services.builder.GradleBuildServiceConnnection
import com.itsaky.androidide.tooling.api.messages.result.InitializeResult
import com.itsaky.androidide.utils.DialogUtils.newMaterialDialogBuilder
import com.itsaky.androidide.utils.RecursiveFileSearcher
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashError
import java.io.File
import java.util.concurrent.CompletableFuture
import java.util.regex.Pattern
@@ -64,9 +63,11 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
protected var mSearchingProgress: ProgressSheet? = null
protected var mFindInProjectDialog: AlertDialog? = null
-
+
protected var isFromSavedInstance = false
protected var shouldInitialize = false
+
+ protected var initializingFuture: CompletableFuture? = null
val findInProjectDialog: AlertDialog
get() {
@@ -98,18 +99,19 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-
+
savedInstanceState?.let {
this.shouldInitialize = it.getBoolean(STATE_KEY_SHOULD_INITIALIZE, true)
this.isFromSavedInstance = it.getBoolean(STATE_KEY_FROM_SAVED_INSTANACE, false)
- } ?: run {
- this.shouldInitialize = true
- this.isFromSavedInstance = false
}
-
+ ?: run {
+ this.shouldInitialize = true
+ this.isFromSavedInstance = false
+ }
+
startServices()
}
-
+
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.apply {
@@ -125,7 +127,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
// sometimes, when the IDE closed and reopened instantly, these values prevent initialization
// of the project
ProjectManager.destroy()
-
+
viewModel.isInitializing = false
viewModel.isBuildInProgress = false
}
@@ -133,17 +135,35 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
override fun preDestroy() {
if (isDestroying) {
+
+ this.initializingFuture?.cancel(true)
+ this.initializingFuture = null
+
closeProject(false)
}
super.preDestroy()
-
+
if (isDestroying) {
+
+ if (IDELanguageClientImpl.isInitialized()) {
+ IDELanguageClientImpl.shutdown()
+ }
+
+ try {
+ stopLanguageServers()
+ } catch (err: Exception) {
+ log.error("Failed to stop editor services.")
+ }
+
try {
unbindService(buildServiceConnection)
+ buildServiceConnection.onConnected = {}
} catch (err: Throwable) {
log.error("Unable to unbind service")
} finally {
+ (Lookup.DEFAULT.lookup(BuildService.KEY_BUILD_SERVICE) as? GradleBuildService?)
+ ?.setEventListener(null)
Lookup.DEFAULT.unregister(BuildService.KEY_BUILD_SERVICE)
viewModel.isBoundToBuildSerice = false
}
@@ -214,7 +234,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
return
}
- val future =
+ this.initializingFuture =
if (shouldInitialize || (!isFromSavedInstance && !initialized)) {
log.debug("Sending init request to tooling server..")
buildService.initializeProject(projectDir.absolutePath)
@@ -228,7 +248,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
}
}
- future.whenCompleteAsync { result, error ->
+ this.initializingFuture!!.whenCompleteAsync { result, error ->
if (result == null || error != null) {
log.error("An error occurred initializing the project with Tooling API", error)
setStatus(getString(string.msg_project_initialization_failed))
@@ -239,11 +259,8 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
}
}
- override fun stopServices() {
+ override fun stopLanguageServers() {
try {
- if (IDELanguageClientImpl.isInitialized()) {
- IDELanguageClientImpl.shutdown()
- }
destroyLanguageServers(isChangingConfigurations)
} catch (err: Throwable) {
log.error("Unable to stop editor services. Please report this issue.", err)
@@ -297,7 +314,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
protected open fun createFindInProjectDialog(): AlertDialog? {
if (rootProject == null) {
log.warn("No root project model found. Is the project initialized?")
- toast(getString(string.msg_project_not_initialized), ERROR)
+ flashError(getString(string.msg_project_not_initialized))
return null
}
@@ -305,7 +322,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
try {
rootProject!!.subModules.stream().map(Project::projectDir).collect(Collectors.toList())
} catch (e: Throwable) {
- toast(getString(string.msg_no_modules), ERROR)
+ flashError(getString(string.msg_no_modules))
emptyList()
}
@@ -342,7 +359,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
builder.setPositiveButton(string.menu_find) { dialog, _ ->
val text = binding.input.editText!!.text.toString().trim()
if (text.isEmpty()) {
- toast(string.msg_empty_search_query, ERROR)
+ flashError(string.msg_empty_search_query)
return@setPositiveButton
}
@@ -374,7 +391,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
}
if (searchDirs.isEmpty()) {
- toast(string.msg_select_search_modules, ERROR)
+ flashError(string.msg_select_search_modules)
} else {
dialog.dismiss()
@@ -414,8 +431,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
}
private fun closeProject(manualFinish: Boolean) {
- stopServices()
-
+
// Make sure we close files
// This will make sure that file contents are not erased.
doCloseAll {
@@ -447,7 +463,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
open fun getProgressSheet(msg: Int): ProgressSheet? {
doDismissSearchProgress()
-
+
mSearchingProgress =
ProgressSheet().also {
it.isCancelable = false
diff --git a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
index 0e71554ebe..81b733127b 100755
--- a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
+++ b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt
@@ -31,14 +31,15 @@ import com.itsaky.androidide.events.LspJavaEventsIndex
import com.itsaky.androidide.events.ProjectsApiEventsIndex
import com.itsaky.androidide.preferences.internal.enableMaterialYou
import com.itsaky.androidide.preferences.internal.uiMode
+import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE
import com.itsaky.androidide.tasks.executeAsync
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.VMUtils
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
-import org.greenrobot.eventbus.EventBus
+import com.itsaky.androidide.utils.flashError
+import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
import java.lang.Thread.UncaughtExceptionHandler
import kotlin.system.exitProcess
+import org.greenrobot.eventbus.EventBus
class IDEApplication : BaseApplication() {
@@ -65,13 +66,15 @@ class IDEApplication : BaseApplication() {
.addIndex(LspApiEventsIndex())
.addIndex(LspJavaEventsIndex())
.installDefaultEventBus()
-
+
AppCompatDelegate.setDefaultNightMode(uiMode)
-
+
if (enableMaterialYou) {
DynamicColors.applyToActivitiesIfAvailable(this)
}
+ EditorColorScheme.setDefault(SchemeAndroidIDE.newInstance(null))
+
executeAsync { IDEColorSchemeProvider.init() }
}
@@ -103,7 +106,7 @@ class IDEApplication : BaseApplication() {
startActivity(intent)
} catch (th: Throwable) {
LOG.error("Unable to start activity to show changelog", th)
- toast("Unable to start activity", ERROR)
+ flashError("Unable to start activity")
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/LogViewFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/LogViewFragment.kt
index bc8a936153..cd519a6e4a 100644
--- a/app/src/main/java/com/itsaky/androidide/fragments/LogViewFragment.kt
+++ b/app/src/main/java/com/itsaky/androidide/fragments/LogViewFragment.kt
@@ -90,6 +90,11 @@ abstract class LogViewFragment : Fragment(), ShareableOutputFragment {
editor.colorScheme = SchemeAndroidIDE.newInstance(requireContext())
editor.setEditorLanguage(LogLanguage())
}
+
+ override fun onDestroyView() {
+ binding?.editor?.release()
+ super.onDestroyView()
+ }
override fun onDestroy() {
super.onDestroy()
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt
index f44b4d26bd..3736702e7f 100644
--- a/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt
+++ b/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt
@@ -8,9 +8,9 @@ import android.view.ViewGroup
import android.widget.TextView
import com.blankj.utilcode.util.ThreadUtils
import com.google.android.material.progressindicator.LinearProgressIndicator
-import com.itsaky.androidide.activities.editor.EditorActivityKt
import com.itsaky.androidide.activities.PreferencesActivity
import com.itsaky.androidide.activities.TerminalActivity
+import com.itsaky.androidide.activities.editor.EditorActivityKt
import com.itsaky.androidide.adapters.MainActionsListAdapter
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.common.databinding.LayoutDialogProgressBinding
@@ -25,11 +25,11 @@ import com.itsaky.androidide.tasks.executeAsyncProvideError
import com.itsaky.androidide.utils.DialogUtils
import com.itsaky.androidide.utils.Environment
import com.itsaky.androidide.utils.ILogger
-import com.itsaky.toaster.toastError
-import com.itsaky.toaster.toastSuccess
-import java.io.File
+import com.itsaky.androidide.utils.flashError
+import com.itsaky.androidide.utils.flashSuccess
import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.ProgressMonitor
+import java.io.File
class MainFragment : BaseFragment(), OnProjectCreatedListener {
private var binding: FragmentMainBinding? = null
@@ -179,14 +179,14 @@ class MainFragment : BaseFragment(), OnProjectCreatedListener {
if (!future.isCancelled) {
showCloneError(error)
}
- } else toastSuccess(string.git_clone_success)
+ } else flashSuccess(string.git_clone_success)
}
}
}
private fun showCloneError(error: Throwable?) {
if (error == null) {
- toastError(string.git_clone_failed)
+ flashError(string.git_clone_failed)
return
}
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt
index 1733b77d29..1ddc31bcda 100644
--- a/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt
+++ b/app/src/main/java/com/itsaky/androidide/fragments/RunTasksDialogFragment.kt
@@ -51,9 +51,9 @@ import com.itsaky.androidide.tooling.api.model.GradleTask
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.SingleTextWatcher
import com.itsaky.androidide.utils.doOnApplyWindowInsets
+import com.itsaky.androidide.utils.flashInfo
import com.itsaky.androidide.utils.updateSystemBarColors
import com.itsaky.androidide.viewmodel.RunTasksViewModel
-import com.itsaky.toaster.toastInfo
/**
* A bottom sheet dialog fragment to show UI which allows the users to select and execute Gradle
@@ -143,7 +143,7 @@ class RunTasksDialogFragment : BottomSheetDialogFragment() {
binding.exec.setOnClickListener {
if (viewModel.selected.isEmpty()) {
- toastInfo(getString(string.msg_err_select_tasks))
+ requireActivity().flashInfo(getString(string.msg_err_select_tasks))
return@setOnClickListener
}
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/SimpleOutputFragment.java b/app/src/main/java/com/itsaky/androidide/fragments/SimpleOutputFragment.java
deleted file mode 100644
index cb32e9fd7d..0000000000
--- a/app/src/main/java/com/itsaky/androidide/fragments/SimpleOutputFragment.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.androidide.fragments;
-
-import android.os.Bundle;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.blankj.utilcode.util.ThreadUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-public class SimpleOutputFragment extends NonEditableEditorFragment {
-
- private final List unsavedLines = new ArrayList<>();
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- if (!unsavedLines.isEmpty()) {
- for (String line : unsavedLines) {
- Objects.requireNonNull(getEditor()).append(line.trim() + "\n");
- }
- unsavedLines.clear();
- }
- }
-
- public void appendOutput(String output) {
- if (getEditor() == null) {
- unsavedLines.add(output);
- return;
- }
- ThreadUtils.runOnUiThread(
- () -> {
- final var message = output == null || output.endsWith("\n") ? output : output + "\n";
- getEditor().append(message);
- });
- }
-}
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/SimpleOutputFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/SimpleOutputFragment.kt
new file mode 100644
index 0000000000..7ef2c2a185
--- /dev/null
+++ b/app/src/main/java/com/itsaky/androidide/fragments/SimpleOutputFragment.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.androidide.fragments
+
+import android.os.Bundle
+import android.view.View
+import com.blankj.utilcode.util.ThreadUtils
+
+class SimpleOutputFragment : NonEditableEditorFragment() {
+ private val unsavedLines: MutableList = ArrayList()
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ if (unsavedLines.isNotEmpty()) {
+ for (line in unsavedLines) {
+ editor?.append("${line!!.trim()}\n")
+ }
+ unsavedLines.clear()
+ }
+ }
+
+ override fun onDestroyView() {
+ editor?.release()
+ super.onDestroyView()
+ }
+
+ fun appendOutput(output: String?) {
+ if (editor == null) {
+ unsavedLines.add(output)
+ return
+ }
+ ThreadUtils.runOnUiThread {
+ val message = if (output == null || output.endsWith("\n")) {
+ output
+ } else {
+ "${output}\n"
+ }
+ editor!!.append(message)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/WizardFragment.java b/app/src/main/java/com/itsaky/androidide/fragments/WizardFragment.java
index 09bf6e32dd..d6f4a0d948 100644
--- a/app/src/main/java/com/itsaky/androidide/fragments/WizardFragment.java
+++ b/app/src/main/java/com/itsaky/androidide/fragments/WizardFragment.java
@@ -34,10 +34,9 @@
import com.itsaky.androidide.utils.DialogUtils;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.FileUtil;
+import com.itsaky.androidide.utils.FlashbarUtilsKt;
import com.itsaky.androidide.utils.SingleTextWatcher;
import com.itsaky.androidide.viewmodel.WizardViewModel;
-import com.itsaky.toaster.Toaster;
-import com.itsaky.toaster.ToastUtilsKt;
import java.io.File;
import java.util.ArrayList;
@@ -133,7 +132,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
if (mProgressSheet != null && mProgressSheet.isShowing()) {
mProgressSheet.dismiss();
}
- ToastUtilsKt.toast(message, Toaster.Type.ERROR);
+ FlashbarUtilsKt.flashError(message);
});
mViewModel
@@ -176,7 +175,7 @@ public void onSuccess(File root) {
if (mProgressSheet != null && mProgressSheet.isShowing()) {
mProgressSheet.dismiss();
}
- ToastUtilsKt.toast(string.project_created_successfully, Toaster.Type.SUCCESS);
+ FlashbarUtilsKt.flashSuccess(string.project_created_successfully);
if (mListener != null) {
getParentFragmentManager().popBackStack();
@@ -223,7 +222,7 @@ private int getSdkVersion(AutoCompleteTextView view) {
.substring("API".length() + 1, "API".length() + 3); // at least 2 digits
return Integer.parseInt(sdk);
} catch (Exception e) {
- ToastUtilsKt.toast(e.getMessage(), Toaster.Type.ERROR);
+ FlashbarUtilsKt.flashError(e.getMessage());
}
return -1;
}
@@ -290,7 +289,8 @@ private List getSdks() {
"API 29: Android 10.0 (Q)",
"API 30: Android 11.0 (R)",
"API 31: Android 12.0 (S)",
- "API 32: Android 12.1L (S)");
+ "API 32: Android 12.1L (S)",
+ "API 33: Android 13.0 (Tiramisu)");
}
private LinkedHashMap getCppToolchans() {
@@ -369,7 +369,7 @@ private void showDetailsView() {
new ArrayAdapter<>(
requireContext(),
androidx.appcompat.R.layout.support_simple_spinner_dropdown_item,
- getCppToolchans().keySet().toArray(new String[getCppToolchans().size()])));
+ getCppToolchans().keySet().toArray(new String[0])));
detailsBinding.etToolchain.setListSelection(0);
detailsBinding.etToolchain.setText(getSelectedItem(0, detailsBinding.etToolchain), false);
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/sheets/TextSheetFragment.java b/app/src/main/java/com/itsaky/androidide/fragments/sheets/TextSheetFragment.java
index d118c2957f..cf84a1fd23 100755
--- a/app/src/main/java/com/itsaky/androidide/fragments/sheets/TextSheetFragment.java
+++ b/app/src/main/java/com/itsaky/androidide/fragments/sheets/TextSheetFragment.java
@@ -16,10 +16,7 @@
*/
package com.itsaky.androidide.fragments.sheets;
-import android.graphics.Color;
-import android.text.SpannableString;
import android.text.SpannableStringBuilder;
-import android.text.style.ForegroundColorSpan;
import android.view.ViewGroup;
import android.widget.LinearLayout;
@@ -51,29 +48,23 @@ public TextSheetFragment setTitleText(String res) {
}
public void append(String text) {
- append(text, -1, true);
+ append(text, true);
}
- public void append(String text, int spanColor, boolean appendLine) {
+ public void append(String text, boolean appendLine) {
if (text != null && text.trim().length() > 0) {
- appendInternal(appendLine && !text.endsWith("\n") ? text.concat("\n") : text, spanColor);
+ appendInternal(appendLine && !text.endsWith("\n") ? text.concat("\n") : text);
}
}
- private void appendInternal(String text, int spanColor) {
- SpannableString str = new SpannableString(text);
- str.setSpan(
- new ForegroundColorSpan(spanColor == -1 ? Color.WHITE : spanColor),
- 0,
- text.length(),
- SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
- getOutputBuilder().append(str);
+ private void appendInternal(String text) {
+ getOutputBuilder().append(text);
if (mDialog != null && mDialog.isShowing()) {
- setToEditor(str);
+ setToEditor(text);
}
}
- private void setToEditor(SpannableString line) {
+ private void setToEditor(CharSequence line) {
if (getActivity() != null)
getActivity()
.runOnUiThread(
diff --git a/app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt b/app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt
index aecf2abda8..fee703029d 100644
--- a/app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt
+++ b/app/src/main/java/com/itsaky/androidide/handlers/EditorBuildEventListener.kt
@@ -20,7 +20,7 @@ package com.itsaky.androidide.handlers
import com.itsaky.androidide.activities.editor.EditorHandlerActivity
import com.itsaky.androidide.preferences.internal.isFirstBuild
import com.itsaky.androidide.resources.R.string
-import com.itsaky.androidide.services.GradleBuildService
+import com.itsaky.androidide.services.builder.GradleBuildService
import com.itsaky.androidide.tooling.events.ProgressEvent
import com.itsaky.androidide.tooling.events.configuration.ProjectConfigurationStartEvent
import com.itsaky.androidide.tooling.events.task.TaskStartEvent
diff --git a/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt b/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt
index acee8276f5..5a77892906 100644
--- a/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt
+++ b/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt
@@ -47,22 +47,24 @@ import com.itsaky.androidide.tasks.executeAsync
import com.itsaky.androidide.utils.ApkInstaller
import com.itsaky.androidide.utils.DialogUtils
import com.itsaky.androidide.utils.Environment
+import com.itsaky.androidide.utils.FlashType.ERROR
+import com.itsaky.androidide.utils.FlashType.SUCCESS
import com.itsaky.androidide.utils.InstallationResultHandler
import com.itsaky.androidide.utils.IntentUtils.startIntent
import com.itsaky.androidide.utils.ProjectWriter
import com.itsaky.androidide.utils.SingleTextWatcher
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.Toaster.Type.SUCCESS
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashError
+import com.itsaky.androidide.utils.flashMessage
+import com.itsaky.androidide.utils.flashSuccess
import com.unnamed.b.atv.model.TreeNode
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode.MAIN
import java.io.File
import java.util.Objects
import java.util.regex.Pattern.compile
import java.util.regex.Pattern.quote
-import javax.lang.model.SourceVersion
-import org.greenrobot.eventbus.EventBus
-import org.greenrobot.eventbus.Subscribe
-import org.greenrobot.eventbus.ThreadMode.MAIN
+import jdkx.lang.model.SourceVersion
/**
* Handles events related to files in filetree.
@@ -141,7 +143,7 @@ class FileTreeActionHandler : BaseEventHandler() {
when (option.id) {
ID_COPY_PATH -> {
ClipboardUtils.copyText("[AndroidIDE] Copied File Path", file.absolutePath)
- toast(string.copied, SUCCESS)
+ flashSuccess(string.copied)
}
ID_RENAME_FILE -> renameFile(context, file)
ID_DELETE_FILE -> delete(context, file)
@@ -247,7 +249,7 @@ class FileTreeActionHandler : BaseEventHandler() {
builder.setPositiveButton(string.text_create) { dialogInterface, _ ->
dialogInterface.dismiss()
if (binding.name.isErrorEnabled) {
- toast(string.msg_invalid_name, ERROR)
+ flashError(string.msg_invalid_name)
return@setPositiveButton
}
@@ -255,7 +257,7 @@ class FileTreeActionHandler : BaseEventHandler() {
val autoLayout = binding.checkButton.isChecked
val pkgName = ProjectWriter.getPackageName(file)
if (pkgName == null || pkgName.trim { it <= ' ' }.isEmpty()) {
- toast(string.msg_get_package_failed, ERROR)
+ flashError(string.msg_get_package_failed)
return@setPositiveButton
}
@@ -312,12 +314,12 @@ class FileTreeActionHandler : BaseEventHandler() {
val layoutName = ProjectWriter.createLayoutName(fileName.replace(".java", ".xml"))
val newFileLayout = File(dir, layoutName)
if (newFileLayout.exists()) {
- toast(string.msg_file_exists, ERROR)
+ flashError(string.msg_file_exists)
return
}
if (!FileIOUtils.writeFileFromString(newFileLayout, ProjectWriter.createLayout())) {
- toast(string.msg_file_creation_failed, ERROR)
+ flashError(string.msg_file_creation_failed)
return
}
@@ -407,23 +409,23 @@ class FileTreeActionHandler : BaseEventHandler() {
content: String
): Boolean {
if (name.length !in 1..40 || name.startsWith("/")) {
- toast(string.msg_invalid_name, ERROR)
+ flashError(string.msg_invalid_name)
return false
}
val newFile = File(directory, name)
if (newFile.exists()) {
- toast(string.msg_file_exists, ERROR)
+ flashError(string.msg_file_exists)
return false
}
if (!FileIOUtils.writeFileFromString(newFile, content)) {
- toast(string.msg_file_creation_failed, ERROR)
+ flashError(string.msg_file_creation_failed)
return false
}
notifyFileCreated(newFile, context)
// TODO Notify language servers about file created event
- toast(string.msg_file_created, SUCCESS)
+ flashSuccess(string.msg_file_created)
if (lastHeld != null) {
val node = TreeNode(newFile)
node.viewHolder = FileTreeViewHolder(context)
@@ -448,22 +450,22 @@ class FileTreeActionHandler : BaseEventHandler() {
dialogInterface.dismiss()
val name: String = binding.name.editText!!.text.toString().trim()
if (name.length !in 1..40 || name.startsWith("/")) {
- toast(string.msg_invalid_name, ERROR)
+ flashError(string.msg_invalid_name)
return@setPositiveButton
}
val newDir = File(currentDir, name)
if (newDir.exists()) {
- toast(string.msg_folder_exists, ERROR)
+ flashError(string.msg_folder_exists)
return@setPositiveButton
}
if (!newDir.mkdirs()) {
- toast(string.msg_folder_creation_failed, ERROR)
+ flashError(string.msg_folder_creation_failed)
return@setPositiveButton
}
- toast(string.msg_folder_created, SUCCESS)
+ flashSuccess(string.msg_folder_created)
if (lastHeld != null) {
val node = TreeNode(newDir)
node.viewHolder = FileTreeViewHolder(context)
@@ -491,7 +493,7 @@ class FileTreeActionHandler : BaseEventHandler() {
val deleted = it ?: false
- toast(
+ flashMessage(
if (deleted) string.deleted else string.delete_failed,
if (deleted) SUCCESS else ERROR
)
@@ -544,7 +546,10 @@ class FileTreeActionHandler : BaseEventHandler() {
dialogInterface.dismiss()
val name: String = binding.name.editText!!.text.toString().trim()
val renamed = name.length in 1..40 && FileUtils.rename(file, name)
- toast(if (renamed) string.renamed else string.rename_failed, if (renamed) SUCCESS else ERROR)
+ flashMessage(
+ if (renamed) string.renamed else string.rename_failed,
+ if (renamed) SUCCESS else ERROR
+ )
if (!renamed) {
return@setPositiveButton
}
diff --git a/app/src/main/java/com/itsaky/androidide/interfaces/IProjectHandler.kt b/app/src/main/java/com/itsaky/androidide/interfaces/IProjectHandler.kt
index 0839cbfe0c..4fe4c63c5e 100644
--- a/app/src/main/java/com/itsaky/androidide/interfaces/IProjectHandler.kt
+++ b/app/src/main/java/com/itsaky/androidide/interfaces/IProjectHandler.kt
@@ -34,5 +34,5 @@ interface IProjectHandler {
fun startServices()
fun initializeProject()
- fun stopServices()
+ fun stopLanguageServers()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/itsaky/androidide/lsp/IDELanguageClientImpl.java b/app/src/main/java/com/itsaky/androidide/lsp/IDELanguageClientImpl.java
index 75f47e6c54..7b6586a282 100755
--- a/app/src/main/java/com/itsaky/androidide/lsp/IDELanguageClientImpl.java
+++ b/app/src/main/java/com/itsaky/androidide/lsp/IDELanguageClientImpl.java
@@ -46,10 +46,9 @@
import com.itsaky.androidide.models.SearchResult;
import com.itsaky.androidide.tasks.TaskExecutor;
import com.itsaky.androidide.ui.editor.CodeEditorView;
+import com.itsaky.androidide.utils.FlashbarActivityUtilsKt;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.LSPUtils;
-import com.itsaky.toaster.ToastUtilsKt;
-import com.itsaky.toaster.Toaster;
import java.io.File;
import java.util.ArrayList;
@@ -104,6 +103,9 @@ public static IDELanguageClientImpl getInstance() {
}
public static void shutdown() {
+ if (mInstance != null) {
+ mInstance.activity = null;
+ }
mInstance = null;
}
@@ -182,7 +184,7 @@ public void performCodeAction(IDEEditor editor, CodeActionItem action) {
"activity=" + activity(),
"editor=" + editor,
"action=" + action);
- ToastUtilsKt.toast(string.msg_cannot_perform_fix, Toaster.Type.ERROR);
+ FlashbarActivityUtilsKt.flashError(activity(), string.msg_cannot_perform_fix);
return;
}
@@ -199,7 +201,7 @@ public void performCodeAction(IDEEditor editor, CodeActionItem action) {
if (result == null || throwable != null || !result) {
LOG.error(
"Unable to perform code action", "result=" + result, "throwable=" + throwable);
- ToastUtilsKt.toast(string.msg_cannot_perform_fix, Toaster.Type.ERROR);
+ FlashbarActivityUtilsKt.flashError(activity(), string.msg_cannot_perform_fix);
} else {
editor.executeCommand(action.getCommand());
}
@@ -309,7 +311,7 @@ public DiagnosticsAdapter newDiagnosticsAdapter() {
private List mapAsGroup(Map> map) {
final var groups = new ArrayList();
var diagnosticMap = map;
- if (diagnosticMap == null || diagnosticMap.size() <= 0) return groups;
+ if (diagnosticMap == null || diagnosticMap.size() == 0) return groups;
if (diagnosticMap.size() > 10) {
LOG.warn("Limiting the diagnostics to 10 files");
@@ -318,7 +320,7 @@ private List mapAsGroup(Map> map) {
for (File file : diagnosticMap.keySet()) {
var fileDiagnostics = diagnosticMap.get(file);
- if (fileDiagnostics == null || fileDiagnostics.size() <= 0) continue;
+ if (fileDiagnostics == null || fileDiagnostics.size() == 0) continue;
// Trim the diagnostics list if we have too many diagnostic items.
// Including a lot of diagnostic items will result in UI lag when they are shown
diff --git a/app/src/main/java/com/itsaky/androidide/preferences/buildAndRun.kt b/app/src/main/java/com/itsaky/androidide/preferences/buildAndRun.kt
index 3cf23c4bb6..e035fac426 100644
--- a/app/src/main/java/com/itsaky/androidide/preferences/buildAndRun.kt
+++ b/app/src/main/java/com/itsaky/androidide/preferences/buildAndRun.kt
@@ -23,8 +23,6 @@ import android.os.Build.VERSION_CODES
import androidx.preference.Preference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputLayout
-import com.itsaky.androidide.resources.R.drawable
-import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.app.BaseApplication
import com.itsaky.androidide.preferences.internal.CUSTOM_GRADLE_INSTALLATION
import com.itsaky.androidide.preferences.internal.GRADLE_CLEAR_CACHE
@@ -39,10 +37,12 @@ import com.itsaky.androidide.preferences.internal.isScanEnabled
import com.itsaky.androidide.preferences.internal.isStacktraceEnabled
import com.itsaky.androidide.preferences.internal.isWarningModeAllEnabled
import com.itsaky.androidide.preferences.internal.tpFix
+import com.itsaky.androidide.resources.R.drawable
+import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.tasks.executeAsync
import com.itsaky.androidide.utils.Environment.GRADLE_USER_HOME
-import com.itsaky.toaster.toastError
-import com.itsaky.toaster.toastSuccess
+import com.itsaky.androidide.utils.flashError
+import com.itsaky.androidide.utils.flashSuccess
import java.io.File
import kotlinx.parcelize.Parcelize
@@ -162,7 +162,7 @@ private class TagPointersFix(
}
@Parcelize
-private class GradleClearCache (
+private class GradleClearCache(
override val key: String = GRADLE_CLEAR_CACHE,
override val title: Int = string.idepref_build_clearCache_title,
override val summary: Int? = string.idepref_build_clearCache_summary,
@@ -176,9 +176,9 @@ private class GradleClearCache (
dlg.dismiss()
executeAsync(callable = this::deleteCaches) {
if (it == true) {
- toastSuccess(string.deleted)
+ flashSuccess(string.deleted)
} else {
- toastError(string.delete_failed)
+ flashError(string.delete_failed)
}
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/services/BuildInProgressException.java b/app/src/main/java/com/itsaky/androidide/services/builder/BuildInProgressException.java
similarity index 95%
rename from app/src/main/java/com/itsaky/androidide/services/BuildInProgressException.java
rename to app/src/main/java/com/itsaky/androidide/services/builder/BuildInProgressException.java
index 366daf716b..ea5a73dff9 100644
--- a/app/src/main/java/com/itsaky/androidide/services/BuildInProgressException.java
+++ b/app/src/main/java/com/itsaky/androidide/services/builder/BuildInProgressException.java
@@ -15,7 +15,7 @@
* along with AndroidIDE. If not, see .
*/
-package com.itsaky.androidide.services;
+package com.itsaky.androidide.services.builder;
/**
* Thrown when a build is requested but another build is already in progress.
diff --git a/app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java b/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java
similarity index 77%
rename from app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java
rename to app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java
index 048233404f..413ca419be 100644
--- a/app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java
+++ b/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java
@@ -15,7 +15,7 @@
* along with AndroidIDE. If not, see .
*/
-package com.itsaky.androidide.services;
+package com.itsaky.androidide.services.builder;
import static com.itsaky.androidide.managers.ToolsManager.getCommonAsset;
import static com.itsaky.androidide.preferences.internal.BuildPreferencesKt.getGradleInstallationDir;
@@ -34,7 +34,6 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.os.Binder;
import android.os.IBinder;
import android.text.TextUtils;
@@ -51,8 +50,9 @@
import com.itsaky.androidide.projects.ProjectManager;
import com.itsaky.androidide.projects.builder.BuildService;
import com.itsaky.androidide.resources.R;
-import com.itsaky.androidide.shell.CommonProcessExecutor;
+import com.itsaky.androidide.services.ToolingServerNotStartedException;
import com.itsaky.androidide.shell.ProcessStreamsHolder;
+import com.itsaky.androidide.tooling.api.ForwardingToolingApiClient;
import com.itsaky.androidide.tooling.api.IProject;
import com.itsaky.androidide.tooling.api.IToolingApiClient;
import com.itsaky.androidide.tooling.api.IToolingApiServer;
@@ -63,11 +63,11 @@
import com.itsaky.androidide.tooling.api.messages.result.GradleWrapperCheckResult;
import com.itsaky.androidide.tooling.api.messages.result.InitializeResult;
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult;
-import com.itsaky.androidide.tooling.api.util.ToolingApiLauncher;
import com.itsaky.androidide.tooling.events.ProgressEvent;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.ILogger;
-import com.itsaky.androidide.utils.InputStreamLineReader;
+
+import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
@@ -76,7 +76,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
-import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -85,18 +84,27 @@
*
* @author Akash Yadav
*/
-public class GradleBuildService extends Service implements BuildService, IToolingApiClient {
+public class GradleBuildService extends Service implements BuildService, IToolingApiClient, ToolingServerRunner.Observer {
private static final ILogger LOG = newInstance("GradleBuildService");
private static final int NOTIFICATION_ID = R.string.app_name;
private static final ILogger SERVER_System_err = newInstance("ToolingApiErrorStream");
private final ILogger SERVER_LOGGER = newInstance("ToolingApiServer");
- private final IBinder mBinder = new GradleServiceBinder();
+ private final IBinder mBinder = new GradleServiceBinder(this);
private boolean isToolingServerStarted = false;
private boolean isBuildInProgress = false;
+
+ /**
+ * We do not provide direct access to GradleBuildService instance to the Tooling API launcher as
+ * it may cause memory leaks. Instead, we create another client object which forwards all calls to us.
+ * So, when the service is destroyed, we release the reference to the service from this client.
+ */
+ private ForwardingToolingApiClient _toolingApiClient;
private ToolingServerRunner toolingServerThread;
+ private OutputReaderThread outputReader;
private NotificationManager notificationManager;
private IToolingApiServer server;
+ @Nullable
private EventListener eventListener;
@Override
@@ -111,6 +119,7 @@ public boolean isToolingServerStarted() {
return isToolingServerStarted;
}
+ @SuppressWarnings("SameParameterValue")
private void showNotification(final String message, final boolean isProgress) {
LOG.info("Showing notification to user...");
startForeground(NOTIFICATION_ID, buildNotification(message, isProgress));
@@ -154,11 +163,32 @@ public void onDestroy() {
notificationManager.cancel(NOTIFICATION_ID);
if (server != null) {
server.cancelCurrentBuild();
- server.shutdown();
+ final var shutdown = server.shutdown();
+
+ //noinspection ConstantConditions
+ if (shutdown != null) {
+ try {
+ LOG.info("Shutting down Tooling API server...");
+ shutdown.get();
+ } catch (Throwable e) {
+ LOG.error("Failed to shutdown Tooling API server", e);
+ }
+ }
}
if (toolingServerThread != null) {
toolingServerThread.interrupt();
+ toolingServerThread = null;
+ }
+
+ if (_toolingApiClient != null) {
+ _toolingApiClient.setClient(null);
+ _toolingApiClient = null;
+ }
+
+ if (outputReader != null) {
+ outputReader.interrupt();
+ outputReader = null;
}
isToolingServerStarted = false;
@@ -170,7 +200,31 @@ public IBinder onBind(Intent intent) {
LOG.debug("onBind() called with: intent = [" + intent + "]");
return mBinder;
}
-
+
+ @Override
+ public void onListenerStarted(@NotNull final IToolingApiServer server, @NotNull IProject projectProxy, @NotNull final ProcessStreamsHolder streams) {
+ startServerOutputReader(streams.err);
+ this.server = server;
+ Lookup.DEFAULT.update(BuildService.KEY_PROJECT_PROXY, projectProxy);
+ this.isToolingServerStarted = true;
+ ProjectManager.INSTANCE.setupProject(projectProxy);
+ }
+
+ @Override
+ public void onServerExited(int exitCode) {
+ LOG.warn("Tooling API process terminated with exit code:", exitCode);
+ stopForeground(true);
+ }
+
+ @NonNull
+ @Override
+ public IToolingApiClient getClient() {
+ if (_toolingApiClient == null) {
+ _toolingApiClient = new ForwardingToolingApiClient(this);
+ }
+ return _toolingApiClient;
+ }
+
@Override
public void logMessage(@NonNull LogLine line) {
SERVER_LOGGER.log(line.priority, line.formattedTagAndMessage());
@@ -400,14 +454,14 @@ protected T markBuildAsFinished(final T result, final Throwable throwable) {
return result;
}
- public void startToolingServer(@Nullable OnServerStartListener listener) {
+ public void startToolingServer(@Nullable ToolingServerRunner.OnServerStartListener listener) {
if (toolingServerThread == null || !toolingServerThread.isAlive()) {
- toolingServerThread = new ToolingServerRunner(listener);
+ toolingServerThread = new ToolingServerRunner(listener, this);
toolingServerThread.start();
return;
}
- if (toolingServerThread.isStarted && listener != null) {
+ if (toolingServerThread.isStarted() && listener != null) {
listener.onServerStarted();
} else {
toolingServerThread.setListener(listener);
@@ -415,6 +469,11 @@ public void startToolingServer(@Nullable OnServerStartListener listener) {
}
public GradleBuildService setEventListener(EventListener eventListener) {
+ if (eventListener == null) {
+ this.eventListener = null;
+ return this;
+ }
+
this.eventListener = wrap(eventListener);
return this;
}
@@ -458,118 +517,16 @@ public void onOutput(String line) {
};
}
- protected void onServerExited(int exitCode) {
- LOG.warn("Tooling API process terminated with exit code:", exitCode);
- stopForeground(true);
- }
-
private void startServerOutputReader(InputStream err) {
- new Thread(new InputStreamLineReader(err, this::onServerOutput)).start();
- }
-
- protected void onServerOutput(String line) {
- SERVER_System_err.error(line);
- }
-
- public class GradleServiceBinder extends Binder {
- public GradleBuildService getService() {
- return GradleBuildService.this;
- }
- }
-
- private class ToolingServerRunner extends Thread {
-
- @Nullable private OnServerStartListener listener;
- private boolean isStarted = false;
-
- public ToolingServerRunner(@Nullable OnServerStartListener listener) {
- super(ToolingServerRunner.class.getSimpleName());
- this.listener = listener;
- }
-
- public void setListener(@Nullable final OnServerStartListener listener) {
- this.listener = listener;
+ if (outputReader == null) {
+ outputReader = new OutputReaderThread(err, SERVER_System_err::error);
}
-
- @Override
- public void run() {
- try {
- LOG.info("Starting tooling API server...");
- final var serverStreams = new ProcessStreamsHolder();
- final var executor = new CommonProcessExecutor();
- executor.execAsync(
- serverStreams,
- GradleBuildService.this::onServerExited,
- false,
-
- // The 'java' binary executable
- Environment.JAVA.getAbsolutePath(),
-
- // Allow reflective access to private members of classes in the following
- // packages:
- // - java.lang
- // - java.io
- // - java.util
- //
- // If any of the model classes in 'tooling-api-model' module send/receive
- // objects from the JDK, their package name must be declared here with
- // '--add-opens' to prevent InaccessibleObjectException.
- // For example, some of the model classes has members of type java.io.File.
- // When sending/receiving these type of objects using LSP4J, members of
- // these objects are reflectively accessed by Gson. If we do no specify
- // '--add-opens' for 'java.io' (for java.io.File) package, JVM will throw an
- // InaccessibleObjectException.
- "--add-opens",
- "java.base/java.lang=ALL-UNNAMED",
- "--add-opens",
- "java.base/java.util=ALL-UNNAMED",
- "--add-opens",
- "java.base/java.io=ALL-UNNAMED",
-
- // The JAR file to run
- "-jar",
- Environment.TOOLING_API_JAR.getAbsolutePath());
-
- final var launcher =
- ToolingApiLauncher.newClientLauncher(
- GradleBuildService.this, serverStreams.in, serverStreams.out);
- final var future = launcher.startListening();
-
- GradleBuildService.this.startServerOutputReader(serverStreams.err);
- GradleBuildService.this.server = (IToolingApiServer) launcher.getRemoteProxy();
- Lookup.DEFAULT.update(KEY_PROJECT_PROXY, ((IProject) launcher.getRemoteProxy()));
-
- GradleBuildService.this.isToolingServerStarted = true;
-
- ProjectManager.INSTANCE.setupProject();
-
- isStarted = true;
- if (listener != null) {
- listener.onServerStarted();
- }
-
- // Wait(block) until the process terminates
- try {
- future.get();
- } catch (Throwable err) {
- if (!(err instanceof CancellationException) && !(err instanceof InterruptedException)) {
- LOG.error("An error occurred while waiting for tooling API server to terminate", err);
- }
- }
-
- } catch (Throwable e) {
- LOG.error("Unable to start tooling API server", e);
- }
+
+ if (!outputReader.isAlive()) {
+ outputReader.start();
}
}
-
- /** Callback to listen for Tooling API server start event. */
- public interface OnServerStartListener {
-
- /** Called when the tooling API server has been successfully started. */
- void onServerStarted();
- }
-
+
/** Handles events received from a Gradle build. */
public interface EventListener {
diff --git a/app/src/main/java/com/itsaky/androidide/services/GradleBuildServiceConnnection.kt b/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildServiceConnnection.kt
similarity index 82%
rename from app/src/main/java/com/itsaky/androidide/services/GradleBuildServiceConnnection.kt
rename to app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildServiceConnnection.kt
index cad035f000..1fbb999862 100644
--- a/app/src/main/java/com/itsaky/androidide/services/GradleBuildServiceConnnection.kt
+++ b/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildServiceConnnection.kt
@@ -15,12 +15,11 @@
* along with AndroidIDE. If not, see .
*/
-package com.itsaky.androidide.services
+package com.itsaky.androidide.services.builder
import android.content.ComponentName
import android.content.ServiceConnection
import android.os.IBinder
-import com.itsaky.androidide.services.GradleBuildService.GradleServiceBinder
import com.itsaky.androidide.utils.ILogger
/**
@@ -30,15 +29,16 @@ import com.itsaky.androidide.utils.ILogger
*/
class GradleBuildServiceConnnection : ServiceConnection {
- internal var onConnected: (GradleBuildService) -> Unit = {}
+ internal var onConnected: ((GradleBuildService) -> Unit)? = null
private val log = ILogger.newInstance("GradleBuildServiceConnnection")
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
- val buildService = (service as GradleServiceBinder).service
- onConnected(buildService)
+ val serviceBinder = service as GradleServiceBinder
+ onConnected?.invoke(serviceBinder.service!!)
}
override fun onServiceDisconnected(name: ComponentName?) {
+ onConnected = null
log.info("Disconnected from Gradle build service")
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/GradleServiceBinder.kt b/app/src/main/java/com/itsaky/androidide/services/builder/GradleServiceBinder.kt
new file mode 100644
index 0000000000..7fda46adb5
--- /dev/null
+++ b/app/src/main/java/com/itsaky/androidide/services/builder/GradleServiceBinder.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.androidide.services.builder
+
+import android.os.Binder
+
+/**
+ * [Binder] implementation for [GradleBuildService] which provides a single-use instance of the
+ * service.
+ *
+ * @author Akash Yadav
+ */
+internal class GradleServiceBinder(service: GradleBuildService?) : Binder() {
+
+ private var released = false
+ var service: GradleBuildService? = service
+ private set
+ get() {
+ check(!released) { "GradleBuildService instance has been released" }
+ return field.also { release() }
+ }
+
+ private fun release() {
+ service = null
+ released = true
+ }
+}
diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/OutputReaderThread.kt b/app/src/main/java/com/itsaky/androidide/services/builder/OutputReaderThread.kt
new file mode 100644
index 0000000000..3632f9fd84
--- /dev/null
+++ b/app/src/main/java/com/itsaky/androidide/services/builder/OutputReaderThread.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.androidide.services.builder
+
+import java.io.InputStream
+import java.util.function.Consumer
+
+/**
+ * Reads output from the Tooling API server.
+ *
+ * @author Akash Yadav
+ */
+class OutputReaderThread(private val input: InputStream, private var onRead: Consumer?) :
+ Thread("ToolingServerOutputReader") {
+
+ override fun run() {
+ input.bufferedReader().use {
+ var line: String? = it.readLine()
+ while (line != null) {
+ onRead?.accept(line)
+ line = it.readLine()
+ }
+ }
+ }
+
+ override fun interrupt() {
+ super.interrupt()
+ onRead = null
+ }
+}
diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt b/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt
new file mode 100644
index 0000000000..3c1f008daf
--- /dev/null
+++ b/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.androidide.services.builder
+
+import com.itsaky.androidide.shell.CommonProcessExecutor
+import com.itsaky.androidide.shell.ProcessStreamsHolder
+import com.itsaky.androidide.tooling.api.IProject
+import com.itsaky.androidide.tooling.api.IToolingApiClient
+import com.itsaky.androidide.tooling.api.IToolingApiServer
+import com.itsaky.androidide.tooling.api.util.ToolingApiLauncher
+import com.itsaky.androidide.utils.Environment
+import com.itsaky.androidide.utils.ILogger
+import java.util.concurrent.CancellationException
+
+/**
+ * Runner thread for the Tooling API.
+ *
+ * @author Akash Yadav
+ */
+internal class ToolingServerRunner(
+ private var listener: OnServerStartListener?,
+ private var observer: Observer?,
+) : Thread(ToolingServerRunner::class.java.simpleName) {
+
+ var isStarted = false
+ private set
+
+ private val log = ILogger.newInstance("ToolingServerRunner")
+
+ fun setListener(listener: OnServerStartListener?) {
+ this.listener = listener
+ }
+
+ override fun run() {
+ try {
+ log.info("Starting tooling API server...")
+ val serverStreams = ProcessStreamsHolder()
+ val executor = CommonProcessExecutor()
+ executor.execAsync(
+ serverStreams,
+ { observer?.onServerExited(it) },
+ false, // The 'java' binary executable
+ Environment.JAVA
+ .absolutePath, // Allow reflective access to private members of classes in the following
+ // packages:
+ // - java.lang
+ // - java.io
+ // - java.util
+ //
+ // If any of the model classes in 'tooling-api-model' module send/receive
+ // objects from the JDK, their package name must be declared here with
+ // '--add-opens' to prevent InaccessibleObjectException.
+ // For example, some of the model classes has members of type java.io.File.
+ // When sending/receiving these type of objects using LSP4J, members of
+ // these objects are reflectively accessed by Gson. If we do no specify
+ // '--add-opens' for 'java.io' (for java.io.File) package, JVM will throw an
+ // InaccessibleObjectException.
+ "--add-opens",
+ "java.base/java.lang=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/java.util=ALL-UNNAMED",
+ "--add-opens",
+ "java.base/java.io=ALL-UNNAMED", // The JAR file to run
+ "-jar",
+ Environment.TOOLING_API_JAR.absolutePath
+ )
+
+ val launcher =
+ ToolingApiLauncher.newClientLauncher(
+ observer?.getClient(),
+ serverStreams.`in`,
+ serverStreams.out
+ )
+
+ val future = launcher.startListening()
+ observer?.onListenerStarted(
+ server = launcher.remoteProxy as IToolingApiServer,
+ projectProxy = launcher.remoteProxy as IProject,
+ streams = serverStreams
+ )
+
+ isStarted = true
+
+ if (listener != null) {
+ listener!!.onServerStarted()
+
+ // we don't need the listener anymore
+ // also, this might be a reference to the activity
+ // release to prevent memory leak
+ listener = null
+ }
+
+ // Wait(block) until the process terminates
+ try {
+ future.get()
+ } catch (err: Throwable) {
+ when (err) {
+ is CancellationException,
+ is InterruptedException,
+ -> log.info("ToolingServerThread has been cancelled or interrupted.")
+ else -> throw err
+ }
+ }
+ } catch (e: Throwable) {
+ log.error("Unable to start tooling API server", e)
+ }
+ }
+
+ override fun interrupt() {
+ super.interrupt()
+ listener = null
+ observer = null
+ }
+
+ interface Observer {
+ fun onListenerStarted(
+ server: IToolingApiServer,
+ projectProxy: IProject,
+ streams: ProcessStreamsHolder,
+ )
+ fun onServerExited(exitCode: Int)
+ fun getClient(): IToolingApiClient
+ }
+
+ /** Callback to listen for Tooling API server start event. */
+ fun interface OnServerStartListener {
+ /** Called when the tooling API server has been successfully started. */
+ fun onServerStarted()
+ }
+}
diff --git a/app/src/main/java/com/itsaky/androidide/tasks/callables/ProjectCreatorCallable.java b/app/src/main/java/com/itsaky/androidide/tasks/callables/ProjectCreatorCallable.java
index 40737b8d5f..027844dea0 100755
--- a/app/src/main/java/com/itsaky/androidide/tasks/callables/ProjectCreatorCallable.java
+++ b/app/src/main/java/com/itsaky/androidide/tasks/callables/ProjectCreatorCallable.java
@@ -1,22 +1,19 @@
-/************************************************************************************
- * This file is part of AndroidIDE.
+/*
+ * 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.
*
- * 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 .
- *
- **************************************************************************************/
+ * You should have received a copy of the GNU General Public License
+ * along with AndroidIDE. If not, see .
+ */
package com.itsaky.androidide.tasks.callables;
@@ -29,9 +26,9 @@
public class ProjectCreatorCallable implements Callable {
- private ProjectTemplate template;
- private NewProjectDetails details;
- private ProjectWriterCallback callback;
+ private final ProjectTemplate template;
+ private final NewProjectDetails details;
+ private final ProjectWriterCallback callback;
public ProjectCreatorCallable(
ProjectTemplate template, NewProjectDetails details, ProjectWriterCallback callback) {
diff --git a/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt b/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt
index e63c4c29c4..77efeb5ddf 100644
--- a/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt
+++ b/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt
@@ -18,11 +18,9 @@
package com.itsaky.androidide.ui
import android.app.Activity
-import android.app.ProgressDialog
import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
-import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewTreeObserver
@@ -33,7 +31,6 @@ import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import androidx.transition.Slide
import androidx.transition.TransitionManager
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.SizeUtils
@@ -59,8 +56,7 @@ import com.itsaky.androidide.ui.editor.CodeEditorView
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.IntentUtils.shareFile
import com.itsaky.androidide.utils.Symbols.forFile
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashError
import java.io.File
import java.io.IOException
import java.nio.charset.StandardCharsets
@@ -142,7 +138,7 @@ constructor(
val filename = fragment.getFilename()
@Suppress("DEPRECATION")
- val progress = ProgressDialog.show(context, null, context.getString(string.please_wait))
+ val progress = android.app.ProgressDialog.show(context, null, context.getString(string.please_wait))
executeAsync(fragment::getContent) {
progress.dismiss()
shareText(it, filename)
@@ -261,10 +257,16 @@ constructor(
val activity = context as Activity
if (KeyboardUtils.isSoftInputVisible(activity)) {
- TransitionManager.beginDelayedTransition(binding.root, MaterialSharedAxis(MaterialSharedAxis.Y, false))
+ TransitionManager.beginDelayedTransition(
+ binding.root,
+ MaterialSharedAxis(MaterialSharedAxis.Y, false)
+ )
binding.headerContainer.displayedChild = CHILD_SYMBOL_INPUT
} else {
- TransitionManager.beginDelayedTransition(binding.root, MaterialSharedAxis(MaterialSharedAxis.Y, false))
+ TransitionManager.beginDelayedTransition(
+ binding.root,
+ MaterialSharedAxis(MaterialSharedAxis.Y, false)
+ )
binding.headerContainer.displayedChild = CHILD_HEADER
}
}
@@ -291,10 +293,10 @@ constructor(
@Suppress("DEPRECATION")
private fun shareText(text: String?, type: String) {
if (text == null || TextUtils.isEmpty(text)) {
- toast(context.getString(string.msg_output_text_extraction_failed), ERROR)
+ flashError(context.getString(string.msg_output_text_extraction_failed))
return
}
- val pd = ProgressDialog.show(context, null, context.getString(string.please_wait), true, false)
+ val pd = android.app.ProgressDialog.show(context, null, context.getString(string.please_wait), true, false)
executeAsyncProvideError(
Callable { writeTempFile(text, type) },
CallbackWithError { result: File?, error: Throwable? ->
diff --git a/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java b/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java
index a880d87d81..ae0aa40e0b 100644
--- a/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java
+++ b/app/src/main/java/com/itsaky/androidide/ui/editor/CodeEditorView.java
@@ -56,9 +56,9 @@
import com.itsaky.androidide.editor.language.treesitter.TreeSitterLanguage;
import com.itsaky.androidide.editor.language.cpp.CppLanguage;
import com.itsaky.androidide.editor.language.groovy.GroovyLanguage;
-import com.itsaky.androidide.editor.language.java.JavaLanguage;
import com.itsaky.androidide.editor.language.kotlin.KotlinLanguage;
-import com.itsaky.androidide.editor.language.xml.XMLLanguage;
+import com.itsaky.androidide.editor.language.treesitter.TreeSitterLanguageProvider;
+import com.itsaky.androidide.editor.schemes.IDEColorScheme;
import com.itsaky.androidide.editor.schemes.IDEColorSchemeProvider;
import com.itsaky.androidide.editor.ui.EditorSearchLayout;
import com.itsaky.androidide.editor.ui.IDEEditor;
@@ -88,6 +88,7 @@
import io.github.rosemoe.sora.lang.Language;
import io.github.rosemoe.sora.text.LineSeparator;
import io.github.rosemoe.sora.widget.component.Magnifier;
+import kotlin.io.FilesKt;
/**
* A view that handles opened code editors.
@@ -165,9 +166,10 @@ public IDEEditor getEditor() {
protected void postRead() {
final var language = createLanguage(file);
+ final var extension = FilesKt.getExtension(file);
if (language instanceof TreeSitterLanguage) {
IDEColorSchemeProvider.INSTANCE.readScheme(getContext(), scheme -> {
- applyTreeSitterLang(language, scheme);
+ applyTreeSitterLang(language, extension, scheme);
});
} else {
binding.editor.setEditorLanguage(language);
@@ -188,12 +190,17 @@ protected void postRead() {
}
}
- private void applyTreeSitterLang(final Language language, SchemeAndroidIDE scheme) {
+ private void applyTreeSitterLang(final Language language, final String extension, SchemeAndroidIDE scheme) {
if (scheme == null) {
LOG.error("Failed to read current color scheme");
scheme = SchemeAndroidIDE.newInstance(getContext());
}
-
+
+ if (scheme instanceof IDEColorScheme && ((IDEColorScheme) scheme).getLanguageScheme(extension) == null) {
+ LOG.warn("Color scheme does not support file type '" + extension + "'");
+ scheme = SchemeAndroidIDE.newInstance(getContext());
+ }
+
if (scheme instanceof DynamicColorScheme) {
((DynamicColorScheme) scheme).apply(getContext());
}
@@ -224,29 +231,31 @@ private ILanguageServer createLanguageServer(File file) {
}
private Language createLanguage(File file) {
- if (file.isFile()) {
- String ext = FileUtils.getFileExtension(file);
- switch (ext) {
- case "java":
- return new JavaLanguage(getContext());
- case "xml":
- return new XMLLanguage(getContext());
- case "gradle":
- return new GroovyLanguage();
- case "kt":
- case "kts":
- return new KotlinLanguage();
- case "c":
- case "h":
- case "cc":
- case "cpp":
- case "cxx":
- return new CppLanguage();
- default:
- return new EmptyLanguage();
- }
+ if (!file.isFile()) {
+ return new EmptyLanguage();
+ }
+
+ final var tsLang = TreeSitterLanguageProvider.INSTANCE.forFile(file, getContext());
+ if (tsLang != null) {
+ return tsLang;
+ }
+
+ String ext = FileUtils.getFileExtension(file);
+ switch (ext) {
+ case "gradle":
+ return new GroovyLanguage();
+ case "kt":
+ case "kts":
+ return new KotlinLanguage();
+ case "c":
+ case "h":
+ case "cc":
+ case "cpp":
+ case "cxx":
+ return new CppLanguage();
+ default:
+ return new EmptyLanguage();
}
- return new EmptyLanguage();
}
private void configureEditorIfNeeded() {
diff --git a/app/src/main/java/com/itsaky/androidide/utils/ApkInstallationSessionCallback.kt b/app/src/main/java/com/itsaky/androidide/utils/ApkInstallationSessionCallback.kt
new file mode 100644
index 0000000000..cd5ed55475
--- /dev/null
+++ b/app/src/main/java/com/itsaky/androidide/utils/ApkInstallationSessionCallback.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.androidide.utils
+
+import com.itsaky.androidide.R.string
+import com.itsaky.androidide.activities.editor.BaseEditorActivity
+import com.itsaky.androidide.ui.EditorBottomSheet
+
+/** @author Akash Yadav */
+class ApkInstallationSessionCallback(private var activity: BaseEditorActivity?) :
+ SingleSessionCallback() {
+
+ private val log = ILogger.newInstance("InstallationSessionCallback")
+
+ override fun onCreated(sessionId: Int) {
+ log.debug("on session created:", sessionId)
+ activity?.binding?.apply {
+ bottomSheet.setActionText(activity!!.getString(string.msg_installing_apk))
+ bottomSheet.setActionProgress(0)
+ bottomSheet.showChild(EditorBottomSheet.CHILD_ACTION)
+ }
+ }
+
+ override fun onProgressChanged(sessionId: Int, progress: Float) {
+ activity?.binding?.bottomSheet?.setActionProgress((progress * 100f).toInt())
+ }
+
+ override fun onFinished(sessionId: Int, success: Boolean) {
+ activity?.binding?.apply {
+ bottomSheet.showChild(EditorBottomSheet.CHILD_HEADER)
+ bottomSheet.setActionProgress(0)
+ if (!success) {
+ activity?.flashError(string.title_installation_failed)
+ }
+
+ activity?.let {
+ it.installationCallback?.destroy()
+ it.installationCallback = null
+ }
+ }
+ }
+
+ fun destroy() {
+ this.activity = null
+ }
+}
diff --git a/app/src/main/java/com/itsaky/androidide/utils/EditorActivityActions.kt b/app/src/main/java/com/itsaky/androidide/utils/EditorActivityActions.kt
index 3d2621c93e..0ebee07063 100644
--- a/app/src/main/java/com/itsaky/androidide/utils/EditorActivityActions.kt
+++ b/app/src/main/java/com/itsaky/androidide/utils/EditorActivityActions.kt
@@ -29,7 +29,6 @@ import com.itsaky.androidide.actions.editor.CutAction
import com.itsaky.androidide.actions.editor.ExpandSelectionAction
import com.itsaky.androidide.actions.editor.PasteAction
import com.itsaky.androidide.actions.editor.SelectAllAction
-import com.itsaky.androidide.actions.etc.DaemonStatusAction
import com.itsaky.androidide.actions.etc.FileTreeAction
import com.itsaky.androidide.actions.etc.FindActionMenu
import com.itsaky.androidide.actions.etc.PreviewLayoutAction
@@ -62,7 +61,6 @@ class EditorActivityActions {
registry.registerAction(PreviewLayoutAction(context))
registry.registerAction(FindActionMenu(context))
registry.registerAction(FileTreeAction(context))
- registry.registerAction(DaemonStatusAction(context))
registry.registerAction(CancelBuildAction(context))
registry.registerAction(ProjectSyncAction(context))
diff --git a/app/src/main/java/com/itsaky/androidide/utils/InstallationResultHandler.kt b/app/src/main/java/com/itsaky/androidide/utils/InstallationResultHandler.kt
index 5f6b3d2ed6..32fca159e4 100644
--- a/app/src/main/java/com/itsaky/androidide/utils/InstallationResultHandler.kt
+++ b/app/src/main/java/com/itsaky/androidide/utils/InstallationResultHandler.kt
@@ -68,6 +68,7 @@ object InstallationResultHandler {
val message = extras.getString(PackageInstaller.EXTRA_STATUS_MESSAGE)
return when (status) {
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
+ @Suppress("DEPRECATION")
extras.get(Intent.EXTRA_INTENT)?.let {
if (it is Intent) {
if ((it.flags and Intent.FLAG_ACTIVITY_NEW_TASK) != Intent.FLAG_ACTIVITY_NEW_TASK) {
diff --git a/app/src/main/java/com/itsaky/androidide/utils/ProjectWriter.java b/app/src/main/java/com/itsaky/androidide/utils/ProjectWriter.java
index d0570f814f..4046498564 100755
--- a/app/src/main/java/com/itsaky/androidide/utils/ProjectWriter.java
+++ b/app/src/main/java/com/itsaky/androidide/utils/ProjectWriter.java
@@ -29,11 +29,11 @@
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.ResourceUtils;
import com.blankj.utilcode.util.ThreadUtils;
-import com.itsaky.androidide.resources.R;
import com.itsaky.androidide.app.IDEApplication;
import com.itsaky.androidide.interfaces.ProjectWriterCallback;
import com.itsaky.androidide.models.NewProjectDetails;
import com.itsaky.androidide.models.ProjectTemplate;
+import com.itsaky.androidide.resources.R;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -168,37 +168,42 @@ public static void write(int id, NewProjectDetails details, ProjectWriterCallbac
if (!FileUtils.delete(tempDir) || !Environment.mkdirIfNotExits(tempDir).exists()) {
notifyFailed(instance.getString(R.string.cannot_create_temp));
}
+
notifyTask(instance.getString(R.string.copying_assets));
projectDir.mkdirs();
File destZip = new File(Environment.TMP_DIR, "templates/" + id + ".zip");
Environment.mkdirIfNotExits(destZip.getParentFile());
- if (ResourceUtils.copyFileFromAssets(
- "templates/" + destZip.getName(), destZip.getAbsolutePath())) {
- unzipTemplate(destZip, tempDir, details);
- notifyTask(instance.getString(R.string.writing_files));
- notifyTask(instance.getString(R.string.copying_files));
- if (FileUtils.createOrExistsDir(projectDir)) {
- boolean success = true;
- final var files = tempDir == null ? null : tempDir.listFiles();
- if (files == null) {
- success = false;
- } else {
- for (File f : files) {
- if (!(success &= FileUtils.copy(f, new File(projectDir, f.getName())))) {
- notifyFailed(instance.getString(R.string.failed_write_file, f.getName()));
- break;
- }
- }
- }
-
- if (success) {
- notifySuccess(projectDir);
+
+ if (!ResourceUtils.copyFileFromAssets(
+ "templates/" + destZip.getName(), destZip.getAbsolutePath())) {
+ notifyFailed(instance.getString(R.string.asset_copy_failed));
+ return;
+ }
+
+ unzipTemplate(destZip, tempDir, details);
+ notifyTask(instance.getString(R.string.writing_files));
+ notifyTask(instance.getString(R.string.copying_files));
+
+ if (!FileUtils.createOrExistsDir(projectDir)) {
+ notifyFailed(instance.getString(R.string.failed_create_project_dir));
+ return;
+ }
+
+ boolean success = true;
+ final var files = tempDir == null ? null : tempDir.listFiles();
+ if (files != null) {
+ for (File f : files) {
+ if (!(success &= FileUtils.copy(f, new File(projectDir, f.getName())))) {
+ notifyFailed(instance.getString(R.string.failed_write_file, f.getName()));
+ break;
}
- } else {
- notifyFailed(instance.getString(R.string.failed_create_project_dir));
}
} else {
- notifyFailed(instance.getString(R.string.asset_copy_failed));
+ success = false;
+ }
+
+ if (success) {
+ notifySuccess(projectDir);
}
}
@@ -324,6 +329,8 @@ private static void notifyTask(String name) {
}
private static void notifySuccess(File root) {
+ final var callback = ProjectWriter.callback;
+ ProjectWriter.callback = null;
ThreadUtils.runOnUiThread(
() -> {
if (callback != null) callback.onSuccess(root);
@@ -331,6 +338,8 @@ private static void notifySuccess(File root) {
}
private static void notifyFailed(String reason) {
+ final var callback = ProjectWriter.callback;
+ ProjectWriter.callback = null;
ThreadUtils.runOnUiThread(
() -> {
if (callback != null) callback.onFailed(reason);
diff --git a/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.kt b/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.kt
index 44e0a04eac..5e4801118e 100644
--- a/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.kt
+++ b/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.kt
@@ -224,12 +224,13 @@ class EditorViewModel : ViewModel() {
file = File(file, "editor/openedFiles.json")
if (file.exists()) {
FileUtils.rename(file, "${file.name}.bak")
- file.createNewFile()
}
if (file.parentFile?.exists() == false) {
file.parentFile?.mkdirs()
}
+
+ file.createNewFile()
return file
}
diff --git a/app/src/main/java/com/itsaky/androidide/viewmodel/WizardViewModel.java b/app/src/main/java/com/itsaky/androidide/viewmodel/WizardViewModel.java
index f918fbb52c..209655ed7f 100644
--- a/app/src/main/java/com/itsaky/androidide/viewmodel/WizardViewModel.java
+++ b/app/src/main/java/com/itsaky/androidide/viewmodel/WizardViewModel.java
@@ -8,17 +8,16 @@
import androidx.lifecycle.MutableLiveData;
import com.blankj.utilcode.util.CollectionUtils;
-import com.itsaky.androidide.resources.R;
import com.itsaky.androidide.interfaces.ProjectWriterCallback;
import com.itsaky.androidide.models.NewProjectDetails;
import com.itsaky.androidide.models.ProjectTemplate;
+import com.itsaky.androidide.resources.R;
import com.itsaky.androidide.tasks.TaskExecutor;
import com.itsaky.androidide.tasks.callables.ProjectCreatorCallable;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.Executors;
public class WizardViewModel extends AndroidViewModel {
diff --git a/build.gradle.kts b/build.gradle.kts
index 3f0959dcd9..968be9f5b5 100755
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -26,7 +26,9 @@ plugins {
alias(libs.plugins.kotlin) apply false
}
-buildscript { dependencies { classpath("com.google.android.gms:oss-licenses-plugin:0.10.6") } }
+buildscript { dependencies { classpath("com.google.android.gms:oss-licenses-plugin:0.10.6")
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10")
+} }
val Project.projectVersionCode by lazy {
val version = rootProject.version.toString()
diff --git a/common/build.gradle.kts b/common/build.gradle.kts
index 6b9494711a..5589ed80e5 100755
--- a/common/build.gradle.kts
+++ b/common/build.gradle.kts
@@ -25,6 +25,7 @@ dependencies {
implementation(projects.eventbusEvents)
implementation(projects.lexers)
implementation(projects.resources)
+ implementation(projects.subprojects.flashbar)
api(projects.shared)
api(projects.logger)
diff --git a/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java b/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java
index dbb9ece725..636fd96f96 100644
--- a/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java
+++ b/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java
@@ -31,12 +31,10 @@
import com.itsaky.androidide.managers.PreferenceManager;
import com.itsaky.androidide.managers.ToolsManager;
import com.itsaky.androidide.resources.R;
-import com.itsaky.androidide.shell.ShellServer;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.FileUtil;
+import com.itsaky.androidide.utils.FlashbarUtilsKt;
import com.itsaky.androidide.utils.JavaCharacter;
-import com.itsaky.toaster.ToastUtilsKt;
-import com.itsaky.toaster.Toaster;
import java.io.File;
import java.util.Arrays;
@@ -88,7 +86,6 @@ public static String getArch() {
public void onCreate() {
instance = this;
Environment.init();
- ToastUtilsKt.init();
super.onCreate();
mPrefsManager = new PreferenceManager(this);
@@ -106,23 +103,7 @@ private void createNotificationChannels() {
NotificationManager.IMPORTANCE_LOW);
NotificationManagerCompat.from(this).createNotificationChannel(buildNotificationChannel);
}
-
- public ShellServer newShell(ShellServer.Callback callback) {
- return newShell(callback, true);
- }
-
- public ShellServer newShell(ShellServer.Callback callback, boolean redirectErrors) {
- ShellServer shellServer =
- new ShellServer(
- callback,
- "sh",
- Environment.mkdirIfNotExits(getRootDir()).getAbsolutePath(),
- Environment.getEnvironment(),
- redirectErrors);
- shellServer.start();
- return shellServer;
- }
-
+
public File getRootDir() {
return new File(getIDEDataDir(), "home");
}
@@ -200,7 +181,7 @@ public void openUrl(String url, String pkg) {
if (pkg != null) {
openUrl(url);
} else {
- ToastUtilsKt.toast(th.getMessage(), Toaster.Type.ERROR);
+ FlashbarUtilsKt.flashError(th.getMessage());
}
}
}
diff --git a/common/src/main/java/com/itsaky/androidide/fragments/BaseFragment.kt b/common/src/main/java/com/itsaky/androidide/fragments/BaseFragment.kt
index 92e12a3f17..83aa1fdf46 100755
--- a/common/src/main/java/com/itsaky/androidide/fragments/BaseFragment.kt
+++ b/common/src/main/java/com/itsaky/androidide/fragments/BaseFragment.kt
@@ -40,16 +40,16 @@ import androidx.core.provider.DocumentsContractCompat.getTreeDocumentId
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment
import com.itsaky.androidide.resources.R.string
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
+import com.itsaky.androidide.utils.flashError
import java.io.File
-open class BaseFragment @JvmOverloads constructor(contentLayoutId: Int = 0) : Fragment(contentLayoutId) {
+open class BaseFragment @JvmOverloads constructor(contentLayoutId: Int = 0) :
+ Fragment(contentLayoutId) {
private var callback: OnDirectoryPickedCallback? = null
private val allowedAuthorities =
setOf(ANDROID_DOCS_AUTHORITY, ANDROIDIDE_DOCS_AUTHORITY, TERMUX_DOCS_AUTHORITY)
-
+
companion object {
const val ANDROID_DOCS_AUTHORITY = "com.android.externalstorage.documents"
const val ANDROIDIDE_DOCS_AUTHORITY = "com.itsaky.androidide.documents"
@@ -63,12 +63,12 @@ open class BaseFragment @JvmOverloads constructor(contentLayoutId: Int = 0) : Fr
val pickedDir = DocumentFile.fromTreeUri(context, uri)
if (pickedDir == null) {
- toast(getString(string.err_invalid_data_by_intent), ERROR)
+ flashError(string.err_invalid_data_by_intent)
return@registerForActivityResult
}
if (!pickedDir.exists()) {
- toast(getString(string.msg_picked_isnt_dir), ERROR)
+ flashError(getString(string.msg_picked_isnt_dir))
return@registerForActivityResult
}
@@ -77,7 +77,7 @@ open class BaseFragment @JvmOverloads constructor(contentLayoutId: Int = 0) : Fr
val authority = docUri.authority
if (!allowedAuthorities.contains(authority)) {
- toast(getString(string.err_authority_not_allowed, authority), ERROR)
+ flashError(getString(string.err_authority_not_allowed, authority))
return@registerForActivityResult
}
@@ -87,7 +87,7 @@ open class BaseFragment @JvmOverloads constructor(contentLayoutId: Int = 0) : Fr
} else {
val split = docId.split(':')
if ("primary" != split[0]) {
- toast(getString(string.msg_select_from_primary_storage), ERROR)
+ flashError(getString(string.msg_select_from_primary_storage))
return@registerForActivityResult
}
@@ -95,7 +95,7 @@ open class BaseFragment @JvmOverloads constructor(contentLayoutId: Int = 0) : Fr
}
if (!dir.exists() || !dir.isDirectory) {
- toast(getString(string.err_invalid_data_by_intent), ERROR)
+ flashError(getString(string.err_invalid_data_by_intent))
return@registerForActivityResult
}
diff --git a/common/src/main/java/com/itsaky/androidide/shell/CommonProcessExecutor.java b/common/src/main/java/com/itsaky/androidide/shell/CommonProcessExecutor.java
index b5d3e3887f..25aa2af4e1 100755
--- a/common/src/main/java/com/itsaky/androidide/shell/CommonProcessExecutor.java
+++ b/common/src/main/java/com/itsaky/androidide/shell/CommonProcessExecutor.java
@@ -116,7 +116,9 @@ public void run() {
// Ignored
}
- listener.onExit(proc.exitValue());
+ if (listener != null) {
+ listener.onExit(proc.exitValue());
+ }
}
}
}
diff --git a/common/src/main/java/com/itsaky/androidide/shell/ShellServer.java b/common/src/main/java/com/itsaky/androidide/shell/ShellServer.java
deleted file mode 100755
index 42f0b6e405..0000000000
--- a/common/src/main/java/com/itsaky/androidide/shell/ShellServer.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/************************************************************************************
- * 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.androidide.shell;
-
-import androidx.annotation.NonNull;
-
-import com.itsaky.androidide.utils.ILogger;
-
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Map;
-
-public class ShellServer extends Thread {
-
- private static final ILogger LOG = ILogger.newInstance("ShellServer");
- private final Callback callback;
- private BufferedReader output;
- private Process process;
-
- public ShellServer(
- Callback callback,
- String command,
- String dirPath,
- Map env,
- boolean redirectErrors) {
- this.callback = callback;
-
- ProcessBuilder processBuilder = new ProcessBuilder(command);
- processBuilder.directory(new File(dirPath));
- processBuilder.redirectErrorStream(redirectErrors);
- processBuilder.environment().putAll(env);
-
- try {
- this.process = processBuilder.start();
- this.output = new BufferedReader(new InputStreamReader(process.getInputStream()));
- } catch (Throwable th) {
- if (callback != null) {
- String out = getFullStackTrace(th).concat("\n");
- callback.output(out);
- }
- }
- }
-
- @NonNull
- private String getFullStackTrace(@NonNull Throwable th) {
- StringWriter sw = new StringWriter();
- th.printStackTrace(new PrintWriter(sw));
- return sw.toString();
- }
-
- public InputStream getProcessInputStream() {
- return process.getInputStream();
- }
-
- public OutputStream getProcessOutputStream() {
- return process.getOutputStream();
- }
-
- public void bgAppend(String str) {
- append(str, false);
- }
-
- public void append(String str, boolean z) {
- if (z) {
- try {
- if (str.endsWith("\n")) {
- output(str);
- } else {
- output(str.concat("\n"));
- }
- } catch (Throwable th) {
- output(th.toString().concat("\n"));
- return;
- }
- }
- try {
- this.process.getOutputStream().write(str.concat("\n").getBytes());
- this.process.getOutputStream().flush();
- } catch (Throwable e) {
- LOG.error("Unable to write to shell server", e);
- }
- }
-
- public void output(String str) {
- if (this.callback != null) {
- this.callback.output(str);
- }
- }
-
- public void append(@NonNull String... strArr) {
- for (String append : strArr) {
- append(append);
- }
- }
-
- public void append(String str) {
- append(str, true);
- }
-
- public void exit() {
- append("exit");
- }
-
- @Override
- public void run() {
- while (true) {
- try {
- String readLine = this.output.readLine();
- if (readLine == null) {
- break;
- }
- output(readLine.concat("\n"));
- } catch (Throwable th) {
- output(th.toString().concat("\n"));
- }
- }
- closeIOQuietly(
- this.output,
- this.process.getInputStream(),
- this.process.getErrorStream(),
- this.process.getOutputStream());
- this.process.destroy();
- }
-
- private void closeIOQuietly(@NonNull Closeable... toClose) {
- for (Closeable c : toClose) {
- try {
- c.close();
- } catch (IOException e) {
- // ignored
- }
- }
- }
-
- public interface Callback {
- void output(String charSequence);
- }
-}
diff --git a/common/src/main/java/com/itsaky/androidide/syntax/colorschemes/SchemeAndroidIDE.java b/common/src/main/java/com/itsaky/androidide/syntax/colorschemes/SchemeAndroidIDE.java
index 73ea27bac6..b2999fb3ac 100644
--- a/common/src/main/java/com/itsaky/androidide/syntax/colorschemes/SchemeAndroidIDE.java
+++ b/common/src/main/java/com/itsaky/androidide/syntax/colorschemes/SchemeAndroidIDE.java
@@ -112,6 +112,9 @@ public static long withoutCompletion(int id) {
}
public static SchemeAndroidIDE newInstance(Context context) {
+ if (context == null) {
+ return new SchemeAndroidIDE();
+ }
final var scheme = new DynamicColorScheme();
scheme.apply(context);
return scheme;
diff --git a/common/src/main/java/com/itsaky/androidide/utils/BootstrapInstaller.java b/common/src/main/java/com/itsaky/androidide/utils/BootstrapInstaller.java
index 160717d4cd..d932400d2a 100644
--- a/common/src/main/java/com/itsaky/androidide/utils/BootstrapInstaller.java
+++ b/common/src/main/java/com/itsaky/androidide/utils/BootstrapInstaller.java
@@ -105,7 +105,7 @@ public static CompletableFuture doInstall(
boolean isDirectory = entry.isDirectory();
final var dir = isDirectory ? targetFile : targetFile.getParentFile();
- if (!FileUtils.createOrExistsDir(dir)) {
+ if (dir != null && !dir.exists() && !dir.mkdirs()) {
LOG.error("Cannot create target file parent directory");
throw new CompletionException(
new InstallationException("Unable to create directory: " + dir));
diff --git a/common/src/main/java/com/itsaky/androidide/utils/FlashbarActivityUtils.kt b/common/src/main/java/com/itsaky/androidide/utils/FlashbarActivityUtils.kt
new file mode 100644
index 0000000000..c0ce127bac
--- /dev/null
+++ b/common/src/main/java/com/itsaky/androidide/utils/FlashbarActivityUtils.kt
@@ -0,0 +1,134 @@
+/*
+ * 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.androidide.utils
+
+import android.app.Activity
+import android.graphics.Color
+import android.graphics.PorterDuff
+import android.graphics.PorterDuff.Mode.SRC_ATOP
+import android.os.Looper
+import android.widget.ImageView.ScaleType
+import android.widget.ImageView.ScaleType.FIT_CENTER
+import androidx.annotation.ColorInt
+import androidx.annotation.DrawableRes
+import androidx.annotation.FloatRange
+import androidx.annotation.StringRes
+import com.blankj.utilcode.util.ThreadUtils
+import com.itsaky.androidide.flashbar.Flashbar
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.TOP
+import com.itsaky.androidide.resources.R
+import com.itsaky.androidide.utils.FlashType.ERROR
+import com.itsaky.androidide.utils.FlashType.INFO
+import com.itsaky.androidide.utils.FlashType.SUCCESS
+
+const val LENGTH_SHORT = 2000L
+const val LENGTH_LONG = 3500L
+
+private val COLOR_SUCCESS = Color.parseColor("#4CAF50")
+private val COLOR_ERROR = Color.parseColor("#f44336")
+private const val COLOR_INFO = Color.DKGRAY
+
+fun Activity.flashbarBuilder(duration: Long = LENGTH_SHORT): Flashbar.Builder {
+ return Flashbar.Builder(this)
+ .gravity(TOP)
+ .duration(duration)
+ .backgroundColor(resolveAttr(R.attr.colorPrimaryContainer))
+ .messageColor(resolveAttr(R.attr.colorOnPrimaryContainer))
+}
+
+fun Activity.flashMessage(msg: String?, type: FlashType) {
+ msg ?: return
+ when (type) {
+ ERROR -> flashError(msg)
+ INFO -> flashInfo(msg)
+ SUCCESS -> flashSuccess(msg)
+ }
+}
+
+fun Activity.flashMessage(@StringRes msg: Int, type: FlashType) {
+ when (type) {
+ ERROR -> flashError(msg)
+ INFO -> flashInfo(msg)
+ SUCCESS -> flashSuccess(msg)
+ }
+}
+
+fun Activity.flashSuccess(msg: String?) {
+ msg ?: return
+ flashbarBuilder().successIcon().message(msg).showOnUiThread()
+}
+
+fun Activity.flashError(msg: String?) {
+ msg ?: return
+ flashbarBuilder().errorIcon().message(msg).showOnUiThread()
+}
+
+fun Activity.flashInfo(msg: String?) {
+ msg ?: return
+ flashbarBuilder().infoIcon().message(msg).showOnUiThread()
+}
+
+fun Activity.flashSuccess(@StringRes msg: Int) {
+ flashbarBuilder().successIcon().message(msg).showOnUiThread()
+}
+
+fun Activity.flashError(@StringRes msg: Int) {
+ flashbarBuilder().errorIcon().message(msg).showOnUiThread()
+}
+
+fun Activity.flashInfo(@StringRes msg: Int) {
+ flashbarBuilder().infoIcon().message(msg).showOnUiThread()
+}
+
+fun Flashbar.Builder.showOnUiThread() {
+ build().showOnUiThread()
+}
+
+fun Flashbar.showOnUiThread() {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ show()
+ } else {
+ ThreadUtils.runOnUiThread { show() }
+ }
+}
+
+private fun Flashbar.Builder.successIcon(): Flashbar.Builder {
+ return withIcon(R.drawable.ic_ok, colorFilter = COLOR_SUCCESS)
+}
+
+private fun Flashbar.Builder.errorIcon(): Flashbar.Builder {
+ return withIcon(R.drawable.ic_error, colorFilter = COLOR_ERROR)
+}
+
+private fun Flashbar.Builder.infoIcon(): Flashbar.Builder {
+ return withIcon(R.drawable.ic_info, colorFilter = COLOR_INFO)
+}
+
+private fun Flashbar.Builder.withIcon(
+ @DrawableRes icon: Int,
+ @FloatRange(from = 0.0, to = 1.0) scale: Float = 1.0f,
+ @ColorInt colorFilter: Int = -1,
+ colorFilterMode: PorterDuff.Mode = SRC_ATOP,
+ scaleType: ScaleType = FIT_CENTER
+): Flashbar.Builder {
+ return showIcon(scale = scale, scaleType = scaleType).icon(icon).also {
+ if (colorFilter != -1) {
+ iconColorFilter(colorFilter, colorFilterMode)
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/itsaky/androidide/utils/FlashbarUtils.kt b/common/src/main/java/com/itsaky/androidide/utils/FlashbarUtils.kt
new file mode 100644
index 0000000000..f667d817f0
--- /dev/null
+++ b/common/src/main/java/com/itsaky/androidide/utils/FlashbarUtils.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.androidide.utils
+
+import android.app.Activity
+import androidx.annotation.StringRes
+import com.blankj.utilcode.util.ActivityUtils
+import com.itsaky.androidide.flashbar.Flashbar
+
+fun flashbarBuilder(): Flashbar.Builder? {
+ return withActivity { flashbarBuilder() }
+}
+
+fun flashMessage(msg: String?, type: FlashType) {
+ withActivity { flashMessage(msg, type) }
+}
+
+fun flashMessage(@StringRes msg: Int, type: FlashType) {
+ withActivity { flashMessage(msg, type) }
+}
+
+fun flashSuccess(msg: String?) {
+ withActivity { flashSuccess(msg) }
+}
+
+fun flashSuccess(@StringRes msg: Int) {
+ withActivity { flashSuccess(msg) }
+}
+
+fun flashError(msg: String?) {
+ withActivity { flashError(msg) }
+}
+
+fun flashError(@StringRes msg: Int) {
+ withActivity { flashError(msg) }
+}
+
+fun flashInfo(msg: String?) {
+ withActivity { flashInfo(msg) }
+}
+
+fun flashInfo(@StringRes msg: Int) {
+ withActivity { flashInfo(msg) }
+}
+
+private fun withActivity(action: Activity.() -> T?): T? {
+ return ActivityUtils.getTopActivity()?.let { it.action() }
+ ?: run {
+ ILogger.instance().warn("Cannot show flashbar message. Cannot get top activity.")
+ null
+ }
+}
+
+/** The type of flashbar message. */
+enum class FlashType {
+ ERROR,
+ INFO,
+ SUCCESS
+}
diff --git a/common/src/main/java/com/itsaky/toaster/ToastWrapper.kt b/common/src/main/java/com/itsaky/toaster/ToastWrapper.kt
deleted file mode 100755
index 27b4dc151d..0000000000
--- a/common/src/main/java/com/itsaky/toaster/ToastWrapper.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.toaster
-
-import android.animation.ValueAnimator
-import android.content.Context
-import android.graphics.Color
-import android.util.AttributeSet
-import android.view.ViewAnimationUtils.createCircularReveal
-import android.widget.LinearLayout
-import com.google.android.material.animation.ArgbEvaluatorCompat
-import kotlin.math.max
-
-class ToastWrapper : LinearLayout {
- constructor(context: Context?) : super(context)
- constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
- constructor(context: Context?, attrs: AttributeSet?, style: Int) : super(context, attrs, style)
-
- override fun onAttachedToWindow() {
- super.onAttachedToWindow()
- startRevealAnimation()
- startIconColorChangeAnimation()
- }
-
- private fun startIconColorChangeAnimation() {
- val anim = ValueAnimator.ofObject(ArgbEvaluatorCompat(), Color.WHITE, toaster.iconColor)
- anim.duration = (Toaster.REVEAL_ANIM_DURATION + 300).toLong()
- anim.addUpdateListener { animator: ValueAnimator ->
- toaster.icon!!.setTint(animator.animatedValue as Int)
- }
- anim.start()
- }
-
- override fun onDetachedFromWindow() {
- super.onDetachedFromWindow()
- setBackgroundColor(Color.TRANSPARENT)
- }
-
- private fun startRevealAnimation() {
- this.background = toaster.backgroundDrawable
- val x = left
- val y = (top + bottom) / 2
- val endRadius = max(height, width)
- createCircularReveal(this, x, y, 0f, endRadius.toFloat()).also {
- it.duration = Toaster.REVEAL_ANIM_DURATION.toLong()
- it.start()
- }
- }
-}
diff --git a/common/src/main/java/com/itsaky/toaster/Toaster.kt b/common/src/main/java/com/itsaky/toaster/Toaster.kt
deleted file mode 100755
index ab0499529a..0000000000
--- a/common/src/main/java/com/itsaky/toaster/Toaster.kt
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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.toaster
-
-import android.content.Context
-import android.graphics.Color
-import android.graphics.PorterDuff.Mode.SRC_ATOP
-import android.graphics.drawable.Drawable
-import android.graphics.drawable.GradientDrawable
-import android.view.LayoutInflater
-import android.widget.Toast
-import androidx.core.content.ContextCompat
-import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
-import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat.create
-import com.blankj.utilcode.util.SizeUtils
-import com.blankj.utilcode.util.ThreadUtils
-import com.itsaky.androidide.app.BaseApplication.getBaseInstance
-import com.itsaky.androidide.resources.R.color
-import com.itsaky.androidide.resources.R.drawable
-import com.itsaky.androidide.common.databinding.LayoutToastBinding
-import com.itsaky.toaster.Toaster.Gravity.BOTTOM_LEFT
-import com.itsaky.toaster.Toaster.Gravity.BOTTOM_RIGHT
-import com.itsaky.toaster.Toaster.Gravity.TOP_LEFT
-import com.itsaky.toaster.Toaster.Gravity.TOP_RIGHT
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.Toaster.Type.INFO
-import com.itsaky.toaster.Toaster.Type.SUCCESS
-
-class Toaster internal constructor(context: Context) {
-
- enum class Type {
- ERROR,
- SUCCESS,
- INFO
- }
-
- enum class Gravity {
- TOP_LEFT,
- TOP_RIGHT,
- BOTTOM_LEFT,
- BOTTOM_RIGHT
- }
-
- companion object {
- val COLOR_SUCCESS = Color.parseColor("#4CAF50")
- val COLOR_ERROR = Color.parseColor("#F44336")
- const val REVEAL_ANIM_DURATION = 500
- const val SHORT = 2000
- const val LONG = 3500
- }
-
- internal val backgroundDrawable: Drawable = createBackgroundDrawable(context)
- private var binding: LayoutToastBinding? = null
-
- var gravity: Gravity? = null
- private set
- var type: Type = INFO
- private set
- var icon: AnimatedVectorDrawableCompat? = null
- private set
- var iconColor = Color.DKGRAY
- private set
- var duration = 0
- private set
-
- init {
- createView(context)
- }
-
- private fun createBackgroundDrawable(context: Context): Drawable {
- val drawable = GradientDrawable()
- drawable.shape = GradientDrawable.RECTANGLE
- drawable.setColor(ContextCompat.getColor(context, color.color_toast_background))
- drawable.cornerRadius = 25f
- return drawable
- }
-
- private fun createView(context: Context) {
- binding = LayoutToastBinding.inflate(LayoutInflater.from(context))
- }
-
- fun show() {
- ThreadUtils.runOnUiThread(this::showInternal)
- }
-
- fun setText(text: String?): Toaster {
- binding!!.toastText.text = text
- return this
- }
-
- fun setText(textResId: Int): Toaster {
- binding!!.toastText.setText(textResId)
- return this
- }
-
- fun setDuration(duration: Int): Toaster {
- this.duration = duration + REVEAL_ANIM_DURATION
- return this
- }
-
- fun setType(type: Type): Toaster {
- this.type = type
- return this
- }
-
- fun setGravity(gravity: Gravity?): Toaster {
- this.gravity = gravity
- return this
- }
-
- private fun showInternal() {
- val dp16 = SizeUtils.dp2px(16f)
- iconColor = getIconColor()
- icon = createToastIconAnimation(iconColor)
- val gravity = getGravity()
- val mToast = Toast.makeText(getBaseInstance(), binding!!.toastText.text, duration)
- mToast.setGravity(gravity, dp16, dp16)
- mToast.duration = duration
-
- @Suppress("DEPRECATION")
- mToast.view = binding!!.root
-
- mToast.show()
- binding!!.toastImage.setImageDrawable(icon)
- icon!!.start()
- }
-
- @JvmName("getIconColorInternal")
- private fun getIconColor(): Int {
- return when (type) {
- SUCCESS -> COLOR_SUCCESS
- ERROR -> COLOR_ERROR
- else -> Color.DKGRAY
- }
- }
-
- private fun getGravity(): Int {
- return when (gravity) {
- TOP_LEFT -> android.view.Gravity.TOP or android.view.Gravity.START
- TOP_RIGHT -> android.view.Gravity.TOP or android.view.Gravity.END
- BOTTOM_RIGHT -> android.view.Gravity.BOTTOM or android.view.Gravity.END
- BOTTOM_LEFT -> android.view.Gravity.BOTTOM or android.view.Gravity.START
- else -> android.view.Gravity.TOP or android.view.Gravity.END
- }
- }
-
- private fun createToastIconAnimation(tintColor: Int): AnimatedVectorDrawableCompat? {
- val imageDrawable =
- create(getBaseInstance(), getIconId())?.also {
- it.setTint(tintColor)
- it.setTintMode(SRC_ATOP)
- }
- binding!!.toastImage.setImageDrawable(imageDrawable)
- return imageDrawable
- }
-
- private fun getIconId(): Int {
- return if (type == SUCCESS) {
- drawable.ic_ok
- } else {
- drawable.ic_error
- }
- }
-}
diff --git a/common/src/main/java/com/itsaky/toaster/toastUtils.kt b/common/src/main/java/com/itsaky/toaster/toastUtils.kt
deleted file mode 100644
index 7a9e0aec56..0000000000
--- a/common/src/main/java/com/itsaky/toaster/toastUtils.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.toaster
-
-import com.itsaky.androidide.app.BaseApplication.getBaseInstance
-import com.itsaky.toaster.Toaster.Type
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.Toaster.Type.INFO
-import com.itsaky.toaster.Toaster.Type.SUCCESS
-
-internal lateinit var toaster: Toaster
-
-internal fun init() {
- toaster = Toaster(getBaseInstance())
-}
-
-fun toast(msg: String?, type: Type) {
- toaster.setDuration(Toaster.SHORT).setText(msg).setType(type).show()
-}
-
-fun toast(msgResId: Int, type: Type) {
- toaster.setDuration(Toaster.SHORT).setText(msgResId).setType(type).show()
-}
-
-fun toastSuccess(msg: String?) {
- toast(msg, SUCCESS)
-}
-
-fun toastError(msg: String?) {
- toast(msg, ERROR)
-}
-
-fun toastInfo(msg: String?) {
- toast(msg, INFO)
-}
-
-fun toastSuccess(msgResId: Int) {
- toast(msgResId, SUCCESS)
-}
-
-fun toastError(msgResId: Int) {
- toast(msgResId, ERROR)
-}
-
-fun toastInfo(msgResId: Int) {
- toast(msgResId, INFO)
-}
-
-fun toastLong(msg: String?, type: Type) {
- toaster.setDuration(Toaster.LONG).setText(msg).setType(type).show()
-}
-
-fun toastLong(msgResId: Int, type: Type) {
- toaster.setDuration(Toaster.LONG).setText(msgResId).setType(type).show()
-}
-
-fun toastLongSuccess(msg: String?) {
- toastLong(msg, SUCCESS)
-}
-
-fun toastLongError(msg: String?) {
- toastLong(msg, ERROR)
-}
-
-fun toastLongInfo(msg: String?) {
- toastLong(msg, INFO)
-}
-
-fun toastLongSuccess(msgResId: Int) {
- toastLong(msgResId, SUCCESS)
-}
-
-fun toastLongError(msgResId: Int) {
- toastLong(msgResId, ERROR)
-}
-
-fun toastLongInfo(msgResId: Int) {
- toastLong(msgResId, INFO)
-}
diff --git a/common/src/main/res/layout/layout_toast.xml b/common/src/main/res/layout/layout_toast.xml
deleted file mode 100755
index 3c2aa7ca7a..0000000000
--- a/common/src/main/res/layout/layout_toast.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/README.md b/docs/README.md
index e84213d1fe..ff2146d52b 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -23,6 +23,7 @@ AndroidIDE is an **Integrated Development Environment (IDE)** to build Gradle ba
- [File tree](./editor/README.md#the-file-tree).
- [Bottom sheet](./editor/README.md#editor-bottomsheet).
- [Code editor](./editor/README.md#the-code-editor).
+- [UI Designer](./uidesigner/README.md).
## Important links
diff --git a/docs/editor/code_editor.md b/docs/editor/code_editor.md
index 4258321c48..290c8b4024 100644
--- a/docs/editor/code_editor.md
+++ b/docs/editor/code_editor.md
@@ -27,4 +27,9 @@ As of now, only [Java code actions](./java_code_actions.md) are available.
See location of code actions item in text actions window
-
\ No newline at end of file
+
+
+## Color schemes
+
+You can define your own color schemes that can be used in the editor. The color schemes are defined with JSON files. [Learn more](./color_schemes.md) about how to
+define your own color schemes.
\ No newline at end of file
diff --git a/docs/editor/color_schemes.md b/docs/editor/color_schemes.md
new file mode 100644
index 0000000000..b3b9681947
--- /dev/null
+++ b/docs/editor/color_schemes.md
@@ -0,0 +1,312 @@
+# Editor Color Schemes
+
+AndroidIDE [`v2.1.4-beta`](https://github.com/AndroidIDEOfficial/AndroidIDE/releases/tag/v2.1.4-beta) added limited support for custom color schemes in the editor. You can create your own color schemes and use it for AndroidIDE's editor. The color schemes are defined using the JSON syntax and are stored in the `$HOME/.androidide/ui/editor/schemes` directory. The default color scheme used is `AndroidIDE Default`.
+
+Custom color schemes are currently used only for languages that use [`tree-sitter`](https://github.com/tree-sitter/tree-sitter) for syntax highlighting.
+
+## File structure
+
+The color schemes stored in the schemes directory must have the following file structure :
+
+```
+$HOME/.androidide/ui/editor/schemes
+└── (directory)
+ └── scheme.prop
+```
+
+Schemes are defined in a directory whose name is same as the id of the scheme.
+For example, the `default` color scheme has the following directory structure :
+
+```
+$HOME/.androidide/ui/editor/schemes
+└── default <-- This is the scheme id
+ ├── ...
+ └── scheme.prop
+```
+
+### Dark variants
+
+Dark variant of a color scheme can be defined by simply creating another color
+scheme with its id suffixed with `-dark`. For example :
+
+```
+$HOME/.androidide/ui/editor/schemes
+├── default <-- 'default' color scheme
+| ├── ...
+| └── scheme.prop
+|
+└── default-dark <-- Dark variant of 'default' color scheme
+ ├── ...
+ └── scheme.prop
+```
+
+## Scheme props
+
+The `scheme.prop` file contains basic information about the color scheme such as the scheme name,
+version, etc. This is the file that is first read by the IDE to get
+information about the color scheme. The supported properties are :
+
+```properties
+# Parsed using the Java Properties parser
+# =
+# --------------------------------
+
+# Name of the color scheme
+scheme.name=
+
+# The version code of the color scheme
+scheme.version=
+
+# Whether the scheme is dark or light
+scheme.isDark=
+
+# The JSON color scheme definition file
+# This is the file which defines the color scheme
+scheme.file=default.json
+```
+
+- `scheme.name` - The name of the color scheme. This is used in the color scheme selector in IDE preferences.
+- `scheme.version` - The color scheme version. This is primarily used by the IDE's `ToolsManager` to check if the color schemes that are bundled with the IDE have been updated or not.
+- `scheme.isDark` - Flag for light and dark color schemes.
+- `scheme.file` - The JSON file which defines the color schemes.
+
+## Color scheme definition
+
+The JSON file that is referenced by the `scheme.prop` file with the `scheme.file` property
+defines the color schemes for tokens. The structure of this file is as follows :
+
+```json5
+{
+ "definitions": {
+ "my_color": "#6f5a4a",
+ "my_other_color": "#f9ddc9",
+ ...
+ },
+
+ "editor": "@editor.json",
+
+ "languages": [
+ "@java.json",
+ "@xml.json"
+ ]
+}
+```
+
+The root element of the JSON file must be a JSON object.
+The root JSON object contains two JSON objects ([`definitions`](#definitions-object) and [`editor`](#editor-object))
+and a JSON array ([`languages`](#languages-array)).
+
+### Definitions object
+
+You can define colors in the `definitions` object and then reuse these color definitions at multiple places.
+Every element in the `definitions` object must be a string whose value must be a HEX color code.
+For example :
+
+```json5
+{
+ // Colors can be defined here
+ // "key": "#hex color code"
+
+ "definitions": {
+ // we define 'my_color' here
+ "my_color": "#6f5a4a",
+ ...
+ },
+
+ "editor": {
+ // then reference 'my_color' here
+ "bg": "@my_color",
+
+ // or here
+ "line.bg": "@my_color",
+ ...
+ },
+
+ "languages" : [
+ {
+ ...
+ "styles" : {
+ // as many times as we want!
+ "comment": "@my_color",
+ }
+ ...
+ }
+ ]
+}
+```
+
+### Editor object
+
+The `editor` element in the root JSON object can be a JSON object or it can be a string value
+which is a reference to another JSON file. If it is a reference to another JSON file,
+then the root element of that file must a JSON object. Either way, the JSON object defines
+the color scheme for the editor.
+
+For example :
+
+```json5
+{
+ "definitions": { ... },
+
+ // this is valid
+ "editor": {
+ "bg": "#......"
+ },
+
+ // this is also valid
+ "editor": "@editor.json"
+}
+```
+
+In the second case, the `editor.json` file must have the following syntax:
+
+```json5
+{
+ "bg": "#......",
+ "...": "#......",
+
+ // previously defined colors can be referred as well
+ "...": "@my_color"
+}
+```
+
+The keys for the editor colors can be found
+[here](https://github.com/AndroidIDEOfficial/AndroidIDE/blob/83b8ffb531e96bf306734332ddea2e38441d9d54/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParser.kt#L33).
+
+### Languages array
+
+The `languages` JSON array contains the color schemes for the supported languages.
+Similar to the [`editor`](#editor-object) object, the _elements_ of the `languages` array
+can be a JSON object or a string value (reference to other JSON files). If the element in
+the array is a reference to a JSON file, then that JSON file must have a JSON object as its
+root element. Either way, the JSON object defines the tree-sitter metadata and styles for
+tree-sitter query capture names.
+
+For example :
+
+```json5
+{
+ "definitions": { ... },
+ "editor": { ... },
+
+ "languages": [
+
+ // You can define the language here
+ {
+ "types": [ "java" ],
+ "styles": { ... }
+ },
+
+ // or reference a file that defines the language
+ "@java.json"
+ ]
+}
+```
+
+### Language object
+
+Each JSON object (or file reference) in the `languages` array defines the properties for
+specific language types. The syntax for a language object is as follows :
+
+```json5
+{
+ "types": [ "cc", "cpp", ... ],
+ "local.scopes": [ "scope", ... ],
+ "local.scopes.members": [ "scope.members", ... ],
+ "local.definitions": [ "definition.var", "definition.field", ... ],
+ "local.definitions.values": [ "definition.val", ... ],
+ "local.references": [ "reference", ... ],
+ "styles": {
+ "": { // is the tree-sitter query capture name
+ "bg": "#......",
+ "fg": "@...",
+ "bold": ,
+ "italic": ,
+ "strikethrough":
+ }
+ }
+}
+```
+
+> Note
+>
+> - `Query` - refers to tree-sitter query.
+> - `Capture name` - refers to the tree-sitter query capture names.
+>
+> Read the [tree-sitter documentation](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries) for more details.
+
+- `types` - The type of files (file extensions) to which this color scheme can be applied. This entry is an array of string. This is helpful for languages that can have multiple file extensions. For example, a C++ source file can have `h`, `cc` or `cpp` file extension.
+
+- `local.scopes` - Capture names for syntax nodes that introduce a new local variable scope.
+- `local.scopes.members` - Capture names for syntax nodes that introde a new scope for member definitions (for example, scope for fields in a class).
+- `local.definition` - Capture names for variable declaration nodes. For example, the `identifier` in a Java variable declaration.
+- `local.definition.values` - Capture names for the value of the local variable declaration, if any. For example, the initializer in a Java variable declaration.
+- `local.references` - Capture names for syntax nodes that are references to a local variable.
+- `styles` - JSON object that defines the styles for the query captures. Key for each entry in this object is a tree-sitter query capture name. The value of each entry can be a string with a HEX color code (or color reference) or it can be a JSON object which defines multiple properties for rendering the text for the captured node. See example below for more information.
+- `styles..bg` - The background color for the node.
+- `styles..fg` - The foreground color for the node.
+- `styles..bold` - Whether the node text must be rendered in bold letters.
+- `styles..italic` - Whether the node text must be rendered in italic letters.
+- `styles..strikethrough` - Whether the node text must have strikethrough.
+
+
+The JSON object below is a part of the Java language definition in the `default` color scheme. You can refer it for a more practical example.
+
+
+See example
+
+The tree-sitter queries for Java that are used in AndroidIDE can be found [here](https://github.com/AndroidIDEOfficial/AndroidIDE/blob/dev/editor/src/main/assets/editor/treesitter/java).
+
+```json5
+{
+ // The types of file to which this language scheme can be applied
+ "types": [
+ "java"
+ ],
+
+ // defined in the tree-sitter query 'locals.scm',
+ // local variable scopes have the capture name 'scope'
+ "local.scopes": [
+ "scope"
+ ],
+
+ // defined in the tree-sitter query 'locals.scm',
+ // member scopes have capture name 'scope.members'
+ "local.scopes.members": [
+ "scope.members"
+ ],
+
+ // defined in the tree-sitter query 'locals.scm',
+ // local variable or field definitions have capture name 'definition.var' and 'definition.field' respectively
+ "local.definitions": [
+ "definition.var",
+ "definition.field"
+ ],
+
+ // defined in the tree-sitter query 'locals.scm',
+ // a reference to a variable has the capture name 'reference'
+ "local.references": [
+ "reference"
+ ],
+
+
+ // this object defines the styles for tree-sitter query captures
+ "styles": {
+
+ // defined in the tree-sitter query 'highlights.scm',
+ // comments in the java source code are marked with the 'comment' capture name
+ "comment": {
+ "fg": "@comment",
+ "italic": true
+ },
+
+ // value can be a reference to a predefined color
+ "number": "@number",
+
+ // or can be a HEX color code
+ "variable": "#f44336",
+ }
+}
+```
+
+
\ No newline at end of file
diff --git a/docs/images/uidesigner/add_attr.png b/docs/images/uidesigner/add_attr.png
new file mode 100755
index 0000000000..bd4d53753d
Binary files /dev/null and b/docs/images/uidesigner/add_attr.png differ
diff --git a/docs/images/uidesigner/drag-n-drop.png b/docs/images/uidesigner/drag-n-drop.png
new file mode 100755
index 0000000000..76a3e2c6f0
Binary files /dev/null and b/docs/images/uidesigner/drag-n-drop.png differ
diff --git a/docs/images/uidesigner/generated_xml.png b/docs/images/uidesigner/generated_xml.png
new file mode 100755
index 0000000000..69f67253e2
Binary files /dev/null and b/docs/images/uidesigner/generated_xml.png differ
diff --git a/docs/images/uidesigner/hierarchy_drawer.png b/docs/images/uidesigner/hierarchy_drawer.png
new file mode 100755
index 0000000000..7499f802b0
Binary files /dev/null and b/docs/images/uidesigner/hierarchy_drawer.png differ
diff --git a/docs/images/uidesigner/view_info.png b/docs/images/uidesigner/view_info.png
new file mode 100755
index 0000000000..2168df5e8e
Binary files /dev/null and b/docs/images/uidesigner/view_info.png differ
diff --git a/docs/images/uidesigner/widgets_drawer.png b/docs/images/uidesigner/widgets_drawer.png
new file mode 100755
index 0000000000..48745bc922
Binary files /dev/null and b/docs/images/uidesigner/widgets_drawer.png differ
diff --git a/docs/images/uidesigner/workspace.png b/docs/images/uidesigner/workspace.png
new file mode 100755
index 0000000000..fb2f75bb02
Binary files /dev/null and b/docs/images/uidesigner/workspace.png differ
diff --git a/docs/uidesigner/README.md b/docs/uidesigner/README.md
index e69de29bb2..2bc83059a6 100644
--- a/docs/uidesigner/README.md
+++ b/docs/uidesigner/README.md
@@ -0,0 +1,63 @@
+# The UI Designer
+
+The UI Designer helps you visually design XML layouts by simply dragging and dropping widgets into the workspace.
+
+This document briefly explains every element of the UI Designer workspace.
+
+## The workspace
+
+Your XML code is parsed and inflated by AndroidIDE's `LayoutInflater API` and then shown in the workspace. You can drag and drop the inflated views and widgets to move them, change their attributes, add new views or delete the existing ones.
+
+
+ Workspace
+
+
+
+
+ Drag-n-Drop
+
+ A placeholder view is used to indicate the drop position of the widget when you start dragging.
+
+
+### Add new views
+
+To add new views into the workspace:
+- Open the left drawer which shows a list of supported views and layouts.
+- Long click on the list items to start the drag. Drop them into the workspace to add to the layout.
+
+To move a view in the workspace, you can simply long press the view to start the drag and then drop it at the desired position.
+
+
+ Widget drawer
+
+
+
+### Edit view attributes
+
+Clicking on any inflated view opens the view info sheet which contains information about the view.
+
+The sheet contains two buttons at the header :
+
+- `Add` - Shows a list of attributes that you can add to the selected view. The list does not contain attributes that have been already applied to the view.
+- `Delete` - Deletes the selected view.
+
+It also contains the list of attributes that have been applied to the selected view.
+
+- Clicking on any attribute opens the value editor which you can use to edit the value of the selected attribute.
+- Clicking on the 'Delete' button next to the attribute deletes that attribute from the view. However, some necessary attributes cannot be deleted (`android:layout_height` and `android:layout_width` for example).
+
+
+ View info sheet
+
+
+
+### The layout hierarchy
+
+When views are invisible in the workspace (height or width is set to 0), it makes it harder to edit the properties/attributes of those views. This is where the layout hierachy view comes in. It shows the layout hierarchy of the views that are shown in the workspace in a tree-like structure.
+
+You can open the layout hierarchy by simply opening the right drawer or clicking on the 'hierarchy' view in the options menu. Clicking on the nodes of the tree is same as clicking on the views in the workspace (opens up the view info sheet).
+
+
+ See screenshot
+
+
\ No newline at end of file
diff --git a/subprojects/jsonrpc/.gitignore b/editor-api/.gitignore
similarity index 100%
rename from subprojects/jsonrpc/.gitignore
rename to editor-api/.gitignore
diff --git a/subprojects/jsonrpc/build.gradle.kts b/editor-api/build.gradle.kts
similarity index 78%
rename from subprojects/jsonrpc/build.gradle.kts
rename to editor-api/build.gradle.kts
index fab7264f09..12d2ea91ac 100644
--- a/subprojects/jsonrpc/build.gradle.kts
+++ b/editor-api/build.gradle.kts
@@ -15,12 +15,18 @@
* along with AndroidIDE. If not, see .
*/
-@Suppress("JavaPluginLanguageLevel")
plugins {
- id("java-library")
+ id("com.android.library")
+ id("kotlin-android")
+}
+
+android {
+ namespace = "com.itsaky.androidide.editor.api"
}
dependencies {
- implementation(libs.google.gson)
- implementation(projects.logger)
+ api(projects.lsp.api)
+ api(projects.lsp.models)
+
+ implementation(projects.common)
}
\ No newline at end of file
diff --git a/editor-api/consumer-rules.pro b/editor-api/consumer-rules.pro
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/editor-api/proguard-rules.pro b/editor-api/proguard-rules.pro
new file mode 100644
index 0000000000..481bb43481
--- /dev/null
+++ b/editor-api/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/editor-api/src/main/AndroidManifest.xml b/editor-api/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..e62e7b210a
--- /dev/null
+++ b/editor-api/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/IEditor.java b/editor-api/src/main/java/com/itsaky/androidide/editor/api/IEditor.java
similarity index 71%
rename from editor/src/main/java/com/itsaky/androidide/editor/IEditor.java
rename to editor-api/src/main/java/com/itsaky/androidide/editor/api/IEditor.java
index 6104eb1ffa..2153217f21 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/IEditor.java
+++ b/editor-api/src/main/java/com/itsaky/androidide/editor/api/IEditor.java
@@ -15,14 +15,10 @@
* along with AndroidIDE. If not, see .
*/
-package com.itsaky.androidide.editor;
+package com.itsaky.androidide.editor.api;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import com.itsaky.androidide.lsp.api.ILanguageClient;
-import com.itsaky.androidide.lsp.api.ILanguageServer;
-import com.itsaky.androidide.lsp.models.SignatureHelp;
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
@@ -51,47 +47,34 @@ public interface IEditor {
*/
boolean isModified();
- /**
- * If any language server is set, requests signature help at the cursor's position. On a valid
- * response, shows the signature help in a popup window.
- */
- void signatureHelp();
-
- /**
- * Shows the given signature help in the editor.
- *
- * @param help The signature help data to show.
- */
- void showSignatureHelp(SignatureHelp help);
-
/**
* Set the selection of this editor to the given position.
*
* @param position The position to select.
*/
void setSelection(@NonNull Position position);
-
+
/**
* Set selection to the given range.
*
* @param range The range to select.
*/
void setSelection(@NonNull Range range);
-
+
/**
* Get the cursor's selection range in the form of {@link Range}.
*
* @return The {@link Range} of the cursor.
*/
Range getCursorLSPRange();
-
+
/**
* Get the cursor's position in the form of {@link Position}.
*
* @return The {@link Position} of the cursor.
*/
Position getCursorLSPPosition();
-
+
/**
* Validates the range if it is invalid and returns a valid range.
*
@@ -99,7 +82,7 @@ public interface IEditor {
* @return A new, validated range.
*/
void validateRange(@NonNull Range range);
-
+
/**
* Checks if the given range is valid for this editor's text.
*
@@ -109,7 +92,7 @@ public interface IEditor {
default boolean isValidRange(Range range) {
return isValidRange(range, false);
}
-
+
/**
* Checks if the given range is valid for this editor's text.
*
@@ -119,7 +102,7 @@ default boolean isValidRange(Range range) {
* @return true if valid, false otherwise.
*/
boolean isValidRange(Range range, boolean allowColumnEqual);
-
+
/**
* Checks if the given position is valid for this editor's text.
*
@@ -129,7 +112,7 @@ default boolean isValidRange(Range range) {
default boolean isValidPosition(Position position) {
return isValidPosition(position, false);
}
-
+
/**
* Checks if the given position is valid for this editor's text.
*
@@ -139,7 +122,7 @@ default boolean isValidPosition(Position position) {
* @return true if valid, false otherwise.
*/
boolean isValidPosition(Position position, boolean allowColumnEqual);
-
+
/**
* Checks if the given line is valid for this editor's text.
*
@@ -147,7 +130,7 @@ default boolean isValidPosition(Position position) {
* @return true if valid, false otherwise.
*/
boolean isValidLine(int line);
-
+
/**
* Checks if the given column is valid for this editor's text.
*
@@ -159,7 +142,7 @@ default boolean isValidPosition(Position position) {
default boolean isValidColumn(int line, int column) {
return isValidColumn(line, column, false);
}
-
+
/**
* Checks if the given column is valid for this editor's text.
*
@@ -170,23 +153,7 @@ default boolean isValidColumn(int line, int column) {
* @return true if valid, false otherwise.
*/
boolean isValidColumn(int line, int column, boolean allowColumnEqual);
-
- /**
- * Set the language server that this editor will connect with. If the language client is not set,
- * it'll be set to {@link ILanguageClient} from the language server.
- *
- * @param server The server to set. Provide null to disable all the language server
- * features.
- */
- void setLanguageServer(ILanguageServer server);
-
- /**
- * Set the language client to this editor.
- *
- * @param client The client to set.
- */
- void setLanguageClient(@Nullable ILanguageClient client);
-
+
/**
* Append the given text at the end of the editor's content.
*
@@ -194,42 +161,14 @@ default boolean isValidColumn(int line, int column) {
* @return The line at which the text was appended.
*/
int append(CharSequence text);
-
+
/**
* Replaces the editor's existing content with the given content.
*
* @param newContent The new content to set to the editor.
*/
void replaceContent(CharSequence newContent);
-
+
/** Set the selection of the editor's cursor to the last line of the it's content. */
void goToEnd();
-
- /**
- * If any language server is set, asks the language server to find the definition of token at the
- * cursor position.
- *
- *
If the server returns a valid response, and the file specified in the response is same the
- * file in this editor, the range specified in the response will be selected.
- */
- void findDefinition();
-
- /**
- * If any language server instance is set, finds the references to of the token at the current
- * cursor position.
- *
- *
If the server returns a valid response, that response is forwarded to the {@link
- * IDELanguageClientImpl}.
- */
- @SuppressWarnings("unused")
- void findReferences();
-
- /**
- * Requests the language server to provided a semantically larger selection than the current
- * selection. If a valid response is received, that range will be selected.
- */
- void expandSelection();
-
- /** Ensures that all the windows are dismissed. */
- void ensureWindowsDismissed();
-}
+}
\ No newline at end of file
diff --git a/editor-api/src/main/java/com/itsaky/androidide/editor/api/ILspEditor.kt b/editor-api/src/main/java/com/itsaky/androidide/editor/api/ILspEditor.kt
new file mode 100644
index 0000000000..62794c50ac
--- /dev/null
+++ b/editor-api/src/main/java/com/itsaky/androidide/editor/api/ILspEditor.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.androidide.editor.api
+
+import com.itsaky.androidide.lsp.api.ILanguageClient
+import com.itsaky.androidide.lsp.api.ILanguageServer
+import com.itsaky.androidide.lsp.models.Command
+import com.itsaky.androidide.lsp.models.SignatureHelp
+
+/**
+ * LSP functions for the editor.
+ *
+ * @author Akash Yadav
+ */
+interface ILspEditor {
+ /**
+ * Set the language server that this editor will connect with. If the language client is not set,
+ * it'll be set to [ILanguageClient] from the language server.
+ *
+ * @param server The server to set. Provide `null` to disable all the language server features.
+ */
+ fun setLanguageServer(server: ILanguageServer?)
+
+ /**
+ * Set the language client to this editor.
+ *
+ * @param client The client to set.
+ */
+ fun setLanguageClient(client: ILanguageClient?)
+
+ /**
+ * Execute the given LSP command in the editor.
+ *
+ * @param command The command to execute.
+ */
+ fun executeCommand(command: Command?)
+
+ /**
+ * If any language server is set, requests signature help at the cursor's position. On a valid
+ * response, shows the signature help in a popup window.
+ */
+ fun signatureHelp()
+
+ /**
+ * Shows the given signature help in the editor.
+ *
+ * @param help The signature help data to show.
+ */
+ fun showSignatureHelp(help: SignatureHelp?)
+
+ /**
+ * If any language server is set, asks the language server to find the definition of token at the
+ * cursor position.
+ *
+ * If the server returns a valid response, and the file specified in the response is same the file
+ * in this editor, the range specified in the response will be selected.
+ */
+ fun findDefinition()
+
+ /**
+ * If any language server instance is set, finds the references to of the token at the current
+ * cursor position.
+ *
+ * If the server returns a valid response, that response is forwarded to the [ ].
+ */
+ fun findReferences()
+
+ /**
+ * Requests the language server to provided a semantically larger selection than the current
+ * selection. If a valid response is received, that range will be selected.
+ */
+ fun expandSelection()
+
+ /** Ensures that all the windows are dismissed. */
+ fun ensureWindowsDismissed()
+}
\ No newline at end of file
diff --git a/editor/build.gradle.kts b/editor/build.gradle.kts
index 8e0daa312c..0319535ed4 100644
--- a/editor/build.gradle.kts
+++ b/editor/build.gradle.kts
@@ -15,6 +15,8 @@ dependencies {
api(libs.common.editor)
api(libs.common.editor.ts)
+ api(projects.editorApi)
+
implementation(libs.androidx.annotation)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.constraintlayout)
diff --git a/editor/src/main/assets/editor/schemes/default-dark/scheme.prop b/editor/src/main/assets/editor/schemes/default-dark/scheme.prop
index 871e7abc23..4333a4cf27 100644
--- a/editor/src/main/assets/editor/schemes/default-dark/scheme.prop
+++ b/editor/src/main/assets/editor/schemes/default-dark/scheme.prop
@@ -7,8 +7,5 @@ scheme.version=2
# Whether the scheme is dark or light
scheme.isDark=true
-# Languages that scheme supports
-scheme.langs=java,xml
-
# The JSON color scheme definition file
scheme.file=default-dark.json
\ No newline at end of file
diff --git a/editor/src/main/assets/editor/schemes/default/scheme.prop b/editor/src/main/assets/editor/schemes/default/scheme.prop
index f4844f4add..eb38c4a0f3 100644
--- a/editor/src/main/assets/editor/schemes/default/scheme.prop
+++ b/editor/src/main/assets/editor/schemes/default/scheme.prop
@@ -7,8 +7,5 @@ scheme.version=5
# Whether the scheme is dark or light
scheme.isDark=false
-# Languages that scheme supports
-scheme.langs=java,xml
-
# The JSON color scheme definition file
scheme.file=default.json
\ No newline at end of file
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/adapters/CompletionListAdapter.kt b/editor/src/main/java/com/itsaky/androidide/editor/adapters/CompletionListAdapter.kt
index 05480eb445..0cb7b8433b 100755
--- a/editor/src/main/java/com/itsaky/androidide/editor/adapters/CompletionListAdapter.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/adapters/CompletionListAdapter.kt
@@ -29,6 +29,7 @@ import com.itsaky.androidide.editor.R
import com.itsaky.androidide.editor.databinding.LayoutCompletionItemBinding
import com.itsaky.androidide.lookup.Lookup
import com.itsaky.androidide.lsp.models.ClassCompletionData
+import com.itsaky.androidide.lsp.models.CompletionItem as LspCompletionItem
import com.itsaky.androidide.lsp.models.CompletionItemKind.CLASS
import com.itsaky.androidide.lsp.models.CompletionItemKind.CONSTRUCTOR
import com.itsaky.androidide.lsp.models.CompletionItemKind.ENUM
@@ -38,7 +39,6 @@ import com.itsaky.androidide.lsp.models.CompletionItemKind.METHOD
import com.itsaky.androidide.lsp.models.MemberCompletionData
import com.itsaky.androidide.lsp.models.MethodCompletionData
import com.itsaky.androidide.preferences.internal.useCustomFont
-import com.itsaky.androidide.resources.R.attr
import com.itsaky.androidide.resources.R.string.msg_api_info_deprecated
import com.itsaky.androidide.resources.R.string.msg_api_info_removed
import com.itsaky.androidide.resources.R.string.msg_api_info_since
@@ -56,7 +56,6 @@ import io.github.rosemoe.sora.lang.completion.CompletionItem
import io.github.rosemoe.sora.widget.component.EditorAutoCompletion
import io.github.rosemoe.sora.widget.component.EditorCompletionAdapter
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
-import com.itsaky.androidide.lsp.models.CompletionItem as LspCompletionItem
class CompletionListAdapter : EditorCompletionAdapter() {
@@ -106,9 +105,7 @@ class CompletionListAdapter : EditorCompletionAdapter() {
)
binding.completionApiInfo.visibility = View.GONE
- if (this.colorScheme != null) {
- applyColorScheme(binding, isCurrentCursorPosition)
- }
+ applyColorScheme(binding, isCurrentCursorPosition)
showApiInfoIfNeeded(item, binding.completionApiInfo)
return binding.root
@@ -198,7 +195,7 @@ class CompletionListAdapter : EditorCompletionAdapter() {
return@executeAsync sb
}) {
- if (it == null || it.isBlank()) {
+ if (it.isNullOrBlank()) {
textView.visibility = View.GONE
return@executeAsync
}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt b/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt
index 59d967ce68..c5ff5e0791 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/language/CommonCompletionProvider.kt
@@ -74,7 +74,7 @@ class CommonCompletionProvider(private val server: ILanguageServer) {
}
// Do not log if completion was interrupted or cancelled
- if (!(e is ProcessCancelledException || e is CompletionCancelledException)) {
+ if (!(e is ProcessCancelledException || e is CompletionCancelledException)) {
if (!server.handleFailure(LSPFailure(COMPLETION, e))) {
log.error("Unable to compute completions", e)
}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/IDELanguage.java b/editor/src/main/java/com/itsaky/androidide/editor/language/IDELanguage.java
index b022e35058..2350ad0f3d 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/language/IDELanguage.java
+++ b/editor/src/main/java/com/itsaky/androidide/editor/language/IDELanguage.java
@@ -20,7 +20,7 @@
import androidx.annotation.NonNull;
-import com.itsaky.androidide.editor.IEditor;
+import com.itsaky.androidide.editor.api.IEditor;
import com.itsaky.androidide.lookup.Lookup;
import com.itsaky.androidide.lsp.api.ICompletionCancelChecker;
import com.itsaky.androidide.lsp.api.ILanguageServer;
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguage.kt b/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguage.kt
index 029cb3d2e5..bd8af3f138 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguage.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguage.kt
@@ -67,9 +67,8 @@ abstract class TreeSitterLanguage(context: Context, lang: TSLanguage, type: Stri
log.error("Invalid color scheme returned by color scheme provider", scheme)
return@readScheme
}
-
- val langScheme =
- checkNotNull(scheme.languages[type]) { "No color scheme found for file type '$type'" }
+
+ val langScheme = scheme.languages[type] ?: return@readScheme
langScheme.styles.forEach { tsTheme.putStyleRule(it.key, it.value.makeStyle()) }
}
}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguageProvider.kt b/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguageProvider.kt
new file mode 100644
index 0000000000..2554189585
--- /dev/null
+++ b/editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguageProvider.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.androidide.editor.language.treesitter
+
+import android.content.Context
+import com.itsaky.androidide.editor.language.java.JavaLanguage
+import com.itsaky.androidide.editor.language.xml.XMLLanguage
+import com.itsaky.androidide.editor.schemes.LanguageSpecProvider.BASE_SPEC_PATH
+import java.io.File
+import java.io.IOException
+
+/**
+ * Provides instance of [TreeSitterLanguage] implementations.
+ *
+ * @author Akash Yadav
+ */
+object TreeSitterLanguageProvider {
+
+ fun forFile(file: File, context: Context): TreeSitterLanguage? {
+ val type = file.extension
+
+ try {
+ // check if there is at least highlights.scm file for this file type
+ context.assets.open("${BASE_SPEC_PATH}/${type}/highlights.scm").close()
+ } catch (e: IOException) {
+ return null
+ }
+
+ return when (type) {
+ "java" -> JavaLanguage(context)
+ "xml" -> XMLLanguage(context)
+ else -> return null
+ }
+ }
+}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorScheme.kt b/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorScheme.kt
index d88d1679bb..b944cbbf56 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorScheme.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorScheme.kt
@@ -35,9 +35,6 @@ class IDEColorScheme(internal val file: File, val key: String) : DynamicColorSch
var version: Int = 0
internal set
- var langs: Array = emptyArray()
- internal set
-
var isDarkScheme: Boolean = false
internal set
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorSchemeProvider.kt b/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorSchemeProvider.kt
index 42a555e1a3..2cb2c2cce9 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorSchemeProvider.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/schemes/IDEColorSchemeProvider.kt
@@ -41,7 +41,6 @@ object IDEColorSchemeProvider {
private const val SCHEME_NAME = "scheme.name"
private const val SCHEME_VERSION = "scheme.version"
private const val SCHEME_IS_DARK = "scheme.isDark"
- private const val SCHEME_LANGS = "scheme.langs"
private const val SCHEME_FILE = "scheme.file"
val currentScheme: IDEColorScheme? by lazy {
@@ -78,7 +77,6 @@ object IDEColorSchemeProvider {
val name = props.getProperty(SCHEME_NAME, "Unknown")
val version = props.getProperty(SCHEME_VERSION, "0").toInt()
val isDark = props.getProperty(SCHEME_IS_DARK, "false").toBoolean()
- val langs = props.getProperty(SCHEME_LANGS, "").split(',').map { it.trim() }
val file =
props.getProperty(SCHEME_FILE)
?: run {
@@ -95,16 +93,11 @@ object IDEColorSchemeProvider {
if (file.isBlank()) {
continue
}
- if (langs.isEmpty()) {
- log.error("Scheme '${schemeDir.name}' does not specify any languages")
- continue
- }
val scheme = IDEColorScheme(File(schemeDir, file), schemeDir.name)
scheme.name = name
scheme.version = version
scheme.isDarkScheme = isDark
- scheme.langs = langs.toTypedArray()
schemes[schemeDir.name] = scheme
}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/schemes/LanguageSpecProvider.kt b/editor/src/main/java/com/itsaky/androidide/editor/schemes/LanguageSpecProvider.kt
index a8175b030c..a7a9507235 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/schemes/LanguageSpecProvider.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/schemes/LanguageSpecProvider.kt
@@ -31,7 +31,7 @@ import io.github.rosemoe.sora.editor.ts.TsLanguageSpec
*/
object LanguageSpecProvider {
- private const val BASE_SPEC_PATH = "editor/treesitter"
+ const val BASE_SPEC_PATH = "editor/treesitter"
private val log = ILogger.newInstance("LanguageSpecProvider")
@JvmStatic
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParser.kt b/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParser.kt
index eab6dd9c4f..db66c5659a 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParser.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParser.kt
@@ -101,30 +101,30 @@ class SchemeParser(private val resolveFileRef: (String) -> File) {
const val KEY_LANGUAGES = "languages"
}
- fun parse(file: File, name: String, isDark: Boolean, langs: Array): IDEColorScheme {
+ fun parse(file: File, name: String, isDark: Boolean): IDEColorScheme {
require(file.exists() && file.isFile) { "File does not exist or is not a file" }
val scheme = IDEColorScheme(file, name)
scheme.name = name
scheme.isDarkScheme = isDark
- scheme.langs = langs
load(scheme)
return scheme
}
internal fun load(scheme: IDEColorScheme) {
- val reader = JsonReader(scheme.file.reader())
- reader.beginObject()
- while (reader.hasNext()) {
- when (reader.nextName()) {
- KEY_DEFINITIONS -> scheme.definitions = scheme.parseDefinitions(reader)
- KEY_EDITOR -> scheme.parseEditorScheme(reader, resolveFileRef)
- KEY_LANGUAGES -> scheme.parseLanguages(reader, resolveFileRef)
+ JsonReader(scheme.file.reader()).use { reader ->
+ reader.beginObject()
+ while (reader.hasNext()) {
+ when (reader.nextName()) {
+ KEY_DEFINITIONS -> scheme.definitions = scheme.parseDefinitions(reader)
+ KEY_EDITOR -> scheme.parseEditorScheme(reader, resolveFileRef)
+ KEY_LANGUAGES -> scheme.parseLanguages(reader, resolveFileRef)
+ }
}
- }
- reader.endObject()
+ reader.endObject()
- if (scheme.name.isBlank()) {
- throw ParseException("A color scheme must a valid name. Current name is '${scheme.name}'")
+ if (scheme.name.isBlank()) {
+ throw ParseException("A color scheme must a valid name. Current name is '${scheme.name}'")
+ }
}
}
}
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/common.kt b/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/common.kt
index 5cb46f77d4..4174c08462 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/common.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/schemes/internal/parser/common.kt
@@ -31,7 +31,11 @@ fun IDEColorScheme.parseEditorScheme(reader: JsonReader, resolveFileRef: (String
val newReader = if (reader.peek() == STRING) {
readerForFileRef(reader, "editor", resolveFileRef)
} else reader
- EditorSchemeParser(newReader).parse(this)
+ EditorSchemeParser(newReader).parse(this).also {
+ if (reader != newReader) {
+ newReader.close()
+ }
+ }
}
/**
@@ -91,7 +95,11 @@ fun IDEColorScheme.parseLanguage(
readerForFileRef(reader, "language", resolveFileRef)
} else reader
- return LanguageParser(newReader).parseLang(this)
+ return LanguageParser(newReader).parseLang(this).also {
+ if (reader != newReader) {
+ newReader.close()
+ }
+ }
}
private fun readerForFileRef(reader: JsonReader, scheme: String, resolveFileRef: (String) -> File): JsonReader {
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/ui/DiagnosticWindow.kt b/editor/src/main/java/com/itsaky/androidide/editor/ui/DiagnosticWindow.kt
index 24b9e8e676..cf38739b80 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/ui/DiagnosticWindow.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/ui/DiagnosticWindow.kt
@@ -23,18 +23,7 @@ import com.itsaky.androidide.lsp.models.DiagnosticItem
*
* @author Akash Yadav
*/
-class DiagnosticWindow
-/**
- * Create a popup window for editor
- *
- * @param editor The editor
- * @see .FEATURE_SCROLL_AS_CONTENT
- *
- * @see .FEATURE_SHOW_OUTSIDE_VIEW_ALLOWED
- *
- * @see .FEATURE_HIDE_WHEN_FAST_SCROLL
- */
-(editor: IDEEditor) : BaseEditorWindow(editor) {
+class DiagnosticWindow(editor: IDEEditor) : BaseEditorWindow(editor) {
/**
* Show the given diagnostic item.
*
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorCompletionWindow.kt b/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorCompletionWindow.kt
index 45ef07ec2e..b5ac25984f 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorCompletionWindow.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorCompletionWindow.kt
@@ -68,7 +68,7 @@ class EditorCompletionWindow(val editor: IDEEditor) : EditorAutoCompletion(edito
}
}
- override fun setAdapter(adapter: EditorCompletionAdapter) {
+ override fun setAdapter(adapter: EditorCompletionAdapter?) {
super.setAdapter(adapter)
mAdapter = adapter
mAdapter!!.attachValues(this, mItems)
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorSearchLayout.kt b/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorSearchLayout.kt
index e6192c57ab..5f9060989e 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorSearchLayout.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/ui/EditorSearchLayout.kt
@@ -70,7 +70,7 @@ class EditorSearchLayout(context: Context, val editor: IDEEditor) : FrameLayout(
it.isChecked = !it.isChecked
val ignoreCase = searchOptions.ignoreCase
- val regex = searchOptions.useRegex
+ val regex = searchOptions.type == SearchOptions.TYPE_REGULAR_EXPRESSION
searchOptions =
when (it.itemId) {
0 -> SearchOptions(it.isChecked, regex)
@@ -149,7 +149,7 @@ class EditorSearchLayout(context: Context, val editor: IDEEditor) : FrameLayout(
// Handle bad regexp
val query =
s.toString().let {
- if (searchOptions.useRegex) {
+ if (searchOptions.type == SearchOptions.TYPE_REGULAR_EXPRESSION) {
try {
Pattern.compile(it)
it
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.java b/editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.java
index b2e8f60e6f..d405a5fd3c 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.java
+++ b/editor/src/main/java/com/itsaky/androidide/editor/ui/IDEEditor.java
@@ -19,8 +19,6 @@
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.getTabSize;
import static com.itsaky.androidide.preferences.internal.EditorPreferencesKt.getVisiblePasswordFlag;
import static com.itsaky.androidide.resources.R.string;
-import static com.itsaky.toaster.ToastUtilsKt.toast;
-
import static java.lang.Math.max;
import static java.lang.Math.min;
@@ -38,6 +36,8 @@
import com.blankj.utilcode.util.ThreadUtils;
import com.itsaky.androidide.editor.adapters.CompletionListAdapter;
+import com.itsaky.androidide.editor.api.IEditor;
+import com.itsaky.androidide.editor.api.ILspEditor;
import com.itsaky.androidide.editor.language.IDELanguage;
import com.itsaky.androidide.eventbus.events.editor.ChangeType;
import com.itsaky.androidide.eventbus.events.editor.DocumentChangeEvent;
@@ -59,8 +59,8 @@
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE;
import com.itsaky.androidide.utils.DocumentUtils;
+import com.itsaky.androidide.utils.FlashbarUtilsKt;
import com.itsaky.androidide.utils.ILogger;
-import com.itsaky.toaster.Toaster;
import org.greenrobot.eventbus.EventBus;
@@ -70,13 +70,12 @@
import io.github.rosemoe.sora.event.ContentChangeEvent;
import io.github.rosemoe.sora.event.SelectionChangeEvent;
import io.github.rosemoe.sora.event.Unsubscribe;
-import io.github.rosemoe.sora.text.Content;
import io.github.rosemoe.sora.widget.CodeEditor;
import io.github.rosemoe.sora.widget.IDEEditorSearcher;
import io.github.rosemoe.sora.widget.component.EditorAutoCompletion;
import io.github.rosemoe.sora.widget.component.EditorTextActionWindow;
-public class IDEEditor extends CodeEditor implements com.itsaky.androidide.editor.IEditor {
+public class IDEEditor extends CodeEditor implements IEditor, ILspEditor {
private static final ILogger LOG = ILogger.newInstance("IDEEditor");
private final EditorActionsMenu actionsMenu;
@@ -475,7 +474,7 @@ public void findDefinition() {
}
final var locations = result.getLocations();
- if (locations.size() <= 0) {
+ if (locations.size() == 0) {
LOG.error("No definitions found", "Size:", locations.size());
showDefinitionNotFound(pd);
return;
@@ -515,7 +514,7 @@ private void showDefinitionNotFound(final ProgressDialog pd) {
//noinspection ConstantConditions
ThreadUtils.runOnUiThread(
() -> {
- toast(string.msg_no_definition, Toaster.Type.ERROR);
+ FlashbarUtilsKt.flashError(string.msg_no_definition);
pd.dismiss();
});
}
@@ -538,7 +537,6 @@ private void dismissOnUiThread(@NonNull final Dialog dialog) {
* ILanguageClient}.
*/
@Override
- @SuppressWarnings("unused")
public void findReferences() {
if (getFile() == null) {
return;
@@ -613,7 +611,7 @@ private void showReferencesNotFound(final ProgressDialog pd) {
//noinspection ConstantConditions
ThreadUtils.runOnUiThread(
() -> {
- toast(string.msg_no_references, Toaster.Type.ERROR);
+ FlashbarUtilsKt.flashError(string.msg_no_references);
pd.dismiss();
});
}
@@ -824,6 +822,7 @@ protected void dispatchDocumentSelectedEvent() {
EventBus.getDefault().post(selectedEvent);
}
+ @Override
@SuppressWarnings("unused")
public void executeCommand(Command command) {
if (command == null) {
diff --git a/editor/src/main/java/com/itsaky/androidide/editor/ui/ReplaceAction.kt b/editor/src/main/java/com/itsaky/androidide/editor/ui/ReplaceAction.kt
index 1526161ea2..594383bbb9 100644
--- a/editor/src/main/java/com/itsaky/androidide/editor/ui/ReplaceAction.kt
+++ b/editor/src/main/java/com/itsaky/androidide/editor/ui/ReplaceAction.kt
@@ -58,11 +58,7 @@ object ReplaceAction {
return@setNeutralButton
}
- editor.searcher.replaceAllAsync(input.text.toString()).whenComplete { _, error ->
- if (error != null) {
- log.error("Unable to replace all matched text", error)
- }
- }
+ editor.searcher.replaceAll(input.text.toString())
}
builder.show()
}
diff --git a/editor/src/main/java/io/github/rosemoe/sora/widget/IDEEditorSearcher.kt b/editor/src/main/java/io/github/rosemoe/sora/widget/IDEEditorSearcher.kt
index 3b061cdd4b..41732085aa 100644
--- a/editor/src/main/java/io/github/rosemoe/sora/widget/IDEEditorSearcher.kt
+++ b/editor/src/main/java/io/github/rosemoe/sora/widget/IDEEditorSearcher.kt
@@ -19,14 +19,7 @@
package io.github.rosemoe.sora.widget
-import android.app.ProgressDialog
-import android.widget.Toast
-import com.itsaky.androidide.resources.R.string
-import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.editor.ui.IDEEditor
-import io.github.rosemoe.sora.text.TextUtils
-import io.github.rosemoe.sora.util.IntPair
-import java.util.concurrent.CompletableFuture
/**
* Search text in editor. As the constructor of [EditorSearcher] is package private, we cannot
@@ -36,8 +29,6 @@ import java.util.concurrent.CompletableFuture
*/
open class IDEEditorSearcher(editor: IDEEditor) : EditorSearcher(editor) {
- private val log = ILogger.newInstance(javaClass.simpleName)
-
var searching = false
private set
@@ -50,25 +41,11 @@ open class IDEEditorSearcher(editor: IDEEditor) : EditorSearcher(editor) {
throw RuntimeException("Unable get instance of editor", error)
}
}
-
+
fun updateSearchOptions(searchOptions: SearchOptions) {
this.searchOptions = searchOptions
}
- fun replaceAllAsync(replacement: String): CompletableFuture {
- markSearching()
- val dialog =
- ProgressDialog.show(
- getEditor().context,
- getEditor().context.getString(string.replaceAll),
- getEditor().context.getString(string.msg_replacing),
- true,
- false
- )
- return CompletableFuture.runAsync { replaceAll(replacement) }
- .thenAccept { getEditor().post { dialog.dismiss() } }
- }
-
override fun replaceAll(replacement: String, whenFinished: Runnable?) {
markSearching()
super.replaceAll(replacement, whenFinished)
@@ -89,69 +66,12 @@ open class IDEEditorSearcher(editor: IDEEditor) : EditorSearcher(editor) {
return super.gotoPrevious()
}
- override fun replaceAll(replacement: String) {
- checkState()
- markSearching()
- if (!isResultValid) {
- Toast.makeText(getEditor().context, "Editor is still preparing", Toast.LENGTH_SHORT).show()
- return
- }
-
- val res = lastResults
- try {
- val sb = getEditor().text.toStringBuilder()
- val newLength = replacement.length
- if (searchOptions.useRegex) {
- var delta = 0
- for (i in 0 until res.size()) {
- val region = res[i]
- val start = IntPair.getFirst(region)
- val end = IntPair.getSecond(region)
- val oldLength = end - start
- sb.replace(start + delta, end + delta, replacement)
- delta += newLength - oldLength
- }
- } else {
- var fromIndex = 0
- var foundIndex: Int
- while (
- TextUtils.indexOf(sb, currentPattern, searchOptions.ignoreCase, fromIndex).also {
- foundIndex = it
- } != -1
- ) {
- sb.replace(foundIndex, foundIndex + currentPattern.length, replacement)
- fromIndex = foundIndex + newLength
- }
- }
- getEditor().post {
- val pos = getEditor().cursor.left()
- // stopSearch();
- getEditor()
- .text
- .replace(
- 0,
- 0,
- getEditor().lineCount - 1,
- getEditor().text.getColumnCount(getEditor().lineCount - 1),
- sb
- )
- getEditor().setSelectionAround(pos.line, pos.column)
- }
- } catch (e: Exception) {
- log.error("Failed to replace", e)
- }
- }
-
override fun stopSearch() {
searching = false
super.stopSearch()
}
- fun markSearching() {
+ private fun markSearching() {
searching = true
}
-
- private fun checkState() {
- check(hasQuery()) { "pattern not set" }
- }
}
diff --git a/editor/src/test/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParserTest.kt b/editor/src/test/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParserTest.kt
index 443f454a19..bf50b1bf03 100644
--- a/editor/src/test/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParserTest.kt
+++ b/editor/src/test/java/com/itsaky/androidide/editor/schemes/internal/parser/SchemeParserTest.kt
@@ -205,7 +205,7 @@ class SchemeParserTest {
private fun parseSyntaxJson(name: String = "syntax.json"): IDEColorScheme {
val basePath = "./src/test/resources"
val parser = SchemeParser { File("$basePath/$it") }
- val scheme = parser.parse(File("$basePath/$name"), "AndroidIDE Test Scheme", false, arrayOf("java", "@log"))
+ val scheme = parser.parse(File("$basePath/$name"), "AndroidIDE Test Scheme", false)
assertThat(scheme).isNotNull()
return scheme
}
diff --git a/eventbus/src/main/java/org/greenrobot/eventbus/SubscriberMethodFinder.java b/eventbus/src/main/java/org/greenrobot/eventbus/SubscriberMethodFinder.java
index 3ba2f289c7..152d5bc06a 100644
--- a/eventbus/src/main/java/org/greenrobot/eventbus/SubscriberMethodFinder.java
+++ b/eventbus/src/main/java/org/greenrobot/eventbus/SubscriberMethodFinder.java
@@ -294,7 +294,9 @@ void moveToSuperclass() {
if (clazzName.startsWith("java.")
|| clazzName.startsWith("javax.")
|| clazzName.startsWith("android.")
- || clazzName.startsWith("androidx.")) {
+ || clazzName.startsWith("androidx.")
+ || clazzName.startsWith("jdkx.")
+ || clazzName.startsWith("openjdk.")) {
clazz = null;
}
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index d1e8ce8c6d..c05cdab8a8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,12 +1,14 @@
[versions]
-agp = "7.4.0-rc03"
-kotlin = "1.8.0"
-tree-sitter = "1.0.10"
-editor = "0.20.4"
+agp = "7.4.1"
+agp-tooling = "7.4.1"
+gradle-tooling = "7.6"
+kotlin = "1.8.10"
+tree-sitter = "1.2.1"
+editor = "0.21.0"
glide = "4.14.2"
androidx-vectordrawable = "1.1.0"
androidx-navigation = "2.5.3"
-ksp = "1.8.0-1.0.8"
+ksp = "1.8.10-1.0.9"
antlr4 = "4.11.1"
[libraries]
@@ -26,7 +28,7 @@ common-glide_ap = { module = "com.github.bumptech.glide:compiler", version.ref =
common-jsoup = { module = "org.jsoup:jsoup", version = "1.15.3" }
common-antlr4 = { module = "org.antlr:antlr4", version.ref = "antlr4" }
common-antlr4-runtime = { module = "org.antlr:antlr4-runtime", version.ref = "antlr4" }
-common-javaparser = { module = "com.github.javaparser:javaparser-symbol-solver-core", version = "3.24.10" }
+common-javaparser = { module = "com.github.javaparser:javaparser-symbol-solver-core", version = "3.25.0" }
common-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.12.0" }
common-io = { module = "commons-io:commons-io", version = "2.11.0" }
common-kotlin = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
@@ -35,10 +37,11 @@ common-eventbus_ap = { module = "org.greenrobot:eventbus-annotation-processor",
common-javapoet = { module = "com.squareup:javapoet", version = "1.13.0" }
common-ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
common-jsonrpc = { module = "org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc", version = "0.19.0" }
+common-leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version = "2.10"}
# AndroidX
androidx-annotation = { module = "androidx.annotation:annotation", version = "1.5.0" }
-androidx-appcompat = { module = "androidx.appcompat:appcompat", version = "1.5.1" }
+androidx-appcompat = { module = "androidx.appcompat:appcompat", version = "1.6.1" }
androidx-cardview = { module = "androidx.cardview:cardview", version = "1.0.0" }
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.4" }
androidx-coordinatorlayout = { module = "androidx.coordinatorlayout:coordinatorlayout", version = "1.2.0" }
@@ -57,8 +60,8 @@ androidx-nav_ui = { module = "androidx.navigation:navigation-ui-ktx", version.re
androidx-nav_dynamic_features = { module = "androidx.navigation:navigation-dynamic-features-fragment", version.ref = "androidx-navigation" }
# Google
-google-material = { module = "com.google.android.material:material", version = "1.7.0" }
-google-gson = { module = "com.google.code.gson:gson", version = "2.10" }
+google-material = { module = "com.google.android.material:material", version = "1.8.0" }
+google-gson = { module = "com.google.code.gson:gson", version = "2.10.1" }
google-guava = { module = "com.google.guava:guava", version = "31.1-android" }
google-guava-jre = { module = "com.google.guava:guava", version = "31.1-jre" }
google-auto-value-annotations = { module = "com.google.auto.value:auto-value-annotations", version = "1.10.1" }
@@ -72,7 +75,7 @@ google-java-format = { module ="com.google.googlejavaformat:google-java-format",
# AAPT2
aapt2-common = { module = "com.android.tools:common", version = "30.2.2" }
aapt2-annotations = { module = "com.android.tools:annotations", version = "30.2.2" }
-aapt2-jb-annotations = { module = "org.jetbrains:annotations", version = "13.0" }
+aapt2-jb-annotations = { module = "org.jetbrains:annotations", version = "24.0.0" }
aapt2-proto = { module = "com.android.tools.build:aapt2-proto", version = "7.2.2-7984345" }
# XML
@@ -80,7 +83,7 @@ xml-xercesImpl = { module = "xerces:xercesImpl", version = "2.12.2" }
xml-apis = { module = "xml-apis:xml-apis", version = "2.0.2" }
xml-remark = { module = "com.kotcrab.remark:remark", version = "1.2.0" }
xml-resolver = { module = "xml-resolver:xml-resolver", version = "1.2" }
-xml-jb-annotations = { module = "org.jetbrains:annotations", version = "23.1.0" }
+xml-jb-annotations = { module = "org.jetbrains:annotations", version = "24.0.0" }
# GIT
git-jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "3.7.1.201504261725-r" }
@@ -94,6 +97,11 @@ tests-androidx-junit = { module = "androidx.test.ext:junit", version = "1.1.5" }
tests-androidx-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.5.1" }
tests-mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "4.1.0" }
+# Tooling
+tooling-builderModel = { module="com.android.tools.build:builder-model", version.ref = "agp-tooling" }
+tooling-gradleApi = { module="org.gradle:gradle-tooling-api", version.ref = "gradle-tooling" }
+tooling-slf4j = { module = "org.slf4j:slf4j-api", version = "2.0.6" }
+
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
diff --git a/lsp/java/build.gradle.kts b/lsp/java/build.gradle.kts
index 7ea41da3f1..6326c91383 100644
--- a/lsp/java/build.gradle.kts
+++ b/lsp/java/build.gradle.kts
@@ -27,6 +27,10 @@ android {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
+
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
}
kapt {
@@ -51,6 +55,7 @@ dependencies {
compileOnly(projects.actions)
compileOnly(projects.common)
+ implementation(projects.editorApi)
implementation(projects.resources)
implementation(projects.lsp.api)
implementation(projects.subprojects.javac)
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaCompilerProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaCompilerProvider.java
index 7d77a8b87f..b01d37e737 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaCompilerProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaCompilerProvider.java
@@ -64,7 +64,7 @@ public synchronized JavaCompilerService forModule(ModuleProject module) {
// TODO This currently destroys all the compiler instances
// We must have a method to destroy only the required instance in
// JavaLanguageServer.handleFailure(LSPFailure)
- public synchronized void destory() {
+ public synchronized void destroy() {
for (final JavaCompilerService compiler : mCompilers.values()) {
compiler.destroy();
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaLanguageServer.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaLanguageServer.java
index f0139480b8..b81b25e6ea 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaLanguageServer.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/JavaLanguageServer.java
@@ -113,7 +113,7 @@ public String getServerId() {
@Override
public void shutdown() {
- JavaCompilerProvider.getInstance().destory();
+ JavaCompilerProvider.getInstance().destroy();
SourceFileManager.clearCache();
CacheFSInfoSingleton.INSTANCE.clearCache();
CachingJarFileSystemProvider.INSTANCE.clearCache();
@@ -157,7 +157,7 @@ public void setupWithProject(@NonNull final Project project) {
CachingJarFileSystemProvider.INSTANCE.clearCachesForPaths(path -> path.endsWith("/R.jar"));
// Clear cached module-specific compilers
- JavaCompilerProvider.getInstance().destory();
+ JavaCompilerProvider.getInstance().destroy();
// Cache classpath locations
for (final Project subModule : project.getSubModules()) {
@@ -260,7 +260,7 @@ public boolean handleFailure(final LSPFailure failure) {
return true;
}
- JavaCompilerProvider.getInstance().destory();
+ JavaCompilerProvider.getInstance().destroy();
return true;
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/FieldBasedAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/FieldBasedAction.kt
index a5eed58c8e..58cd11c2f8 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/FieldBasedAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/FieldBasedAction.kt
@@ -24,21 +24,20 @@ 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.resources.R
import com.itsaky.androidide.lsp.java.compiler.CompileTask
import com.itsaky.androidide.lsp.java.visitors.FindTypeDeclarationAt
import com.itsaky.androidide.projects.ProjectManager
+import com.itsaky.androidide.resources.R
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.tree.Tree.Kind.VARIABLE
-import com.sun.source.tree.VariableTree
+import com.itsaky.androidide.utils.flashInfo
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.Tree.Kind.VARIABLE
+import openjdk.source.tree.VariableTree
import io.github.rosemoe.sora.widget.CodeEditor
import java.nio.file.Path
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionException
-import javax.lang.model.element.Modifier.STATIC
+import jdkx.lang.model.element.Modifier.STATIC
/**
* Any action that has to work with fields in the current class can inherit this action.
@@ -134,7 +133,7 @@ abstract class FieldBasedAction : BaseJavaCodeAction() {
}
if (result.isEmpty()) {
- toast(data[Context::class.java]!!.getString(R.string.msg_no_fields_found), Toaster.Type.INFO)
+ flashInfo(data[Context::class.java]!!.getString(R.string.msg_no_fields_found))
return
}
@@ -175,10 +174,7 @@ abstract class FieldBasedAction : BaseJavaCodeAction() {
dialog.dismiss()
if (checkedNames.isEmpty()) {
- toast(
- data[Context::class.java]!!.getString(R.string.msg_no_fields_selected),
- Toaster.Type.ERROR
- )
+ flashInfo(data[Context::class.java]!!.getString(R.string.msg_no_fields_selected))
return@setPositiveButton
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/FindReferencesAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/FindReferencesAction.kt
index ad24c4fa58..609cd593a1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/FindReferencesAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/FindReferencesAction.kt
@@ -19,9 +19,10 @@ package com.itsaky.androidide.lsp.java.actions.common
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
-import com.itsaky.androidide.resources.R
+import com.itsaky.androidide.editor.api.IEditor
+import com.itsaky.androidide.editor.api.ILspEditor
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
-import com.itsaky.androidide.utils.ILogger
+import com.itsaky.androidide.resources.R
import io.github.rosemoe.sora.widget.CodeEditor
import java.io.File
@@ -31,16 +32,16 @@ import java.io.File
* @author Akash Yadav
*/
class FindReferencesAction : BaseJavaCodeAction() {
+
override val titleTextRes: Int = R.string.action_find_references
override val id: String = "lsp_java_findReferences"
override var label: String = ""
override var requiresUIThread: Boolean = true
- private val log = ILogger.newInstance(javaClass.simpleName)
override fun prepare(data: ActionData) {
super.prepare(data)
- if (!visible || !data.hasRequiredData( CodeEditor::class.java, File::class.java)) {
+ if (!visible || !data.hasRequiredData(CodeEditor::class.java, File::class.java)) {
markInvisible()
return
}
@@ -48,17 +49,6 @@ class FindReferencesAction : BaseJavaCodeAction() {
override fun execAction(data: ActionData): Any {
val editor = data[CodeEditor::class.java]!!
- return tryExecFindDefinition(editor)
- }
-
- private fun tryExecFindDefinition(editor: CodeEditor): Boolean {
- return try {
- val method = editor::class.java.getDeclaredMethod("findReferences")
- method.isAccessible = true
- method.invoke(editor)
- true
- } catch (error: Throwable) {
- false
- }
+ return (editor as? ILspEditor)?.findReferences() ?: false
}
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/GoToDefinitionAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/GoToDefinitionAction.kt
index 3f2aef41e9..35aa7b0712 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/GoToDefinitionAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/common/GoToDefinitionAction.kt
@@ -19,8 +19,10 @@ package com.itsaky.androidide.lsp.java.actions.common
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.hasRequiredData
import com.itsaky.androidide.actions.markInvisible
-import com.itsaky.androidide.resources.R
+import com.itsaky.androidide.editor.api.IEditor
+import com.itsaky.androidide.editor.api.ILspEditor
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
+import com.itsaky.androidide.resources.R
import com.itsaky.androidide.utils.ILogger
import io.github.rosemoe.sora.widget.CodeEditor
import java.io.File
@@ -41,7 +43,7 @@ class GoToDefinitionAction : BaseJavaCodeAction() {
override fun prepare(data: ActionData) {
super.prepare(data)
- if (!visible || !data.hasRequiredData( CodeEditor::class.java, File::class.java)) {
+ if (!visible || !data.hasRequiredData(CodeEditor::class.java, File::class.java)) {
markInvisible()
return
}
@@ -49,17 +51,6 @@ class GoToDefinitionAction : BaseJavaCodeAction() {
override fun execAction(data: ActionData): Any {
val editor = data[CodeEditor::class.java]!!
- return tryExecFindDefinition(editor)
- }
-
- private fun tryExecFindDefinition(editor: CodeEditor): Boolean {
- return try {
- val method = editor::class.java.getDeclaredMethod("findDefinition")
- method.isAccessible = true
- method.invoke(editor)
- true
- } catch (error: Throwable) {
- false
- }
+ return (editor as? ILspEditor)?.findDefinition() ?: false
}
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/AddImportAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/AddImportAction.kt
index 855bf46771..cd21bbc0c3 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/AddImportAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/AddImportAction.kt
@@ -36,8 +36,8 @@ import com.itsaky.androidide.lsp.models.DiagnosticItem
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.utils.ILogger
-import javax.tools.Diagnostic
-import javax.tools.JavaFileObject
+import jdkx.tools.Diagnostic
+import jdkx.tools.JavaFileObject
/** @author Akash Yadav */
class AddImportAction : BaseJavaCodeAction() {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/ImplementAbstractMethodsAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/ImplementAbstractMethodsAction.kt
index ccdb9f0f7b..71741f12bf 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/ImplementAbstractMethodsAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/diagnostics/ImplementAbstractMethodsAction.kt
@@ -25,8 +25,8 @@ 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
-import javax.tools.Diagnostic
-import javax.tools.JavaFileObject
+import jdkx.tools.Diagnostic
+import jdkx.tools.JavaFileObject
/** @author Akash Yadav */
class ImplementAbstractMethodsAction : BaseJavaCodeAction() {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateConstructorAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateConstructorAction.kt
index 84f949cceb..0b07ad8dd6 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateConstructorAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateConstructorAction.kt
@@ -26,25 +26,24 @@ 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.resources.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.lsp.java.utils.ShortTypePrinter.NO_PACKAGE
import com.itsaky.androidide.projects.ProjectManager
+import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.utils.ILogger
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
-import com.itsaky.toaster.toastLong
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.VariableTree
-import com.sun.source.util.TreePath
-import com.sun.tools.javac.api.JavacTrees
-import com.sun.tools.javac.code.Symbol.ClassSymbol
-import com.sun.tools.javac.code.Symbol.VarSymbol
-import com.sun.tools.javac.code.Type
-import com.sun.tools.javac.tree.JCTree
-import com.sun.tools.javac.tree.TreeInfo
-import com.sun.tools.javac.util.ListBuffer
+import com.itsaky.androidide.utils.flashError
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.VariableTree
+import openjdk.source.util.TreePath
+import openjdk.tools.javac.api.JavacTrees
+import openjdk.tools.javac.code.Symbol.ClassSymbol
+import openjdk.tools.javac.code.Symbol.VarSymbol
+import openjdk.tools.javac.code.Type
+import openjdk.tools.javac.tree.JCTree
+import openjdk.tools.javac.tree.TreeInfo
+import openjdk.tools.javac.util.ListBuffer
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.concurrent.CompletableFuture
@@ -64,7 +63,7 @@ class GenerateConstructorAction : FieldBasedAction() {
.whenComplete { _, error ->
if (error != null) {
log.error("Unable to generate constructor for the selected fields", error)
- toast(string.msg_cannot_generate_constructor, ERROR)
+ flashError(string.msg_cannot_generate_constructor)
}
}
}
@@ -106,7 +105,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)
+ flashError(data[Context::class.java]!!.getString(string.msg_constructor_available))
return
}
@@ -147,13 +146,13 @@ class GenerateConstructorAction : FieldBasedAction() {
val paramType = paramTypes[i]
val paramName = paramNames[i]
- constructor.addParameter(paramType.tsym.simpleName.toString(), paramName)
+ constructor.addParameter(NO_PACKAGE.print(paramType), paramName)
}
return constructor
}
- private fun mapTypes(paths: List): com.sun.tools.javac.util.List {
+ private fun mapTypes(paths: List): openjdk.tools.javac.util.List {
val buffer = ListBuffer()
for (path in paths) {
val leaf = path.leaf
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateSettersAndGettersAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateSettersAndGettersAction.kt
index 33fdbc9676..33a7114199 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateSettersAndGettersAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateSettersAndGettersAction.kt
@@ -37,15 +37,14 @@ import com.itsaky.androidide.lsp.java.utils.TypeUtils.toType
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.resources.R
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 com.itsaky.androidide.utils.flashError
+import openjdk.source.tree.ClassTree
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.concurrent.CompletableFuture
-import javax.lang.model.element.Modifier.FINAL
-import javax.lang.model.element.VariableElement
+import jdkx.lang.model.element.Modifier.FINAL
+import jdkx.lang.model.element.VariableElement
/**
* Allows the user to select fields from the current class, then generates setters and getters for
@@ -69,9 +68,8 @@ 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
+ flashError(
+ data[Context::class.java]!!.getString(R.string.msg_cannot_generate_setters_getters)
)
}
return@whenComplete
@@ -133,7 +131,7 @@ class GenerateSettersAndGettersAction : FieldBasedAction() {
}
private fun createGetter(variable: VariableElement, indent: Int): String {
- val name: String = variable.simpleName.toString()
+ val name = variable.simpleName.toString()
val method =
createMethod(variable, "get", toType(variable.asType())) { _, body ->
body.addStatement(createReturnStmt(name))
@@ -154,7 +152,7 @@ class GenerateSettersAndGettersAction : FieldBasedAction() {
body.addStatement(createAssignmentStmt(name))
}
- var text = "\n" + method.toString()
+ var text = "\n" + JavaParserUtils.prettyPrint(method) { false }
text = text.replace("\n", "\n${EditHelper.repeatSpaces(indent)}")
return text
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateToStringMethodAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateToStringMethodAction.kt
index b810121979..66f41ac404 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateToStringMethodAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/GenerateToStringMethodAction.kt
@@ -26,27 +26,26 @@ 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.resources.R
-import com.itsaky.androidide.resources.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.resources.R
+import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.utils.ILogger
-import com.itsaky.toaster.Toaster.Type.ERROR
-import com.itsaky.toaster.toast
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.VariableTree
-import com.sun.source.util.TreePath
-import com.sun.tools.javac.api.JavacTrees
-import com.sun.tools.javac.code.Symbol.ClassSymbol
-import com.sun.tools.javac.code.Symbol.MethodSymbol
-import com.sun.tools.javac.tree.JCTree
-import com.sun.tools.javac.tree.TreeInfo
-import com.sun.tools.javac.util.Names
+import com.itsaky.androidide.utils.flashError
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.VariableTree
+import openjdk.source.util.TreePath
+import openjdk.tools.javac.api.JavacTrees
+import openjdk.tools.javac.code.Symbol.ClassSymbol
+import openjdk.tools.javac.code.Symbol.MethodSymbol
+import openjdk.tools.javac.tree.JCTree
+import openjdk.tools.javac.tree.TreeInfo
+import openjdk.tools.javac.util.Names
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.concurrent.CompletableFuture
-import javax.lang.model.element.VariableElement
+import jdkx.lang.model.element.VariableElement
/**
* Generates the `toString()` method for the current class.
@@ -67,9 +66,8 @@ class GenerateToStringMethodAction : FieldBasedAction() {
if (error != null) {
log.error("Unable to generate toString() implementation", error)
ThreadUtils.runOnUiThread {
- toast(
- data[Context::class.java]!!.getString(R.string.msg_cannot_generate_toString),
- ERROR
+ flashError(
+ data[Context::class.java]!!.getString(R.string.msg_cannot_generate_toString)
)
}
return@whenComplete
@@ -106,7 +104,7 @@ class GenerateToStringMethodAction : FieldBasedAction() {
) {
if (isToStringOverridden(task, type)) {
ThreadUtils.runOnUiThread {
- toast(data[Context::class.java]!!.getString(string.msg_toString_overridden), ERROR)
+ flashError(data[Context::class.java]!!.getString(string.msg_toString_overridden))
}
log.warn("toString() method has already been overridden in class ${type.simpleName}")
return
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/OverrideSuperclassMethodsAction.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/OverrideSuperclassMethodsAction.kt
index 8cab3a52ed..76aaa53ebd 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/OverrideSuperclassMethodsAction.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/actions/generators/OverrideSuperclassMethodsAction.kt
@@ -25,7 +25,6 @@ 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.resources.R
import com.itsaky.androidide.lsp.java.actions.BaseJavaCodeAction
import com.itsaky.androidide.lsp.java.compiler.CompileTask
import com.itsaky.androidide.lsp.java.compiler.CompilerProvider
@@ -37,22 +36,22 @@ import com.itsaky.androidide.lsp.java.utils.JavaParserUtils
import com.itsaky.androidide.lsp.java.utils.MethodPtr
import com.itsaky.androidide.lsp.java.visitors.FindTypeDeclarationAt
import com.itsaky.androidide.projects.ProjectManager
+import com.itsaky.androidide.resources.R
import com.itsaky.androidide.utils.ILogger
-import com.itsaky.toaster.Toaster
-import com.itsaky.toaster.toast
-import com.sun.source.tree.MethodTree
-import com.sun.source.util.Trees
+import com.itsaky.androidide.utils.flashError
+import openjdk.source.tree.MethodTree
+import openjdk.source.util.Trees
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.Arrays
import java.util.Optional
import java.util.concurrent.CompletableFuture
-import javax.lang.model.element.ElementKind
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.DeclaredType
-import javax.lang.model.type.ExecutableType
-import javax.tools.JavaFileObject
+import jdkx.lang.model.element.ElementKind
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.type.DeclaredType
+import jdkx.lang.model.type.ExecutableType
+import jdkx.tools.JavaFileObject
/**
* Allows the user to override multiple methods from superclass at once.
@@ -147,10 +146,7 @@ class OverrideSuperclassMethodsAction : BaseJavaCodeAction() {
override fun postExec(data: ActionData, result: Any) {
if (result !is List<*> || result.isEmpty() || position < 0) {
log.warn("Unable to find any overridable method")
- toast(
- data[Context::class.java]!!.getString(R.string.msg_no_overridable_methods),
- Toaster.Type.ERROR
- )
+ flashError(data[Context::class.java]!!.getString(R.string.msg_no_overridable_methods))
return
}
@@ -172,10 +168,7 @@ class OverrideSuperclassMethodsAction : BaseJavaCodeAction() {
dialog.dismiss()
if (checkedMethods.isEmpty()) {
- toast(
- data[Context::class.java]!!.getString(R.string.msg_no_methods_selected),
- Toaster.Type.ERROR
- )
+ flashError(data[Context::class.java]!!.getString(R.string.msg_no_methods_selected))
return@setPositiveButton
}
@@ -186,9 +179,8 @@ class OverrideSuperclassMethodsAction : BaseJavaCodeAction() {
log.error("An error occurred overriding methods")
ThreadUtils.runOnUiThread {
- toast(
- data[Context::class.java]!!.getString(R.string.msg_cannot_override_methods),
- Toaster.Type.ERROR
+ flashError(
+ data[Context::class.java]!!.getString(R.string.msg_cannot_override_methods)
)
}
}
@@ -198,6 +190,7 @@ class OverrideSuperclassMethodsAction : BaseJavaCodeAction() {
builder.show()
}
+ @Suppress("Since15")
private fun overrideMethods(data: ActionData, checkedMethods: MutableList) {
val compiler =
JavaCompilerProvider.get(ProjectManager.findModuleForFile(data.requireFile()) ?: return)
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilationTaskProcessor.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilationTaskProcessor.kt
index 17a0fee631..04f32e1ee8 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilationTaskProcessor.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilationTaskProcessor.kt
@@ -17,8 +17,8 @@
package com.itsaky.androidide.lsp.java.compiler
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.tools.javac.api.JavacTaskImpl
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.tools.javac.api.JavacTaskImpl
import java.util.function.*
/**
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java
index 636f75664c..2caba1c41d 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileBatch.java
@@ -28,25 +28,22 @@
import androidx.core.util.Pair;
import com.itsaky.androidide.builder.model.IJavaCompilerSettings;
-import com.itsaky.androidide.config.JavacConfigProvider;
import com.itsaky.androidide.javac.services.compiler.ReusableBorrow;
import com.itsaky.androidide.javac.services.partial.DiagnosticListenerImpl;
import com.itsaky.androidide.lsp.java.visitors.MethodRangeScanner;
import com.itsaky.androidide.models.Range;
-import com.itsaky.androidide.projects.api.AndroidModule;
import com.itsaky.androidide.projects.api.ModuleProject;
import com.itsaky.androidide.projects.util.StringSearch;
import com.itsaky.androidide.tooling.api.IProject;
import com.itsaky.androidide.utils.ClassTrie;
-import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.SourceClassTrie;
import com.itsaky.androidide.utils.StopWatch;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.TreePath;
-import com.sun.tools.javac.api.ClientCodeWrapper;
-import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.util.JCDiagnostic;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.TreePath;
+import openjdk.tools.javac.api.ClientCodeWrapper;
+import openjdk.tools.javac.api.JavacTaskImpl;
+import openjdk.tools.javac.code.Kinds;
+import openjdk.tools.javac.util.JCDiagnostic;
import java.io.File;
import java.nio.file.Path;
@@ -61,16 +58,14 @@
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import javax.lang.model.SourceVersion;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
+import jdkx.lang.model.SourceVersion;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.JavaFileObject;
public class CompileBatch implements AutoCloseable {
public static final String DEFAULT_COMPILER_SOURCE_AND_TARGET_VERSION = "11";
- private static final ILogger LOG = ILogger.newInstance("CompileBatch");
protected final JavaCompilerService parent;
protected final ReusableBorrow borrow;
protected final JavacTaskImpl task;
@@ -100,7 +95,7 @@ public class CompileBatch implements AutoCloseable {
private void processCompilationUnit(final CompilationUnitTree root) {
roots.add(root);
- updatePositions(root, false);
+// updatePositions(root, false);
}
void updatePositions(CompilationUnitTree tree, boolean allowDuplicate) {
@@ -141,7 +136,7 @@ private ReusableBorrow batchTask(
@NonNull
private List options() {
List options = new ArrayList<>();
-
+
// This won't be used if the current module is Android module project
System.setProperty(PROP_ANDROIDIDE_JAVA_HOME, JAVA_HOME.getAbsolutePath());
if (this.parent.module != null && this.parent.module.getType() == IProject.Type.Android) {
@@ -198,15 +193,6 @@ protected void setupCompileOptions(final ModuleProject module, final List classOrSourcePath) {
- return classOrSourcePath.stream()
- .map(Path::toString)
- .collect(Collectors.joining(File.pathSeparator));
- }
-
@Override
public void close() {
closed = true;
@@ -231,7 +217,6 @@ Set needsAdditionalSources() {
if (!isValidFileRange(err)) {
continue;
}
-
String packageName = packageName(err);
ClassTrie.Node node = parent.getModule().compileJavaSourceClasses.findNode(packageName);
if (node != null && node.isClass() && node instanceof SourceClassTrie.SourceNode) {
@@ -241,7 +226,7 @@ Set needsAdditionalSources() {
return addFiles;
}
- private String packageName(javax.tools.Diagnostic extends javax.tools.JavaFileObject> err) {
+ private String packageName(Diagnostic extends JavaFileObject> err) {
if (err instanceof ClientCodeWrapper.DiagnosticSourceUnwrapper) {
JCDiagnostic diagnostic = ((ClientCodeWrapper.DiagnosticSourceUnwrapper) err).d;
JCDiagnostic.DiagnosticPosition pos = diagnostic.getDiagnosticPosition();
@@ -257,7 +242,7 @@ private String packageName(javax.tools.Diagnostic extends javax.tools.JavaFile
return StringSearch.packageName(file);
}
- private boolean isValidFileRange(javax.tools.Diagnostic extends JavaFileObject> d) {
+ private boolean isValidFileRange(Diagnostic extends JavaFileObject> d) {
return d.getSource().toUri().getScheme().equals("file")
&& d.getStartPosition() >= 0
&& d.getEndPosition() >= 0;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileTask.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileTask.java
index 411a07a41f..b99914b6cb 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileTask.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompileTask.java
@@ -20,14 +20,14 @@
import androidx.annotation.NonNull;
import com.itsaky.androidide.javac.services.partial.DiagnosticListenerImpl;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.tools.javac.api.JavacTaskImpl;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.tools.javac.api.JavacTaskImpl;
import java.nio.file.Path;
import java.util.List;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.JavaFileObject;
public class CompileTask implements AutoCloseable {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilerProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilerProvider.java
index 6f080446b6..a5251f1b82 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilerProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/CompilerProvider.java
@@ -28,7 +28,7 @@
import java.util.TreeSet;
import java.util.stream.Collectors;
-import javax.tools.JavaFileObject;
+import jdkx.tools.JavaFileObject;
public interface CompilerProvider {
Path NOT_FOUND = Paths.get("");
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt
index ee9c70ef70..bdd340baee 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/DefaultCompilationTaskProcessor.kt
@@ -17,10 +17,9 @@
package com.itsaky.androidide.lsp.java.compiler
-import com.itsaky.androidide.javac.services.util.JavacTaskUtil
import com.itsaky.androidide.utils.StopWatch
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.tools.javac.api.JavacTaskImpl
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.tools.javac.api.JavacTaskImpl
import java.util.function.Consumer
/**
@@ -37,7 +36,11 @@ class DefaultCompilationTaskProcessor : CompilationTaskProcessor {
trees.forEach(processCompilationUnit::accept)
watch.lapFromLast("Processed trees")
-
+
+// val entered = JavacTaskUtil.enterTrees(task, trees)
+// watch.lapFromLast("Entered trees")
+//
+// val analyzed = JavacTaskUtil.analyze(task, entered)
task.analyze()
watch.lapFromLast("Analyzed all trees")
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java
index 32d3cf36c6..bc27762429 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerService.java
@@ -44,11 +44,11 @@
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.SourceClassTrie;
import com.itsaky.androidide.utils.StopWatch;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
import java.io.BufferedReader;
import java.io.File;
@@ -69,9 +69,9 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardLocation;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.StandardLocation;
public class JavaCompilerService implements CompilerProvider {
@@ -269,22 +269,22 @@ private boolean needsCompilation(Collection extends JavaFileObject> sources) {
}
private synchronized void reparseOrRecompile(CompilationRequest request) {
- if (needsRecompilation(request)) {
- LOG.warn("Cannot reparse. Recompilation is required");
+// if (needsRecompilation(request)) {
+// LOG.warn("Cannot reparse. Recompilation is required");
recompile(request);
- } else {
- LOG.debug("Trying to perform a reparse...");
- tryReparse(request);
- }
+// } else {
+// LOG.debug("Trying to perform a reparse...");
+// tryReparse(request);
+// }
}
private boolean needsRecompilation(final CompilationRequest request) {
return this.cachedCompile == null
- || this.cachedCompile.closed
- || request.partialRequest == null
- || request.partialRequest.cursor < 0
- || !isChangeValidForReparse()
- || request.sources.size() != 1; // Cannot perform a reparse if there are multiple files
+ || this.cachedCompile.closed;
+// || request.partialRequest == null
+// || request.partialRequest.cursor < 0
+// || !isChangeValidForReparse()
+// || request.sources.size() != 1; // Cannot perform a reparse if there are multiple files
}
private boolean isChangeValidForReparse() {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileManager.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileManager.java
index d948ce5a3f..d273b92a3d 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileManager.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileManager.java
@@ -33,9 +33,9 @@
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.SourceClassTrie;
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.api.JavacTool;
+import openjdk.tools.javac.file.JavacFileManager;
+import openjdk.tools.javac.util.Context;
import java.io.File;
import java.io.IOException;
@@ -51,10 +51,10 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardLocation;
+import jdkx.tools.FileObject;
+import jdkx.tools.ForwardingJavaFileManager;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.StandardLocation;
@SuppressWarnings("Since15")
public class SourceFileManager extends ForwardingJavaFileManager {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileObject.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileObject.java
index 930ff34fc2..4f07d2f8f7 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileObject.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SourceFileObject.java
@@ -31,9 +31,9 @@
import java.nio.file.Path;
import java.time.Instant;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.NestingKind;
-import javax.tools.JavaFileObject;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.NestingKind;
+import jdkx.tools.JavaFileObject;
public class SourceFileObject implements JavaFileObject {
/** path is the absolute path to this file on disk */
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/models/CompilationRequest.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/models/CompilationRequest.kt
index a66721c010..469e597590 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/models/CompilationRequest.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/models/CompilationRequest.kt
@@ -19,7 +19,7 @@ package com.itsaky.androidide.lsp.java.models
import com.itsaky.androidide.lsp.java.compiler.CompilationTaskProcessor
import com.itsaky.androidide.lsp.java.compiler.DefaultCompilationTaskProcessor
-import javax.tools.JavaFileObject
+import jdkx.tools.JavaFileObject
/**
* Data sent to compiler to request a compilation.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/ParseTask.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/ParseTask.java
index 80b7b92843..86830877c1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/ParseTask.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/ParseTask.java
@@ -17,8 +17,8 @@
package com.itsaky.androidide.lsp.java.parser;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.JavacTask;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.JavacTask;
public class ParseTask {
public final JavacTask task;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/Parser.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/Parser.java
index 9ed8195ec9..806cff7c9d 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/Parser.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/Parser.java
@@ -24,17 +24,17 @@
import com.itsaky.androidide.projects.ProjectManager;
import com.itsaky.androidide.projects.api.ModuleProject;
import com.itsaky.androidide.utils.ILogger;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.api.JavacTool;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
+import openjdk.tools.javac.api.JavacTool;
import java.io.IOException;
import java.nio.file.Path;
@@ -43,8 +43,8 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
+import jdkx.tools.JavaCompiler;
+import jdkx.tools.JavaFileObject;
public class Parser {
@@ -92,7 +92,7 @@ private static JavacTask singleFileTask(JavaFileObject file) {
Collections.singletonList(file));
}
- private static void ignoreError(javax.tools.Diagnostic extends JavaFileObject> __) {
+ private static void ignoreError(jdkx.tools.Diagnostic extends JavaFileObject> __) {
// Too noisy, this only comes up in parse tasks which tend to be less important
// LOG.warning(err.getMessage(Locale.getDefault()));
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java
index c3d66387d2..e47ca3cefd 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/CompletionProvider.java
@@ -43,6 +43,7 @@
import com.itsaky.androidide.lsp.java.providers.completion.SwitchConstantCompletionProvider;
import com.itsaky.androidide.lsp.java.providers.completion.TopLevelSnippetsProvider;
import com.itsaky.androidide.lsp.java.utils.ASTFixer;
+import com.itsaky.androidide.lsp.java.utils.CancelChecker;
import com.itsaky.androidide.lsp.java.visitors.FindCompletionsAt;
import com.itsaky.androidide.lsp.java.visitors.PruneMethodBodies;
import com.itsaky.androidide.lsp.models.CompletionParams;
@@ -50,8 +51,8 @@
import com.itsaky.androidide.utils.DocumentUtils;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.StopWatch;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.TreePath;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.TreePath;
import java.nio.file.Path;
import java.time.Duration;
@@ -104,6 +105,13 @@ public CompletionResult complete(@NonNull CompletionParams params) {
abortIfCancelled();
abortCompletionIfCancelled();
return completeInternal(params);
+ } catch (Throwable err) {
+ if (CancelChecker.isCancelled(err)) {
+ LOG.info("Completion request cancelled");
+ } else {
+ LOG.error("An error occurred while computing completions", err);
+ }
+ throw err;
} finally {
completing.set(false);
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DefinitionProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DefinitionProvider.java
index f2931d8cbf..2a46ad16ed 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DefinitionProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DefinitionProvider.java
@@ -42,10 +42,10 @@
import java.util.List;
import java.util.Optional;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeKind;
-import javax.tools.JavaFileObject;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.TypeKind;
+import jdkx.tools.JavaFileObject;
public class DefinitionProvider {
public static final List NOT_SUPPORTED = Collections.emptyList();
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt
index e49481907e..2f02eb86c2 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/DiagnosticsProvider.kt
@@ -25,26 +25,24 @@ import com.itsaky.androidide.lsp.models.DiagnosticItem
import com.itsaky.androidide.lsp.models.DiagnosticSeverity
import com.itsaky.androidide.lsp.models.DiagnosticSeverity.WARNING
import com.itsaky.androidide.models.Range
-import com.itsaky.androidide.progress.ProgressManager
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
import com.itsaky.androidide.projects.FileManager
import com.itsaky.androidide.utils.DocumentUtils.isSameFile
-import com.sun.source.tree.BlockTree
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.LineMap
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.VariableTree
-import com.sun.source.util.TreePath
-import com.sun.source.util.Trees
-import com.sun.tools.javac.code.Symbol.ClassSymbol
+import openjdk.source.tree.BlockTree
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.LineMap
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.VariableTree
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
import java.nio.file.Path
import java.nio.file.Paths
-import java.util.*
-import java.util.regex.*
-import javax.lang.model.element.Element
-import javax.tools.Diagnostic
-import javax.tools.JavaFileObject
+import java.util.Locale
+import java.util.regex.Pattern
+import jdkx.lang.model.element.Element
+import jdkx.tools.Diagnostic
+import jdkx.tools.JavaFileObject
/**
* Finds errors and warnings from a compilation task.
@@ -74,15 +72,15 @@ object DiagnosticsProvider {
break
}
}
-
+
abortIfCancelled()
-
+
if (root == null) {
// CompilationUnitTree for the file was not found
// Can't do anything...
return result
}
-
+
addCompilerErrors(task, root, result)
abortIfCancelled()
addDiagnosticsByVisiting(task, root, result)
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt
index 818959cc5c..1f4a3381aa 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaDiagnosticProvider.kt
@@ -84,12 +84,17 @@ class JavaDiagnosticProvider {
}
private fun doAnalyze(file: Path, task: CompileTask): DiagnosticResult {
- return if (!isTaskValid(task)) {
- // Do not use Collections.emptyList ()
- // The returned list is accessed and the list returned by Collections.emptyList()
- // throws exception when trying to access.
- cachedDiagnostics
- } else DiagnosticResult(file, findDiagnostics(task, file).sortedBy { it.range })
+ val result =
+ if (!isTaskValid(task)) {
+ // Do not use Collections.emptyList ()
+ // The returned list is accessed and the list returned by Collections.emptyList()
+ // throws exception when trying to access.
+ log.info("Using cached diagnostics")
+ cachedDiagnostics
+ } else DiagnosticResult(file, findDiagnostics(task, file).sortedBy { it.range })
+ return result.also {
+ log.info("Analyze file completed. Found ${result.diagnostics.size} diagnostic items")
+ }
}
private fun isTaskValid(task: CompileTask?): Boolean {
@@ -105,11 +110,11 @@ class JavaDiagnosticProvider {
try {
compiler.compile(file).get { task -> doAnalyze(file, task) }
} catch (err: Throwable) {
-
- if (!CancelChecker.isCancelled(err)) {
+ if (CancelChecker.isCancelled(err)) {
+ log.error("Analyze request cancelled")
+ } else {
log.warn("Unable to analyze file", err)
}
-
DiagnosticResult.NO_UPDATE
} finally {
compiler.destroy()
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProvider.java
index 2659f0f0da..1ff21dcfc3 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProvider.java
@@ -24,7 +24,7 @@
import com.itsaky.androidide.lsp.java.visitors.FindBiggerRange;
import com.itsaky.androidide.lsp.models.ExpandSelectionParams;
import com.itsaky.androidide.models.Range;
-import com.sun.source.tree.CompilationUnitTree;
+import openjdk.source.tree.CompilationUnitTree;
/**
* Selection provider implementation for Java.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/ReferenceProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/ReferenceProvider.java
index 59703c72a2..0375626787 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/ReferenceProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/ReferenceProvider.java
@@ -28,16 +28,16 @@
import com.itsaky.androidide.lsp.models.ReferenceParams;
import com.itsaky.androidide.lsp.models.ReferenceResult;
import com.itsaky.androidide.models.Location;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.TreePath;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.TreePath;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.TypeElement;
public class ReferenceProvider {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/SignatureProvider.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/SignatureProvider.java
index e9a8a92bf8..75ef902d50 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/SignatureProvider.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/SignatureProvider.java
@@ -32,20 +32,20 @@
import com.itsaky.androidide.lsp.models.SignatureHelp;
import com.itsaky.androidide.lsp.models.SignatureHelpParams;
import com.itsaky.androidide.lsp.models.SignatureInformation;
-import com.sun.source.doctree.DocCommentTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.Scope;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.DocTrees;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
+import openjdk.source.doctree.DocCommentTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.NewClassTree;
+import openjdk.source.tree.Scope;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.DocTrees;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -55,19 +55,19 @@
import java.util.StringJoiner;
import java.util.function.Predicate;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.tools.JavaFileObject;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.ElementKind;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.element.VariableElement;
+import jdkx.lang.model.type.ArrayType;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.ErrorType;
+import jdkx.lang.model.type.PrimitiveType;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.type.TypeVariable;
+import jdkx.tools.JavaFileObject;
public class SignatureProvider {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ClassNamesCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ClassNamesCompletionProvider.kt
index 959a99a7e2..a4bf9a7cb1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ClassNamesCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ClassNamesCompletionProvider.kt
@@ -24,9 +24,9 @@ import com.itsaky.androidide.lsp.java.providers.CompletionProvider
import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.util.TreePath
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.util.TreePath
import java.nio.file.Path
import java.nio.file.Paths
import java.util.Objects
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IJavaCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IJavaCompletionProvider.kt
index 4ceaaca65b..e023fa9291 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IJavaCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IJavaCompletionProvider.kt
@@ -43,30 +43,30 @@ import com.itsaky.androidide.lsp.models.MatchLevel
import com.itsaky.androidide.lsp.models.MethodCompletionData
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
import com.itsaky.androidide.utils.ILogger
-import com.sun.source.tree.Tree
-import com.sun.source.util.TreePath
+import openjdk.source.tree.Tree
+import openjdk.source.util.TreePath
import java.nio.file.Path
-import javax.lang.model.element.Element
-import javax.lang.model.element.ElementKind.ANNOTATION_TYPE
-import javax.lang.model.element.ElementKind.CLASS
-import javax.lang.model.element.ElementKind.CONSTRUCTOR
-import javax.lang.model.element.ElementKind.ENUM
-import javax.lang.model.element.ElementKind.ENUM_CONSTANT
-import javax.lang.model.element.ElementKind.EXCEPTION_PARAMETER
-import javax.lang.model.element.ElementKind.FIELD
-import javax.lang.model.element.ElementKind.INSTANCE_INIT
-import javax.lang.model.element.ElementKind.INTERFACE
-import javax.lang.model.element.ElementKind.LOCAL_VARIABLE
-import javax.lang.model.element.ElementKind.METHOD
-import javax.lang.model.element.ElementKind.OTHER
-import javax.lang.model.element.ElementKind.PACKAGE
-import javax.lang.model.element.ElementKind.PARAMETER
-import javax.lang.model.element.ElementKind.RESOURCE_VARIABLE
-import javax.lang.model.element.ElementKind.STATIC_INIT
-import javax.lang.model.element.ElementKind.TYPE_PARAMETER
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.TypeElement
-import javax.lang.model.element.VariableElement
+import jdkx.lang.model.element.Element
+import jdkx.lang.model.element.ElementKind.ANNOTATION_TYPE
+import jdkx.lang.model.element.ElementKind.CLASS
+import jdkx.lang.model.element.ElementKind.CONSTRUCTOR
+import jdkx.lang.model.element.ElementKind.ENUM
+import jdkx.lang.model.element.ElementKind.ENUM_CONSTANT
+import jdkx.lang.model.element.ElementKind.EXCEPTION_PARAMETER
+import jdkx.lang.model.element.ElementKind.FIELD
+import jdkx.lang.model.element.ElementKind.INSTANCE_INIT
+import jdkx.lang.model.element.ElementKind.INTERFACE
+import jdkx.lang.model.element.ElementKind.LOCAL_VARIABLE
+import jdkx.lang.model.element.ElementKind.METHOD
+import jdkx.lang.model.element.ElementKind.OTHER
+import jdkx.lang.model.element.ElementKind.PACKAGE
+import jdkx.lang.model.element.ElementKind.PARAMETER
+import jdkx.lang.model.element.ElementKind.RESOURCE_VARIABLE
+import jdkx.lang.model.element.ElementKind.STATIC_INIT
+import jdkx.lang.model.element.ElementKind.TYPE_PARAMETER
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.element.VariableElement
/**
* Completion provider for Java source code.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IdentifierCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IdentifierCompletionProvider.kt
index 1c0dec94f2..38127841a1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IdentifierCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/IdentifierCompletionProvider.kt
@@ -23,7 +23,7 @@ import com.itsaky.androidide.lsp.java.compiler.JavaCompilerService
import com.itsaky.androidide.lsp.models.CompletionItem
import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.util.TreePath
+import openjdk.source.util.TreePath
import java.nio.file.Path
/** @author Akash Yadav */
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ImportCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ImportCompletionProvider.kt
index 24f1ea8b11..f49658d604 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ImportCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ImportCompletionProvider.kt
@@ -30,26 +30,26 @@ import com.itsaky.androidide.projects.api.ModuleProject
import com.itsaky.androidide.projects.util.BootClasspathProvider
import com.itsaky.androidide.utils.ClassTrie
import com.itsaky.androidide.utils.ClassTrie.Node
-import com.sun.source.util.TreePath
-import com.sun.tools.javac.api.JavacTrees
-import com.sun.tools.javac.code.Symbol.MethodSymbol
-import com.sun.tools.javac.model.JavacTypes
-import com.sun.tools.javac.tree.JCTree.JCImport
+import openjdk.source.util.TreePath
+import openjdk.tools.javac.api.JavacTrees
+import openjdk.tools.javac.code.Symbol.MethodSymbol
+import openjdk.tools.javac.model.JavacTypes
+import openjdk.tools.javac.tree.JCTree.JCImport
import java.nio.file.Path
-import javax.lang.model.element.Element
-import javax.lang.model.element.ElementKind
-import javax.lang.model.element.ElementKind.ANNOTATION_TYPE
-import javax.lang.model.element.ElementKind.CLASS
-import javax.lang.model.element.ElementKind.CONSTRUCTOR
-import javax.lang.model.element.ElementKind.ENUM
-import javax.lang.model.element.ElementKind.ENUM_CONSTANT
-import javax.lang.model.element.ElementKind.FIELD
-import javax.lang.model.element.ElementKind.INSTANCE_INIT
-import javax.lang.model.element.ElementKind.INTERFACE
-import javax.lang.model.element.ElementKind.METHOD
-import javax.lang.model.element.ElementKind.STATIC_INIT
-import javax.lang.model.element.Modifier.STATIC
-import javax.lang.model.element.TypeElement
+import jdkx.lang.model.element.Element
+import jdkx.lang.model.element.ElementKind
+import jdkx.lang.model.element.ElementKind.ANNOTATION_TYPE
+import jdkx.lang.model.element.ElementKind.CLASS
+import jdkx.lang.model.element.ElementKind.CONSTRUCTOR
+import jdkx.lang.model.element.ElementKind.ENUM
+import jdkx.lang.model.element.ElementKind.ENUM_CONSTANT
+import jdkx.lang.model.element.ElementKind.FIELD
+import jdkx.lang.model.element.ElementKind.INSTANCE_INIT
+import jdkx.lang.model.element.ElementKind.INTERFACE
+import jdkx.lang.model.element.ElementKind.METHOD
+import jdkx.lang.model.element.ElementKind.STATIC_INIT
+import jdkx.lang.model.element.Modifier.STATIC
+import jdkx.lang.model.element.TypeElement
/**
* Provides completions for imports.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/KeywordCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/KeywordCompletionProvider.kt
index 10d8307c60..42ae53765a 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/KeywordCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/KeywordCompletionProvider.kt
@@ -24,11 +24,11 @@ import com.itsaky.androidide.lsp.models.CompletionItem
import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.Tree
-import com.sun.source.util.TreePath
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.Tree
+import openjdk.source.util.TreePath
import java.nio.file.Path
/**
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberReferenceCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberReferenceCompletionProvider.kt
index e8d0c60d25..1cad804f91 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberReferenceCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberReferenceCompletionProvider.kt
@@ -25,18 +25,18 @@ import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.lsp.models.MatchLevel
import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.tree.MemberReferenceTree
-import com.sun.source.tree.Scope
-import com.sun.source.util.TreePath
-import com.sun.source.util.Trees
+import openjdk.source.tree.MemberReferenceTree
+import openjdk.source.tree.Scope
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
import java.nio.file.Path
-import javax.lang.model.element.ElementKind.METHOD
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier.STATIC
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.ArrayType
-import javax.lang.model.type.DeclaredType
-import javax.lang.model.type.TypeVariable
+import jdkx.lang.model.element.ElementKind.METHOD
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier.STATIC
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.type.ArrayType
+import jdkx.lang.model.type.DeclaredType
+import jdkx.lang.model.type.TypeVariable
/**
* Completions for member reference.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt
index f6a8e4f389..f49b663222 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/MemberSelectCompletionProvider.kt
@@ -26,19 +26,20 @@ import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.lsp.models.MatchLevel
import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.tree.MemberSelectTree
-import com.sun.source.tree.Scope
-import com.sun.source.util.TreePath
-import com.sun.source.util.Trees
+import openjdk.source.tree.MemberSelectTree
+import openjdk.source.tree.Scope
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
+import openjdk.tools.javac.code.Symbol
import java.nio.file.Path
-import javax.lang.model.element.ElementKind.CONSTRUCTOR
-import javax.lang.model.element.ElementKind.METHOD
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier.STATIC
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.ArrayType
-import javax.lang.model.type.DeclaredType
-import javax.lang.model.type.TypeVariable
+import jdkx.lang.model.element.ElementKind.CONSTRUCTOR
+import jdkx.lang.model.element.ElementKind.METHOD
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier.STATIC
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.type.ArrayType
+import jdkx.lang.model.type.DeclaredType
+import jdkx.lang.model.type.TypeVariable
/**
* Completions for member select.
@@ -59,7 +60,13 @@ class MemberSelectCompletionProvider(
endsWithParen: Boolean,
): CompletionResult {
val trees = Trees.instance(task.task)
- val select = path.leaf as MemberSelectTree
+ val select =
+ path.leaf as? MemberSelectTree
+ ?: run {
+ log.error("A member select tree was expected but was ${path.leaf.javaClass}")
+ return CompletionResult.EMPTY
+ }
+
log.info("...complete members of " + select.expression)
val exprPath = TreePath(path, select.expression)
@@ -136,10 +143,11 @@ class MemberSelectCompletionProvider(
): CompletionResult {
val trees = Trees.instance(task.task)
val typeElement = type.asElement() as TypeElement
- val list: MutableList = ArrayList()
+ val list = mutableListOf()
val methods = mutableMapOf>()
- val matchLevels: MutableMap =
- mutableMapOf()
+ val matchLevels = mutableMapOf()
+
+ log.debug("DeclaredType $typeElement with members ${(typeElement as Symbol).members()} in scope: $scope")
abortIfCancelled()
abortCompletionIfCancelled()
@@ -168,6 +176,8 @@ class MemberSelectCompletionProvider(
}
}
+ log.debug("Found ${list.size} members along with ${methods.size} methods")
+
abortIfCancelled()
abortCompletionIfCancelled()
for ((key, value) in methods) {
@@ -198,11 +208,13 @@ class MemberSelectCompletionProvider(
if (method != null && method.modifiers.contains(STATIC)) {
return false
}
+
// If we find the enclosing class
val thisElement = s.enclosingClass
if (thisElement != null && thisElement.asType() == type) {
return true
}
+
// If the enclosing class is static, stop looking
if (thisElement != null && thisElement.modifiers.contains(STATIC)) {
return false
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ScopeCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ScopeCompletionProvider.kt
index c6dd3b3ed3..4b9bd64375 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ScopeCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/ScopeCompletionProvider.kt
@@ -38,25 +38,25 @@ import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
import com.itsaky.androidide.projects.FileManager
import com.squareup.javapoet.MethodSpec.Builder
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.Tree.Kind.CLASS
-import com.sun.source.util.TreePath
-import com.sun.source.util.Trees
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.Tree.Kind.CLASS
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
import java.nio.file.Path
import java.util.*
import java.util.function.*
-import javax.lang.model.element.ElementKind.METHOD
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier.FINAL
-import javax.lang.model.element.Modifier.PRIVATE
-import javax.lang.model.element.Modifier.STATIC
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.DeclaredType
-import javax.tools.JavaFileObject
+import jdkx.lang.model.element.ElementKind.METHOD
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier.FINAL
+import jdkx.lang.model.element.Modifier.PRIVATE
+import jdkx.lang.model.element.Modifier.STATIC
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.type.DeclaredType
+import jdkx.tools.JavaFileObject
/**
- * Provides completions using [com.sun.source.tree.Scope].
+ * Provides completions using [openjdk.source.tree.Scope].
*
* @author Akash Yadav
*/
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/StaticImportCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/StaticImportCompletionProvider.kt
index db9fa48203..8e7efebaae 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/StaticImportCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/StaticImportCompletionProvider.kt
@@ -26,17 +26,17 @@ import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.lsp.models.MatchLevel
import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.MemberSelectTree
-import com.sun.source.util.TreePath
-import com.sun.source.util.Trees
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.MemberSelectTree
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
import java.nio.file.Path
-import javax.lang.model.element.Element
-import javax.lang.model.element.ElementKind.METHOD
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier.STATIC
-import javax.lang.model.element.Name
-import javax.lang.model.element.TypeElement
+import jdkx.lang.model.element.Element
+import jdkx.lang.model.element.ElementKind.METHOD
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier.STATIC
+import jdkx.lang.model.element.Name
+import jdkx.lang.model.element.TypeElement
/**
* Completes static imports.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/SwitchConstantCompletionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/SwitchConstantCompletionProvider.kt
index f26692d1ee..ed4ccf2d8d 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/SwitchConstantCompletionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/SwitchConstantCompletionProvider.kt
@@ -23,14 +23,14 @@ import com.itsaky.androidide.lsp.java.compiler.JavaCompilerService
import com.itsaky.androidide.lsp.models.CompletionResult
import com.itsaky.androidide.lsp.models.MatchLevel.NO_MATCH
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
-import com.sun.source.tree.SwitchTree
-import com.sun.source.util.TreePath
-import com.sun.source.util.Trees
+import openjdk.source.tree.SwitchTree
+import openjdk.source.util.TreePath
+import openjdk.source.util.Trees
import java.nio.file.Path
-import javax.lang.model.element.ElementKind.ENUM
-import javax.lang.model.element.ElementKind.ENUM_CONSTANT
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.DeclaredType
+import jdkx.lang.model.element.ElementKind.ENUM
+import jdkx.lang.model.element.ElementKind.ENUM_CONSTANT
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.type.DeclaredType
/**
* Provides completions for switch constants.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/TopLevelSnippetsProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/TopLevelSnippetsProvider.kt
index c93e128a2b..768beb93b1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/TopLevelSnippetsProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/completion/TopLevelSnippetsProvider.kt
@@ -29,8 +29,8 @@ import com.itsaky.androidide.lsp.models.MatchLevel.CASE_INSENSITIVE_EQUAL
import com.itsaky.androidide.lsp.models.SnippetDescription
import com.itsaky.androidide.progress.ProgressManager.Companion.abortIfCancelled
import com.itsaky.androidide.projects.ProjectManager
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.Tree.Kind.ERRONEOUS
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.Tree.Kind.ERRONEOUS
import java.nio.file.Path
import java.nio.file.Paths
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/ErroneousDefinitionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/ErroneousDefinitionProvider.kt
index 258a5c8a5e..1533cd52a0 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/ErroneousDefinitionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/ErroneousDefinitionProvider.kt
@@ -25,12 +25,12 @@ import com.itsaky.androidide.lsp.java.utils.FindHelper
import com.itsaky.androidide.models.Location
import com.itsaky.androidide.models.Position
import com.itsaky.androidide.utils.DocumentUtils.isSameFile
-import com.sun.source.util.Trees
+import openjdk.source.util.Trees
import java.nio.file.Path
import java.nio.file.Paths
-import javax.lang.model.element.Element
-import javax.lang.model.element.TypeElement
-import javax.tools.JavaFileObject
+import jdkx.lang.model.element.Element
+import jdkx.lang.model.element.TypeElement
+import jdkx.tools.JavaFileObject
/**
* Finds definition for erroneous elements.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/IJavaDefinitionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/IJavaDefinitionProvider.kt
index 15e9bebfe9..3617f6c9f1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/IJavaDefinitionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/IJavaDefinitionProvider.kt
@@ -25,7 +25,7 @@ import com.itsaky.androidide.models.Location
import com.itsaky.androidide.models.Position
import com.itsaky.androidide.utils.ILogger
import java.nio.file.Path
-import javax.lang.model.element.Element
+import jdkx.lang.model.element.Element
/**
* Provides definition for a specific symbol in Java source code.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/LocalDefinitionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/LocalDefinitionProvider.kt
index 85dbbd9f95..3616604710 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/LocalDefinitionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/LocalDefinitionProvider.kt
@@ -22,9 +22,9 @@ import com.itsaky.androidide.lsp.java.compiler.JavaCompilerService
import com.itsaky.androidide.lsp.java.utils.FindHelper
import com.itsaky.androidide.models.Location
import com.itsaky.androidide.models.Position
-import com.sun.source.util.Trees
+import openjdk.source.util.Trees
import java.nio.file.Path
-import javax.lang.model.element.Element
+import jdkx.lang.model.element.Element
/**
* Provides definition for local elements.
@@ -44,7 +44,7 @@ class LocalDefinitionProvider(
val path = trees.getPath(element)
if (path == null) {
log.error("TreePath of element is null. Cannot find definition.", "Element is", element)
- emptyList()
+ return@get emptyList()
}
var name = element.simpleName
@@ -52,7 +52,7 @@ class LocalDefinitionProvider(
name = element.enclosingElement.simpleName
}
- listOf(FindHelper.location(it, path, name))
+ return@get listOf(FindHelper.location(it, path, name))
}
}
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/RemoteDefinitionProvider.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/RemoteDefinitionProvider.kt
index 6d446c85f6..bf2e17429f 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/RemoteDefinitionProvider.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/providers/definition/RemoteDefinitionProvider.kt
@@ -24,8 +24,8 @@ import com.itsaky.androidide.lsp.java.utils.NavigationHelper
import com.itsaky.androidide.models.Location
import com.itsaky.androidide.models.Position
import java.nio.file.Path
-import javax.lang.model.element.Element
-import javax.tools.JavaFileObject
+import jdkx.lang.model.element.Element
+import jdkx.tools.JavaFileObject
/**
* Finds definition of an element in other source locations.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddException.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddException.java
index c55eb833b9..a91e6b2881 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddException.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddException.java
@@ -25,16 +25,16 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
-import javax.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.ExecutableElement;
public class AddException extends Rewrite {
final String className, methodName;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddImport.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddImport.java
index 87dde85db0..6c632f6c05 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddImport.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddImport.java
@@ -25,10 +25,10 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ImportTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ImportTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Collections;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddSuppressWarningAnnotation.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddSuppressWarningAnnotation.java
index 677a60b4e6..4a10be898c 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddSuppressWarningAnnotation.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/AddSuppressWarningAnnotation.java
@@ -26,16 +26,16 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
-import javax.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.ExecutableElement;
public class AddSuppressWarningAnnotation extends Rewrite {
final String className, methodName;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertFieldToBlock.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertFieldToBlock.java
index 7bd97fbead..e4d8bfd49a 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertFieldToBlock.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertFieldToBlock.java
@@ -27,17 +27,17 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
-import javax.lang.model.element.Modifier;
+import jdkx.lang.model.element.Modifier;
public class ConvertFieldToBlock extends Rewrite {
final Path file;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertVariableToStatement.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertVariableToStatement.java
index aa7aecca01..81bafa28f3 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertVariableToStatement.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ConvertVariableToStatement.java
@@ -25,12 +25,12 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Collections;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/CreateMissingMethod.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/CreateMissingMethod.java
index 750e9f5128..7336c818fb 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/CreateMissingMethod.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/CreateMissingMethod.java
@@ -28,17 +28,17 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.MemberReferenceTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -46,10 +46,10 @@
import java.util.Map;
import java.util.StringJoiner;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.Name;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.TypeMirror;
public class CreateMissingMethod extends Rewrite {
private static final ILogger LOG = ILogger.newInstance("main");
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/GenerateRecordConstructor.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/GenerateRecordConstructor.java
index 7074ee9056..eb5a05dd11 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/GenerateRecordConstructor.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/GenerateRecordConstructor.java
@@ -27,12 +27,12 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.io.IOException;
import java.nio.file.Path;
@@ -43,8 +43,8 @@
import java.util.Set;
import java.util.StringJoiner;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeElement;
public class GenerateRecordConstructor extends Rewrite {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ImplementAbstractMethods.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ImplementAbstractMethods.java
index de8fd40658..b7b40cca3b 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ImplementAbstractMethods.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/ImplementAbstractMethods.java
@@ -33,12 +33,12 @@
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
import com.squareup.javapoet.MethodSpec;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ImportTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.util.JCDiagnostic;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.ImportTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.Trees;
+import openjdk.tools.javac.util.JCDiagnostic;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -50,12 +50,12 @@
import java.util.TreeSet;
import java.util.stream.Collectors;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Elements;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.ElementKind;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.util.Elements;
public class ImplementAbstractMethods extends Rewrite {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveClass.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveClass.java
index 9825500d1b..c22114474d 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveClass.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveClass.java
@@ -24,7 +24,7 @@
import com.itsaky.androidide.lsp.java.utils.EditHelper;
import com.itsaky.androidide.lsp.java.visitors.FindTypeDeclarationAt;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ClassTree;
+import openjdk.source.tree.ClassTree;
import java.nio.file.Path;
import java.util.Collections;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveException.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveException.java
index 9c8f13922e..1803a4bcd6 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveException.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveException.java
@@ -24,14 +24,14 @@
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
import com.itsaky.androidide.utils.ILogger;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
import java.io.IOException;
import java.nio.file.Path;
@@ -40,9 +40,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.DeclaredType;
public class RemoveException extends Rewrite {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveMethod.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveMethod.java
index efe0db60a4..20d29d632c 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveMethod.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/rewrite/RemoveMethod.java
@@ -20,14 +20,14 @@
import com.itsaky.androidide.lsp.java.utils.EditHelper;
import com.itsaky.androidide.lsp.java.utils.FindHelper;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
-import javax.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.ExecutableElement;
public class RemoveMethod extends Rewrite {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ASTFixer.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ASTFixer.java
index 6ae877e5d3..6672bc1926 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ASTFixer.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ASTFixer.java
@@ -22,12 +22,12 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
-import com.sun.source.tree.LineMap;
-import com.sun.tools.javac.parser.Scanner;
-import com.sun.tools.javac.parser.ScannerFactory;
-import com.sun.tools.javac.parser.Tokens;
-import com.sun.tools.javac.parser.Tokens.TokenKind;
-import com.sun.tools.javac.util.Context;
+import openjdk.source.tree.LineMap;
+import openjdk.tools.javac.parser.Scanner;
+import openjdk.tools.javac.parser.ScannerFactory;
+import openjdk.tools.javac.parser.Tokens;
+import openjdk.tools.javac.parser.Tokens.TokenKind;
+import openjdk.tools.javac.util.Context;
import org.jetbrains.annotations.Contract;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/CodeActionUtils.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/CodeActionUtils.java
index fe06a5c418..5f99694837 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/CodeActionUtils.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/CodeActionUtils.java
@@ -32,14 +32,14 @@
import com.itsaky.androidide.lsp.models.CodeActionItem;
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.util.JCDiagnostic;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
+import openjdk.tools.javac.util.JCDiagnostic;
import org.jetbrains.annotations.Contract;
@@ -47,10 +47,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.JavaFileObject;
/**
* @author Akash Yadav
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/EditHelper.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/EditHelper.java
index be39c9691d..c8ed5fda62 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/EditHelper.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/EditHelper.java
@@ -24,14 +24,14 @@
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.lsp.models.TextEdit;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.util.Arrays;
@@ -41,14 +41,14 @@
import java.util.Set;
import java.util.StringJoiner;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.Name;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.ArrayType;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.ExecutableType;
+import jdkx.lang.model.type.TypeMirror;
public class EditHelper {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/FindHelper.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/FindHelper.java
index 32af4a2653..cced72aeec 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/FindHelper.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/FindHelper.java
@@ -23,20 +23,20 @@
import com.itsaky.androidide.models.Location;
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
-import com.sun.source.tree.ArrayTypeTree;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ParameterizedTypeTree;
-import com.sun.source.tree.PrimitiveTypeTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ArrayTypeTree;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.ParameterizedTypeTree;
+import openjdk.source.tree.PrimitiveTypeTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
import java.io.IOException;
import java.net.URI;
@@ -44,12 +44,12 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Types;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.ElementKind;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.util.Types;
public class FindHelper {
@@ -128,12 +128,14 @@ public static Location location(CompileTask task, TreePath path) {
}
public static Location location(CompileTask task, TreePath path, CharSequence name) {
- LineMap lines = path.getCompilationUnit().getLineMap();
+ final CompilationUnitTree compilationUnit = path.getCompilationUnit();
+ final Tree leaf = path.getLeaf();
+ LineMap lines = compilationUnit.getLineMap();
SourcePositions pos = Trees.instance(task.task).getSourcePositions();
- int start = (int) pos.getStartPosition(path.getCompilationUnit(), path.getLeaf());
- int end = (int) pos.getEndPosition(path.getCompilationUnit(), path.getLeaf());
+ int start = (int) pos.getStartPosition(compilationUnit, leaf);
+ int end = (int) pos.getEndPosition(compilationUnit, leaf);
if (name.length() > 0) {
- start = FindHelper.findNameIn(path.getCompilationUnit(), name, start, end);
+ start = FindHelper.findNameIn(compilationUnit, name, start, end);
end = start + name.length();
}
@@ -144,7 +146,7 @@ public static Location location(CompileTask task, TreePath path, CharSequence na
int endColumn = (int) lines.getColumnNumber(end);
Position endPos = new Position(endLine - 1, endColumn - 1);
Range range = new Range(startPos, endPos);
- URI uri = path.getCompilationUnit().getSourceFile().toUri();
+ URI uri = compilationUnit.getSourceFile().toUri();
return new Location(Paths.get(uri), range);
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaParserUtils.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaParserUtils.kt
index ce87f3c7e8..5d8c130df9 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaParserUtils.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaParserUtils.kt
@@ -76,40 +76,41 @@ import com.github.javaparser.ast.type.TypeParameter
import com.github.javaparser.printer.DefaultPrettyPrinter
import com.github.javaparser.printer.configuration.DefaultPrinterConfiguration
import com.github.javaparser.printer.configuration.PrinterConfiguration
-import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.lsp.java.utils.TypeUtils.toType
import com.itsaky.androidide.lsp.java.visitors.PrettyPrintingVisitor
-import com.sun.source.tree.AnnotationTree
-import com.sun.source.tree.AssignmentTree
-import com.sun.source.tree.BlockTree
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.ErroneousTree
-import com.sun.source.tree.ExpressionStatementTree
-import com.sun.source.tree.ExpressionTree
-import com.sun.source.tree.IdentifierTree
-import com.sun.source.tree.ImportTree
-import com.sun.source.tree.LiteralTree
-import com.sun.source.tree.MemberSelectTree
-import com.sun.source.tree.MethodInvocationTree
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.PackageTree
-import com.sun.source.tree.StatementTree
-import com.sun.source.tree.Tree
-import com.sun.source.tree.TypeParameterTree
-import com.sun.source.tree.VariableTree
-import org.jetbrains.annotations.Contract
+import com.itsaky.androidide.utils.ILogger
+import openjdk.source.tree.AnnotationTree
+import openjdk.source.tree.AssignmentTree
+import openjdk.source.tree.BlockTree
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.ErroneousTree
+import openjdk.source.tree.ExpressionStatementTree
+import openjdk.source.tree.ExpressionTree
+import openjdk.source.tree.IdentifierTree
+import openjdk.source.tree.ImportTree
+import openjdk.source.tree.LiteralTree
+import openjdk.source.tree.MemberSelectTree
+import openjdk.source.tree.MethodInvocationTree
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.PackageTree
+import openjdk.source.tree.StatementTree
+import openjdk.source.tree.Tree
+import openjdk.source.tree.TypeParameterTree
+import openjdk.source.tree.VariableTree
import java.util.*
import java.util.function.*
import java.util.stream.*
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier
-import javax.lang.model.element.TypeParameterElement
-import javax.lang.model.element.VariableElement
-import javax.lang.model.type.ExecutableType
-import javax.lang.model.type.TypeKind
-import javax.lang.model.type.TypeMirror
-import javax.lang.model.type.TypeVariable
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier
+import jdkx.lang.model.element.TypeParameterElement
+import jdkx.lang.model.element.VariableElement
+import jdkx.lang.model.type.ExecutableType
+import jdkx.lang.model.type.TypeKind
+import jdkx.lang.model.type.TypeMirror
+import jdkx.lang.model.type.TypeVariable
+import kotlin.jvm.optionals.getOrNull
+import org.jetbrains.annotations.Contract
object JavaParserUtils {
@@ -245,6 +246,7 @@ object JavaParserUtils {
}
}
+ @Suppress("Since15")
fun toCompilationUnit(tree: CompilationUnitTree): CompilationUnit {
val compilationUnit = CompilationUnit()
compilationUnit.setPackageDeclaration(toPackageDeclaration(tree.getPackage()))
@@ -259,6 +261,7 @@ object JavaParserUtils {
return compilationUnit
}
+ @Suppress("Since15")
fun toPackageDeclaration(tree: PackageTree): PackageDeclaration {
val declaration = PackageDeclaration()
declaration.setName(tree.packageName.toString())
@@ -464,22 +467,19 @@ object JavaParserUtils {
method.modifiers.flags.stream().map { toModifier(it) }.collect(NodeList.toNodeList())
methodDeclaration.parameters =
method.parameters
- .stream()
- .map { toParameter(it) }
- .peek { parameter: Parameter? ->
- val firstType = getTypeWithoutBounds(parameter!!.type)
- parameter.type = firstType
+ .map { variable ->
+ return@map toParameter(variable).also { param ->
+ val firstType = getTypeWithoutBounds(param.type)
+ param.type = firstType
+ }
}
- .collect(NodeList.toNodeList())
+ .toNodeList()
methodDeclaration.typeParameters =
method.typeParameters
- .stream()
- .map { toType(it as Tree?) }
- .filter { obj: Type? -> Objects.nonNull(obj) }
- .map { type1: Type? -> if (type1 != null) type1.toTypeParameter() else Optional.empty() }
- .filter { obj: Optional? -> obj!!.isPresent }
- .map { obj: Optional? -> obj!!.get() }
- .collect(NodeList.toNodeList())
+ .mapNotNull {
+ return@mapNotNull toType(it as Tree?)?.toTypeParameter()?.getOrNull()
+ }
+ .toNodeList()
if (method.body != null) {
methodDeclaration.setBody(toBlockStatement(method.body))
}
@@ -505,29 +505,23 @@ object JavaParserUtils {
expr.setName(toType(tree.annotationType).toString())
expr.pairs =
tree.arguments
- .stream()
- .map { arg: ExpressionTree? ->
- if (arg is AssignmentTree) {
- val assignExpr = toAssignExpression((arg as AssignmentTree?)!!)
+ .map {
+ return@map if (it is AssignmentTree) {
+ val assignExpr = toAssignExpression((it as AssignmentTree?)!!)
val pair = MemberValuePair()
pair.setName(assignExpr.target.toString())
pair.value = assignExpr.value
- return@map pair
- }
- null
+ pair
+ } else null
}
- .collect(NodeList.toNodeList())
+ .toNodeList()
return expr
}
fun toParameter(tree: VariableTree): Parameter {
val parameter = Parameter()
parameter.type = toType(tree.type)
- tree.modifiers.flags
- .stream()
- .map { toModifier(it) }
- .collect(NodeList.toNodeList())
- .also { parameter.modifiers = it }
+ tree.modifiers.flags.map { toModifier(it) }.toNodeList().also { parameter.modifiers = it }
parameter.setName(tree.name.toString())
return parameter
}
@@ -540,8 +534,7 @@ object JavaParserUtils {
val parameter = Parameter()
parameter.setType(EditHelper.printType(type))
parameter.setName(name.name.toString())
- parameter.modifiers =
- name.modifiers.flags.stream().map { toModifier(it) }.collect(NodeList.toNodeList())
+ parameter.modifiers = name.modifiers.flags.map { toModifier(it) }.toNodeList()
parameter.setName(name.name.toString())
return parameter
}
@@ -578,22 +571,19 @@ object JavaParserUtils {
)
methodDeclaration.parameters =
IntStream.range(0, method.parameters.size)
- .mapToObj { i: Int -> toParameter(type!!.parameterTypes[i], method.parameters[i]) }
- .peek { parameter: Parameter? ->
- val firstType = getTypeWithoutBounds(parameter!!.type)
- parameter.type = firstType
+ .mapToObj {
+ return@mapToObj toParameter(type!!.parameterTypes[it], method.parameters[it]).also {
+ parameter ->
+ val firstType = getTypeWithoutBounds(parameter.type)
+ parameter.type = firstType
+ }
}
.collect(NodeList.toNodeList())
methodDeclaration.typeParameters =
type!!
.typeVariables
- .stream()
- .map { toType(it as TypeMirror?) }
- .filter { obj: Type? -> Objects.nonNull(obj) }
- .map { type1: Type? -> if (type1 != null) type1.toTypeParameter() else Optional.empty() }
- .filter { obj: Optional? -> obj!!.isPresent }
- .map { obj: Optional? -> obj!!.get() }
- .collect(NodeList.toNodeList())
+ .mapNotNull { toType(it as TypeMirror?)?.toTypeParameter()?.getOrNull() }
+ .toNodeList()
return methodDeclaration
}
@@ -620,26 +610,31 @@ object JavaParserUtils {
}
}
}
- if (type.isClassOrInterfaceType) {
- val typeArguments = type.asClassOrInterfaceType().typeArguments
- if (typeArguments!!.isPresent) {
- if (typeArguments.get().isNonEmpty) {
- val first = typeArguments.get().first
- if (first!!.isPresent) {
- if (first.get().isTypeParameter) {
- val typeBound = first.get().asTypeParameter().typeBound
- if (typeBound!!.isNonEmpty) {
- val first1 = typeBound.first
- if (first1!!.isPresent) {
- type.asClassOrInterfaceType().setTypeArguments(first1.get())
- return type
- }
- }
- }
- }
- }
- }
+ if (!type.isClassOrInterfaceType) {
+ return type
+ }
+
+ val typeArguments = type.asClassOrInterfaceType().typeArguments
+ if (!typeArguments!!.isPresent || !typeArguments.get().isNonEmpty) {
+ return type
+ }
+
+ val first = typeArguments.get().first
+ if (!first!!.isPresent || !first.get().isTypeParameter) {
+ return type
}
+
+ val typeBound = first.get().asTypeParameter().typeBound
+ if (!typeBound!!.isNonEmpty) {
+ return type
+ }
+
+ val first1 = typeBound.first
+ if (!first1!!.isPresent) {
+ return type
+ }
+
+ type.asClassOrInterfaceType().setTypeArguments(first1.get())
return type
}
@@ -675,14 +670,13 @@ object JavaParserUtils {
val parameter = Parameter()
parameter.setType(EditHelper.printType(type))
if (parameter.type.isArrayType) {
- if ((type as com.sun.tools.javac.code.Type.ArrayType?)!!.isVarargs) {
+ if ((type as openjdk.tools.javac.code.Type.ArrayType?)!!.isVarargs) {
parameter.type = parameter.type.asArrayType().componentType
parameter.isVarArgs = true
}
}
parameter.setName(name!!.simpleName.toString())
- parameter.modifiers =
- name.modifiers.stream().map { toModifier(it) }.collect(NodeList.toNodeList())
+ parameter.modifiers = name.modifiers.map { toModifier(it) }.toNodeList()
parameter.setName(name.simpleName.toString())
return parameter
}
@@ -783,6 +777,10 @@ object JavaParserUtils {
}
}
+private fun Collection.toNodeList(): NodeList {
+ return NodeList(this)
+}
+
private inline fun Stream.asArray(): Array {
val arr = mutableListOf()
for (element in this) {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaPoetUtils.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaPoetUtils.kt
index 23f2b7cfcd..087ad6fc28 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaPoetUtils.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/JavaPoetUtils.kt
@@ -20,13 +20,13 @@ package com.itsaky.androidide.lsp.java.utils
import com.squareup.javapoet.AnnotationSpec
import com.squareup.javapoet.ImportCollectingCodeWriter
import com.squareup.javapoet.MethodSpec
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier
-import javax.lang.model.type.DeclaredType
-import javax.lang.model.type.NoType
-import javax.lang.model.type.NullType
-import javax.lang.model.type.TypeKind
-import javax.lang.model.util.Types
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier
+import jdkx.lang.model.type.DeclaredType
+import jdkx.lang.model.type.NoType
+import jdkx.lang.model.type.NullType
+import jdkx.lang.model.type.TypeKind
+import jdkx.lang.model.util.Types
/** @author Akash Yadav */
class JavaPoetUtils {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MarkdownHelper.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MarkdownHelper.java
index 56228b37e4..6735a2c853 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MarkdownHelper.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MarkdownHelper.java
@@ -19,8 +19,8 @@
import com.itsaky.androidide.lsp.models.MarkupContent;
import com.itsaky.androidide.lsp.models.MarkupKind;
-import com.sun.source.doctree.DocCommentTree;
-import com.sun.source.doctree.DocTree;
+import openjdk.source.doctree.DocCommentTree;
+import openjdk.source.doctree.DocTree;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MethodPtr.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MethodPtr.java
index d3c2594071..bf7e5580d7 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MethodPtr.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/MethodPtr.java
@@ -21,18 +21,18 @@
import com.squareup.javapoet.ImportCollectingCodeWriter;
import com.squareup.javapoet.TypeName;
-import com.sun.source.util.JavacTask;
+import openjdk.source.util.JavacTask;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Types;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.element.VariableElement;
+import jdkx.lang.model.type.TypeKind;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.util.Types;
/**
* @author Akash Yadav
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/NavigationHelper.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/NavigationHelper.java
index 48eb8c2216..5647981472 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/NavigationHelper.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/NavigationHelper.java
@@ -36,14 +36,14 @@
import com.itsaky.androidide.lsp.java.compiler.CompileTask;
import com.itsaky.androidide.lsp.java.visitors.FindNameAt;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.Modifier;
public class NavigationHelper {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java
index 6de80d07cb..97613e6aa4 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ScopeHelper.java
@@ -18,18 +18,18 @@
package com.itsaky.androidide.lsp.java.utils;
import com.itsaky.androidide.lsp.java.compiler.CompileTask;
-import com.sun.source.tree.Scope;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.Scope;
+import openjdk.source.util.Trees;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.util.Elements;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.util.Elements;
public class ScopeHelper {
public static List scopeMembers(
@@ -37,7 +37,7 @@ public static List scopeMembers(
Trees trees = Trees.instance(task.task);
Elements elements = task.task.getElements();
boolean isStatic = false;
- List list = new ArrayList();
+ List list = new ArrayList<>();
for (Scope scope : fastScopes(inner)) {
if (scope.getEnclosingMethod() != null) {
isStatic = isStatic || scope.getEnclosingMethod().getModifiers().contains(Modifier.STATIC);
@@ -88,9 +88,7 @@ public static List fastScopes(Scope start) {
// Scopes may be contained in an enclosing scope.
// The outermost scope contains those elements available via "star import" declarations;
// the scope within that contains the top level elements of the compilation unit, including
- // any
- // named
- // imports.
+ // any named imports.
// https://parent.docs.oracle.com/en/java/javase/11/docs/api/jdk.compiler/com/sun/source/tree/Scope.html
return scopes.subList(0, scopes.size() - 2);
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ShortTypePrinter.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ShortTypePrinter.java
index e88076714d..5d9ee3a311 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ShortTypePrinter.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/ShortTypePrinter.java
@@ -2,19 +2,19 @@
import java.util.stream.Collectors;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.IntersectionType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.NullType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.UnionType;
-import javax.lang.model.type.WildcardType;
-import javax.lang.model.util.AbstractTypeVisitor8;
+import jdkx.lang.model.type.ArrayType;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.ErrorType;
+import jdkx.lang.model.type.ExecutableType;
+import jdkx.lang.model.type.IntersectionType;
+import jdkx.lang.model.type.NoType;
+import jdkx.lang.model.type.NullType;
+import jdkx.lang.model.type.PrimitiveType;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.type.TypeVariable;
+import jdkx.lang.model.type.UnionType;
+import jdkx.lang.model.type.WildcardType;
+import jdkx.lang.model.util.AbstractTypeVisitor8;
public class ShortTypePrinter extends AbstractTypeVisitor8 {
public static final ShortTypePrinter NO_PACKAGE = new ShortTypePrinter("*");
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TreeUtils.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TreeUtils.kt
index 267f0e6dfd..a9e67596a0 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TreeUtils.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TreeUtils.kt
@@ -17,13 +17,13 @@
package com.itsaky.androidide.lsp.java.utils
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.Tree
-import com.sun.source.tree.Tree.Kind.ANNOTATION_TYPE
-import com.sun.source.tree.Tree.Kind.CLASS
-import com.sun.source.tree.Tree.Kind.ENUM
-import com.sun.source.tree.Tree.Kind.INTERFACE
-import com.sun.source.tree.Tree.Kind.METHOD
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.Tree
+import openjdk.source.tree.Tree.Kind.ANNOTATION_TYPE
+import openjdk.source.tree.Tree.Kind.CLASS
+import openjdk.source.tree.Tree.Kind.ENUM
+import openjdk.source.tree.Tree.Kind.INTERFACE
+import openjdk.source.tree.Tree.Kind.METHOD
/**
* Utility methods for Javac Trees.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TypeUtils.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TypeUtils.java
index 1287244234..b08a17aecc 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TypeUtils.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/utils/TypeUtils.java
@@ -36,25 +36,25 @@
import com.github.javaparser.printer.configuration.DefaultPrinterConfiguration;
import com.github.javaparser.printer.configuration.PrinterConfiguration;
import com.itsaky.androidide.lsp.java.visitors.PrettyPrintingVisitor;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.ParameterizedTypeTree;
-import com.sun.source.tree.PrimitiveTypeTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TypeParameterTree;
-import com.sun.source.tree.WildcardTree;
-import com.sun.tools.javac.code.BoundKind;
-import com.sun.tools.javac.tree.JCTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.ParameterizedTypeTree;
+import openjdk.source.tree.PrimitiveTypeTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.TypeParameterTree;
+import openjdk.source.tree.WildcardTree;
+import openjdk.tools.javac.code.BoundKind;
+import openjdk.tools.javac.tree.JCTree;
import java.nio.file.Path;
import java.util.Objects;
import java.util.function.Predicate;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.NoType;
+import jdkx.lang.model.type.TypeKind;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.type.TypeVariable;
public class TypeUtils {
@@ -151,21 +151,21 @@ public static Type getPrimitiveType(PrimitiveTypeTree tree) {
public static Type toType(TypeMirror typeMirror) {
if (typeMirror.getKind() == TypeKind.ARRAY) {
- return toArrayType((javax.lang.model.type.ArrayType) typeMirror);
+ return toArrayType((jdkx.lang.model.type.ArrayType) typeMirror);
}
if (typeMirror.getKind().isPrimitive()) {
- return toPrimitiveType((javax.lang.model.type.PrimitiveType) typeMirror);
+ return toPrimitiveType((jdkx.lang.model.type.PrimitiveType) typeMirror);
}
- if (typeMirror instanceof javax.lang.model.type.IntersectionType) {
- return toIntersectionType((javax.lang.model.type.IntersectionType) typeMirror);
+ if (typeMirror instanceof jdkx.lang.model.type.IntersectionType) {
+ return toIntersectionType((jdkx.lang.model.type.IntersectionType) typeMirror);
}
- if (typeMirror instanceof javax.lang.model.type.WildcardType) {
- return toWildcardType((javax.lang.model.type.WildcardType) typeMirror);
+ if (typeMirror instanceof jdkx.lang.model.type.WildcardType) {
+ return toWildcardType((jdkx.lang.model.type.WildcardType) typeMirror);
}
- if (typeMirror instanceof javax.lang.model.type.DeclaredType) {
+ if (typeMirror instanceof jdkx.lang.model.type.DeclaredType) {
return toClassOrInterfaceType((DeclaredType) typeMirror);
}
- if (typeMirror instanceof javax.lang.model.type.TypeVariable) {
+ if (typeMirror instanceof jdkx.lang.model.type.TypeVariable) {
return toType(((TypeVariable) typeMirror));
}
if (typeMirror instanceof NoType) {
@@ -176,7 +176,7 @@ public static Type toType(TypeMirror typeMirror) {
// type mirrors
- public static IntersectionType toIntersectionType(javax.lang.model.type.IntersectionType type) {
+ public static IntersectionType toIntersectionType(jdkx.lang.model.type.IntersectionType type) {
NodeList collect =
type.getBounds().stream()
.map(TypeUtils::toType)
@@ -207,7 +207,7 @@ public static Type toType(TypeVariable typeVariable) {
return typeParameter;
}
- public static WildcardType toWildcardType(javax.lang.model.type.WildcardType type) {
+ public static WildcardType toWildcardType(jdkx.lang.model.type.WildcardType type) {
WildcardType wildcardType = new WildcardType();
if (type.getSuperBound() != null) {
Type result = toType(type.getSuperBound());
@@ -224,12 +224,12 @@ public static WildcardType toWildcardType(javax.lang.model.type.WildcardType typ
return wildcardType;
}
- public static PrimitiveType toPrimitiveType(javax.lang.model.type.PrimitiveType type) {
+ public static PrimitiveType toPrimitiveType(jdkx.lang.model.type.PrimitiveType type) {
PrimitiveType.Primitive primitive = PrimitiveType.Primitive.valueOf(type.getKind().name());
return new PrimitiveType(primitive);
}
- public static ArrayType toArrayType(javax.lang.model.type.ArrayType type) {
+ public static ArrayType toArrayType(jdkx.lang.model.type.ArrayType type) {
Type componentType = toType(type.getComponentType());
return new ArrayType(componentType);
}
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/DiagnosticVisitor.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/DiagnosticVisitor.kt
index 8bbd3f178b..7165df7c96 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/DiagnosticVisitor.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/DiagnosticVisitor.kt
@@ -17,35 +17,35 @@
package com.itsaky.androidide.lsp.java.visitors
import com.itsaky.androidide.utils.ILogger
-import com.sun.source.tree.BlockTree
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.DoWhileLoopTree
-import com.sun.source.tree.ForLoopTree
-import com.sun.source.tree.IdentifierTree
-import com.sun.source.tree.IfTree
-import com.sun.source.tree.MemberReferenceTree
-import com.sun.source.tree.MemberSelectTree
-import com.sun.source.tree.MethodInvocationTree
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.NewClassTree
-import com.sun.source.tree.ThrowTree
-import com.sun.source.tree.Tree
-import com.sun.source.tree.TryTree
-import com.sun.source.tree.VariableTree
-import com.sun.source.tree.WhileLoopTree
-import com.sun.source.util.TreePath
-import com.sun.source.util.TreeScanner
-import com.sun.source.util.Trees
-import com.sun.tools.javac.api.JavacTaskImpl
+import openjdk.source.tree.BlockTree
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.DoWhileLoopTree
+import openjdk.source.tree.ForLoopTree
+import openjdk.source.tree.IdentifierTree
+import openjdk.source.tree.IfTree
+import openjdk.source.tree.MemberReferenceTree
+import openjdk.source.tree.MemberSelectTree
+import openjdk.source.tree.MethodInvocationTree
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.NewClassTree
+import openjdk.source.tree.ThrowTree
+import openjdk.source.tree.Tree
+import openjdk.source.tree.TryTree
+import openjdk.source.tree.VariableTree
+import openjdk.source.tree.WhileLoopTree
+import openjdk.source.util.TreePath
+import openjdk.source.util.TreeScanner
+import openjdk.source.util.Trees
+import openjdk.tools.javac.api.JavacTaskImpl
import java.util.*
-import javax.lang.model.element.Element
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.Modifier
-import javax.lang.model.element.TypeElement
-import javax.lang.model.type.DeclaredType
-import javax.lang.model.type.TypeKind
-import javax.lang.model.type.TypeMirror
+import jdkx.lang.model.element.Element
+import jdkx.lang.model.element.ExecutableElement
+import jdkx.lang.model.element.Modifier
+import jdkx.lang.model.element.TypeElement
+import jdkx.lang.model.type.DeclaredType
+import jdkx.lang.model.type.TypeKind
+import jdkx.lang.model.type.TypeMirror
class DiagnosticVisitor(task: JavacTaskImpl?) :
TreeScanner>() {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindAnonymousTypeDeclaration.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindAnonymousTypeDeclaration.java
index 47d5985e74..434f5bbec1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindAnonymousTypeDeclaration.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindAnonymousTypeDeclaration.java
@@ -17,14 +17,14 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.NewClassTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
/**
* @author Akash Yadav
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindBiggerRange.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindBiggerRange.java
index 7164f29d67..a685cde740 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindBiggerRange.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindBiggerRange.java
@@ -23,15 +23,15 @@
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.models.Position;
import com.itsaky.androidide.models.Range;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TryTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreeScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.TryTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreeScanner;
+import openjdk.source.util.Trees;
/**
* @author Akash Yadav
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindCompletionsAt.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindCompletionsAt.java
index 2114cf0c2e..41deeb3b72 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindCompletionsAt.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindCompletionsAt.java
@@ -17,19 +17,19 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ErroneousTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.ImportTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CaseTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.ErroneousTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.ImportTree;
+import openjdk.source.tree.MemberReferenceTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
public class FindCompletionsAt extends TreePathScanner {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindInvocationAt.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindInvocationAt.java
index 2d2531ce17..18e57e4ea9 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindInvocationAt.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindInvocationAt.java
@@ -17,14 +17,14 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.NewClassTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
public class FindInvocationAt extends TreePathScanner {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodAt.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodAt.kt
index 9ce19e7d88..7314cddc2f 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodAt.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodAt.kt
@@ -17,12 +17,12 @@
package com.itsaky.androidide.lsp.java.visitors
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.MethodTree
-import com.sun.source.util.JavacTask
-import com.sun.source.util.TreePath
-import com.sun.source.util.TreePathScanner
-import com.sun.source.util.Trees
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.MethodTree
+import openjdk.source.util.JavacTask
+import openjdk.source.util.TreePath
+import openjdk.source.util.TreePathScanner
+import openjdk.source.util.Trees
/**
* Finds method declaration at the given cursor position.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodCallAt.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodCallAt.java
index db19013263..8129ce3f31 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodCallAt.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodCallAt.java
@@ -18,23 +18,23 @@
package com.itsaky.androidide.lsp.java.visitors;
import com.itsaky.androidide.utils.ILogger;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
-
-import javax.lang.model.element.Element;
-import javax.lang.model.element.NestingKind;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
+import openjdk.source.tree.AssignmentTree;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
+
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.NestingKind;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.TypeKind;
+import jdkx.lang.model.type.TypeMirror;
public class FindMethodCallAt extends TreePathScanner {
private static final ILogger LOG = ILogger.newInstance("main");
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodDeclarationAt.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodDeclarationAt.java
index fa6b31ee07..28243dc7f1 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodDeclarationAt.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindMethodDeclarationAt.java
@@ -17,12 +17,12 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreeScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreeScanner;
+import openjdk.source.util.Trees;
public class FindMethodDeclarationAt extends TreeScanner {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindNameAt.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindNameAt.java
index 682ab2de05..917d3ad587 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindNameAt.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindNameAt.java
@@ -19,22 +19,22 @@
import com.itsaky.androidide.lsp.java.compiler.CompileTask;
import com.itsaky.androidide.lsp.java.utils.FindHelper;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
-
-import javax.lang.model.element.Name;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.MemberReferenceTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.NewClassTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
+
+import jdkx.lang.model.element.Name;
public class FindNameAt extends TreePathScanner {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindReferences.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindReferences.java
index fd29d69868..b2a1d5dd32 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindReferences.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindReferences.java
@@ -17,18 +17,18 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.MemberReferenceTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.NewClassTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
import java.util.List;
-import javax.lang.model.element.Element;
+import jdkx.lang.model.element.Element;
public class FindReferences extends TreePathScanner> {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationAt.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationAt.java
index d9d7f1dc5e..7f45f1b124 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationAt.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationAt.java
@@ -17,13 +17,13 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
public class FindTypeDeclarationAt extends TreePathScanner {
private final SourcePositions pos;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationNamed.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationNamed.java
index b31aade7f7..d5f5e615b6 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationNamed.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarationNamed.java
@@ -17,9 +17,9 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.TreeScanner;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.TreeScanner;
import java.util.ArrayList;
import java.util.List;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarations.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarations.java
index 04eed55780..2ca611a85d 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarations.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindTypeDeclarations.java
@@ -17,9 +17,9 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.TreeScanner;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.util.TreeScanner;
import java.util.ArrayList;
import java.util.List;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariableAtCursor.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariableAtCursor.java
index 3e4d7b39d2..057c6be63f 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariableAtCursor.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariableAtCursor.java
@@ -17,12 +17,12 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreeScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreeScanner;
+import openjdk.source.util.Trees;
public class FindVariableAtCursor extends TreeScanner {
private final SourcePositions pos;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariablesBetween.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariablesBetween.java
index 5caaf92cc4..22c8e0ec13 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariablesBetween.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/FindVariablesBetween.java
@@ -19,13 +19,13 @@
import androidx.annotation.NonNull;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
import java.util.ArrayList;
import java.util.List;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/MethodRangeScanner.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/MethodRangeScanner.kt
index d8566cc45e..2e2908c40e 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/MethodRangeScanner.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/MethodRangeScanner.kt
@@ -21,13 +21,13 @@ import androidx.core.util.Pair
import com.itsaky.androidide.models.Position
import com.itsaky.androidide.models.Range
import com.itsaky.androidide.utils.ILogger
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.LineMap
-import com.sun.source.tree.MethodTree
-import com.sun.source.util.TreePath
-import com.sun.source.util.TreePathScanner
-import com.sun.source.util.Trees
-import com.sun.tools.javac.api.JavacTaskImpl
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.LineMap
+import openjdk.source.tree.MethodTree
+import openjdk.source.util.TreePath
+import openjdk.source.util.TreePathScanner
+import openjdk.source.util.Trees
+import openjdk.tools.javac.api.JavacTaskImpl
/**
* Visits all methods and adds them to the given list of pair of method range and its tree.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PrintingVisitor.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PrintingVisitor.kt
index 59f53e7019..3f81be0204 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PrintingVisitor.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PrintingVisitor.kt
@@ -18,9 +18,9 @@
package com.itsaky.androidide.lsp.java.visitors
import com.itsaky.androidide.utils.ILogger
-import com.sun.tools.javac.tree.JCTree
-import com.sun.tools.javac.tree.JCTree.JCErroneous
-import com.sun.tools.javac.tree.TreeScanner
+import openjdk.tools.javac.tree.JCTree
+import openjdk.tools.javac.tree.JCTree.JCErroneous
+import openjdk.tools.javac.tree.TreeScanner
/**
* Prints all the trees it visits. For debugging/testing purposes only.
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PruneMethodBodies.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PruneMethodBodies.java
index 3a68d692e4..5745a21e9a 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PruneMethodBodies.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/PruneMethodBodies.java
@@ -17,12 +17,12 @@
package com.itsaky.androidide.lsp.java.visitors;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreeScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.util.JavacTask;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreeScanner;
+import openjdk.source.util.Trees;
import java.io.IOException;
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/SemanticHighlighter.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/SemanticHighlighter.java
index 64eae33827..7346f59a48 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/SemanticHighlighter.java
+++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/visitors/SemanticHighlighter.java
@@ -28,29 +28,29 @@
import com.itsaky.androidide.models.Range;
import com.itsaky.androidide.projects.FileManager;
import com.itsaky.androidide.utils.ILogger;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.LineMap;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.SourcePositions;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.LineMap;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.SourcePositions;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.Trees;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.ElementKind;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.Name;
public class SemanticHighlighter extends TreePathScanner> {
diff --git a/lsp/java/src/main/java/com/itsaky/androidide/utils/ClassBuilder.kt b/lsp/java/src/main/java/com/itsaky/androidide/utils/ClassBuilder.kt
index de727f7694..2fb3a0266c 100644
--- a/lsp/java/src/main/java/com/itsaky/androidide/utils/ClassBuilder.kt
+++ b/lsp/java/src/main/java/com/itsaky/androidide/utils/ClassBuilder.kt
@@ -6,8 +6,8 @@ import com.itsaky.androidide.preferences.internal.tabSize
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.TypeSpec
-import javax.lang.model.element.Modifier.PROTECTED
-import javax.lang.model.element.Modifier.PUBLIC
+import jdkx.lang.model.element.Modifier.PROTECTED
+import jdkx.lang.model.element.Modifier.PUBLIC
object ClassBuilder {
@JvmStatic
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/AnnotationSpec.java b/lsp/java/src/main/java/com/squareup/javapoet/AnnotationSpec.java
index 1a10e5ebc5..3bc73f6020 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/AnnotationSpec.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/AnnotationSpec.java
@@ -32,14 +32,14 @@
import java.util.Map;
import java.util.Objects;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+import jdkx.lang.model.SourceVersion;
+import jdkx.lang.model.element.AnnotationMirror;
+import jdkx.lang.model.element.AnnotationValue;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.element.VariableElement;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.util.SimpleAnnotationValueVisitor8;
/** A generated annotation on a declaration. */
public final class AnnotationSpec {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/ArrayTypeName.java b/lsp/java/src/main/java/com/squareup/javapoet/ArrayTypeName.java
index faa4856cd7..852c4f7aea 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/ArrayTypeName.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/ArrayTypeName.java
@@ -25,8 +25,8 @@
import java.util.List;
import java.util.Map;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.ArrayType;
+import jdkx.lang.model.element.TypeParameterElement;
+import jdkx.lang.model.type.ArrayType;
public final class ArrayTypeName extends TypeName {
public final TypeName componentType;
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/ClassName.java b/lsp/java/src/main/java/com/squareup/javapoet/ClassName.java
index 4ce5cda640..ba0f37b6c4 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/ClassName.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/ClassName.java
@@ -25,10 +25,10 @@
import java.util.Map;
import java.util.Objects;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.SimpleElementVisitor8;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.PackageElement;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.util.SimpleElementVisitor8;
/** A fully-qualified class name for top-level and member classes. */
public final class ClassName extends TypeName implements Comparable {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/CodeBlock.java b/lsp/java/src/main/java/com/squareup/javapoet/CodeBlock.java
index cef5d314b9..7209341789 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/CodeBlock.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/CodeBlock.java
@@ -27,8 +27,8 @@
import java.util.stream.Collector;
import java.util.stream.StreamSupport;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeMirror;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.type.TypeMirror;
/**
* A fragment of a .java file, potentially containing declarations, statements, and documentation.
@@ -50,8 +50,8 @@
*
{@code $S} escapes the value as a string, wraps it with double quotes, and emits
* that. For example, {@code 6" sandwich} is emitted {@code "6\" sandwich"}.
*
{@code $T} emits a type reference. Types will be imported if possible. Arguments
- * for types may be {@linkplain Class classes}, {@linkplain javax.lang.model.type.TypeMirror
- * ,* type mirrors}, and {@linkplain javax.lang.model.element.Element elements}.
+ * for types may be {@linkplain Class classes}, {@linkplain jdkx.lang.model.type.TypeMirror
+ * ,* type mirrors}, and {@linkplain jdkx.lang.model.element.Element elements}.
*
{@code $$} emits a dollar sign.
*
{@code $W} emits a space or a newline, depending on its position on the line. This prefers
* to wrap lines before 100 columns.
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/CodeWriter.java b/lsp/java/src/main/java/com/squareup/javapoet/CodeWriter.java
index d1f15246b0..94ed193c0e 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/CodeWriter.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/CodeWriter.java
@@ -35,8 +35,8 @@
import java.util.Set;
import java.util.regex.Pattern;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Modifier;
+import jdkx.lang.model.SourceVersion;
+import jdkx.lang.model.element.Modifier;
/**
* Converts a {@link JavaFile} to a string suitable to both human- and javac-consumption. This
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/FieldSpec.java b/lsp/java/src/main/java/com/squareup/javapoet/FieldSpec.java
index 57bf50eb47..64eab2b73b 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/FieldSpec.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/FieldSpec.java
@@ -26,8 +26,8 @@
import java.util.List;
import java.util.Set;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Modifier;
+import jdkx.lang.model.SourceVersion;
+import jdkx.lang.model.element.Modifier;
/** A generated field declaration. */
public final class FieldSpec {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/JavaFile.java b/lsp/java/src/main/java/com/squareup/javapoet/JavaFile.java
index 1e47223e57..889a106695 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/JavaFile.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/JavaFile.java
@@ -36,9 +36,9 @@
import java.util.Set;
import java.util.TreeSet;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.JavaFileObject.Kind;
+import jdkx.tools.SimpleJavaFileObject;
/** A Java file containing a single top level class. */
public final class JavaFile {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/MethodSpec.java b/lsp/java/src/main/java/com/squareup/javapoet/MethodSpec.java
index 527b5728b3..84226c31d8 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/MethodSpec.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/MethodSpec.java
@@ -29,16 +29,16 @@
import java.util.Map;
import java.util.Set;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ExecutableType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.util.Types;
+import jdkx.lang.model.SourceVersion;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeParameterElement;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.ExecutableType;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.type.TypeVariable;
+import jdkx.lang.model.util.Types;
/** A generated constructor or method declaration. */
public final class MethodSpec {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/NameAllocator.java b/lsp/java/src/main/java/com/squareup/javapoet/NameAllocator.java
index 0e75085b63..4408aa412c 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/NameAllocator.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/NameAllocator.java
@@ -23,7 +23,7 @@
import java.util.Set;
import java.util.UUID;
-import javax.lang.model.SourceVersion;
+import jdkx.lang.model.SourceVersion;
/**
* Assigns Java identifier names to avoid collisions, keywords, and invalid characters. To use,
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/ParameterSpec.java b/lsp/java/src/main/java/com/squareup/javapoet/ParameterSpec.java
index 5a7b5dd876..b9aeb5e995 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/ParameterSpec.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/ParameterSpec.java
@@ -25,11 +25,11 @@
import java.util.List;
import java.util.Set;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.VariableElement;
+import jdkx.lang.model.SourceVersion;
+import jdkx.lang.model.element.ElementKind;
+import jdkx.lang.model.element.ExecutableElement;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.VariableElement;
/** A generated parameter declaration. */
public final class ParameterSpec {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/TypeName.java b/lsp/java/src/main/java/com/squareup/javapoet/TypeName.java
index 37aaef9452..da6a86a2ae 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/TypeName.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/TypeName.java
@@ -27,17 +27,17 @@
import java.util.List;
import java.util.Map;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.ErrorType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.SimpleTypeVisitor8;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.element.TypeParameterElement;
+import jdkx.lang.model.type.ArrayType;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.ErrorType;
+import jdkx.lang.model.type.NoType;
+import jdkx.lang.model.type.PrimitiveType;
+import jdkx.lang.model.type.TypeKind;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.util.SimpleTypeVisitor8;
/**
* Any type in Java's type system, plus {@code void}. This class is an identifier for primitive
@@ -184,12 +184,12 @@ public TypeName visitError(ErrorType t, Void p) {
}
@Override
- public TypeName visitTypeVariable(javax.lang.model.type.TypeVariable t, Void p) {
+ public TypeName visitTypeVariable(jdkx.lang.model.type.TypeVariable t, Void p) {
return TypeVariableName.get(t, typeVariables);
}
@Override
- public TypeName visitWildcard(javax.lang.model.type.WildcardType t, Void p) {
+ public TypeName visitWildcard(jdkx.lang.model.type.WildcardType t, Void p) {
return WildcardTypeName.get(t, typeVariables);
}
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/TypeSpec.java b/lsp/java/src/main/java/com/squareup/javapoet/TypeSpec.java
index 4b854cae0d..a0c0f29252 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/TypeSpec.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/TypeSpec.java
@@ -36,14 +36,14 @@
import java.util.Map;
import java.util.Set;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.NoType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
+import jdkx.lang.model.SourceVersion;
+import jdkx.lang.model.element.Element;
+import jdkx.lang.model.element.Modifier;
+import jdkx.lang.model.element.TypeElement;
+import jdkx.lang.model.type.DeclaredType;
+import jdkx.lang.model.type.NoType;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.util.ElementFilter;
/** A generated class, interface, or enum declaration. */
public final class TypeSpec {
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/TypeVariableName.java b/lsp/java/src/main/java/com/squareup/javapoet/TypeVariableName.java
index 51c6f56490..13684db229 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/TypeVariableName.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/TypeVariableName.java
@@ -27,9 +27,9 @@
import java.util.List;
import java.util.Map;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
+import jdkx.lang.model.element.TypeParameterElement;
+import jdkx.lang.model.type.TypeMirror;
+import jdkx.lang.model.type.TypeVariable;
public final class TypeVariableName extends TypeName {
public final String name;
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/Util.java b/lsp/java/src/main/java/com/squareup/javapoet/Util.java
index 428add6138..2ea738b2af 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/Util.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/Util.java
@@ -27,7 +27,7 @@
import java.util.Map;
import java.util.Set;
-import javax.lang.model.element.Modifier;
+import jdkx.lang.model.element.Modifier;
/**
* Like Guava, but worse and standalone. This makes it easier to mix JavaPoet with libraries that
diff --git a/lsp/java/src/main/java/com/squareup/javapoet/WildcardTypeName.java b/lsp/java/src/main/java/com/squareup/javapoet/WildcardTypeName.java
index 0c7b21c963..4fe2e69a52 100644
--- a/lsp/java/src/main/java/com/squareup/javapoet/WildcardTypeName.java
+++ b/lsp/java/src/main/java/com/squareup/javapoet/WildcardTypeName.java
@@ -26,8 +26,8 @@
import java.util.List;
import java.util.Map;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.TypeMirror;
+import jdkx.lang.model.element.TypeParameterElement;
+import jdkx.lang.model.type.TypeMirror;
public final class WildcardTypeName extends TypeName {
public final List upperBounds;
@@ -67,12 +67,12 @@ public static WildcardTypeName supertypeOf(TypeName lowerBound) {
Collections.singletonList(OBJECT), Collections.singletonList(lowerBound));
}
- public static TypeName get(javax.lang.model.type.WildcardType mirror) {
+ public static TypeName get(jdkx.lang.model.type.WildcardType mirror) {
return get(mirror, new LinkedHashMap<>());
}
static TypeName get(
- javax.lang.model.type.WildcardType mirror,
+ jdkx.lang.model.type.WildcardType mirror,
Map typeVariables) {
TypeMirror extendsBound = mirror.getExtendsBound();
if (extendsBound == null) {
diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaCompilerProviderTest.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaCompilerProviderTest.kt
index 7f3a8cb3a0..64df3da393 100644
--- a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaCompilerProviderTest.kt
+++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaCompilerProviderTest.kt
@@ -60,7 +60,7 @@ class JavaCompilerProviderTest {
assertThat(compilers).hasSize(5)
compilers.clear()
- JavaCompilerProvider.getInstance().destory()
+ JavaCompilerProvider.getInstance().destroy()
assertThat(JavaCompilerProvider.get(appModule)).isNotEqualTo(appCompiler)
}
diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt
index eb0f524965..8d682a06f2 100644
--- a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt
+++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt
@@ -26,24 +26,26 @@ import com.itsaky.androidide.lsp.java.models.CompilationRequest
import com.itsaky.androidide.lsp.java.models.PartialReparseRequest
import com.itsaky.androidide.lsp.java.visitors.PrintingVisitor
import com.itsaky.androidide.models.Range
-import com.sun.source.tree.ExpressionStatementTree
-import com.sun.source.tree.LiteralTree
-import com.sun.source.tree.Tree
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl
-import com.sun.tools.javac.tree.JCTree.JCMethodInvocation
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl
-import com.sun.tools.javac.tree.TreeScanner
+import openjdk.source.tree.ExpressionStatementTree
+import openjdk.source.tree.LiteralTree
+import openjdk.source.tree.Tree
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit
+import openjdk.tools.javac.tree.JCTree.JCMethodDecl
+import openjdk.tools.javac.tree.JCTree.JCMethodInvocation
+import openjdk.tools.javac.tree.JCTree.JCVariableDecl
+import openjdk.tools.javac.tree.TreeScanner
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
-import javax.lang.model.type.ArrayType
+import jdkx.lang.model.type.ArrayType
/** @author Akash Yadav */
@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.DEFAULT_VALUE_STRING)
+@Ignore("Partial reparser is currently unused")
class PartialReparserImplTest {
@Before
diff --git a/lsp/models/src/main/java/com/itsaky/androidide/lsp/edits/DefaultEditHandler.kt b/lsp/models/src/main/java/com/itsaky/androidide/lsp/edits/DefaultEditHandler.kt
index d33aa36049..1023056a7d 100644
--- a/lsp/models/src/main/java/com/itsaky/androidide/lsp/edits/DefaultEditHandler.kt
+++ b/lsp/models/src/main/java/com/itsaky/androidide/lsp/edits/DefaultEditHandler.kt
@@ -105,6 +105,7 @@ open class DefaultEditHandler : IEditHandler {
if (command == null) {
return
}
+
try {
val klass = editor::class.java
val method = klass.getMethod("executeCommand", Command::class.java)
diff --git a/lsp/xml/build.gradle.kts b/lsp/xml/build.gradle.kts
index e04d8f1f57..aeac6fec16 100644
--- a/lsp/xml/build.gradle.kts
+++ b/lsp/xml/build.gradle.kts
@@ -42,7 +42,6 @@ dependencies {
implementation(projects.lsp.api)
implementation(projects.lexers)
implementation(projects.subprojects.xmlDom)
- implementation(projects.subprojects.xmlFormatter)
implementation(projects.subprojects.xmlUtils)
implementation(libs.androidx.ktx)
@@ -65,4 +64,4 @@ dependencies {
compileOnly(projects.common)
compileOnly(libs.common.antlr4)
-}
\ No newline at end of file
+}
diff --git a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/AttrValueCompletionProvider.kt b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/AttrValueCompletionProvider.kt
index 71760df24d..c17d4ebebb 100644
--- a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/AttrValueCompletionProvider.kt
+++ b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/AttrValueCompletionProvider.kt
@@ -101,12 +101,16 @@ open class AttrValueCompletionProvider(provider: ICompletionProvider) :
}
fun completeValue(
- namespace: String,
+ namespace: String?,
prefix: String,
attrName: String,
attrValue: String? = null
): CompletionResult {
+ if (namespace.isNullOrBlank()) {
+ return EMPTY
+ }
+
val tables = findResourceTables(namespace)
if (tables.isEmpty()) {
return EMPTY
@@ -377,9 +381,14 @@ open class AttrValueCompletionProvider(provider: ICompletionProvider) :
}
}
- override fun findResourceTables(nsUri: String): Set {
+ override fun findResourceTables(nsUri: String?): Set {
// When completing values, all namespaces must be included
val tables = HashSet(findAllModuleResourceTables())
+
+ if (nsUri.isNullOrBlank()) {
+ return tables
+ }
+
tables.addAll(super.findResourceTables(nsUri))
log.info("Found ${tables.size} resource tables for namespace: $nsUri")
return tables
diff --git a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/IXmlCompletionProvider.kt b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/IXmlCompletionProvider.kt
index 7a8ef21294..8dc7a57856 100644
--- a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/IXmlCompletionProvider.kt
+++ b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/IXmlCompletionProvider.kt
@@ -246,7 +246,10 @@ abstract class IXmlCompletionProvider(private val provider: ICompletionProvider)
}
}
- protected open fun findResourceTables(nsUri: String): Set {
+ protected open fun findResourceTables(nsUri: String?): Set {
+ if (nsUri.isNullOrBlank()) {
+ return emptySet()
+ }
if (nsUri == NAMESPACE_AUTO) {
return findAllModuleResourceTables()
}
diff --git a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrCompletionProvider.kt b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrCompletionProvider.kt
index 0eeb8c80c7..31cad9a7ac 100644
--- a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrCompletionProvider.kt
+++ b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrCompletionProvider.kt
@@ -42,7 +42,7 @@ class ManifestAttrCompletionProvider(provider: ICompletionProvider) :
return super.canProvideCompletions(pathData, type) && canCompleteManifest(pathData, type)
}
- override fun findResourceTables(nsUri: String) = manifestResourceTable()
+ override fun findResourceTables(nsUri: String?) = manifestResourceTable()
override fun findNodeStyleables(node: DOMNode, styleables: ResourceGroup): Set {
val name = node.nodeName
diff --git a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrValueCompletionProvider.kt b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrValueCompletionProvider.kt
index c1c128c9a5..04fad07b8c 100644
--- a/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrValueCompletionProvider.kt
+++ b/lsp/xml/src/main/java/com/itsaky/androidide/lsp/xml/providers/completion/manifest/ManifestAttrValueCompletionProvider.kt
@@ -190,8 +190,11 @@ class ManifestAttrValueCompletionProvider(provider: ICompletionProvider) :
?: throw IllegalStateException("No module project provided")
}
- override fun findResourceTables(nsUri: String): Set {
+ override fun findResourceTables(nsUri: String?): Set {
val tables = manifestResourceTable().toMutableSet()
+ if (nsUri.isNullOrBlank()) {
+ return tables
+ }
tables.addAll(super.findResourceTables(nsUri))
log.info("Found ${tables.size} resource tables for namespace: $nsUri")
return tables
diff --git a/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/CommonAttrValueCompletionTest.kt b/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/CommonAttrValueCompletionTest.kt
index b19fafa9f0..8d67719d76 100644
--- a/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/CommonAttrValueCompletionTest.kt
+++ b/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/CommonAttrValueCompletionTest.kt
@@ -48,7 +48,7 @@ class CommonAttrValueCompletionTest : CompletionHelper by CompletionHelperImpl()
fun `test simple anim attributes`() {
XMLLSPTest.apply {
openFile("../res/anim/TestSimpleAttrValue")
- val (incomplete, items) = complete()
+ val (_, items) = complete()
// Only integer values
assertThat(items.filter { it.startsWith("@integer/") || it.startsWith("@android:integer/") })
.hasSize(items.size)
@@ -59,7 +59,7 @@ class CommonAttrValueCompletionTest : CompletionHelper by CompletionHelperImpl()
fun `test simple transition attributes`() {
XMLLSPTest.apply {
openFile("../res/transition/TestSimpleAttrValue")
- val (incomplete, items) = complete()
+ val (_, items) = complete()
// Only integer values
assertThat(items.filter { it.startsWith("@integer/") || it.startsWith("@android:integer/") })
.hasSize(items.size)
diff --git a/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/ManifestAttrValueCompletionProviderTest.kt b/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/ManifestAttrValueCompletionProviderTest.kt
index 8f0d16eb09..cad93f931d 100644
--- a/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/ManifestAttrValueCompletionProviderTest.kt
+++ b/lsp/xml/src/test/java/com/itsaky/androidide/lsp/xml/providers/completion/ManifestAttrValueCompletionProviderTest.kt
@@ -181,7 +181,7 @@ class ManifestAttrValueCompletionProviderTest : CompletionHelper by CompletionHe
private fun XMLLSPTest.assertHasSingleLineEntries(file: String, expect: Array) {
openFile("completion/$file")
- val (incomplete, items) = complete()
+ val (_, items) = complete()
assertThat(items).containsAtLeastElementsIn(expect)
}
}
diff --git a/resources/src/main/res/values-ar/strings.xml b/resources/src/main/res/values-ar/strings.xml
index 7f261dfe70..ffcf877d4a 100644
--- a/resources/src/main/res/values-ar/strings.xml
+++ b/resources/src/main/res/values-ar/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEيستخدم AndroidIDE نسخة معدلة من JDK مرخصة بموجب رخصة GNU العامة 2.0 يمكن الحصول على كود المصدر ورخصة JDK على العنوان التالي:تراخيص البرامج مفتوحة المصدرمرخص له تحت:البريد الإلكترونيالموقع الإلكتروني
- AndroidIDE v\u2022 %s
- AndroidIDE %1$s for %2$s
+ AndroidIDE %1$s لـ %2$sببساطة، منصة بناء تطبيقات للاندرويدفشل في استخراج اسم الحزمة!إن AndroidIDE هو بيئة تنمية متكاملة لبناء تطبيقات الأندرويد على هاتفك الذكي الخاص بك. إنه يدعم:\n1. Gradle \n2. OpenJDK 17.0–22.\n3. إكمال جافا تلقائي متقدم\n4. إكمال XML التلقائي \n5. دعم كوتلين وأكثر بكثير\n\nتحميل AndroidIDE على https://androidide.comإذا كنت تواجه مشكلات أثناء استخدام AndroidIDE أو مع بناء التطبيقات ، يمكنك الانضمام إلى مجموعة التيليغرام وطلب المساعدة هناك.\n\nيمكنك أيضًا إرسال ملاحظات متضمنة على بريدنا الإلكتروني.مناقشة والمساعدة
- GitHubتحتاج للمساعدة؟أخرىشارك مع الأصدقاء
@@ -49,12 +46,8 @@
لسوء الحظ، جهازك غير مدعوم في الوقت الراهن. نحن آسفون على الإزعاج.\n\nوحدة المعالجة المركزية المدعومة: aarch64 و Armeabi-v7aLint
- lintDebug
- lintReleaseبناء
- assembleDebugمخرجات البناء
- assembleReleaseمهام Lintتنظيف & بناءتنظيف
@@ -70,7 +63,6 @@
تثبيت ملفات APKمسح المخرجاتتشغيل
- Gradleأول بناءهذه هي المرة الأولى التي يتم فيها البناء بعد تثبيت AndroidIDE. يستغرق البناء الأول عادة وقتاً بينما يقوم تنزيل Gradle بتحميل جميع التبعيات والإضافات. قد تستغرق هذه العملية حوالي 10 - 15 دقيقة. لكن هذا يعتمد كلياً على اتصال الشبكة الخاصة بك.\n\nالرجاء التحلي بالصبر…
@@ -100,13 +92,11 @@
مشروع درج التنقللعبة LibGDXمشروع لعبة LibGDX تم إعداده لتقديم صورة كمثال.
- Jetpack Composeمشروع Jetpack الأساسي لإنشاء مشروع \"مرحبا بالعالم\".نشاط التنقل السفليإنشاء نشاط جديد مع أسفل التنقلنشاط التبويبإنشاء نشاط فارغ جديد مع علامات التبويب
- التجزئات (فراغمنت) + عرض النموذج (ViewModel)الأصل C++إنشاء مشروع جديد مع نشاط فارغ مكون لاستخدام JNIلا يوجد نشاط
@@ -255,7 +245,6 @@
توسيع التحديدمطابقة المكملات في حالة الأحرف الصغيرةالشائعة
- Javaالملفات غير المحفوظةلم يتم حفظ بعض الملفات. هل ترغب في حفظها قبل الإغلاق؟ الملفات غير المحفوظة هي: \n%sحفظ قبل إغلاق الملفات
@@ -274,7 +263,7 @@
درج الملفاتمورد اللونمنتقي ألوان
- قيمة النص
+ قيمة السمةمورد نصيأي مرجع للموردالإجراءات
@@ -318,7 +307,6 @@
فشل البناء. راجع إخراج البناء لمزيد من التفاصيل.تم البناء بنجاحفشل الحصول على نص من المحرر
- تطبيقيالبيانات غير صالحة للقصد.حدد مجلد من وحدة التخزين الرئيسيةالسلطة \'\'%s\' غير مسموح بها
@@ -345,7 +333,6 @@
المزيد عن AndroidIDE.إعدادات IDE العامة.تهيئة المحرر.
- XMLتقليم السطر الجديد النهائيإدراج سطر جديد نهائيإزالة سطر فارغ إضافي في نهاية الملف
@@ -372,6 +359,7 @@
أقصى عرض للسطرالحد الأقصى لعدد الأحرف التي يجب أن تكون في السطر.فصل حجم العوز للسمات
+ عدد المسافات المراد إضافتها لسمات التقسيم.احتفظ بخطوط جديدة• الحد الأقصى لعدد فترات التوقف المستمرة التي ينبغي الحفاظ عليها.سلوك العناصر الفارغة
@@ -445,33 +433,6 @@
جارٍ تحميل المهام...كل المهاملم يتم تنفيذ هذه الميزة بعد.
- الأدوات الذكية
- الصفحات
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutنسخنسخ مشروع Git
@@ -479,5 +440,16 @@
نسخ مشروع Git...تم نسخ مشروع Git بنجاحفشل في استنساخ مشروع git
- عدد المسافات المراد إضافتها لسمات التقسيم.
+ حدد سمة من القائمة أدناه
+ عرض التسلسل الهرمي للتخطيط
+ تشكيلات الألوان
+ اختر مخطط الألوان لاستخدامه في المحرر
+ نمط واجهة المستخدم
+ اختر وضع واجهة المستخدم لـ IDE
+ فاتح
+ مظلم
+ اتبع النظام
+ استمتع بتجربة أقرب إلى جهازك (يتطلب إعادة تشغيل).
+ تهيئة المشروع
+ فشل في تشغيل التطبيق. راجع سجلات IDE لمزيد من المعلومات.
diff --git a/resources/src/main/res/values-bn/strings.xml b/resources/src/main/res/values-bn/strings.xml
index 66a4b83827..46a2ad4e91 100755
--- a/resources/src/main/res/values-bn/strings.xml
+++ b/resources/src/main/res/values-bn/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE JDK-এর একটি পরিবর্তিত বিল্ড ব্যবহার করে যা GNU জেনারেল পাবলিক লাইসেন্স v2.0-এর অধীনে লাইসেন্সপ্রাপ্ত৷ সোর্স কোড এবং JDK এর লাইসেন্স এখানে পাওয়া যাবে : ওপেন সোর্স লাইসেন্সগুলিদত্তাধিকার: ইমেলওয়েবসাইট
- AndroidIDE v\u2022 %s
- AndroidIDE %1$s for %2$s
+ %2$s এর জন্য AndroidIDE %1$sসহজভাবে, Android এর জন্য একটি IDEপ্যাকেজের নাম বের করতে ব্যর্থ!AndroidIDE হল একটি ইন্টিগ্রেটেড ডেভেলপমেন্ট এনভায়রনমেন্ট যা আপনার অ্যান্ড্রয়েড স্মার্টফোনে অ্যান্ড্রয়েড অ্যাপ তৈরি করার জন্য। এটি সমর্থন করে:\n1. গ্রেডেল \n2. OpenJDK 17.0-22.\n3. উন্নত জাভা অটোকমপ্লিট\n4. XML অটোকমপ্লিট \n5. কটলিন সমর্থন এবং আরও অনেক কিছু।\n\nhttps://androidide.com থেকে AndroidIDE ডাউনলোড করুনআপনি যদি AndroidIDE ব্যবহার করার সময় বা অ্যান্ড্রয়েড অ্যাপস তৈরি করার সময় সমস্যার সম্মুখীন হন, তাহলে আপনি টেলিগ্রাম গ্রুপে যোগ দিতে পারেন সেখানে সাহায্য চাইতে পারেন।\n\nআপনি আমাদের ইমেলে পরামর্শও পাঠাতে পারেন।আলোচনা এবং সাহায্য করুন
- গিটহাবসাহায্য প্রয়োজন?অন্যান্যবন্ধুদের সাথে শেয়ার করুন
@@ -49,12 +46,8 @@
দুর্ভাগ্যবশত, আপনার ডিভাইসটি এই মুহূর্তে সমর্থিত নয়৷ অসুবিধার জন্য আমরা দুঃখিত৷\n\nসমর্থিত CPU ABIs: aarch64 এবং armeabi-v7aলিন্ট
- লিন্ট ডিবাগ
- লিন্ট রিলিজবিল্ড
- অ্যাসেম্বেল বিভাগবিল্ড আউটপুট
- অ্যাসেম্বেল রিলিজলিন্ট প্রক্রিয়াগুলিপরিষ্কার করে বিল্ড করুনপরিষ্কার করুন
@@ -70,7 +63,6 @@
APK(গুলি) ইনস্টল করুনআউটপুট পরিস্কার করুনচালান
- গ্রাডলপ্রথম বিল্ডআপনি AndroidIDE ইনস্টল করার পর এটিই প্রথমবার বিল্ড। প্রথম বিল্ডে সাধারণত সময় লাগে কারণ Gradle সমস্ত ডিপেনডেন্সি এবং প্লাগইন ডাউনলোড করে। এই প্রক্রিয়াটি প্রায় 10-15 মিনিট সময় নিতে পারে। কিন্তু এটি সম্পূর্ণরূপে আপনার নেটওয়ার্ক সংযোগের উপর নির্ভর করে।\n\nদয়া করে ধৈর্য ধরুন।…
@@ -100,13 +92,11 @@
নেভিগেশন ড্রয়ার প্রকল্পLibGDX গেমLibGDX গেম প্রজেক্ট এর একটি উদাহরণ হিসেবে একটি ছবি রেন্ডার করার জন্য সেট আপ করা হয়েছে।
- জেটপ্যাক কম্পোজবেসিক জেটপ্যাক কম্পোজ হ্যালো ওয়ার্ল্ড প্রজেক্ট।বটম নেভিগেশন অ্যাক্টিভিটিনীচে নেভিগেশন সহ একটি নতুন কার্যকলাপ তৈরি করেট্যাবড এক্টিভিটিট্যাব সহ একটি নতুন ফাঁকা কার্যকলাপ তৈরি করে
- ফ্রাগমেন্ট + ভিউ মডেলনেটিভ C++JNI ব্যবহার করার জন্য কনফিগার করা একটি খালি কার্যকলাপ সহ একটি নতুন প্রকল্প তৈরি করেঅ্যাক্টিভিটিবিহীন
@@ -183,8 +173,8 @@
সঞ্চয়স্থানের অনুমতি দেওয়া হয়েছে!অন্য অ্যাপ দিয়ে খুলুন...
- Undo
- Redo
+ আনডু
+ রিডুএডিটর ফন্ট সাইজAndroidIDE সম্পর্কে
@@ -255,7 +245,6 @@
নির্বাচন প্রসারিত করুনছোট হাতের অক্ষর এও কমপ্লিশন করুনসাধারণ
- জাভাঅসংরক্ষিত ফাইলকিছু ফাইল সংরক্ষিত নেই৷ আপনি বন্ধ করার আগে তাদের সংরক্ষণ করতে চান? অসংরক্ষিত ফাইলগুলি হল: \n%sফাইলগুলি বন্ধ করার আগে সংরক্ষণ করুন
@@ -274,7 +263,7 @@
ফাইল ট্রিকালার রিসোর্সকালার পিকার
- স্ট্রিং এর মান
+ আ্যট্রিবিউট এর মানস্ট্রিং রিসোর্সযেকোনো রিসোর্স এর উল্লেখক্রিয়া
@@ -318,7 +307,6 @@
বিল্ড ব্যর্থ হয়েছে৷ আরো বিস্তারিত জানার জন্য বিল্ড আউটপুট দেখুন।বিল্ড সফল হয়েছেসম্পাদক থেকে পাঠ্য পেতে ব্যর্থ
- My Applicationইন্টেন্ট অবৈধ ডেটা ফেরত দিয়েছেপ্রাথমিক স্টোরেজ থেকে একটি ডিরেক্টরি নির্বাচন করুনকর্তৃপক্ষ \'%s\' অনুমোদিত নয়
@@ -345,7 +333,6 @@
AndroidIDE সম্পর্কে আরো কিছু।সাধারণ IDE কনফিগারেশন।সম্পাদক কনফিগার করুন৷
- XMLচূড়ান্ত নতুন লাইন বাদ দিনচূড়ান্ত নতুন লাইন যোগ করুনফাইলের শেষে অতিরিক্ত খালি লাইন সরান
@@ -372,6 +359,7 @@
সর্বোচ্চ লাইন প্রস্থএকটি লাইনে সর্বাধিক যতগুলি অক্ষর থাকা উচিত৷বিভক্ত অ্যাট্রিবিউট ইন্ডেন্ট সাইজ
+ বিভক্ত অ্যাট্রিবিউট গুলির ইন্ডেন্ট করার জন্য স্পেস-এর সংখ্যা৷লাইন সংরক্ষণসর্বোচ্চ সংখ্যক ক্রমাগত লাইন বিরতি যা সংরক্ষণ করা হবে৷খালি উপাদানের আচরণ
@@ -445,33 +433,6 @@
প্রক্রিয়া লোড করা হচ্ছে...সমস্ত প্রক্রিয়াগুলিএই বৈশিষ্ট্যটি এখনও বাস্তবায়িত হয়নি।
- Widgets
- Layouts
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutক্লোনগিট রেপোসিটরি ক্লোন করুন
@@ -479,5 +440,16 @@
রেপোসিটরি ক্লোন করা হচ্ছেগিট ক্লোন সফল হয়েছেগিট রেপোসিটরি ক্লোন করতে ব্যর্থ
- বিভক্ত অ্যাট্রিবিউট গুলির ইন্ডেন্ট করার জন্য স্পেস-এর সংখ্যা৷
+ নীচের লিস্ট থেকে অ্যাট্রিবিউট নির্বাচন করুন
+ লেআউট-এর শ্রেণিবিন্যাস দেখান
+ কালার স্কিম
+ এডিটর-এ ব্যাবহার করার জন্য কালার স্কিম নির্বাচন করুন
+ UI মোড
+ IDE এর জন্য UI মোড নির্বাচন করুন
+ লাইট
+ ডার্ক
+ সিস্টেম কে অনুসরন করুন
+ আপনার ডিভাইসের কাছাকাছি একটি অভিজ্ঞতা উপভোগ করুন (আ্যপ এর রিস্টার্ট প্রয়োজন)।
+ প্রকল্প কনফিগারেশন
+ অ্যাপ্লিকেশন শুরু করতে ব্যর্থ। আরো তথ্য জানার জন্য IDE লগ চেক করুন।
diff --git a/resources/src/main/res/values-de/strings.xml b/resources/src/main/res/values-de/strings.xml
index e232610705..159f21ab3f 100644
--- a/resources/src/main/res/values-de/strings.xml
+++ b/resources/src/main/res/values-de/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE verwendet einen modifizierten Build des JDK, das unter der GNU General Public License v2.0 lizenziert ist. Der Quellcode und die Lizenz des JDK sind verfügbar unter:Open-Source-LizenzenLizenziert unter:E-MailInternetseite
- AndroidIDE v\u2022 %sAndroidIDE %1$s für %2$sDie IDE für Android GeräteFehler beim Extrahieren des Paketnamens!AndroidIDE ist eine integrierte Entwicklungsumgebung zum Erstellen von Android-Apps auf Ihrem Android-Smartphone. Es unterstützt:\n1. Gradle \n2. OpenJDK 17.0-22.\n3. Erweiterte automatische Java-Vervollständigung\n4. Automatische XML-Vervollständigung \n5. Kotlin-Support und vieles mehr.\n\nLaden sie AndroidIDE unter https://androidide.com herunterWenn Sie bei der Verwendung von AndroidIDE oder beim Erstellen von Android-Apps auf Probleme stoßen, können Sie unserer Telegram-Gruppe beitreten und dort um Hilfe bitten.\n\nSie können uns auch Vorschläge per E-Mail senden.Diskutieren & Hilfe
- GitHubBrauchen Sie Hilfe?AndereMit Freunden teilen
@@ -49,12 +46,8 @@
Leider wird Ihr Gerät derzeit nicht unterstützt. Wir entschuldigen uns für die Unannehmlichkeiten.\n\nUnterstützte CPU-ABIs: aarch64 und armeabi-v7aLint
- lintDebug
- lintReleaseBauen
- AssembleDebugBuild-Ausgabe
- assembbleReleaseLint-AufgabenClean & buildSäubern
@@ -70,7 +63,6 @@
APK(s) installierenAusgabe säubernAusführen
- GradleErster BuildDies ist der erste Build, nachdem Sie AndroidIDE installiert haben. Der erste Build dauert normalerweise einige Zeit, da Gradle benötigte Dateien herunterlädt. Dieser Vorgang kann etwa 10 bis 15 Minuten dauern. Dies hängt jedoch von Ihrer Netzwerkverbindung ab.\n\nBitte haben Sie etwas Geduld …
@@ -100,13 +92,11 @@
Projekt mit NavigationDrawerLibGDX SpielLibGDX-Spieleprojekt eingerichtet, um ein Bild als Beispiel zu rendern.
- Jetpack ComposeBasic Jetpack Compose Hello World Projekt.Bottom Navigation ActivityErstellt eine neue Activity mit eine bottom navigationTabbed ActivityErstellt eine neue leere Activity mit Tabs
- Fragment + ViewModelNative C++Erstellt ein neues Projekt mit einer leeren Activity konfiguriert um JNI zu benutzenKeine Activity
@@ -255,7 +245,6 @@
Auswahl erweiternVervollständigungen in Kleinbuchstaben nutzenCommon
- JavaUngespeicherte DateienEinige Dateien wurden noch nicht gespeichert. Möchtest du diese nun speichern? Nicht gespeicherte Dateien: %sDateien vor dem schließen speichern
@@ -274,7 +263,7 @@
DateipfadFarbwertFarbauswahl
- String-Wert
+ Attribute valueString-RessourceAny resource referenceAktionen
@@ -318,7 +307,6 @@
Build ist fehlgeschlagen. Sieh dir die Ausgabe an für mehr InformationenBuild erfolgreichFehler beim empfangen des Textes vom Editor
- Meine AppDer Intent hat falsche Daten zurückgeliefertWählen Sie ein Verzeichnis aus dem Primärspeicher ausAuthority \'%s\' ist nicht erlaubt
@@ -345,7 +333,6 @@
Mehr über AndroidIDE.Allgemeine IDE-Konfiguration.Configure the editor.
- XMLTrim final new lineInsert final new lineRemove extra empty line at the end of file
@@ -372,6 +359,7 @@
Max. LinienbreiteThe maximum number of characters a line should have.Split attributes indent size
+ The number of spaces to indent for split attributes.Preserved new linesThe maximum number of continuous line breaks that should be preserved.Empty elements behaviour
@@ -445,33 +433,6 @@
Aufgaben werden geladen...Alle AufgabenDiese Funktion ist noch nicht implementiert.
- Widgets
- Layouts
- TextView
- Button
- CheckBox
- CheckedTextViev
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutCloneClone git repository
@@ -479,5 +440,16 @@
Cloning repositoryGit clone successfulFailed to clone git repository
- The number of spaces to indent for split attributes.
+ Select an attribute from the below list
+ Show layout hierarchy
+ Color Scheme
+ Choose color scheme to use in editor
+ UI Mode
+ Choose UI mode for the IDE
+ Light
+ Dark
+ Follow system
+ Enjoy an experience closer to your device (requires restart).
+ Project configuration
+ Failed to launch application. See IDE logs for more info.
diff --git a/resources/src/main/res/values-es/strings.xml b/resources/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000000..edd793e1de
--- /dev/null
+++ b/resources/src/main/res/values-es/strings.xml
@@ -0,0 +1,455 @@
+
+
+
+ Android IDE utiliza una versión modificada del JDK que está licenciado bajo la GNU General Public License v2.0. El código fuente y la licencia del JDK están disponibles en:
+ Licencias de código abierto
+ Bajo Licencia:
+ Correo
+ Web
+ Android IDE %1$s para %2$s
+ Simplemente un IDE para Android
+ ¡Error al extraer el nombre del paquete!
+ Android IDE es un Entorno de Desarrollo Integrado para crear aplicaciones Android en su Smartphone. Soporta:\n1. Gradle \n2. OpenJDK 17.0–22.\n3. Autocompletado avanzado de Java \n4. Autocompletado de XML \n5. Soporte de Kotlin y mucho más.\n\nDescargue Android IDE en https://androidide.com
+ Si estás enfrentando problemas durante el uso de Android IDE o con la creación de aplicaciones Android, puedes unirte al grupo en Telegram para pedir ayuda.\n\nTambién puedes enviar sugerencias a nuestro correo electrónico.
+ Debate & ayuda
+ ¿Necesitas Ayuda?
+ Otro
+ Compartir con amigos
+ Configuración
+ Debates en Telegram
+ Canal Oficial en Telegram
+ No tengo nada que mostrar…
+ Terminal
+ Reiniciar
+ Registros de la app
+ Registros del IDE
+ Imagen de bienvenida
+ Comenzar
+
+ No se puede realizar la corrección rápida
+ Ejecutando acción de código…
+ Desde la API %d
+ Eliminado en la API %d
+ Obsoleto en la API %d
+ Buscando referencias…
+ Buscando definición…
+ Definición no encontrada
+ No se encontraron referencias
+ Diagnósticos
+
+ Instalación fallida
+ ¡Prepárate para algo increíble!
+ ¡El archivo elegido no es un directorio!
+ Por favor, elija un solo directorio
+ Por favor, espere un momento…
+ Dispositivo no compatible
+ Desafortunadamente, su dispositivo no es compatible en este momento. Lamentamos las molestias. \n\nABI de CPU compatibles: aarch64 y armeabi-v7a
+
+ Lint
+ Compilar
+ Salida de Compilación
+ Lint tasks
+ Limpiar & compilar
+ Limpiar
+ Crear AAB
+ Crear tareas
+ Quick run
+ Gradle files have changed. Please rebuild your project to sync dependencies and configurations.
+ Preparing
+ Preparing. First build may take up to 10–15 minutes!
+ Gradle Wrapper is not available!\nInstalling default one. Gradle v7.4 will be downloaded if necessary.
+ Getting Daemon status, please wait…
+ Gradle daemon status
+ Install APK(s)
+ Clear output
+ Run
+ First Build
+ This is the first time build after you installed AndroidIDE. First build usually takes time as Gradle downloads all dependencies and plugins. This process may take about 10–15 minutes. But this totally depends on your network connection.\n\nPlease be patient …
+
+ Create project
+ Minimum SDK
+ Target SDK
+ New project
+ Package name
+ App name
+ Start your new awesome project!
+ Open last project?
+ Do you want me to open last opened project? Opened project was:\n%s
+ Project
+ Close this project
+ Last opened project doesn\'t exist!
+ Create new project
+ Open existing project
+ Close project
+ Are you sure you want to close this project? All started Gradle daemons will be stopped after this project is closed.
+ A project with same name already exists!
+
+ Basic Project
+ A basic project with AppCompat Toolbar and a Floating Action Button
+ An empty project with default toolbar. Suitable when you want to do all the basic things yourself.
+ Project with AppCompat Toolbar, DrawerLayout and NavigationView
+ Empty project
+ Navigation drawer project
+ LibGDX Game
+ LibGDX game project set up to render an image as an example.
+ Basic Jetpack Compose hello world project.
+ Bottom Navigation Activity
+ Creates a new activity with bottom navigation
+ Tabbed Activity
+ Creates a new blank activity with tabs
+ Native C++
+ Creates a new project with an Empty Activity configured to use JNI
+ No Activity
+ Creates a new project without activity
+ NoAndroidX
+ Crea un nuevo proyecto sin librería de AndroidX
+
+ Guardar Cambios
+ Find
+ Find in file
+ Find in project
+ Search in modules
+ No modules found in project
+ Filter file extensions (optional)
+ Separated by \'|\'
+ Please enter text
+ Select modules to search
+ Finding in project, please wait…
+ Search results
+ Copying files
+ Writing files
+ Copying assets
+ Failed to create project dir!
+ Failed to write file: %s
+ Failed to copy template to storage!
+ Failed to create temporary project directory!
+ Project created successfully!
+ Starting writing process
+ Failed to create folder!
+ Failed to create file!
+ Folder created successfully!
+ File created successfully!
+ Folder already exists!
+ File already exists!
+ Invalid Name!
+ Create
+ If the path contains File separator (\'/\'), then the required (parent) directories will be created if they don\'t exist.
+ Folder Name
+ File Name
+ New name
+ New file
+ Create layout file automatically
+ New Java class
+ New XML resource
+ New folder
+ Confirm delete
+ Are you sure you want to delete:\n%s?
+ Copied successfully!
+ Enter new name for file/folder.
+ Renamed successfully!
+ Unable to rename file!
+ Deleted successfully!
+ Unable to delete file!
+ Copy path
+ Rename
+ Delete
+ File options
+ Close all
+ Close others
+ Close this
+ All files saved!
+ Destination: %s/
+ Drawable
+ Layout
+ Menu
+ Other
+ Class
+ Activity
+ Interface
+ Enum
+ Checking storage permissions
+ Failed to list project files!
+ Can\'t proceed without storage permissions
+ Storage permissions granted!
+ Open with...
+
+ Undo
+ Redo
+
+ Editor font size
+ About AndroidIDE
+ Clear Gradle caches
+ Clear Gradle caches directory. This will delete all dependencies downloaded by Gradle. Required files will be downloaded again in next build.
+ Additional Gradle commands
+ Choose additional commands that will be added while executing every task
+ Font size
+ Font size of the editor
+ Non-printable painting flags
+ Choose what non-printable characters should be drawn by the editor
+ Draw hex color strings
+ Should the editor draw hex color string?
+ Word Wrap
+ Use wordwrap of the editor
+ Enable Magnifier
+ Magnify text at cursor position while selecting text in editor
+ Editor
+ Build & Run
+ Open last project
+ If checked, the IDE will remember the last opened project and it will be reopened on next startup.
+ Confirm project opening
+ Ask before opening last opened project.
+ Use system shell in terminal
+ If checked, \'/system/bin/sh\' will be used in terminal.
+ General
+ Tab size
+ Specify number of spaces for TAB
+ Preferences
+ Changelog
+ Please choose default font size of editor :
+ This will delete caches directory created by Gradle. If you delete it, the next build may take a bit longer than normal as Gradle will download required files again.\nIMPORTANT: This will also delete AAPT2. You will need to reinstall it otherwise you\'ll end up with a build failure.\n\nAre you sure you want to delete caches?
+
+ Unable to initialize SDK Info
+ Unable to preview layout
+ Unable to inflate layout
+
+ Unable to preview layout!
+ Preview Layout
+ Main UI designer content
+ Applicable attributes
+ Actions
+ Delete
+ Select parent
+ This view does not have a parent
+ Please confirm
+ Are you sure?
+ Unable to delete the view.
+ No views have been added. Click to add.
+ No attribute format is available for this attribute.
+ Failed to generate XML code
+ Generating XML code
+ Code generation failed
+ Failed to generate XML code. Would you like to exit anyway?
+ UI Designer returned invalid result
+ Swipe up for build output, logs and more.
+ AndroidIDE crashed
+ Please open an issue on github with the following stacktrace :
+ Click on the button below to copy log and open issues page.
+ Copy and report
+ Reading bootstrap archive…
+ Bootstrap installation failed with the following exception.
+ Translations
+ Installing compiler module
+ Compiler module is being installed, please wait…
+ Compiler module installation failed. The error was:\n%s
+ Compiler module installed successfully!
+ Expand selection
+ Match completions in lower case
+ Common
+ Unsaved files
+ Some files are not saved. Would you like to save them before closing? Unsaved files are: \n%s
+ Save before closing files
+ Save files before closing them. This is an EXPERIMENTAL feature. You are expected to save the files yourself.
+ If enabled, then typing a lower case or upper case letters will suggest class names as well as scope members.
+ Font ligatures
+ Enable/disable font ligatures
+ Yes
+ No
+ Unable to start intent for installing APK
+ Add attribute
+ Search attributes…
+ Dimension value
+ Dimension resource
+ Boolean resource
+ File tree
+ Color resource
+ Color picker
+ Attribute value
+ String resource
+ Any resource reference
+ Actions
+ Format code
+ Use Google Java Style code formatting
+ Use Google Java Style code formatting configuration for formatting Java source code.
+ Visible password flag
+ Use for visible password input type flag in editor. This makes sure that no suggestions are proposed by soft keyboard.
+ Previous
+ Replacing…
+ Gradle build service started
+ Gradle build service
+ AndroidIDE\'s Gradle build service is running in the background.
+ Cancel build
+ Warning
+ NDK is currently not officially supported. This template works only after you setup NDK
+ Initializing project
+ Project initialized
+ Project initialization failed
+ Project is not initialized
+ Running task: \'%1$s\'
+ Replacement
+ Sync project
+ Name cannot be empty.
+ Name cannot contain illegal characters
+ Save location
+ Project Language
+ Templates loading…
+ C++ Standard
+ Next
+ Exit
+ JDK 11 tag pointers fix
+ Set LD_PRELOAD to libhook.so to fix tag pointers issue for JDK 11 in Android 11 [DEPRECATED - Prefer using JDK 17].
+ Custom Gradle installation
+ Specify a custom Gradle installation to use for build. This OVERRIDES the version specified in gradle-wrapper.properties.
+ Gradle installation path
+ Leave empty to use Gradle wrapper.
+ You need to install the JDK and Android SDK for the IDE to work. To install click \'Yes\' and follow the instructions here]]>
+ No builds in progress
+ Build in progress…
+ Build failed. See build output for more details.
+ Build successful
+ Failed to get text from editor
+ Intent returned invalid data
+ Select a directory from primary storage
+ Authority \'%s\' not allowed
+ Use ICU lib
+ Use ICU library to use retrive word edges for double-tap and long-press word selection.
+
+
+ Swipe left for @@files@@.
+ Swipe up for @@build output@@.
+ Use soft tab
+ Choose whether to use spaces instead of tab character (\\t).
+ Sponsor
+ Documentation
+ Close
+ Ignore case
+ Use regex
+ Configure the Gradle build.
+ Configure
+ About
+ AndroidIDE is open source!
+ Subscribe for latest updates.
+ Discuss featues, bugs and improvements here.
+ What\'s new in this version?
+ More about AndroidIDE.
+ General IDE configuration.
+ Configure the editor.
+ Trim final new line
+ Insert final new line
+ Remove extra empty line at the end of file
+ Inserts an empty new line at the end of file.
+ Split attributes
+ Format attributes on new line
+ Join CDATA lines
+ Normalize content inside CDATA.
+ Join comment lines
+ Normalize content inside comments.
+ Join content lines
+ Normalize content inside elements.
+ Space before empty close tag
+ Insert whitespace before self closing tag end bracket.
+ Preserve empty content
+ Preserve empty content inside elements (whitespaces, new lines, tabs, etc).
+ Preserve attribute line breaks
+ Preserve line breaks between attributes.
+ Closing bracket on new line
+ Place closing bracket on a new line.
+ Trim trailing whitespace
+ Remove extra whitespaces at the end of lines.
+ Formatter options
+ Max line width
+ The maximum number of characters a line should have.
+ Split attributes indent size
+ The number of spaces to index for splitted attributes.
+ Preserved new lines
+ The maximum number of continuous line breaks that should be preserved.
+ Empty elements behaviour
+ Choose the formatting behavior for empty elements.
+ XML formatting options
+ Configure the XML formatter
+ Use custom font
+ If enabled, the file at \"/data/data/com.itsaky.androidide/files/home/.androidide/ui/font.ttf\" will be used as Editor font.
+ Choose custom font
+ Choose font to use in the Terminal (and optionally, in the Editor).
+ Installing APK...
+ Installed successfully
+ Do you want to open the application?
+ AndroidIDE Gradle build service
+ Hex color code
+ Pick
+ Setting executable permissions…
+ Linking %1$s to %2$s
+ Extracting hook libraries…
+ Package name is empty
+ Package name is not a valid
+ Package name is to long
+ The character \'_\' cannot be the first character in a package segment
+ A digit cannot be the first character in a package segment
+ The character \"%1$s\" is not allowed in Android application package names
+ The package must have at least one \'.\' separator
+ Import class(es)
+ Generate setters/getters
+ Add \'throws\'
+ Comment line
+ Create missing method
+ Convert to block
+ Generate constructor
+ Implement abstract method(s)
+ Remove class
+ Remove method
+ Remove unused throws
+ Suppress \'unchecked\' warning
+ Uncomment line
+ Convert to statement
+ Select fields
+ No fields selected
+ No fields found
+ Override superclass methods
+ No methods selected
+ Unable to override methods
+ Unable to generate setters and getters
+ Select methods to override
+ Unable to find any overridable method
+ Go to definition
+ Find references
+ Generate toString()
+ Remove unused imports
+ Organize imports
+ Unable to generate toString() implementation
+ toString() is already overridden
+ Generate missing constructor
+ Unable to generate constructor
+ A constructor with same parameter types is already available
+ Cannot create view for tag: %s
+ No attribute adapter implementation found for %s
+ View %s is not supported currently.
+ Replace
+ Replace all
+ Run tasks
+ Search tasks…
+ Selected tasks
+ Please select tasks to run
+ Confirmation
+ The following tasks will be run, in order. Click the \'Run\' button again to confirm.\n\n%1$s
+ Loading tasks...
+ All tasks
+ This feature is not implemented yet.
+
+ Clone
+ Clone git repository
+ Repository URL
+ Cloning repository
+ Git clone successful
+ Failed to clone git repository
+ Select an attribute from the below list
+ Show layout hierarchy
+ Color Scheme
+ Choose color scheme to use in editor
+ UI Mode
+ Choose UI mode for the IDE
+ Light
+ Dark
+ Follow system
+ Enjoy an experience closer to your device (requires restart).
+ Project configuration
+ Failed to launch application. See IDE logs for more info.
+
diff --git a/resources/src/main/res/values-fr/strings.xml b/resources/src/main/res/values-fr/strings.xml
index cee0246f2f..ef46b3b471 100644
--- a/resources/src/main/res/values-fr/strings.xml
+++ b/resources/src/main/res/values-fr/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE utilise une version modifiée du JDK d\'ont la licence est sous GNU General Public licence v2.0. Le code source et la licence du JDK sont disponibles ici : licence Open Sourcelicence sous: ÉmailSite Web
- AndroidIDE v\u2022 %sAndroidIDE %1$s pour %2$sSimplement, un IDE pour AndroidImpossible d\'extraire le nom du package !AndroidIDE est un Environnement de développement integré (IDE) pour la création d\'application Android sur votre appareil android. Il support :\n1. Gradle \n2. OpenJDK 17.0-22.\n3. Complétation Java automatique \n4. Complétation XML Auto \n5. Support Kotlin et bien plus.\n\nTélecharger AndroidIDE sur https://androidide.comSi vous rencontrez des problémes lorsque vous utilisez AndroidIDE (ex: pendant la compilation d\'une application), vous pouvez demandez de l\'aide sur le groupe Telegram (Anglais).\n\nVous pouvez également demander de l\'aide sur notre émail.Discussions & Aides
- GithubBesoin d\'aide ?AutrePartager avec des amis
@@ -49,12 +46,8 @@
Malheureusement, votre appareil n\'est pas supporté pour le moment, nous sommes désolés pour le problème occasionné.\n\nCPU ABIs supportés: aarch64 et armeabi-v7aLint
- lintDebug
- lintReleaseCompiler
- assembleDebugBuild output
- assembleReleaseLint tasksNettoyer et compilerNettoyer
@@ -70,7 +63,6 @@
Installer l\'APKNettoyer la consoleCompiler
- GradlePremière compilationC\'est la première compilation que vous effectuez après l\'installation de AndroidIDE. La première compilation met un peu plus de temps car il télécharge les dépendances et les plugins. Ce processus prendra environ 10–15 minutes, cela dépends également de votre connexion internet.\n\Soyez patient…
@@ -100,13 +92,11 @@
Projet navigation drawerJeu LibGDXProjet Jeu LibGDX, affiche une image comme example.
- Jetpack ComposeSimple projet Jetpack Compose.Activité Bottom Navigation Créer une nouvelle activité avec le Bottom Navigation Projet avec les TabsCréer un projet vide avec Tabs
- Fragment + ViewModelNative C++Créez un nouveau projet avec une activité vide configuré pour utiliser JNIPas d\'activité
@@ -255,7 +245,6 @@
Sélection expansionFaire correspondre les complétions en minusculesCommon
- JavaFichiers non sauvegardésCertains fichiers n\'ont pas été sauvegardés, voulez vous les sauvegarder avant de les fermer ? Fichiers non sauvegardés: \n%sSauvegarder avant de fermer les fichiers
@@ -274,7 +263,7 @@
FichiersColor resourceColor picker
- String value
+ Attribute valueString resourceany resource referenceActions
@@ -318,7 +307,6 @@
Build failed. See build output for more details.Build successfulFailed to get text from editor
- My ApplicationIntent returned invalid dataSelect a directory from primary storageAuthority \'%s\' not allowed
@@ -345,7 +333,6 @@
More about AndroidIDE.General IDE configuration.Configure the editor.
- XMLTrim final new lineInsert final new lineRemove extra empty line at the end of file
@@ -372,6 +359,7 @@
Max line widthThe maximum number of characters a line should have.Split attributes indent size
+ The number of spaces to indent for split attributes.Preserved new linesThe maximum number of continuous line breaks that should be preserved.Empty elements behaviour
@@ -445,33 +433,6 @@
Loading tasks...All tasksThis feature is not implemented yet.
- Widgets
- Layouts
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutCloneClone git repository
@@ -479,5 +440,16 @@
Cloning repositoryGit clone successfulFailed to clone git repository
- The number of spaces to indent for split attributes.
+ Select an attribute from the below list
+ Show layout hierarchy
+ Color Scheme
+ Choose color scheme to use in editor
+ UI Mode
+ Choose UI mode for the IDE
+ Light
+ Dark
+ Follow system
+ Enjoy an experience closer to your device (requires restart).
+ Project configuration
+ Failed to launch application. See IDE logs for more info.
diff --git a/resources/src/main/res/values-hi/strings.xml b/resources/src/main/res/values-hi/strings.xml
index db09247aa8..165102201b 100644
--- a/resources/src/main/res/values-hi/strings.xml
+++ b/resources/src/main/res/values-hi/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE JDK के एक संशोधित निर्माण का उपयोग करता है जिसे GNU General Public License v2.0 के तहत लाइसेंस प्राप्त है। स्रोत कोड और जेडीके का लाइसेंस यहां उपलब्ध है: ओपन सोर्स लाइसेंसलाइसेंसईमेलवेबसाइट
- AndroidIDE v\u2022 %s
- AndroidIDE %1$s for %2$s
+ %2$s के लिए AndroidIDE %1$sबस, एक आईडीई एंड्रॉयड के लिएपैकेज का नाम निकालने में विफल रहे !AndroidIDE आपके Android स्मार्टफ़ोन पर एंड्रॉइड ऐप्स बनाने के लिए एक एकीकृत विकास परिवेश है । यह समर्थन करता है : \n1. Gradle \n2. OpenJDK 17.0-22.\n3. Advanced Java auto completion\n4. XML Auto Completion \n5. Kotlin Support और भी बहुत कुछ।\n\n AndroidIDE यहा से डाउनलोड करे https://androidide.comयदि आपको AndroidIDE का उपयोग करते समय या Android ऐप्स बनाते समय समस्याओं का सामना करना पड़ रहा है, तो आप टेलीग्राम समूह में शामिल हो सकते हैं और वहां सहायता मांग सकते हैं।\n\nआप हमारे ईमेल पर भी सुझाव भेज सकते हैं।चर्चा और मदद
- GitHubमदद की ज़रूरत है?अन्यमित्रो के साथ शेयर करे
@@ -49,12 +46,8 @@
दुर्भाग्य से, आपका डिवाइस इस समय समर्थित नहीं है। असुविधा के लिए हमें खेद है.\n\nसमर्थित CPU ABIs: aarch64 और armeabi-v7aलिंट
- लिंट डिबग
- लिंट रिलीज़बिल्ड
- असेंबल डिबगबिल्ड आउटपुट
- असेंबल रिलीज़लिंट टास्क्सक्लीन & बिल्डक्लीन
@@ -70,7 +63,6 @@
APK(s) इंस्टॉल करेंआउटपुट हटाएँरन
- Gradleपहला निर्माणAndroidIDE इंस्टॉल करने के बाद यह पहली बार बिल्ड है। पहले निर्माण में आमतौर पर समय लगता है क्योंकि ग्रेडल सभी डिपेंडेंसीज और प्लगइन्स को डाउनलोड करता है। इस प्रक्रिया में लगभग 10–15 मिनट का समय लग सकता है। लेकिन यह पूरी तरह से आपके नेटवर्क कनेक्शन पर निर्भर करता है।\n\nकृपया धैर्य रखें…
@@ -100,13 +92,11 @@
Navigation drawer प्रोजेक्टLibGDX गेमएक उदाहरण के रूप में एक छवि प्रस्तुत करने के लिए स्थापित LibGDX गेम प्रोजेक्ट।
- Jetpack Composeबुनियादी Jetpack Compose हेलो वर्ल्ड प्रोजेक्ट।BottomNavigationView एक्टिविटीBottomNavigationView के साथ एक नई एक्टिविटी बनाता हैटैब एक्टिविटीटैब के साथ एक नई खाली एक्टिविटी बनाता है
- Fragment + ViewModelनेटिव C++JNI का उपयोग करने के लिए कॉन्फ़िगर की गई खाली एक्टिविटी के साथ एक नया प्रोजेक्ट बनाता हैबिना किसी एक्टिविटी के
@@ -255,7 +245,6 @@
चयन का विस्तार करेंकम्पलेशन्स लोअर केस में मिलायेसामान्य
- जावाफ़ाइल्स सेव नहीं की गयी हैकुछ फ़ाइलें सेव नहीं की गई हैं। क्या आप बंद करने से पहले उन्हें सेव करना चाहेंगे? सेव न की गयी फ़ाइल्स : %sफ़ाइलें बंद करने से पहले सेव करे
@@ -274,7 +263,7 @@
फ़ाइल ट्रीरंग रिसोर्सरंग पीकर
- स्ट्रिंग वैल्यू
+ एट्रिब्यूट वैल्यूस्ट्रिंग रिसोर्सकोई रिसोर्स संदर्भकोड क्रियाएं
@@ -318,7 +307,6 @@
निर्माण विफल रहा। अधिक विवरण के लिए बिल्ड आउटपुट देखें।निर्माण सफल हुआएडिटर से टेक्स्ट प्राप्त करने में विफल रहे
- मेरा एप्लीकेशनइन्टेंट ने इंवालिड डेटा रिटर्न कियाप्राइमरी स्टोरेज से एक डायरेक्टरी का चयन करेंअथॉरिटी \'%s\' अलाउ नही है
@@ -345,7 +333,6 @@
AndroidIDE के बारे में अधिक |सामान्य IDE कॉन्फ़िगरेशन |एडिटर को कॉन्फ़िगर करें।
- XMLअंतिम नई लाइन ट्रिम करेंअंतिम नई लाइन सम्मिलित करें।फ़ाइल के अंत में अतिरिक्त खाली पंक्ति निकालें
@@ -372,6 +359,7 @@
मैक्स लाइन विड्थएक पंक्ति में वर्णों की अधिकतम संख्या चुनें।विभाजित ऐट्रिब्यूट्स का इंडेंट साइज
+ विभाजित ऐट्रिब्यूट्स के लिए इंडेंट करने के लिए रिक्त स्थान की संख्या।संरक्षित नई लाइनेंनिरंतर लाइन ब्रेक की अधिकतम संख्या जिसे संरक्षित किया जाना चाहिए।खाली एलिमेंट्स का व्यवहार
@@ -445,33 +433,6 @@
टास्क लोड हो रहे हैं...सभी टास्कसयह सुविधा अभी तक लागू नहीं हुई है।
- विजेट
- लेआउट
- टेक्सटव्यू
- बटन
- चेकबॉक्स
- चेक्ड टेक्सटव्यू
- एडिटेक्सट
- इमेज बटन
- इमेज व्यू
- प्रोग्रेस बार
- रेडियो बटन
- सीक बार
- स्पिनर
- लीनियर लेआउट
- रिलेटिव लेआउट
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutक्लोनGit रिपॉजिटरी क्लोन करें
@@ -479,5 +440,16 @@
रिपॉजिटरी क्लोन हो रही हैGit क्लोन सफल हुआGit रिपॉजिटरी क्लोन करने में विफल
- विभाजित ऐट्रिब्यूट्स के लिए इंडेंट करने के लिए रिक्त स्थान की संख्या।
+ नीचे दी गई सूची से एक एट्रिब्यूट का चयन करें
+ लेआउट हायरार्की दिखाएं
+ कलर स्कीम
+ एडिटर में उपयोग करने के लिए कलर स्कीम चुनें
+ UI मोड
+ IDE के लिए UI मोड चुनें
+ लाइट
+ डार्क
+ सिस्टम का पालन करें
+ अपने डिवाइस के करीब एक अनुभव का आनंद लें (पुनः आरंभ करने की आवश्यकता है)।
+ प्रोजेक्ट कॉन्फ़िगरेशन
+ एप्लिकेशन लॉन्च करने में विफल। अधिक जानकारी के लिए IDE लॉग देखें।
diff --git a/resources/src/main/res/values-id/strings.xml b/resources/src/main/res/values-id/strings.xml
index 3531011655..d98a2567bc 100644
--- a/resources/src/main/res/values-id/strings.xml
+++ b/resources/src/main/res/values-id/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE menggunakan build JDK yang dimodifikasi yang dilisensikan di bawah Lisensi Publik Umum GNU v2.0. Kode sumber dan lisensi JDK tersedia di : Lisensi sumber terbukaBerlisensi di bawah: EmailWebsite
- AndroidIDE v\u2022 %sAndroidIDE %1$s untuk %2$sSimpel, sebuah IDE untuk AndroidGagal mengekstrak nama paket!AndroidIDE adalah Integrated Development Environment (IDE) untuk membuat aplikasi Android pada Smartphone Android anda. AndroidIDE mendukung :\n1. Gradle \n2. OpenJDK 17.0-22.\n3. Perlengkapan otomatis Java tingkat lanjut\n4. Perlengkapan Otomatis XML \n5. Dukungan Kotlin dan lainnya.\n\nUnduh AndroidIDE di https://androidide.comJika anda mengalami masalah ketika menggunakan AndroidIDE atau dengan pembuatan Aplikasi Android, anda dapat bergabung ke Grup Telegram dan bertanya disana.\n\nAnda juga dapat mengirim saran pada Email kami.Diskusi & bantuan
- GitHubButuh Bantuan?LainnyaBerbagi dengan Teman
@@ -49,12 +46,8 @@
Sayang sekali, perangkat anda tidak didukung saat ini. Kami mohon maaf atas ketidaknyamanannya.\n\nCPU ABI yang didukung: aarch64 dan armeabi-v7aLint
- lintDebug
- lintReleaseBuild
- assembleDebugHasil Build
- assembleReleaseLint tasksClean & buildBersihkan
@@ -70,7 +63,6 @@
Instal AplikasiBersihkan hasilJalankan
- GradleBuild PertamaIni adalah build pertama setelah anda memasang AndroidIDE. Build pertama biasanya memakan waktu selama Gradle mengunduh semua dependensi dan plugin. Proses ini diperkirakan sekitar 10–15 menit. Tetapi ini bergantung pada kecepatan koneksi internet anda.\n\nMohon bersabar …
@@ -100,13 +92,11 @@
Projek NavigationDrawerGim LibGDXPersiapan projek gim LibGDX untuk menampilkan gambar as sebagai contoh.
- Jetpack ComposeProjek sederhana Jetpack Compose.Bottom Navigation ActivityBuat Activity baru dengan Bottom NavigationTabbed ActivityBuat Blank Activity baru dengan Tabs
- Fragment + ViewModelNative C++Buat Proyek baru dengan Empty Activity yang dikonfigurasi untuk menggunakan JNITidak ada Activity
@@ -255,7 +245,6 @@
Perluas seleksiSamakan penyelesaian dalam huruf kecilUmum
- JavaFile tidak tersimpanBeberapa file belum disimpan. Apakah anda ingin menyimpan sebelum menutup file tersebut? File yang belum tersimpan: \n%sSimpan sebelum menutup file
@@ -274,7 +263,7 @@
Cabang fileSumber warnaPemilih warna
- Isi string
+ Nilai AtributSumber stringReferensi sumber lainQuickfixes
@@ -318,7 +307,6 @@
Build gagal. Lihat output build untuk detail selengkapnya.Build suksesGagal mendapatkan teks dari editor
- Aplikasi sayaIntent mengembalikan data yang tidak validPilih direktori dari penyimpanan utamaOtoritas \'%s\' tidak diizinkan
@@ -345,7 +333,6 @@
Lebih lanjut tentang AndroidIDE.Konfigurasi IDE umum.Konfigurasikan editornya.
- XMLPotong baris baru terakhirSisipkan baris baru terakhirHapus baris kosong ekstra di akhir file
@@ -372,6 +359,7 @@
Lebar baris maksimalJumlah maksimum karakter yang harus dimiliki sebuah baris.Pisahkan ukuran indentasi atribut
+ Jumlah spasi untuk indentasi untuk atribut terpisah.Baris baru dipertahankanJumlah maksimum jeda baris kontinu yang harus dipertahankan.Perilaku elemen kosong
@@ -445,33 +433,6 @@
Memuat task...Semua taskFitur ini belum diterapkan.
- Widget
- Tata letak
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutCloneClone repositori git
@@ -479,5 +440,16 @@
Cloning repositoriGit clone berhasilGagal mengkloning repositori git
- Jumlah spasi untuk indentasi untuk atribut terpisah.
+ Pilih atribut dari daftar di bawah ini
+ Tampilkan hierarki tata letak
+ Skema warna
+ Pilih skema warna untuk digunakan dalam editor
+ Mode UI
+ Pilih mode UI untuk IDE
+ Light
+ Dark
+ Ikuti sistem
+ Nikmati pengalaman yang lebih dekat dengan perangkat Anda (perlu dimulai ulang).
+ Konfigurasi proyek
+ Gagal meluncurkan aplikasi. Lihat log IDE untuk info lebih lanjut.
diff --git a/resources/src/main/res/values-pt/strings.xml b/resources/src/main/res/values-pt/strings.xml
index a94ae4df02..5496c312d9 100644
--- a/resources/src/main/res/values-pt/strings.xml
+++ b/resources/src/main/res/values-pt/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE usa uma construção modificada do JDK que é licenciada sob a GNU General Public License v2.0. O código fonte e a licença do JDK estão disponíveis em :Licenças de código abertoLicenciado sob:E-mailWebsite
- AndroidIDE v\u2022 %sAndroidIDE %1$s para %2$sSimplesmente, uma IDE para AndroidFalha ao extrair o nome do pacote!AndroidIDE é um ambiente de desenvolvimento integrado para construir aplicativos Android no seu Smartphone. Ele suporta :\n1. Gradle \n2. OpenJDK 17.0-22.\n3. Autocomplete avançado de Java\n4. Autocomplete automático de XML \n5. Suporte a Kotlin e muito mais.\n\nInstale AndroidIDE em https://androidide.comSe você estiver enfrentando problemas durante o uso do AndroidIDE ou com a construção de aplicativos Android, você pode se juntar ao Grupo do Telegram para pedir ajuda lá.\n\nVocê também pode enviar sugestões em nosso e-mail.Discutir & ajuda
- GitHubPrecisa de ajuda?OutroCompartilhe com amigos
@@ -49,12 +46,8 @@
Infelizmente, seu dispositivo não é compatível no momento. Lamentamos o inconveniente.\n\nABIs de CPU compatíveis: aarch64 e armeabi-v7aLint
- lintDebug
- lintReleaseCompilar
- assembleDebugLogs de compilação
- assembleReleaseLintLimpar & construirLimpar
@@ -70,7 +63,6 @@
Instalar APK(s)Limpar logsCompilar
- GradlePrimeira compilaçãoEsta é a primeira vez que se compila depois de instalar o AndroidIDE. A primeira compilação geralmente leva tempo, pois a Gradle baixa todas as dependências e plugins. Este processo pode demorar cerca de 10-15 minutos. Mas isto depende totalmente de sua conexão de rede.\n\nPor favor, seja paciente...
@@ -100,13 +92,11 @@
Projeto com Drawer NavigationJogo LibGDXProjeto de jogo LibGDX criado para renderizar uma imagem como exemplo.
- Jetpack ComposeProjeto básico Jetpack Compose hello world.Activity Bottom NavigationCria uma nova activity com bottom navigationActivity com abasCria uma nova activity em branco com abas
- Fragment + ViewModelC++ nativoCria um novo projeto com uma Activity Vazia configurada para usar JNISem Activity
@@ -169,12 +159,12 @@
FecharTodos os arquivos foram salvos!Destino: %s/
- Drawable
- Layout
+ Desenhável
+ DisposiçãoMenuOutroClasse
- Activity
+ AtividadeInterfaceEnumVerificando as permissões de armazenamento
@@ -255,7 +245,6 @@
Expandir seleçãoAutocomplete sugerir com letras minúsculasComum
- JavaArquivos não salvosAlguns arquivos não foram salvos. Gostaria de salvá-los antes de fechar? Os arquivos não salvos são: \n%sSalve antes de fechar os arquivos
@@ -274,7 +263,7 @@
Lista de arquivosRecurso de coresSeletor de cores
- Valor da string
+ Valor do atributoRecurso de stringQualquer referência de recursoAções
@@ -303,7 +292,7 @@
Local de salvamentoLinguagem do ProjetoCarregando modelos...
- C++ Standard
+ C++ PadrãoPróximoSairCorreção de ponteiros de tag do JDK 11
@@ -318,7 +307,6 @@
Falha na compilação. Consulte os logs de compilação para obter mais detalhes.Construir com sucessoFalha ao obter texto do editor
- Meu aplicativoA intent retornou dados inválidosSelecione um diretório do armazenamento primárioAutoridade \'%s\' não permitida
@@ -345,7 +333,6 @@
Mais sobre o AndroidIDE.Configuração geral da IDE.Configurar o editor.
- XMLRetirar linha finalInserir linha finalRemover linha extra vazia no final do arquivo
@@ -372,6 +359,7 @@
Largura máxima da linhaO número máximo de caracteres que uma linha deve ter.Dividir o tamanho do recuo dos atributos
+ O número de espaços a serem indexados para atributos divididos.Novas linhas preservadasO número máximo de quebras de linha contínuas que devem ser preservadas.Comportamento de elementos vazios
@@ -445,33 +433,6 @@
Carregando tarefas...Todas as tarefasEste recurso ainda não foi implementado.
- Widgets
- Layouts
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutClonarClonar repositório git
@@ -479,5 +440,16 @@
Clonando repositórioGit clonado com sucessoFalha ao clonar repositório git
- O número de espaços a serem indexados para atributos divididos.
+ Selecione um atributo da lista abaixo
+ Mostrar hierarquia de disposição
+ Esquema de cores
+ Escolha o esquema de cores para usar no editor
+ Modo UI
+ Escolha o modo de UI para o IDE
+ Claro
+ Escuro
+ Seguir o sistema
+ Aproveite uma experiência mais próxima do seu dispositivo (requer reinicialização).
+ Configuração do projeto
+ Falha ao iniciar a aplicação. Consulte os logs do IDE para obter mais informações.
diff --git a/resources/src/main/res/values-ru/strings.xml b/resources/src/main/res/values-ru/strings.xml
index eaed29fb14..a81ae8d143 100644
--- a/resources/src/main/res/values-ru/strings.xml
+++ b/resources/src/main/res/values-ru/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE использует модифицированную версию JDK, которая лицензирована согласно GNU General Public License v2.0. Исходный код JDK и лицензия доступны здесь: Лицензирование открытого кодаЛицензия: EmailВебсайт
- AndroidIDE v\u2022 %sAndroidIDE %1$s для %2$sПросто IDE для AndroidОшибка распаковки имени пакета!AndroidIDE - это IDE (Integrated Development Environment - интегрированная среда разработки) для создания Android приложений на вашем Android смартфоне. AndroidIDE поддерживает:\n1. Gradle \n2. OpenJDK 11.0.1. \n3. Продвинутое автодополнение для Java \n4. Автодополнение для XML \n5. Поддержка Kotlin и многое другое. \n\nСкачайте AndroidIDE здесь: https://androidide.comЕсли вы столкнулись с какими-либо проблемами при использовании AndroidIDE или при сборке Android приложений, вы можете присоединиться к нашей группе в Telegram и попросить о помощи там.\n\nВы также можете присылать нам свои пожелания и предложения на наш электронный адрес.Обсуждение и помощь
- GitHubНужна помощь?ДругоеПоделиться с друзьями
@@ -49,12 +46,8 @@
К сожалению, на данный момент ваше устройство не поддерживается. Приносим свои извинения.\n\nПоддерживаемые ABI: aarch64 и armeabi-v7aLint
- lintDebug
- lintReleaseСборка
- assembleDebugРезультат сборки
- assembleReleaseСценарии LintОчистить и собратьОчистить проект
@@ -70,7 +63,6 @@
Установить APK файл(ы)Очистить выходные файлыЗапустить
- GradleПервая сборкаЭто первая сборка после установки AndroidIDE. Первая сборка обычно занимает больше времени, так как Gradle скачивает все зависимости и плагины. Этот процесс может занять 10–15 минут, в зависимости от производительности вашего устройства.\n\nПожалуйста, подождите…
@@ -100,13 +92,11 @@
Проект с Navigation DrawerИгра LibGDXПроект игры LibGDX. Выводит изображение на экран в качестве примера.
- Jetpack ComposeБазовый hello world проект Jetpack Compose.Проект с Bottom NavigationСоздаёт новую пустую активность с Bottom NavigationПроект с вкладкамиСоздаёт новую пустую активность с вкладками
- Проект Fragment + ViewModelНативный проект на C++Создаёт новый проект с Empty Activity, сконфигурированный для использования JNIПроект без активности
@@ -255,7 +245,6 @@
Расширить выделениеИскать совпадения в строчном регистреОбщее
- JavaНесохраненные файлыНекоторые файлы не сохранены. Хотите сохранить их перед закрытием? Список несохраненных файлов: \n%sСохранять файлы перед закрытием
@@ -274,7 +263,7 @@
Дерево файловЦветовой ресурсСредство выбора цвета
- Строковое значение
+ Attribute valueСтроковый ресурсЛюбая ссылка на ресурсДействия
@@ -318,7 +307,6 @@
Сборка завершилась неудачей. Дополнительные сведения см. в выводе сборки.Сборка прошла успешноНе удалось получить текст из редактора
- My ApplicationНамерение вернуло недопустимые данныеВыберите каталог из основного хранилищаПолномочия \'%s\' не разрешены
@@ -345,7 +333,6 @@
More about AndroidIDE.General IDE configuration.Configure the editor.
- XMLTrim final new lineInsert final new lineRemove extra empty line at the end of file
@@ -372,6 +359,7 @@
Max line widthThe maximum number of characters a line should have.Split attributes indent size
+ The number of spaces to indent for split attributes.Preserved new linesThe maximum number of continuous line breaks that should be preserved.Empty elements behaviour
@@ -445,33 +433,6 @@
Loading tasks...All tasksThis feature is not implemented yet.
- Widgets
- Layouts
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutCloneClone git repository
@@ -479,5 +440,16 @@
Cloning repositoryGit clone successfulFailed to clone git repository
- The number of spaces to indent for split attributes.
+ Select an attribute from the below list
+ Show layout hierarchy
+ Color Scheme
+ Choose color scheme to use in editor
+ UI Mode
+ Choose UI mode for the IDE
+ Light
+ Dark
+ Follow system
+ Enjoy an experience closer to your device (requires restart).
+ Project configuration
+ Failed to launch application. See IDE logs for more info.
diff --git a/resources/src/main/res/values-tr/strings.xml b/resources/src/main/res/values-tr/strings.xml
index c96246bfbf..c5a938ba44 100644
--- a/resources/src/main/res/values-tr/strings.xml
+++ b/resources/src/main/res/values-tr/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE, GNU Genel Kamu Lisansı v2.0 kapsamında lisanslanan değiştirilmiş bir JDK yapısı kullanır. JDK\'nın kaynak kodu ve lisansı şu adreste mevcuttur: Açık kaynak lisanslarıAltında lisanlıEmailWebsite
- AndroidIDE v\u2022 %sAndroidIDE %1$s for %2$sBasitçe, Android için bir IDEApk dosyası ayıklanamadı!AndroidIDE akıllı telefonunuzda Android uygulamaları oluşturmak içindir. Şunları destekler:\n1. Gradle \n2. OpenJDK 17.0-22.\n3. Gelişmiş Java otomatik tamamlama\n4. XML otomatik tamamlama \n5. Kotlin desteği ve daha fazlası.\n \nAndroidIDE\'yi indir: https://androidide.comEğer AndroidIDE\'yi kullanırken sorunlar yaşıyorsan veya uygulama inşa ederken, soeu sormak için Telegram Grubumuza katılabilirsin.\n\nVe yine öneriler için email gönderebilirsin.Tartış & yardım edin
- GitHubYardım mı lazım?DiğerArkadaşlarınla Paylaş
@@ -49,12 +46,8 @@
Üzgünüz ki cihazınız şu an desteklenmiyor. Rahatsızlık için üzgünüz.\n\nDesteklenen CPU\'lar: aarch64 ve armeabi-v7aFanila
- lintDebug
- lintReleaseİnşa et
- assembleDebugYapım İşi Çıktısı
- assembleReleaseLint tasks& \'yi temizle ve inşa etTemizle
@@ -70,7 +63,6 @@
Apk(lar)\'ı yükleÇıktıyı temizleÇalıştır
- Gradleİlk İnşaBu AndroidIDE\'yi yüklendikten sonra ilk inşa. İlk inşa bağımlılıkları ve eklentileri yükler bu yüzden biraz zaman alabilir. Bu işlem 10-15 dakika sürer. Ama genellikle internetine bağlı.\n\nLütfen sabırlı olun…
@@ -100,13 +92,11 @@
Navigasyon drawer projesiLibGDX oyunuLibGDX oyun projesi, bir görüntüyü örnek olarak işlemek içindir.
- Jetpack ComposeTemel Jetpack Compose merhaba dünya projesi.Alt Gezinme EtkinliğiAl gezinti ile yeni bir etkinlik oluştururSekmeli etkinlikSekmeler ile boş bir etkinlik oluşturur
- Fragment + ViewModelNative C++JNI kullanacak şekilde yapılandırılmış bir Boş Etkinlik ile yeni bir proje oluştururEtkinlik yok
@@ -255,7 +245,6 @@
Seçimi genişletMatch completions in lower caseGenel
- JavaKaydedilmemiş dosyalarBazı dosyalar kaydedilmedi. Kapatmadan önce kaydetmek ister misin? Kaydedilmemiş dosyalar:\n%sDosyaları kapatmadan önce kaydet
@@ -274,7 +263,7 @@
DosyalarRenk kaynağıRenk seçici
- Dize değeri
+ Attribute valueDize kaynağıHerhangi bir kaynak referansıEylemler
@@ -318,7 +307,6 @@
Yapı başarısız. Daha fazla detay için çıktıya bak.İnşa başarılıYazı editörden alınamadı
- My ApplicationIntent returned invalid dataHafızadan bir dizin seçAuthority \'%s\' not allowed
@@ -345,7 +333,6 @@
More about AndroidIDE.General IDE configuration.Configure the editor.
- XMLTrim final new lineInsert final new lineRemove extra empty line at the end of file
@@ -372,6 +359,7 @@
Max line widthThe maximum number of characters a line should have.Split attributes indent size
+ The number of spaces to indent for split attributes.Preserved new linesThe maximum number of continuous line breaks that should be preserved.Empty elements behaviour
@@ -445,33 +433,6 @@
Loading tasks...All tasksThis feature is not implemented yet.
- Widgets
- Layouts
- TextView
- Button
- CheckBox
- CheckedTextView
- EditText
- ImageButton
- ImageView
- ProgressBar
- RadioButton
- SeekBar
- Spinner
- LinearLayout
- RelativeLayout
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutCloneClone git repository
@@ -479,5 +440,16 @@
Cloning repositoryGit clone successfulFailed to clone git repository
- The number of spaces to indent for split attributes.
+ Select an attribute from the below list
+ Show layout hierarchy
+ Color Scheme
+ Choose color scheme to use in editor
+ UI Mode
+ Choose UI mode for the IDE
+ Light
+ Dark
+ Follow system
+ Enjoy an experience closer to your device (requires restart).
+ Project configuration
+ Failed to launch application. See IDE logs for more info.
diff --git a/resources/src/main/res/values-zh/strings.xml b/resources/src/main/res/values-zh/strings.xml
index 6c9bb288a4..a43dbfb8f2 100644
--- a/resources/src/main/res/values-zh/strings.xml
+++ b/resources/src/main/res/values-zh/strings.xml
@@ -1,20 +1,17 @@
- AndroidIDEAndroidIDE使用了以GPL v2.0开源的JDK的修改版构建版本。你可以在此处找到它的源代码和许可证: 开源许可证许可证: 邮件网站
- AndroidIDE v\u2022 %sAndroidIDE %1$s (%2$s)简单地说,一款适用于 Android 的 IDE获取包名失败!AndroidIDE是一个用于在Android设备上构建Android应用的集成开发环境。它支持: \n1. Gradle \n2. OpenJDK 17.0-22\n3. 先进的Java自动补全\n4. XML自动补全 \n5. Kotlin支持,还有更多\n\n请从这里下载AndroidIDE:https://androidide.com如果您在使用AndroidIDE构建应用时遇到任何问题,您可以加入Telegram群组寻求帮助。\n\n您也可以通过电子邮件对我们提出建议。讨论 & 帮助
- GitHub需要帮助?其他分享给朋友
@@ -49,12 +46,8 @@
很不幸,您的设备当前不受我们支持。我们对其产生的不便很抱歉。\n\n支持的CPU架构: aarch64 与 armeabi-v7aLint
- lintDebug
- lintReleaseBuild
- assembleDebug编译输出
- assembleReleaseLint 任务清理 & 构建清理缓存
@@ -70,7 +63,6 @@
安装APK清空输出运行
- Gradle第一次编译这是您安装AndroidIDE后第一次编译项目,由于需要下载Gradle和各种依赖项目,第一次编译需要较长时间。这可能要花费10–15分钟,但这完全取决于您的网络连接。\n\n请耐心等待 …
@@ -100,13 +92,11 @@
导航侧滑项目LibGDX 游戏LibGDX 游戏项目图像渲染示例
- Jetpack ComposeJetpack Compose 基本 hello world 项目底部导航栏 Activity创建一个带有底部导航栏的 Activity选项卡 Activity新建一个带有选项卡的空白 Activity
- Fragment + ViewModelNative C++创建一个使用 JNI 空白 Activity 的新项目无 Activity
@@ -255,7 +245,6 @@
扩选代码补全匹配小写字母通用
- Java未保存文件部分文件并未保存,是否在关闭项目之前保存?未保存的文件:\n%s关闭文件前自动保存
@@ -274,7 +263,7 @@
文件列表Color 资源取色器
- String 值
+ Attribute valueString 资源任一资源引用操作
@@ -318,7 +307,6 @@
构建失败,请参阅构建输出以获取详情构建成功无法从编辑器获取文本
- My ApplicationIntent 返回了无效数据从内部存储中选择目录权限“%s”不被允许
@@ -345,7 +333,6 @@
更多关于 AndroidIDE常规 IDE 配置编辑器 配置
- XML删除 末尾新行插入 末尾新行删除文件末尾多余的空行
@@ -372,6 +359,7 @@
最大行宽每行字符数最高上限拆分属性缩进大小
+ The number of spaces to indent for split attributes.新线保留应保留连续换行符的最大数目空元素行为
@@ -445,33 +433,6 @@
Loading tasks...All tasksThis feature is not implemented yet.
- Widgets
- Layouts
- 文本
- 按钮
- 复选框
- 复选框文本
- 编辑框
- 图像按钮
- 图片
- 进度条
- 单选框
- 拖动条
- 下拉框
- 线性布局
- 相对布局
- AutoCompleteTextView
- ListView
- SurfaceView
- Switch
- TextureView
- ToggleButton
- WebView
- FrameLayout
- GridLayout
- LinearLayout (H)
- LinearLayout (V)
- RelativeLayoutCloneClone git repository
@@ -479,5 +440,16 @@
Cloning repositoryGit clone successfulFailed to clone git repository
- The number of spaces to indent for split attributes.
+ Select an attribute from the below list
+ Show layout hierarchy
+ Color Scheme
+ Choose color scheme to use in editor
+ UI Mode
+ Choose UI mode for the IDE
+ Light
+ Dark
+ Follow system
+ Enjoy an experience closer to your device (requires restart).
+ Project configuration
+ Failed to launch application. See IDE logs for more info.
diff --git a/resources/src/main/res/values/strings.xml b/resources/src/main/res/values/strings.xml
index 13686d0dc7..bbc160f6a4 100644
--- a/resources/src/main/res/values/strings.xml
+++ b/resources/src/main/res/values/strings.xml
@@ -2,20 +2,20 @@
- AndroidIDE
+ AndroidIDEAndroidIDE uses a modified build of the JDK which is licensed under the GNU General Public License v2.0. The source code and the license of the JDK is available at : Open source licensesLicensed under: EmailWebsite
- AndroidIDE v\u2022 %s
+ AndroidIDE v\u2022 %sAndroidIDE %1$s for %2$sSimply, an IDE for AndroidFailed to extract package name!AndroidIDE is an Integrated Development Environment for building Android apps on your Android Smartphone. It supports :\n1. Gradle \n2. OpenJDK 17.0–22.\n3. Advanced Java auto completion\n4. XML Auto Completion \n5. Kotlin Support and much more.\n\nDownload AndroidIDE at https://androidide.comIf you\'re facing issues while using AndroidIDE or with building Android Apps, you can join the Telegram Group ask for help there.\n\nYou can also send suggesstions on our email.Discuss & help
- GitHub
+ GitHubNeed Help?OtherShare with Friends
@@ -53,12 +53,12 @@
Lint
- lintDebug
- lintRelease
+ lintDebug
+ lintRelease
+ assembleDebug
+ assembleReleaseBuild
- assembleDebugBuild output
- assembleReleaseLint tasksClean & buildClean
@@ -74,7 +74,7 @@
Install APK(s)Clear outputRun
- Gradle
+ GradleFirst BuildThis is the first time build after you installed AndroidIDE. First build usually takes time as Gradle downloads all dependencies and plugins. This process may take about 10–15 minutes. But this totally depends on your network connection.\n\nPlease be patient …
@@ -106,13 +106,13 @@
Navigation drawer projectLibGDX GameLibGDX game project set up to render an image as an example.
- Jetpack Compose
+ Jetpack ComposeBasic Jetpack Compose hello world project.Bottom Navigation ActivityCreates a new activity with bottom navigationTabbed ActivityCreates a new blank activity with tabs
- Fragment + ViewModel
+ Fragment + ViewModelNative C++Creates a new project with an Empty Activity configured to use JNINo Activity
@@ -270,7 +270,7 @@
Match completions in lower caseCommon@string/title_common
- Java
+ JavaUnsaved filesSome files are not saved. Would you like to save them before closing? Unsaved files are: \n%sSave before closing files
@@ -334,7 +334,7 @@
Build failed. See build output for more details.Build successfulFailed to get text from editor
- My Application
+ My ApplicationIntent returned invalid dataSelect a directory from primary storageAuthority \'%s\' not allowed
@@ -362,7 +362,7 @@
More about AndroidIDE.General IDE configuration.Configure the editor.
- XML
+ XMLTrim final new lineInsert final new lineRemove extra empty line at the end of file
@@ -467,8 +467,9 @@
Loading tasks...All tasksThis feature is not implemented yet.
- Widgets
- Layouts
+
+ Widgets
+ LayoutsViewTextView
@@ -533,7 +534,8 @@
LightDarkFollow system
- Material You
+ Material YouEnjoy an experience closer to your device (requires restart).Project configuration
+ Failed to launch application. See IDE logs for more info.
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 4568f67703..a5f0a464f4 100755
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,7 +1,6 @@
@file:Suppress("UnstableApiUsage")
import com.mooltiverse.oss.nyx.gradle.NyxExtension
-import com.mooltiverse.oss.nyx.services.github.GitHub
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
@@ -14,7 +13,7 @@ pluginManagement {
}
}
-plugins { id("com.mooltiverse.oss.nyx") version "1.3.0" }
+plugins { id("com.mooltiverse.oss.nyx") version "2.2.0" }
extensions.configure {
git {
@@ -47,6 +46,7 @@ include(
":app",
":common",
":editor",
+ ":editor-api",
":emulatorview",
":eventbus",
":eventbus-android",
@@ -69,6 +69,7 @@ include(
":subprojects:aaptcompiler",
":subprojects:builder-model-impl",
":subprojects:classfile",
+ ":subprojects:flashbar",
":subprojects:framework-stubs",
":subprojects:fuzzysearch",
":subprojects:google-java-format",
@@ -76,7 +77,6 @@ include(
":subprojects:javac-services",
":subprojects:jaxp",
":subprojects:jdt",
- ":subprojects:jsonrpc",
":subprojects:layoutlib-api",
":subprojects:projects",
":subprojects:tooling-api",
diff --git a/shared/src/main/java/com/itsaky/androidide/utils/ReaderInputStream.java b/shared/src/main/java/com/itsaky/androidide/utils/ReaderInputStream.java
index 1d153b8b3b..81a1eee71a 100644
--- a/shared/src/main/java/com/itsaky/androidide/utils/ReaderInputStream.java
+++ b/shared/src/main/java/com/itsaky/androidide/utils/ReaderInputStream.java
@@ -64,7 +64,7 @@
* is typically used in situations where an existing API only accepts an {@link InputStream}, but
* where the most natural way to produce the data is as a character stream, i.e. by providing a
* {@link Reader} instance. An example of a situation where this problem may appear is when
- * implementing the {@code javax.activation.DataSource} interface from the Java Activation
+ * implementing the {@code jdkx.activation.DataSource} interface from the Java Activation
* Framework.
*
*
Given the fact that the {@link Reader} class doesn't provide any way to predict whether the
diff --git a/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt b/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt
index 30ab03bd2f..a0c0d32a1f 100644
--- a/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt
+++ b/shared/src/main/java/com/itsaky/androidide/utils/StopWatch.kt
@@ -24,12 +24,13 @@ package com.itsaky.androidide.utils
* @param label The label for the log message.
* @author Akash Yadav
*/
-class StopWatch(
+class StopWatch
+@JvmOverloads
+constructor(
val label: String,
val start: Long = System.currentTimeMillis(),
var lastLap: Long = start
) {
- constructor(label: String) : this(label, System.currentTimeMillis())
private val log = ILogger.newInstance(javaClass.simpleName)
diff --git a/subprojects/builder-model-impl/build.gradle.kts b/subprojects/builder-model-impl/build.gradle.kts
index 4d15513f59..143c330352 100644
--- a/subprojects/builder-model-impl/build.gradle.kts
+++ b/subprojects/builder-model-impl/build.gradle.kts
@@ -23,5 +23,5 @@ plugins {
dependencies {
implementation(libs.common.jkotlin)
- api("com.android.tools.build:builder-model:7.3.1")
+ api(libs.tooling.builderModel)
}
\ No newline at end of file
diff --git a/subprojects/builder-model-impl/src/main/java/com/itsaky/androidide/builder/model/DefaultAndroidArtifact.kt b/subprojects/builder-model-impl/src/main/java/com/itsaky/androidide/builder/model/DefaultAndroidArtifact.kt
index f05391bf10..9174c3c71d 100644
--- a/subprojects/builder-model-impl/src/main/java/com/itsaky/androidide/builder/model/DefaultAndroidArtifact.kt
+++ b/subprojects/builder-model-impl/src/main/java/com/itsaky/androidide/builder/model/DefaultAndroidArtifact.kt
@@ -18,12 +18,14 @@ package com.itsaky.androidide.builder.model
import com.android.builder.model.v2.ide.AndroidArtifact
import com.android.builder.model.v2.ide.CodeShrinker
+import com.android.builder.model.v2.ide.PrivacySandboxSdkInfo
import java.io.File
import java.io.Serializable
/** @author Akash Yadav */
class DefaultAndroidArtifact : AndroidArtifact, Serializable {
private val serialVersionUID = 1L
+ override var applicationId: String? = ""
override var resGenTaskName: String? = null
override var abiFilters: Set? = null
override var assembleTaskOutputListingFile: File? = null
@@ -43,4 +45,5 @@ class DefaultAndroidArtifact : AndroidArtifact, Serializable {
override var ideSetupTaskNames: Set = emptySet()
override var targetSdkVersionOverride: DefaultApiVersion? = null
override var modelSyncFiles: Collection = emptyList()
+ override var privacySandboxSdkInfo: PrivacySandboxSdkInfo? = null
}
diff --git a/subprojects/xml-formatter/.gitignore b/subprojects/flashbar/.gitignore
similarity index 100%
rename from subprojects/xml-formatter/.gitignore
rename to subprojects/flashbar/.gitignore
diff --git a/subprojects/flashbar/README.md b/subprojects/flashbar/README.md
new file mode 100644
index 0000000000..021e27fd54
--- /dev/null
+++ b/subprojects/flashbar/README.md
@@ -0,0 +1,21 @@
+# Flashbar
+
+Based on [Flashbar](https://github.com/aritraroy/Flashbar).
+
+## License
+
+```
+Copyright 2016 aritraroy
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```
\ No newline at end of file
diff --git a/subprojects/xml-formatter/build.gradle.kts b/subprojects/flashbar/build.gradle.kts
similarity index 69%
rename from subprojects/xml-formatter/build.gradle.kts
rename to subprojects/flashbar/build.gradle.kts
index 8d455b0eb1..9e753d14f9 100644
--- a/subprojects/xml-formatter/build.gradle.kts
+++ b/subprojects/flashbar/build.gradle.kts
@@ -1,27 +1,33 @@
-/*
- * 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 .
- */
-
-@Suppress("JavaPluginLanguageLevel")
-plugins {
- id("java-library")
-}
-
-dependencies {
- implementation(libs.aapt2.common)
- implementation(libs.google.guava.jre)
- implementation(libs.xml.jb.annotations)
+/*
+ * 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 .
+ */
+
+plugins {
+ id("com.android.library")
+ id("kotlin-android")
+}
+
+android {
+ namespace = "com.itsaky.androidide.flashbar"
+}
+
+dependencies {
+ implementation(libs.androidx.appcompat)
+ implementation(libs.androidx.annotation)
+ implementation(libs.androidx.ktx)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.google.material)
}
\ No newline at end of file
diff --git a/subprojects/flashbar/consumer-rules.pro b/subprojects/flashbar/consumer-rules.pro
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/subprojects/flashbar/proguard-rules.pro b/subprojects/flashbar/proguard-rules.pro
new file mode 100644
index 0000000000..481bb43481
--- /dev/null
+++ b/subprojects/flashbar/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/AndroidManifest.xml b/subprojects/flashbar/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..1a6faaa403
--- /dev/null
+++ b/subprojects/flashbar/src/main/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/Flashbar.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/Flashbar.kt
new file mode 100644
index 0000000000..c618cf37c7
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/Flashbar.kt
@@ -0,0 +1,674 @@
+/*
+ * 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.androidide.flashbar
+
+import android.app.Activity
+import android.graphics.Bitmap
+import android.graphics.PorterDuff
+import android.graphics.Typeface
+import android.graphics.drawable.Drawable
+import android.text.Spanned
+import android.widget.ImageView.ScaleType
+import android.widget.ImageView.ScaleType.CENTER_CROP
+import androidx.annotation.ColorInt
+import androidx.annotation.ColorRes
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.annotation.StyleRes
+import androidx.core.content.ContextCompat
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.BOTTOM
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.TOP
+import com.itsaky.androidide.flashbar.Flashbar.ProgressPosition.LEFT
+import com.itsaky.androidide.flashbar.Flashbar.ProgressPosition.RIGHT
+import com.itsaky.androidide.flashbar.anim.FlashAnim
+import com.itsaky.androidide.flashbar.anim.FlashAnimBarBuilder
+import com.itsaky.androidide.flashbar.anim.FlashAnimIconBuilder
+
+private const val DEFAULT_SHADOW_STRENGTH = 4
+private const val DEFAUT_ICON_SCALE = 1.0f
+
+@Suppress("UNUSED", "MemberVisibilityCanBePrivate")
+class Flashbar private constructor(private var builder: Builder) {
+
+ private lateinit var flashbarContainerView: FlashbarContainerView
+ private lateinit var flashbarView: FlashbarView
+
+ /** Shows a flashbar */
+ fun show() {
+ flashbarContainerView.show(builder.activity)
+ }
+
+ /** Dismisses a flashbar */
+ fun dismiss() {
+ flashbarContainerView.dismiss()
+ }
+
+ /**
+ * Returns true/false depending on whether the flashbar is showing or not This represents the
+ * partial appearance of the flashbar
+ */
+ fun isShowing() = flashbarContainerView.isBarShowing()
+
+ /**
+ * Returns true/false depending on whether the flashbar has been completely shown or not This
+ * represents the complete appearance of the flashbar
+ */
+ fun isShown() = flashbarContainerView.isBarShown()
+
+ private fun construct() {
+ flashbarContainerView = FlashbarContainerView(builder.activity)
+ flashbarContainerView.adjustOrientation(builder.activity)
+ flashbarContainerView.addParent(this)
+
+ flashbarView = FlashbarView(builder.activity)
+ flashbarView.init(builder.gravity, builder.castShadow, builder.shadowStrength)
+ flashbarView.adjustWitPositionAndOrientation(builder.activity, builder.gravity)
+ flashbarView.addParent(flashbarContainerView)
+
+ flashbarContainerView.attach(flashbarView)
+
+ initializeContainerDecor()
+ initializeBarDecor()
+
+ flashbarContainerView.construct()
+ }
+
+ private fun initializeContainerDecor() {
+ with(flashbarContainerView) {
+ setDuration(builder.duration)
+ setBarShowListener(builder.onBarShowListener)
+ setBarDismissListener(builder.onBarDismissListener)
+ setBarDismissOnTapOutside(builder.barDismissOnTapOutside)
+ setOnTapOutsideListener(builder.onTapOutsideListener)
+ setOverlay(builder.overlay)
+ setOverlayColor(builder.overlayColor)
+ setOverlayBlockable(builder.overlayBlockable)
+ setVibrationTargets(builder.vibrationTargets)
+ setIconAnim(builder.iconAnimBuilder)
+
+ setEnterAnim(builder.enterAnimBuilder!!)
+ setExitAnim(builder.exitAnimBuilder!!)
+ enableSwipeToDismiss(builder.enableSwipeToDismiss)
+ }
+ }
+
+ private fun initializeBarDecor() {
+ with(flashbarView) {
+ setBarBackgroundColor(builder.backgroundColor)
+ setBarBackgroundDrawable(builder.backgroundDrawable)
+ setBarTapListener(builder.onBarTapListener)
+
+ setTitle(builder.title)
+ setTitleSpanned(builder.titleSpanned)
+ setTitleTypeface(builder.titleTypeface)
+ setTitleSizeInPx(builder.titleSizeInPx)
+ setTitleSizeInSp(builder.titleSizeInSp)
+ setTitleColor(builder.titleColor)
+ setTitleAppearance(builder.titleAppearance)
+
+ setMessage(builder.message)
+ setMessageSpanned(builder.messageSpanned)
+ setMessageTypeface(builder.messageTypeface)
+ setMessageSizeInPx(builder.messageSizeInPx)
+ setMessageSizeInSp(builder.messageSizeInSp)
+ setMessageColor(builder.messageColor)
+ setMessageAppearance(builder.messageAppearance)
+
+ setPrimaryActionText(builder.primaryActionText)
+ setPrimaryActionTextSpanned(builder.primaryActionTextSpanned)
+ setPrimaryActionTextTypeface(builder.primaryActionTextTypeface)
+ setPrimaryActionTextSizeInPx(builder.primaryActionTextSizeInPx)
+ setPrimaryActionTextSizeInSp(builder.primaryActionTextSizeInSp)
+ setPrimaryActionTextColor(builder.primaryActionTextColor)
+ setPrimaryActionTextAppearance(builder.primaryActionTextAppearance)
+ setPrimaryActionTapListener(builder.onPrimaryActionTapListener)
+
+ setPositiveActionText(builder.positiveActionText)
+ setPositiveActionTextSpanned(builder.positiveActionTextSpanned)
+ setPositiveActionTextTypeface(builder.positiveActionTextTypeface)
+ setPositiveActionTextSizeInPx(builder.positiveActionTextSizeInPx)
+ setPositiveActionTextSizeInSp(builder.positiveActionTextSizeInSp)
+ setPositiveActionTextColor(builder.positiveActionTextColor)
+ setPositiveActionTextAppearance(builder.positiveActionTextAppearance)
+ setPositiveActionTapListener(builder.onPositiveActionTapListener)
+
+ setNegativeActionText(builder.negativeActionText)
+ setNegativeActionTextSpanned(builder.negativeActionTextSpanned)
+ setNegativeActionTextTypeface(builder.negativeActionTextTypeface)
+ setNegativeActionTextSizeInPx(builder.negativeActionTextSizeInPx)
+ setNegativeActionTextSizeInSp(builder.negativeActionTextSizeInSp)
+ setNegativeActionTextColor(builder.negativeActionTextColor)
+ setNegativeActionTextAppearance(builder.negativeActionTextAppearance)
+ setNegativeActionTapListener(builder.onNegativeActionTapListener)
+
+ showIcon(builder.showIcon)
+ showIconScale(builder.iconScale, builder.iconScaleType)
+ setIconDrawable(builder.iconDrawable)
+ setIconBitmap(builder.iconBitmap)
+ setIconColorFilter(builder.iconColorFilter, builder.iconColorFilterMode)
+
+ setProgressPosition(builder.progressPosition)
+ setProgressTint(builder.progressTint, builder.progressPosition)
+ }
+ }
+
+ class Builder(internal var activity: Activity) {
+ internal var gravity: Gravity = BOTTOM
+ internal var backgroundColor: Int? = null
+ internal var backgroundDrawable: Drawable? = null
+ internal var duration: Long = DURATION_INDEFINITE
+ internal var onBarTapListener: OnTapListener? = null
+ internal var onBarShowListener: OnBarShowListener? = null
+ internal var onBarDismissListener: OnBarDismissListener? = null
+ internal var barDismissOnTapOutside: Boolean = false
+ internal var onTapOutsideListener: OnTapListener? = null
+ internal var overlay: Boolean = false
+ internal var overlayColor: Int = ContextCompat.getColor(activity, R.color.modal)
+ internal var overlayBlockable: Boolean = false
+ internal var castShadow: Boolean = true
+ internal var shadowStrength: Int = DEFAULT_SHADOW_STRENGTH
+ internal var enableSwipeToDismiss: Boolean = false
+ internal var vibrationTargets: List = emptyList()
+
+ internal var title: String? = null
+ internal var titleSpanned: Spanned? = null
+ internal var titleTypeface: Typeface? = null
+ internal var titleSizeInPx: Float? = null
+ internal var titleSizeInSp: Float? = null
+ internal var titleColor: Int? = null
+ internal var titleAppearance: Int? = null
+
+ internal var message: String? = null
+ internal var messageSpanned: Spanned? = null
+ internal var messageTypeface: Typeface? = null
+ internal var messageSizeInPx: Float? = null
+ internal var messageSizeInSp: Float? = null
+ internal var messageColor: Int? = null
+ internal var messageAppearance: Int? = null
+
+ internal var primaryActionText: String? = null
+ internal var primaryActionTextSpanned: Spanned? = null
+ internal var primaryActionTextTypeface: Typeface? = null
+ internal var primaryActionTextSizeInPx: Float? = null
+ internal var primaryActionTextSizeInSp: Float? = null
+ internal var primaryActionTextColor: Int? = null
+ internal var primaryActionTextAppearance: Int? = null
+ internal var onPrimaryActionTapListener: OnActionTapListener? = null
+
+ internal var positiveActionText: String? = null
+ internal var positiveActionTextSpanned: Spanned? = null
+ internal var positiveActionTextTypeface: Typeface? = null
+ internal var positiveActionTextSizeInPx: Float? = null
+ internal var positiveActionTextSizeInSp: Float? = null
+ internal var positiveActionTextColor: Int? = null
+ internal var positiveActionTextAppearance: Int? = null
+ internal var onPositiveActionTapListener: OnActionTapListener? = null
+
+ internal var negativeActionText: String? = null
+ internal var negativeActionTextSpanned: Spanned? = null
+ internal var negativeActionTextTypeface: Typeface? = null
+ internal var negativeActionTextSizeInPx: Float? = null
+ internal var negativeActionTextSizeInSp: Float? = null
+ internal var negativeActionTextColor: Int? = null
+ internal var negativeActionTextAppearance: Int? = null
+ internal var onNegativeActionTapListener: OnActionTapListener? = null
+
+ internal var showIcon: Boolean = false
+ internal var iconScale: Float = DEFAUT_ICON_SCALE
+ internal var iconScaleType: ScaleType = CENTER_CROP
+ internal var iconDrawable: Drawable? = null
+ internal var iconBitmap: Bitmap? = null
+ internal var iconColorFilter: Int? = null
+ internal var iconColorFilterMode: PorterDuff.Mode? = null
+ internal var iconAnimBuilder: FlashAnimIconBuilder? = null
+
+ internal var progressPosition: ProgressPosition? = null
+ internal var progressTint: Int? = null
+
+ internal var enterAnimBuilder: FlashAnimBarBuilder? = null
+ internal var exitAnimBuilder: FlashAnimBarBuilder? = null
+
+ /**
+ * Specifies the gravity from where the flashbar will be shown (top/bottom) Default gravity is
+ * TOP
+ */
+ fun gravity(gravity: Gravity) = apply { this.gravity = gravity }
+
+ /** Specifies the background drawable of the flashbar */
+ fun backgroundDrawable(drawable: Drawable) = apply { this.backgroundDrawable = drawable }
+
+ /** Specifies the background drawable resource of the flashbar */
+ fun backgroundDrawable(@DrawableRes drawableId: Int) = apply {
+ this.backgroundDrawable = ContextCompat.getDrawable(activity, drawableId)
+ }
+
+ /** Specifies the background color of the flashbar */
+ fun backgroundColor(@ColorInt color: Int) = apply { this.backgroundColor = color }
+
+ /** Specifies the background color resource of the flashbar */
+ fun backgroundColorRes(@ColorRes colorId: Int) = apply {
+ this.backgroundColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Sets listener to receive tap events on the surface of the bar */
+ fun listenBarTaps(listener: OnTapListener) = apply { this.onBarTapListener = listener }
+
+ /**
+ * Specifies the duration for which the flashbar will be visible By default, the duration is
+ * infinite
+ */
+ fun duration(milliseconds: Long) = apply {
+ require(milliseconds > 0) { "Duration can not be negative or zero" }
+ this.duration = milliseconds
+ }
+
+ /** Sets listener to receive bar showing/shown events */
+ fun barShowListener(listener: OnBarShowListener) = apply { this.onBarShowListener = listener }
+
+ /** Sets listener to receive bar dismissing/dismissed events */
+ fun barDismissListener(listener: OnBarDismissListener) = apply {
+ this.onBarDismissListener = listener
+ }
+
+ /** Sets listener to receive tap events outside flashbar surface */
+ fun listenOutsideTaps(listener: OnTapListener) = apply { this.onTapOutsideListener = listener }
+
+ /** Dismisses the bar on being tapped outside */
+ fun dismissOnTapOutside() = apply { this.barDismissOnTapOutside = true }
+
+ /** Shows the modal overlay */
+ fun showOverlay() = apply { this.overlay = true }
+
+ /** Specifies modal overlay color */
+ fun overlayColor(@ColorInt color: Int) = apply { this.overlayColor = color }
+
+ /**
+ * Specifies modal overlay color resource Modal overlay is automatically shown if color is set
+ */
+ fun overlayColorRes(@ColorRes colorId: Int) = apply {
+ this.overlayColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Specifies if modal overlay is blockable and should comsume touch events */
+ fun overlayBlockable() = apply { this.overlayBlockable = true }
+
+ /** Specifies if the flashbar should cast shadow and the strength of it */
+ @JvmOverloads
+ fun castShadow(shadow: Boolean = true, strength: Int = DEFAULT_SHADOW_STRENGTH) = apply {
+ require(strength > 0) { "Shadow strength can not be negative or zero" }
+
+ this.castShadow = shadow
+ this.shadowStrength = strength
+ }
+
+ /** Specifies the enter animation of the flashbar */
+ fun enterAnimation(builder: FlashAnimBarBuilder) = apply { this.enterAnimBuilder = builder }
+
+ /** Specifies the exit animation of the flashbar */
+ fun exitAnimation(builder: FlashAnimBarBuilder) = apply { this.exitAnimBuilder = builder }
+
+ /** Enables swipe-to-dismiss for the flashbar */
+ fun enableSwipeToDismiss() = apply { this.enableSwipeToDismiss = true }
+
+ /** Specifies whether the device should vibrate during flashbar enter/exit/both */
+ fun vibrateOn(vararg vibrate: Vibration) = apply {
+ require(vibrate.isNotEmpty()) { "Vibration targets can not be empty" }
+ this.vibrationTargets = vibrate.toList()
+ }
+
+ /** Specifies the title string */
+ fun title(title: String) = apply { this.title = title }
+
+ /** Specifies the title string res */
+ fun title(@StringRes titleId: Int) = apply { this.title = activity.getString(titleId) }
+
+ /** Specifies the title span */
+ fun title(title: Spanned) = apply { this.titleSpanned = title }
+
+ /** Specifies the title typeface */
+ fun titleTypeface(typeface: Typeface) = apply { this.titleTypeface = typeface }
+
+ /** Specifies the title size (in pixels) */
+ fun titleSizeInPx(size: Float) = apply { this.titleSizeInPx = size }
+
+ /** Specifies the title size (in sp) */
+ fun titleSizeInSp(size: Float) = apply { this.titleSizeInSp = size }
+
+ /** Specifies the title color */
+ fun titleColor(@ColorInt color: Int) = apply { this.titleColor = color }
+
+ /** Specifies the title color resource */
+ fun titleColorRes(@ColorRes colorId: Int) = apply {
+ this.titleColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Specifies the title appearance */
+ fun titleAppearance(@StyleRes appearance: Int) = apply { this.titleAppearance = appearance }
+
+ /** Specifies the message string */
+ fun message(message: String) = apply { this.message = message }
+
+ /** Specifies the message string resource */
+ fun message(@StringRes messageId: Int) = apply { this.message = activity.getString(messageId) }
+
+ /** Specifies the message string span */
+ fun message(message: Spanned) = apply { this.messageSpanned = message }
+
+ /** Specifies the message typeface */
+ fun messageTypeface(typeface: Typeface) = apply { this.messageTypeface = typeface }
+
+ /** Specifies the message size (in pixels) */
+ fun messageSizeInPx(size: Float) = apply { this.messageSizeInPx = size }
+
+ /** Specifies the message size (in sp) */
+ fun messageSizeInSp(size: Float) = apply { this.messageSizeInSp = size }
+
+ /** Specifies the message color */
+ fun messageColor(@ColorInt color: Int) = apply { this.messageColor = color }
+
+ /** Specifies the message color resource */
+ fun messageColorRes(@ColorRes colorId: Int) = apply {
+ this.messageColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Specifies the message appearance */
+ fun messageAppearance(@StyleRes appearance: Int) = apply { this.messageAppearance = appearance }
+
+ /** Specifies the primary action text string */
+ fun primaryActionText(text: String) = apply {
+ require(progressPosition != RIGHT) { "Cannot show action button if right progress is set" }
+ this.primaryActionText = text
+ }
+
+ /** Specifies the primary action text string resource */
+ fun primaryActionText(@StringRes actionTextId: Int) = apply {
+ primaryActionText(activity.getString(actionTextId))
+ }
+
+ /** Specifies the primary action text string span */
+ fun primaryActionText(actionText: Spanned) = apply {
+ this.primaryActionTextSpanned = actionText
+ }
+
+ /** Specifies the primary action text typeface */
+ fun primaryActionTextTypeface(typeface: Typeface) = apply {
+ this.primaryActionTextTypeface = typeface
+ }
+
+ /** Specifies the primary action text size (in pixels) */
+ fun primaryActionTextSizeInPx(size: Float) = apply { this.primaryActionTextSizeInPx = size }
+
+ /** Specifies the primary action text size (in sp) */
+ fun primaryActionTextSizeInSp(size: Float) = apply { this.primaryActionTextSizeInSp = size }
+
+ /** Specifies the primary action text color */
+ fun primaryActionTextColor(@ColorInt color: Int) = apply { this.primaryActionTextColor = color }
+
+ /** Specifies the primary action text color resource */
+ fun primaryActionTextColorRes(@ColorRes colorId: Int) = apply {
+ this.primaryActionTextColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Specifies the primary action text appearance */
+ fun primaryActionTextAppearance(@StyleRes appearance: Int) = apply {
+ this.primaryActionTextAppearance = appearance
+ }
+
+ /** Sets listener to receive tap events on the primary action */
+ fun primaryActionTapListener(onActionTapListener: OnActionTapListener) = apply {
+ this.onPrimaryActionTapListener = onActionTapListener
+ }
+
+ /** Specifies the positive action text string */
+ fun positiveActionText(text: String) = apply { this.positiveActionText = text }
+
+ /** Specifies the positive action text string resource */
+ fun positiveActionText(@StringRes actionTextId: Int) = apply {
+ positiveActionText(activity.getString(actionTextId))
+ }
+
+ /** Specifies the positive action text string span */
+ fun positiveActionText(actionText: Spanned) = apply {
+ this.positiveActionTextSpanned = actionText
+ }
+
+ /** Specifies the positive action text typeface */
+ fun positiveActionTextTypeface(typeface: Typeface) = apply {
+ this.positiveActionTextTypeface = typeface
+ }
+
+ /** Specifies the positive action text size (in pixels) */
+ fun positiveActionTextSizeInPx(size: Float) = apply { this.positiveActionTextSizeInPx = size }
+
+ /** Specifies the positive action text size (in sp) */
+ fun positiveActionTextSizeInSp(size: Float) = apply { this.positiveActionTextSizeInSp = size }
+
+ /** Specifies the positive action text color */
+ fun positiveActionTextColor(@ColorInt color: Int) = apply {
+ this.positiveActionTextColor = color
+ }
+
+ /** Specifies the positive action text color resource */
+ fun positiveActionTextColorRes(@ColorRes colorId: Int) = apply {
+ this.positiveActionTextColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Specifies the positive action text appearance */
+ fun positiveActionTextAppearance(@StyleRes appearance: Int) = apply {
+ this.positiveActionTextAppearance = appearance
+ }
+
+ /** Sets listener to receive tap events on the positive action */
+ fun positiveActionTapListener(onActionTapListener: OnActionTapListener) = apply {
+ this.onPositiveActionTapListener = onActionTapListener
+ }
+
+ /** Specifies the negative action text string */
+ fun negativeActionText(text: String) = apply { this.negativeActionText = text }
+
+ /** Specifies the negative action text string resource */
+ fun negativeActionText(@StringRes actionTextId: Int) = apply {
+ negativeActionText(activity.getString(actionTextId))
+ }
+
+ /** Specifies the negative action text string span */
+ fun negativeActionText(actionText: Spanned) = apply {
+ this.negativeActionTextSpanned = actionText
+ }
+
+ /** Specifies the negative action text typeface */
+ fun negativeActionTextTypeface(typeface: Typeface) = apply {
+ this.negativeActionTextTypeface = typeface
+ }
+
+ /** Specifies the negative action text size (in pixels) */
+ fun negativeActionTextSizeInPx(size: Float) = apply { this.negativeActionTextSizeInPx = size }
+
+ /** Specifies the negative action text size (in sp) */
+ fun negativeActionTextSizeInSp(size: Float) = apply { this.negativeActionTextSizeInSp = size }
+
+ /** Specifies the negative action text color */
+ fun negativeActionTextColor(@ColorInt color: Int) = apply {
+ this.negativeActionTextColor = color
+ }
+
+ /** Specifies the negative action text color resource */
+ fun negativeActionTextColorRes(@ColorRes colorId: Int) = apply {
+ this.negativeActionTextColor = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Specifies the negative action text appearance */
+ fun negativeActionTextAppearance(@StyleRes appearance: Int) = apply {
+ this.negativeActionTextAppearance = appearance
+ }
+
+ /** Sets listener to receive tap events on the negative action */
+ fun negativeActionTapListener(onActionTapListener: OnActionTapListener) = apply {
+ this.onNegativeActionTapListener = onActionTapListener
+ }
+
+ /** Specifies if the icon should be shown. Also configures its scale factor and scale type */
+ @JvmOverloads
+ fun showIcon(scale: Float = DEFAUT_ICON_SCALE, scaleType: ScaleType = CENTER_CROP) = apply {
+ require(progressPosition != LEFT) { "Cannot show icon if left progress is set" }
+ require(scale > 0) { "Icon scale cannot be negative or zero" }
+
+ this.showIcon = true
+ this.iconScale = scale
+ this.iconScaleType = scaleType
+ }
+
+ /** Specifies the icon drawable */
+ fun icon(icon: Drawable) = apply { this.iconDrawable = icon }
+
+ /** Specifies the icon drawable resource */
+ fun icon(@DrawableRes iconId: Int) = apply {
+ this.iconDrawable = ContextCompat.getDrawable(activity, iconId)
+ }
+
+ /** Specifies the icon bitmap */
+ fun icon(bitmap: Bitmap) = apply { this.iconBitmap = bitmap }
+
+ /** Specifies the icon color filter and mode */
+ @JvmOverloads
+ fun iconColorFilter(@ColorInt color: Int, mode: PorterDuff.Mode? = null) = apply {
+ this.iconColorFilter = color
+ this.iconColorFilterMode = mode
+ }
+
+ /** Specifies the icon color filter resource and mode */
+ @JvmOverloads
+ fun iconColorFilterRes(@ColorRes colorId: Int, mode: PorterDuff.Mode? = null) = apply {
+ this.iconColorFilter = ContextCompat.getColor(activity, colorId)
+ this.iconColorFilterMode = mode
+ }
+
+ /** Specifies the icon builder */
+ fun iconAnimation(builder: FlashAnimIconBuilder) = apply { this.iconAnimBuilder = builder }
+
+ /** Specifies the gravity in which the indeterminate progress is shown (left/right) */
+ fun showProgress(position: ProgressPosition) = apply {
+ this.progressPosition = position
+
+ if (progressPosition == LEFT && showIcon) {
+ throw IllegalArgumentException("Cannot show progress at left if icon is already set")
+ }
+
+ if (progressPosition == RIGHT && primaryActionText != null) {
+ throw IllegalArgumentException(
+ "Cannot show progress at right if action button is already set"
+ )
+ }
+ }
+
+ /** Specifies the indeterminate progress tint */
+ fun progressTint(@ColorInt color: Int) = apply { this.progressTint = color }
+
+ /** Specifies the indeterminate progress tint resource */
+ fun progressTintRes(@ColorRes colorId: Int) = apply {
+ this.progressTint = ContextCompat.getColor(activity, colorId)
+ }
+
+ /** Builds a flashbar instance */
+ fun build(): Flashbar {
+ configureAnimation()
+ val flashbar = Flashbar(this)
+ flashbar.construct()
+ return flashbar
+ }
+
+ /** Shows the flashbar */
+ fun show() = build().show()
+
+ private fun configureAnimation() {
+ enterAnimBuilder =
+ if (enterAnimBuilder == null) {
+ when (gravity) {
+ TOP -> FlashAnim.with(activity).animateBar().enter().fromTop()
+ BOTTOM -> FlashAnim.with(activity).animateBar().enter().fromBottom()
+ }
+ } else {
+ when (gravity) {
+ TOP -> enterAnimBuilder!!.enter().fromTop()
+ BOTTOM -> enterAnimBuilder!!.enter().fromBottom()
+ }
+ }
+
+ exitAnimBuilder =
+ if (exitAnimBuilder == null) {
+ when (gravity) {
+ TOP -> FlashAnim.with(activity).animateBar().exit().fromTop()
+ BOTTOM -> FlashAnim.with(activity).animateBar().exit().fromBottom()
+ }
+ } else {
+ when (gravity) {
+ TOP -> exitAnimBuilder!!.exit().fromTop()
+ BOTTOM -> exitAnimBuilder!!.exit().fromBottom()
+ }
+ }
+ }
+ }
+
+ companion object {
+ const val DURATION_SHORT = 1000L
+ const val DURATION_LONG = 2500L
+ const val DURATION_INDEFINITE = -1L
+ }
+
+ enum class Gravity {
+ TOP,
+ BOTTOM
+ }
+
+ enum class DismissEvent {
+ TIMEOUT,
+ MANUAL,
+ TAP_OUTSIDE,
+ SWIPE
+ }
+
+ enum class Vibration {
+ SHOW,
+ DISMISS
+ }
+
+ enum class ProgressPosition {
+ LEFT,
+ RIGHT
+ }
+
+ interface OnActionTapListener {
+ fun onActionTapped(bar: Flashbar)
+ }
+
+ interface OnBarDismissListener {
+ fun onDismissing(bar: Flashbar, isSwiped: Boolean)
+ fun onDismissProgress(bar: Flashbar, progress: Float)
+ fun onDismissed(bar: Flashbar, event: DismissEvent)
+ }
+
+ interface OnTapListener {
+ fun onTap(flashbar: Flashbar)
+ }
+
+ interface OnBarShowListener {
+ fun onShowing(bar: Flashbar)
+ fun onShowProgress(bar: Flashbar, progress: Float)
+ fun onShown(bar: Flashbar)
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/FlashbarContainerView.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/FlashbarContainerView.kt
new file mode 100644
index 0000000000..1827280864
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/FlashbarContainerView.kt
@@ -0,0 +1,298 @@
+/*
+ * 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.androidide.flashbar
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.Rect
+import android.view.HapticFeedbackConstants.VIRTUAL_KEY
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.widget.RelativeLayout
+import com.itsaky.androidide.flashbar.Flashbar.Companion.DURATION_INDEFINITE
+import com.itsaky.androidide.flashbar.Flashbar.DismissEvent
+import com.itsaky.androidide.flashbar.Flashbar.DismissEvent.*
+import com.itsaky.androidide.flashbar.Flashbar.Vibration.DISMISS
+import com.itsaky.androidide.flashbar.SwipeDismissTouchListener.DismissCallbacks
+import com.itsaky.androidide.flashbar.anim.FlashAnim
+import com.itsaky.androidide.flashbar.Flashbar.OnBarDismissListener
+import com.itsaky.androidide.flashbar.Flashbar.OnBarShowListener
+import com.itsaky.androidide.flashbar.Flashbar.OnTapListener
+import com.itsaky.androidide.flashbar.Flashbar.Vibration
+import com.itsaky.androidide.flashbar.Flashbar.Vibration.SHOW
+import com.itsaky.androidide.flashbar.anim.FlashAnimBarBuilder
+import com.itsaky.androidide.flashbar.anim.FlashAnimIconBuilder
+import com.itsaky.androidide.flashbar.util.NavigationBarPosition.*
+import com.itsaky.androidide.flashbar.util.afterMeasured
+import com.itsaky.androidide.flashbar.util.getNavigationBarPosition
+import com.itsaky.androidide.flashbar.util.getNavigationBarSizeInPx
+import com.itsaky.androidide.flashbar.util.getRootView
+
+/**
+ * Container withView matching the height and width of the parent to hold a FlashbarView.
+ * It will occupy the entire screens size but will be completely transparent. The
+ * FlashbarView inside is the only visible component in it.
+ */
+internal class FlashbarContainerView(context: Context)
+ : RelativeLayout(context), DismissCallbacks {
+
+ private val dismissRunnable = Runnable { dismissInternal(TIMEOUT) }
+
+ internal lateinit var parentFlashbar: Flashbar
+
+ private lateinit var flashbarView: FlashbarView
+
+ private lateinit var enterAnimBuilder: FlashAnimBarBuilder
+ private lateinit var exitAnimBuilder: FlashAnimBarBuilder
+ private lateinit var vibrationTargets: List
+
+ private var onBarShowListener: OnBarShowListener? = null
+ private var onBarDismissListener: OnBarDismissListener? = null
+ private var onTapOutsideListener: OnTapListener? = null
+ private var overlayColor: Int? = null
+ private var iconAnimBuilder: FlashAnimIconBuilder? = null
+
+ private var duration = DURATION_INDEFINITE
+ private var isBarShowing = false
+ private var isBarShown = false
+ private var isBarDismissing = false
+ private var barDismissOnTapOutside: Boolean = false
+ private var showOverlay: Boolean = false
+ private var overlayBlockable: Boolean = false
+
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
+ when (event.action) {
+ ACTION_DOWN -> {
+ val rect = Rect()
+ flashbarView.getHitRect(rect)
+
+ // Checks if the tap was outside the bar
+ if (!rect.contains(event.x.toInt(), event.y.toInt())) {
+ onTapOutsideListener?.onTap(parentFlashbar)
+
+ if (barDismissOnTapOutside) {
+ dismissInternal(TAP_OUTSIDE)
+ }
+ }
+ }
+ }
+ return super.onInterceptTouchEvent(event)
+ }
+
+ override fun onSwipe(isSwiping: Boolean) {
+ isBarDismissing = isSwiping
+ if (isSwiping) {
+ onBarDismissListener?.onDismissing(parentFlashbar, true)
+ }
+ }
+
+ override fun onDismiss(view: View) {
+ removeCallbacks(dismissRunnable)
+
+ (parent as? ViewGroup)?.removeView(this@FlashbarContainerView)
+ isBarShown = false
+
+ flashbarView.stopIconAnimation()
+
+ if (vibrationTargets.contains(DISMISS)) {
+ performHapticFeedback(VIRTUAL_KEY)
+ }
+
+ onBarDismissListener?.onDismissed(parentFlashbar, SWIPE)
+ }
+
+ internal fun attach(flashbarView: FlashbarView) {
+ this.flashbarView = flashbarView
+ }
+
+ internal fun construct() {
+ isHapticFeedbackEnabled = true
+
+ if (showOverlay) {
+ setBackgroundColor(overlayColor!!)
+
+ if (overlayBlockable) {
+ isClickable = true
+ isFocusable = true
+ }
+ }
+
+ addView(flashbarView)
+ }
+
+ internal fun addParent(flashbar: Flashbar) {
+ this.parentFlashbar = flashbar
+ }
+
+ internal fun adjustOrientation(activity: Activity) {
+ val flashbarContainerViewLp = LayoutParams(MATCH_PARENT, MATCH_PARENT)
+
+ val navigationBarPosition = activity.getNavigationBarPosition()
+ val navigationBarSize = activity.getNavigationBarSizeInPx()
+
+ when (navigationBarPosition) {
+ LEFT -> flashbarContainerViewLp.leftMargin = navigationBarSize
+ TOP -> flashbarContainerViewLp.topMargin = navigationBarSize
+ RIGHT -> flashbarContainerViewLp.rightMargin = navigationBarSize
+ BOTTOM -> flashbarContainerViewLp.bottomMargin = navigationBarSize
+ }
+
+ layoutParams = flashbarContainerViewLp
+ }
+
+
+ internal fun show(activity: Activity) {
+ if (isBarShowing || isBarShown) return
+
+ val activityRootView = activity.getRootView() ?: return
+
+ // Only add the withView to the parent once
+ if (this.parent == null) activityRootView.addView(this)
+
+ activityRootView.afterMeasured {
+ val enterAnim = enterAnimBuilder.withView(flashbarView).build()
+ enterAnim.start(object : FlashAnim.InternalAnimListener {
+ override fun onStart() {
+ isBarShowing = true
+ onBarShowListener?.onShowing(parentFlashbar)
+ }
+
+ override fun onUpdate(progress: Float) {
+ onBarShowListener?.onShowProgress(parentFlashbar, progress)
+ }
+
+ override fun onStop() {
+ isBarShowing = false
+ isBarShown = true
+
+ flashbarView.startIconAnimation(iconAnimBuilder)
+
+ if (vibrationTargets.contains(SHOW)) {
+ performHapticFeedback(VIRTUAL_KEY)
+ }
+
+ onBarShowListener?.onShown(parentFlashbar)
+ }
+ })
+
+ handleDismiss()
+ }
+ }
+
+ internal fun dismiss() {
+ dismissInternal(MANUAL)
+ }
+
+ internal fun isBarShowing() = isBarShowing
+
+ internal fun isBarShown() = isBarShown
+
+ internal fun setDuration(duration: Long) {
+ this.duration = duration
+ }
+
+ internal fun setBarShowListener(listener: OnBarShowListener?) {
+ this.onBarShowListener = listener
+ }
+
+ internal fun setBarDismissListener(listener: OnBarDismissListener?) {
+ this.onBarDismissListener = listener
+ }
+
+ internal fun setBarDismissOnTapOutside(dismiss: Boolean) {
+ this.barDismissOnTapOutside = dismiss
+ }
+
+ internal fun setOnTapOutsideListener(listener: OnTapListener?) {
+ this.onTapOutsideListener = listener
+ }
+
+ internal fun setOverlay(overlay: Boolean) {
+ this.showOverlay = overlay
+ }
+
+ internal fun setOverlayColor(color: Int) {
+ this.overlayColor = color
+ }
+
+ internal fun setOverlayBlockable(blockable: Boolean) {
+ this.overlayBlockable = blockable
+ }
+
+ internal fun setEnterAnim(builder: FlashAnimBarBuilder) {
+ this.enterAnimBuilder = builder
+ }
+
+ internal fun setExitAnim(builder: FlashAnimBarBuilder) {
+ this.exitAnimBuilder = builder
+ }
+
+ internal fun enableSwipeToDismiss(enable: Boolean) {
+ this.flashbarView.enableSwipeToDismiss(enable, this)
+ }
+
+ internal fun setVibrationTargets(targets: List) {
+ this.vibrationTargets = targets
+ }
+
+ internal fun setIconAnim(builder: FlashAnimIconBuilder?) {
+ this.iconAnimBuilder = builder
+ }
+
+ private fun handleDismiss() {
+ if (duration != DURATION_INDEFINITE) {
+ postDelayed(dismissRunnable, duration)
+ }
+ }
+
+ private fun dismissInternal(event: DismissEvent) {
+ if (isBarDismissing || isBarShowing || !isBarShown) {
+ return
+ }
+
+ removeCallbacks(dismissRunnable)
+
+ val exitAnim = exitAnimBuilder.withView(flashbarView).build()
+ exitAnim.start(object : FlashAnim.InternalAnimListener {
+ override fun onStart() {
+ isBarDismissing = true
+ onBarDismissListener?.onDismissing(parentFlashbar, false)
+ }
+
+ override fun onUpdate(progress: Float) {
+ onBarDismissListener?.onDismissProgress(parentFlashbar, progress)
+ }
+
+ override fun onStop() {
+ isBarDismissing = false
+ isBarShown = false
+
+ if (vibrationTargets.contains(DISMISS)) {
+ performHapticFeedback(VIRTUAL_KEY)
+ }
+
+ onBarDismissListener?.onDismissed(parentFlashbar, event)
+
+ post { (parent as? ViewGroup)?.removeView(this@FlashbarContainerView) }
+ }
+ })
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/FlashbarView.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/FlashbarView.kt
new file mode 100644
index 0000000000..fc1fe86b3d
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/FlashbarView.kt
@@ -0,0 +1,484 @@
+/*
+ * 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.androidide.flashbar
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.PorterDuff
+import android.graphics.Typeface
+import android.graphics.drawable.Drawable
+import android.text.Spanned
+import android.text.TextUtils
+import android.util.TypedValue
+import android.view.LayoutInflater
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM
+import android.widget.RelativeLayout.ALIGN_PARENT_TOP
+import android.widget.TextView
+import androidx.annotation.ColorInt
+import com.itsaky.androidide.flashbar.Flashbar.Gravity
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.BOTTOM
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.TOP
+import com.itsaky.androidide.flashbar.Flashbar.OnActionTapListener
+import com.itsaky.androidide.flashbar.Flashbar.OnTapListener
+import com.itsaky.androidide.flashbar.Flashbar.ProgressPosition
+import com.itsaky.androidide.flashbar.Flashbar.ProgressPosition.LEFT
+import com.itsaky.androidide.flashbar.Flashbar.ProgressPosition.RIGHT
+import com.itsaky.androidide.flashbar.SwipeDismissTouchListener.DismissCallbacks
+import com.itsaky.androidide.flashbar.anim.FlashAnimIconBuilder
+import com.itsaky.androidide.flashbar.databinding.FlashBarViewBinding
+import com.itsaky.androidide.flashbar.util.convertDpToPx
+import com.itsaky.androidide.flashbar.util.getStatusBarHeightInPx
+import com.itsaky.androidide.flashbar.view.FbButton
+import com.itsaky.androidide.flashbar.view.FbProgress
+import com.itsaky.androidide.flashbar.view.ShadowView
+
+/**
+ * The actual Flashbar withView representation that can consist of the title, message, button, icon,
+ * etc. Its size is adaptive and depends solely on the amount of content present in it. It always
+ * matches the width of the screen.
+ *
+ * It can either be present at the top or at the bottom of the screen. It will always consume touch
+ * events and respond as necessary.
+ */
+internal class FlashbarView(context: Context) : LinearLayout(context) {
+
+ private val compensationMarginTop =
+ resources.getDimension(R.dimen.fb_top_compensation_margin).toInt()
+ private val compensationMarginBottom =
+ resources.getDimension(R.dimen.fb_bottom_compensation_margin).toInt()
+
+ private lateinit var binding: FlashBarViewBinding
+ private lateinit var parentFlashbarContainer: FlashbarContainerView
+ private lateinit var gravity: Gravity
+
+ private var isMarginCompensationApplied: Boolean = false
+
+ private val fbContent: LinearLayout
+ get() = this.binding.fbContent
+
+ private val fbRoot: LinearLayout
+ get() = this.binding.fbRoot
+
+ private val fbIcon: ImageView
+ get() = this.binding.fbIcon
+
+ private val fbLeftProgress: FbProgress
+ get() = this.binding.fbLeftProgress
+
+ private val fbRightProgress: FbProgress
+ get() = this.binding.fbRightProgress
+
+ private val fbMessage: TextView
+ get() = this.binding.fbMessage
+
+ private val fbPrimaryAction: FbButton
+ get() = this.binding.fbPrimaryAction
+
+ private val fbPositiveAction: FbButton
+ get() = this.binding.fbPositiveAction
+
+ private val fbNegativeAction: FbButton
+ get() = this.binding.fbNegativeAction
+
+ private val fbSecondaryActionContainer: LinearLayout
+ get() = this.binding.fbSecondaryActionContainer
+
+ private val fbTitle: TextView
+ get() = this.binding.fbTitle
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+
+ if (!isMarginCompensationApplied) {
+ isMarginCompensationApplied = true
+
+ val params = layoutParams as MarginLayoutParams
+ when (gravity) {
+ TOP -> params.topMargin = -compensationMarginTop
+ BOTTOM -> params.bottomMargin = -compensationMarginBottom
+ }
+ requestLayout()
+ }
+ }
+
+ internal fun init(gravity: Gravity, castShadow: Boolean, shadowStrength: Int) {
+ this.gravity = gravity
+ this.orientation = VERTICAL
+
+ // If the bar appears with the bottom, then the shadow needs to added to the top of it,
+ // Thus, before the inflation of the bar
+ if (castShadow && gravity == BOTTOM) {
+ castShadow(ShadowView.ShadowType.TOP, shadowStrength)
+ }
+
+ this.binding = FlashBarViewBinding.inflate(LayoutInflater.from(context), this, true)
+
+ // If the bar appears with the top, then the shadow needs to added to the bottom of it,
+ // Thus, after the inflation of the bar
+ if (castShadow && gravity == TOP) {
+ castShadow(ShadowView.ShadowType.BOTTOM, shadowStrength)
+ }
+ }
+
+ internal fun adjustWitPositionAndOrientation(activity: Activity, gravity: Gravity) {
+ val flashbarViewLp = RelativeLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
+ val statusBarHeight = activity.getStatusBarHeightInPx()
+
+ val flashbarViewContentLp = fbContent.layoutParams as LayoutParams
+
+ when (gravity) {
+ TOP -> {
+ flashbarViewContentLp.topMargin = statusBarHeight.plus(compensationMarginTop / 2)
+ flashbarViewLp.addRule(ALIGN_PARENT_TOP)
+ }
+ BOTTOM -> {
+ flashbarViewContentLp.bottomMargin = compensationMarginBottom
+ flashbarViewLp.addRule(ALIGN_PARENT_BOTTOM)
+ }
+ }
+ fbContent.layoutParams = flashbarViewContentLp
+ layoutParams = flashbarViewLp
+ }
+
+ internal fun addParent(flashbarContainerView: FlashbarContainerView) {
+ this.parentFlashbarContainer = flashbarContainerView
+ }
+
+ internal fun setBarBackgroundDrawable(drawable: Drawable?) {
+ if (drawable == null) return
+ this.fbRoot.background = drawable
+ }
+
+ internal fun setBarBackgroundColor(@ColorInt color: Int?) {
+ if (color == null) return
+ this.fbRoot.setBackgroundColor(color)
+ }
+
+ internal fun setBarTapListener(listener: OnTapListener?) {
+ if (listener == null) return
+
+ this.fbRoot.setOnClickListener { listener.onTap(parentFlashbarContainer.parentFlashbar) }
+ }
+
+ internal fun setTitle(title: String?) {
+ if (TextUtils.isEmpty(title)) return
+
+ this.fbTitle.text = title
+ this.fbTitle.visibility = VISIBLE
+ }
+
+ internal fun setTitleSpanned(title: Spanned?) {
+ if (title == null) return
+
+ this.fbTitle.text = title
+ this.fbTitle.visibility = VISIBLE
+ }
+
+ internal fun setTitleTypeface(typeface: Typeface?) {
+ if (typeface == null) return
+ fbTitle.typeface = typeface
+ }
+
+ internal fun setTitleSizeInPx(size: Float?) {
+ if (size == null) return
+ fbTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
+ }
+
+ internal fun setTitleSizeInSp(size: Float?) {
+ if (size == null) return
+ fbTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
+ }
+
+ internal fun setTitleColor(color: Int?) {
+ if (color == null) return
+ fbTitle.setTextColor(color)
+ }
+
+ internal fun setTitleAppearance(titleAppearance: Int?) {
+ if (titleAppearance == null) return
+ this.fbTitle.setTextAppearance(titleAppearance)
+ }
+
+ internal fun setMessage(message: String?) {
+ if (TextUtils.isEmpty(message)) return
+
+ this.fbMessage.text = message
+ this.fbMessage.visibility = VISIBLE
+ }
+
+ internal fun setMessageSpanned(message: Spanned?) {
+ if (message == null) return
+
+ this.fbMessage.text = message
+ this.fbMessage.visibility = VISIBLE
+ }
+
+ internal fun setMessageTypeface(typeface: Typeface?) {
+ if (typeface == null) return
+ this.fbMessage.typeface = typeface
+ }
+
+ internal fun setMessageSizeInPx(size: Float?) {
+ if (size == null) return
+ this.fbMessage.setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
+ }
+
+ internal fun setMessageSizeInSp(size: Float?) {
+ if (size == null) return
+ this.fbMessage.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
+ }
+
+ internal fun setMessageColor(color: Int?) {
+ if (color == null) return
+ this.fbMessage.setTextColor(color)
+ }
+
+ internal fun setMessageAppearance(messageAppearance: Int?) {
+ if (messageAppearance == null) return
+ this.fbMessage.setTextAppearance(messageAppearance)
+ }
+
+ internal fun setPrimaryActionText(text: String?) {
+ if (TextUtils.isEmpty(text)) return
+
+ this.fbPrimaryAction.text = text
+ this.fbPrimaryAction.visibility = VISIBLE
+ }
+
+ internal fun setPrimaryActionTextSpanned(text: Spanned?) {
+ if (text == null) return
+
+ this.fbPrimaryAction.text = text
+ this.fbPrimaryAction.visibility = VISIBLE
+ }
+
+ internal fun setPrimaryActionTextTypeface(typeface: Typeface?) {
+ if (typeface == null) return
+ this.fbPrimaryAction.typeface = typeface
+ }
+
+ internal fun setPrimaryActionTextSizeInPx(size: Float?) {
+ if (size == null) return
+ this.fbPrimaryAction.setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
+ }
+
+ internal fun setPrimaryActionTextSizeInSp(size: Float?) {
+ if (size == null) return
+ this.fbPrimaryAction.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
+ }
+
+ internal fun setPrimaryActionTextColor(color: Int?) {
+ if (color == null) return
+ this.fbPrimaryAction.setTextColor(color)
+ }
+
+ internal fun setPrimaryActionTextAppearance(messageAppearance: Int?) {
+ if (messageAppearance == null) return
+ this.fbPrimaryAction.setTextAppearance(messageAppearance)
+ }
+
+ internal fun setPrimaryActionTapListener(listener: OnActionTapListener?) {
+ if (listener == null) return
+
+ this.fbPrimaryAction.setOnClickListener {
+ listener.onActionTapped(parentFlashbarContainer.parentFlashbar)
+ }
+ }
+
+ internal fun setPositiveActionText(text: String?) {
+ if (TextUtils.isEmpty(text)) return
+
+ this.fbSecondaryActionContainer.visibility = VISIBLE
+ this.fbPositiveAction.text = text
+ this.fbPositiveAction.visibility = VISIBLE
+ }
+
+ internal fun setPositiveActionTextSpanned(text: Spanned?) {
+ if (text == null) return
+
+ this.fbSecondaryActionContainer.visibility = VISIBLE
+ this.fbPositiveAction.text = text
+ this.fbPositiveAction.visibility = VISIBLE
+ }
+
+ internal fun setPositiveActionTextTypeface(typeface: Typeface?) {
+ if (typeface == null) return
+ this.fbPositiveAction.typeface = typeface
+ }
+
+ internal fun setPositiveActionTextSizeInPx(size: Float?) {
+ if (size == null) return
+ this.fbPositiveAction.setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
+ }
+
+ internal fun setPositiveActionTextSizeInSp(size: Float?) {
+ if (size == null) return
+ this.fbPositiveAction.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
+ }
+
+ internal fun setPositiveActionTextColor(color: Int?) {
+ if (color == null) return
+ this.fbPositiveAction.setTextColor(color)
+ }
+
+ internal fun setPositiveActionTextAppearance(messageAppearance: Int?) {
+ if (messageAppearance == null) return
+ this.fbPositiveAction.setTextAppearance(messageAppearance)
+ }
+
+ internal fun setPositiveActionTapListener(listener: OnActionTapListener?) {
+ if (listener == null) return
+
+ this.fbPositiveAction.setOnClickListener {
+ listener.onActionTapped(parentFlashbarContainer.parentFlashbar)
+ }
+ }
+
+ internal fun setNegativeActionText(text: String?) {
+ if (TextUtils.isEmpty(text)) return
+
+ this.fbSecondaryActionContainer.visibility = VISIBLE
+ this.fbNegativeAction.text = text
+ this.fbNegativeAction.visibility = VISIBLE
+ }
+
+ internal fun setNegativeActionTextSpanned(text: Spanned?) {
+ if (text == null) return
+
+ this.fbSecondaryActionContainer.visibility = VISIBLE
+ this.fbNegativeAction.text = text
+ this.fbNegativeAction.visibility = VISIBLE
+ }
+
+ internal fun setNegativeActionTextTypeface(typeface: Typeface?) {
+ if (typeface == null) return
+ this.fbNegativeAction.typeface = typeface
+ }
+
+ internal fun setNegativeActionTextSizeInPx(size: Float?) {
+ if (size == null) return
+ this.fbNegativeAction.setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
+ }
+
+ internal fun setNegativeActionTextSizeInSp(size: Float?) {
+ if (size == null) return
+ this.fbNegativeAction.setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
+ }
+
+ internal fun setNegativeActionTextColor(color: Int?) {
+ if (color == null) return
+ this.fbNegativeAction.setTextColor(color)
+ }
+
+ internal fun setNegativeActionTextAppearance(messageAppearance: Int?) {
+ if (messageAppearance == null) return
+ this.fbNegativeAction.setTextAppearance(messageAppearance)
+ }
+
+ internal fun setNegativeActionTapListener(listener: OnActionTapListener?) {
+ if (listener == null) return
+
+ this.fbNegativeAction.setOnClickListener {
+ listener.onActionTapped(parentFlashbarContainer.parentFlashbar)
+ }
+ }
+
+ internal fun showIcon(showIcon: Boolean) {
+ this.fbIcon.visibility = if (showIcon) VISIBLE else GONE
+ }
+
+ internal fun showIconScale(scale: Float, scaleType: ImageView.ScaleType?) {
+ this.fbIcon.scaleX = scale
+ this.fbIcon.scaleY = scale
+ this.fbIcon.scaleType = scaleType
+ }
+
+ internal fun setIconDrawable(icon: Drawable?) {
+ if (icon == null) return
+ this.fbIcon.setImageDrawable(icon)
+ }
+
+ internal fun setIconBitmap(bitmap: Bitmap?) {
+ if (bitmap == null) return
+ this.fbIcon.setImageBitmap(bitmap)
+ }
+
+ internal fun setIconColorFilter(colorFilter: Int?, filterMode: PorterDuff.Mode?) {
+ if (colorFilter == null) return
+ if (filterMode == null) {
+ this.fbIcon.setColorFilter(colorFilter)
+ } else {
+ this.fbIcon.setColorFilter(colorFilter, filterMode)
+ }
+ }
+
+ internal fun startIconAnimation(animator: FlashAnimIconBuilder?) {
+ animator?.withView(fbIcon)?.build()?.start()
+ }
+
+ internal fun stopIconAnimation() {
+ fbIcon.clearAnimation()
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ internal fun enableSwipeToDismiss(enable: Boolean, callbacks: DismissCallbacks) {
+ if (enable) {
+ fbRoot.setOnTouchListener(SwipeDismissTouchListener(this, callbacks))
+ }
+ }
+
+ internal fun setProgressPosition(position: ProgressPosition?) {
+ if (position == null) return
+ when (position) {
+ LEFT -> {
+ fbLeftProgress.visibility = VISIBLE
+ fbRightProgress.visibility = GONE
+ }
+ RIGHT -> {
+ fbLeftProgress.visibility = GONE
+ fbRightProgress.visibility = VISIBLE
+ }
+ }
+ }
+
+ internal fun setProgressTint(progressTint: Int?, position: ProgressPosition?) {
+ if (position == null || progressTint == null) return
+
+ val progressBar =
+ when (position) {
+ LEFT -> fbLeftProgress
+ RIGHT -> fbRightProgress
+ }
+
+ progressBar.setBarColor(progressTint)
+ }
+
+ private fun castShadow(shadowType: ShadowView.ShadowType, strength: Int) {
+ val params = RelativeLayout.LayoutParams(MATCH_PARENT, context.convertDpToPx(strength))
+ val shadow = ShadowView(context)
+ shadow.applyShadow(shadowType)
+ addView(shadow, params)
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/SwipeDismissTouchListener.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/SwipeDismissTouchListener.kt
new file mode 100644
index 0000000000..61130d315d
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/SwipeDismissTouchListener.kt
@@ -0,0 +1,200 @@
+/*
+ * 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.androidide.flashbar
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.view.MotionEvent
+import android.view.VelocityTracker
+import android.view.View
+import android.view.ViewConfiguration
+import kotlin.math.abs
+
+internal class SwipeDismissTouchListener(
+ private val view: View,
+ private val callbacks: DismissCallbacks
+) : View.OnTouchListener {
+
+ private val slop: Int
+ private val minFlingVelocity: Int
+ private val animationTime: Long
+ private var viewWidth = 1
+
+ private var downX: Float = 0.toFloat()
+ private var downY: Float = 0.toFloat()
+ private var swiping: Boolean = false
+ private var swipingSlop: Int = 0
+ private var velocityTracker: VelocityTracker? = null
+ private var translationX: Float = 0.toFloat()
+
+ init {
+ val vc = ViewConfiguration.get(view.context)
+ slop = vc.scaledTouchSlop
+ minFlingVelocity = vc.scaledMinimumFlingVelocity * 16
+ animationTime =
+ view.context.resources.getInteger(android.R.integer.config_shortAnimTime).toLong()
+ }
+
+ override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
+ motionEvent.offsetLocation(translationX, 0f)
+
+ if (viewWidth < 2) {
+ viewWidth = this.view.width
+ }
+
+ when (motionEvent.actionMasked) {
+ MotionEvent.ACTION_DOWN -> {
+ downX = motionEvent.rawX
+ downY = motionEvent.rawY
+ velocityTracker = VelocityTracker.obtain()
+ velocityTracker!!.addMovement(motionEvent)
+ return false
+ }
+ MotionEvent.ACTION_UP -> {
+ if (velocityTracker != null) {
+ val deltaX = motionEvent.rawX - downX
+ velocityTracker!!.addMovement(motionEvent)
+ velocityTracker!!.computeCurrentVelocity(1000)
+ val velocityX = velocityTracker!!.xVelocity
+ val absVelocityX = abs(velocityX)
+ val absVelocityY = abs(velocityTracker!!.yVelocity)
+ var dismiss = false
+ var dismissRight = false
+ if (abs(deltaX) > viewWidth / 2 && swiping) {
+ dismiss = true
+ dismissRight = deltaX > 0
+ } else if (minFlingVelocity <= absVelocityX && absVelocityY < absVelocityX && swiping) {
+ dismiss = velocityX < 0 == deltaX < 0
+ dismissRight = velocityTracker!!.xVelocity > 0
+ }
+ if (dismiss) {
+ this.view
+ .animate()
+ .translationX(if (dismissRight) viewWidth.toFloat() else -viewWidth.toFloat())
+ .alpha(0f)
+ .setDuration(animationTime)
+ .setListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ performDismiss()
+ }
+ }
+ )
+ } else if (swiping) {
+ this.view
+ .animate()
+ .translationX(0f)
+ .alpha(1f)
+ .setDuration(animationTime)
+ .setListener(null)
+ }
+ velocityTracker!!.recycle()
+ velocityTracker = null
+ translationX = 0f
+ downX = 0f
+ downY = 0f
+ swiping = false
+ callbacks.onSwipe(false)
+ }
+ }
+ MotionEvent.ACTION_CANCEL -> {
+ if (velocityTracker != null) {
+ this.view
+ .animate()
+ .translationX(0f)
+ .alpha(1f)
+ .setDuration(animationTime)
+ .setListener(null)
+ velocityTracker!!.recycle()
+ velocityTracker = null
+ translationX = 0f
+ downX = 0f
+ downY = 0f
+ swiping = false
+ callbacks.onSwipe(false)
+ }
+ }
+ MotionEvent.ACTION_MOVE -> {
+ if (velocityTracker != null) {
+ velocityTracker!!.addMovement(motionEvent)
+ val deltaX = motionEvent.rawX - downX
+ val deltaY = motionEvent.rawY - downY
+ if (abs(deltaX) > slop && abs(deltaY) < abs(deltaX) / 2) {
+ swiping = true
+ callbacks.onSwipe(true)
+ swipingSlop = if (deltaX > 0) slop else -slop
+ this.view.parent.requestDisallowInterceptTouchEvent(true)
+
+ val cancelEvent = MotionEvent.obtain(motionEvent)
+ cancelEvent.action =
+ MotionEvent.ACTION_CANCEL or
+ (motionEvent.actionIndex shl MotionEvent.ACTION_POINTER_INDEX_SHIFT)
+ this.view.onTouchEvent(cancelEvent)
+ cancelEvent.recycle()
+ }
+
+ if (swiping) {
+ translationX = deltaX
+ this.view.translationX = deltaX - swipingSlop
+ this.view.alpha = 0f.coerceAtLeast(1f.coerceAtMost(1f - 2f * abs(deltaX) / viewWidth))
+ return true
+ }
+ }
+ }
+ else -> {
+ view.performClick()
+ return false
+ }
+ }
+ return false
+ }
+
+ private fun performDismiss() {
+ val lp = view.layoutParams
+ val originalHeight = view.height
+
+ val animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(animationTime)
+
+ animator.addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ callbacks.onDismiss(view)
+ view.alpha = 1f
+ view.translationX = 0f
+ lp.height = originalHeight
+ view.layoutParams = lp
+ }
+ }
+ )
+
+ animator.addUpdateListener { valueAnimator ->
+ lp.height = valueAnimator.animatedValue as Int
+ view.layoutParams = lp
+ }
+
+ animator.start()
+ }
+
+ internal interface DismissCallbacks {
+
+ fun onSwipe(isSwiping: Boolean)
+
+ fun onDismiss(view: View)
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/BaseFlashAnimBuilder.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/BaseFlashAnimBuilder.kt
new file mode 100644
index 0000000000..a4ffa6423c
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/BaseFlashAnimBuilder.kt
@@ -0,0 +1,52 @@
+package com.itsaky.androidide.flashbar.anim
+
+import android.content.Context
+import android.view.View
+import android.view.animation.AccelerateDecelerateInterpolator
+import android.view.animation.AccelerateInterpolator
+import android.view.animation.AnimationUtils
+import android.view.animation.DecelerateInterpolator
+import android.view.animation.Interpolator
+import androidx.annotation.CallSuper
+import androidx.annotation.InterpolatorRes
+import com.itsaky.androidide.flashbar.R
+
+abstract class BaseFlashAnimBuilder(private val context: Context) {
+
+ private val DEFAULT_DURATION =
+ context.resources.getInteger(R.integer.default_animation_duration).toLong()
+
+ protected val DEFAULT_ALPHA_START = 0.2f
+ protected val DEFAULT_ALPHA_END = 1.0f
+
+ protected var view: View? = null
+ protected var duration = DEFAULT_DURATION
+ protected var interpolator: Interpolator? = null
+
+ protected var alpha: Boolean = false
+
+ @CallSuper
+ open fun duration(millis: Long) = apply {
+ require(duration >= 0) { "Duration must not be negative" }
+ this.duration = millis
+ }
+
+ @CallSuper open fun accelerate() = apply { this.interpolator = AccelerateInterpolator() }
+
+ @CallSuper open fun decelerate() = apply { this.interpolator = DecelerateInterpolator() }
+
+ @CallSuper
+ open fun accelerateDecelerate() = apply { this.interpolator = AccelerateDecelerateInterpolator() }
+
+ @CallSuper
+ open fun interpolator(interpolator: Interpolator) = apply { this.interpolator = interpolator }
+
+ @CallSuper
+ open fun interpolator(@InterpolatorRes id: Int) = apply {
+ this.interpolator = AnimationUtils.loadInterpolator(context, id)
+ }
+
+ @CallSuper open fun alpha() = apply { this.alpha = true }
+
+ @CallSuper internal open fun withView(view: View) = apply { this.view = view }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnim.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnim.kt
new file mode 100644
index 0000000000..337bac8b57
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnim.kt
@@ -0,0 +1,56 @@
+package com.itsaky.androidide.flashbar.anim
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.content.Context
+
+class FlashAnim(private val compositeAnim: AnimatorSet) {
+
+ companion object {
+ @JvmStatic fun with(context: Context) = FlashAnimRetriever(context)
+ }
+
+ internal fun start(listener: InternalAnimListener? = null) {
+ if (listener != null) {
+ val primaryAnim = compositeAnim.childAnimations[0] as ObjectAnimator
+
+ primaryAnim.addListener(
+ object : Animator.AnimatorListener {
+ override fun onAnimationRepeat(animator: Animator) {}
+
+ override fun onAnimationEnd(animator: Animator) {
+ listener.onStop()
+
+ primaryAnim.removeAllListeners()
+ primaryAnim.removeAllUpdateListeners()
+ }
+
+ override fun onAnimationCancel(animator: Animator) {}
+
+ override fun onAnimationStart(animator: Animator) {
+ listener.onStart()
+ }
+ }
+ )
+
+ primaryAnim.addUpdateListener { listener.onUpdate(it.animatedFraction) }
+ }
+
+ compositeAnim.start()
+ }
+
+ internal interface InternalAnimListener {
+ fun onStart()
+ fun onUpdate(progress: Float)
+ fun onStop()
+ }
+}
+
+class FlashAnimRetriever(private val context: Context) {
+ /** Retrieves the builder for animating flashbar */
+ fun animateBar() = FlashAnimBarBuilder(context)
+
+ /** Retrieves the builder for animating the icon in the flashbar */
+ fun animateIcon() = FlashAnimIconBuilder(context)
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnimBarBuilder.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnimBarBuilder.kt
new file mode 100644
index 0000000000..7b8a716246
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnimBarBuilder.kt
@@ -0,0 +1,140 @@
+package com.itsaky.androidide.flashbar.anim
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.content.Context
+import android.view.View
+import android.view.animation.AnticipateInterpolator
+import android.view.animation.Interpolator
+import android.view.animation.OvershootInterpolator
+import androidx.annotation.InterpolatorRes
+import com.itsaky.androidide.flashbar.Flashbar
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.BOTTOM
+import com.itsaky.androidide.flashbar.Flashbar.Gravity.TOP
+import com.itsaky.androidide.flashbar.anim.FlashAnimBarBuilder.Direction.LEFT
+import com.itsaky.androidide.flashbar.anim.FlashAnimBarBuilder.Direction.RIGHT
+import com.itsaky.androidide.flashbar.anim.FlashAnimBarBuilder.Type.ENTER
+import com.itsaky.androidide.flashbar.anim.FlashAnimBarBuilder.Type.EXIT
+
+class FlashAnimBarBuilder(context: Context) : BaseFlashAnimBuilder(context) {
+
+ private var type: Type? = null
+ private var gravity: Flashbar.Gravity? = null
+ private var direction: Direction? = null
+
+ /** Specifies the duration (in millis) for the animation */
+ override fun duration(millis: Long) = apply { super.duration(millis) }
+
+ /** Specifies accelerate interpolator for the animation */
+ override fun accelerate() = apply { super.accelerate() }
+
+ /** Specifies decelerate interpolator for the animation */
+ override fun decelerate() = apply { super.decelerate() }
+
+ /** Specifies accelerate-decelerate interpolator for the animation */
+ override fun accelerateDecelerate() = apply { super.accelerateDecelerate() }
+
+ /** Specifies custom interpolator for the animation */
+ override fun interpolator(interpolator: Interpolator) = apply { super.interpolator(interpolator) }
+
+ /** Specifies custom interpolator resource for the animation */
+ override fun interpolator(@InterpolatorRes id: Int) = apply { super.interpolator(id) }
+
+ /** Specifies that the animation should have alpha effect */
+ override fun alpha() = apply { super.alpha() }
+
+ /** Specifies that the bar should slide to/from the left */
+ fun slideFromLeft() = apply { this.direction = LEFT }
+
+ /** Specifies that the bar should slide to/from the right */
+ fun slideFromRight() = apply { this.direction = RIGHT }
+
+ /** Specifies overshoot interpolator for the animation */
+ fun overshoot() = apply { this.interpolator = OvershootInterpolator() }
+
+ /** Specifies overshoot-anticipate interpolator for the animation */
+ fun anticipateOvershoot() = apply { this.interpolator = AnticipateInterpolator() }
+
+ override fun withView(view: View) = apply { super.withView(view) }
+
+ internal fun enter() = apply { this.type = ENTER }
+
+ internal fun exit() = apply { this.type = EXIT }
+
+ internal fun fromTop() = apply { this.gravity = TOP }
+
+ internal fun fromBottom() = apply { this.gravity = BOTTOM }
+
+ internal fun build(): FlashAnim {
+ requireNotNull(view, { "Target view can not be null" })
+
+ val compositeAnim = AnimatorSet()
+ val animators = linkedSetOf()
+
+ val translationAnim = ObjectAnimator()
+ // Slide from left/right animation is not specified, default top/bottom
+ // animation is applied
+ if (direction == null) {
+ translationAnim.setPropertyName("translationY")
+
+ when (type!!) {
+ ENTER ->
+ when (gravity!!) {
+ TOP -> translationAnim.setFloatValues(-view!!.height.toFloat(), 0f)
+ BOTTOM -> translationAnim.setFloatValues(view!!.height.toFloat(), 0f)
+ }
+ EXIT ->
+ when (gravity!!) {
+ TOP -> translationAnim.setFloatValues(0f, -view!!.height.toFloat())
+ BOTTOM -> translationAnim.setFloatValues(0f, view!!.height.toFloat())
+ }
+ }
+ } else {
+ translationAnim.setPropertyName("translationX")
+
+ when (type!!) {
+ ENTER ->
+ when (direction!!) {
+ LEFT -> translationAnim.setFloatValues(-view!!.width.toFloat(), 0f)
+ RIGHT -> translationAnim.setFloatValues(view!!.width.toFloat(), 0f)
+ }
+ EXIT ->
+ when (direction!!) {
+ LEFT -> translationAnim.setFloatValues(0f, -view!!.width.toFloat())
+ RIGHT -> translationAnim.setFloatValues(0f, view!!.width.toFloat())
+ }
+ }
+ }
+
+ translationAnim.target = view
+ animators.add(translationAnim)
+
+ if (alpha) {
+ val alphaAnim = ObjectAnimator()
+ alphaAnim.setPropertyName("alpha")
+ alphaAnim.target = view
+
+ when (type!!) {
+ ENTER -> alphaAnim.setFloatValues(DEFAULT_ALPHA_START, DEFAULT_ALPHA_END)
+ EXIT -> alphaAnim.setFloatValues(DEFAULT_ALPHA_END, DEFAULT_ALPHA_START)
+ }
+ animators.add(alphaAnim)
+ }
+
+ compositeAnim.playTogether(animators)
+ compositeAnim.duration = duration
+ compositeAnim.interpolator = interpolator
+
+ return FlashAnim(compositeAnim)
+ }
+
+ enum class Type {
+ ENTER,
+ EXIT
+ }
+ enum class Direction {
+ LEFT,
+ RIGHT
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnimIconBuilder.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnimIconBuilder.kt
new file mode 100644
index 0000000000..df325d0704
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/anim/FlashAnimIconBuilder.kt
@@ -0,0 +1,90 @@
+package com.itsaky.androidide.flashbar.anim
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.animation.PropertyValuesHolder
+import android.animation.ValueAnimator.INFINITE
+import android.animation.ValueAnimator.REVERSE
+import android.content.Context
+import android.view.View
+import android.view.animation.Interpolator
+import androidx.annotation.InterpolatorRes
+
+class FlashAnimIconBuilder(context: Context) : BaseFlashAnimBuilder(context) {
+
+ private val DEFAULT_PULSE_START = 1.0f
+ private val DEFAULT_PULSE_END = 0.6f
+
+ private var pulse: Boolean = false
+ private var pulseStart = 0f
+ private var pulseEnd = 0f
+
+ /** Specifies the duration (in millis) for the animation */
+ override fun duration(millis: Long) = apply { super.duration(millis) }
+
+ /** Specifies accelerate interpolator for the animation */
+ override fun accelerate() = apply { super.accelerate() }
+
+ /** Specifies decelerate interpolator for the animation */
+ override fun decelerate() = apply { super.decelerate() }
+
+ /** Specifies accelerate-decelerate interpolator for the animation */
+ override fun accelerateDecelerate() = apply { super.accelerateDecelerate() }
+
+ /** Specifies custom interpolator for the animation */
+ override fun interpolator(interpolator: Interpolator) = apply { super.interpolator(interpolator) }
+
+ /** Specifies custom interpolator resource for the animation */
+ override fun interpolator(@InterpolatorRes id: Int) = apply { super.interpolator(id) }
+
+ /** Specifies that the animation should have alpha effect */
+ override fun alpha() = apply { super.alpha() }
+
+ /** Specifies that the animation should have pulse effect */
+ @JvmOverloads
+ fun pulse(start: Float = DEFAULT_PULSE_START, end: Float = DEFAULT_PULSE_END) = apply {
+ this.pulse = true
+ this.pulseStart = start
+ this.pulseEnd = end
+ }
+
+ override fun withView(view: View) = apply { super.withView(view) }
+
+ internal fun build(): FlashAnim {
+ requireNotNull(view, { "Target view can not be null" })
+
+ val compositeAnim = AnimatorSet()
+ val animators = linkedSetOf()
+
+ if (pulse) {
+ val scaleAnim =
+ ObjectAnimator.ofPropertyValuesHolder(
+ view,
+ PropertyValuesHolder.ofFloat("scaleX", pulseStart, pulseEnd),
+ PropertyValuesHolder.ofFloat("scaleY", pulseStart, pulseEnd)
+ )
+
+ scaleAnim.repeatCount = INFINITE
+ scaleAnim.repeatMode = REVERSE
+
+ animators.add(scaleAnim)
+ }
+
+ if (alpha) {
+ val alpha = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.6f)
+
+ alpha.repeatCount = INFINITE
+ alpha.repeatMode = REVERSE
+
+ animators.add(alpha)
+ }
+
+ compositeAnim.playTogether(animators)
+
+ compositeAnim.duration = duration
+ compositeAnim.interpolator = interpolator
+
+ return FlashAnim(compositeAnim)
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/util/CommonUtils.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/util/CommonUtils.kt
new file mode 100644
index 0000000000..2801aa39da
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/util/CommonUtils.kt
@@ -0,0 +1,125 @@
+package com.itsaky.androidide.flashbar.util
+
+import android.app.Activity
+import android.content.Context
+import android.graphics.Point
+import android.graphics.Rect
+import android.os.Build
+import android.util.DisplayMetrics
+import android.view.Surface.ROTATION_0
+import android.view.Surface.ROTATION_180
+import android.view.Surface.ROTATION_270
+import android.view.Surface.ROTATION_90
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver
+import android.view.Window
+import android.view.WindowManager
+import com.itsaky.androidide.flashbar.util.NavigationBarPosition.BOTTOM
+import com.itsaky.androidide.flashbar.util.NavigationBarPosition.LEFT
+import com.itsaky.androidide.flashbar.util.NavigationBarPosition.RIGHT
+import com.itsaky.androidide.flashbar.util.NavigationBarPosition.TOP
+import kotlin.math.roundToInt
+
+internal fun Activity.getStatusBarHeightInPx(): Int {
+ val rectangle = Rect()
+
+ window.decorView.getWindowVisibleDisplayFrame(rectangle)
+
+ val statusBarHeight = rectangle.top
+ val contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT).top
+ return if (contentViewTop == 0) { // Actionbar is not present
+ statusBarHeight
+ } else {
+ contentViewTop - statusBarHeight
+ }
+}
+
+internal fun Activity.getNavigationBarPosition(): NavigationBarPosition {
+ val display =
+ if (Build.VERSION.SDK_INT >= 30) {
+ display
+ } else {
+ @Suppress("DEPRECATION") windowManager.defaultDisplay
+ }
+ return when (display?.rotation) {
+ ROTATION_0 -> BOTTOM
+ ROTATION_90 -> RIGHT
+ ROTATION_180 -> TOP
+ ROTATION_270 -> LEFT
+ else -> BOTTOM
+ }
+}
+
+internal fun Activity.getNavigationBarSizeInPx(): Int {
+ val realScreenSize = getRealScreenSize()
+ val appUsableScreenSize = getAppUsableScreenSize()
+ val navigationBarPosition = getNavigationBarPosition()
+
+ return if (navigationBarPosition == LEFT || navigationBarPosition == RIGHT) {
+ realScreenSize.x - appUsableScreenSize.x
+ } else {
+ realScreenSize.y - appUsableScreenSize.y
+ }
+}
+
+internal fun Activity?.getRootView(): ViewGroup? {
+ if (this == null || window == null) {
+ return null
+ }
+ return window.decorView as ViewGroup
+}
+
+internal fun Context.convertDpToPx(dp: Int): Int {
+ return (dp * (resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)).roundToInt()
+}
+
+internal fun Context.convertPxToDp(px: Int): Int {
+ return (px / (resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)).roundToInt()
+}
+
+private fun Activity.getRealScreenSize(): Point {
+ val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val defaultDisplay =
+ if (Build.VERSION.SDK_INT >= 30) {
+ display
+ } else {
+ @Suppress("DEPRECATION") windowManager.defaultDisplay
+ }
+
+ val size = Point()
+ defaultDisplay?.getRealSize(size)
+ return size
+}
+
+private fun Activity.getAppUsableScreenSize(): Point {
+ val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val defaultDisplay = windowManager.defaultDisplay
+ val size = Point()
+ defaultDisplay.getSize(size)
+ return size
+}
+
+inline fun T.afterMeasured(crossinline f: T.() -> Unit) {
+ viewTreeObserver.addOnGlobalLayoutListener(
+ object : ViewTreeObserver.OnGlobalLayoutListener {
+ override fun onGlobalLayout() {
+ if (measuredWidth > 0 && measuredHeight > 0) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ viewTreeObserver.removeOnGlobalLayoutListener(this)
+ } else {
+ viewTreeObserver.removeGlobalOnLayoutListener(this)
+ }
+ f()
+ }
+ }
+ }
+ )
+}
+
+internal enum class NavigationBarPosition {
+ BOTTOM,
+ RIGHT,
+ LEFT,
+ TOP
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/FbButton.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/FbButton.kt
new file mode 100644
index 0000000000..50ae547c6c
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/FbButton.kt
@@ -0,0 +1,17 @@
+package com.itsaky.androidide.flashbar.view
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
+import com.itsaky.androidide.flashbar.R
+
+internal class FbButton : AppCompatTextView {
+ constructor(context: Context) : this(context, null)
+ constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, R.style.FbButtonStyle)
+
+ constructor(
+ context: Context,
+ attrs: AttributeSet?,
+ defStyleAttr: Int
+ ) : super(context, attrs, defStyleAttr)
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/FbProgress.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/FbProgress.kt
new file mode 100644
index 0000000000..39f0ee508f
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/FbProgress.kt
@@ -0,0 +1,581 @@
+package com.itsaky.androidide.flashbar.view
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.RectF
+import android.os.Build
+import android.os.Build.VERSION
+import android.os.Parcel
+import android.os.Parcelable
+import android.os.SystemClock
+import android.provider.Settings
+import android.util.AttributeSet
+import android.util.TypedValue
+import android.view.View
+import com.itsaky.androidide.flashbar.R
+import kotlin.math.cos
+import kotlin.math.pow
+import kotlin.math.roundToInt
+
+/** Forked from Todd Davies' Progress Wheel https://github.com/Todd-Davies/ProgressWheel */
+class FbProgress : View {
+
+ private val barLength = 16
+ private val barMaxLength = 270
+ private val pauseGrowingTime: Long = 200
+
+ private var circleRadius = 28
+ private var barWidth = 4
+ private var rimWidth = 4
+ private var fillRadius = false
+ private var timeStartGrowing = 0.0
+ private var barSpinCycleTime = 460.0
+ private var barExtraLength = 0f
+ private var barGrowingFromFront = true
+ private var pausedTimeWithoutGrowing: Long = 0
+
+ private var barColor = -0x56000000
+ private var rimColor = 0x00FFFFFF
+
+ private val barPaint = Paint()
+ private val rimPaint = Paint()
+
+ private var circleBounds = RectF()
+
+ private var spinSpeed = 230.0f
+ private var lastTimeAnimated: Long = 0
+ private var linearProgress: Boolean = false
+
+ private var progress = 0.0f
+ private var targetProgress = 0.0f
+ private var isSpinning = false
+ private var shouldAnimate: Boolean = false
+
+ private var callback: ProgressCallback? = null
+
+ constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
+ parseAttributes(context.obtainStyledAttributes(attrs, R.styleable.FbProgress))
+ setAnimationEnabled()
+ }
+
+ constructor(context: Context) : super(context) {
+ setAnimationEnabled()
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+
+ val viewWidth = circleRadius + this.paddingLeft + this.paddingRight
+ val viewHeight = circleRadius + this.paddingTop + this.paddingBottom
+
+ val widthMode = MeasureSpec.getMode(widthMeasureSpec)
+ val widthSize = MeasureSpec.getSize(widthMeasureSpec)
+ val heightMode = MeasureSpec.getMode(heightMeasureSpec)
+ val heightSize = MeasureSpec.getSize(heightMeasureSpec)
+
+ val width: Int =
+ when (widthMode) {
+ MeasureSpec.EXACTLY -> widthSize
+ MeasureSpec.AT_MOST -> viewWidth.coerceAtMost(widthSize)
+ else -> viewWidth
+ }
+
+ val height: Int =
+ when {
+ heightMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.EXACTLY -> heightSize
+ heightMode == MeasureSpec.AT_MOST -> viewHeight.coerceAtMost(heightSize)
+ else -> viewHeight
+ }
+
+ setMeasuredDimension(width, height)
+ }
+
+ override fun onSizeChanged(w: Int, h: Int, oldW: Int, oldH: Int) {
+ super.onSizeChanged(w, h, oldW, oldH)
+
+ setupBounds(w, h)
+ setupPaints()
+ invalidate()
+ }
+
+ override fun onDraw(canvas: Canvas) {
+ super.onDraw(canvas)
+
+ canvas.drawArc(circleBounds, 360f, 360f, false, rimPaint)
+
+ var mustInvalidate = false
+
+ if (!shouldAnimate) {
+ return
+ }
+
+ if (isSpinning) {
+ mustInvalidate = true
+
+ val deltaTime = SystemClock.uptimeMillis() - lastTimeAnimated
+ val deltaNormalized = deltaTime * spinSpeed / 1000.0f
+
+ updateBarLength(deltaTime)
+
+ progress += deltaNormalized
+ if (progress > 360) {
+ progress -= 360f
+
+ runCallback(-1.0f)
+ }
+ lastTimeAnimated = SystemClock.uptimeMillis()
+
+ var from = progress - 90
+ var length = barLength + barExtraLength
+
+ if (isInEditMode) {
+ from = 0f
+ length = 135f
+ }
+ canvas.drawArc(circleBounds, from, length, false, barPaint)
+ } else {
+ val oldProgress = progress
+
+ if (progress != targetProgress) {
+ mustInvalidate = true
+
+ val deltaTime = (SystemClock.uptimeMillis() - lastTimeAnimated).toFloat() / 1000
+ val deltaNormalized = deltaTime * spinSpeed
+
+ progress = (progress + deltaNormalized).coerceAtMost(targetProgress)
+ lastTimeAnimated = SystemClock.uptimeMillis()
+ }
+
+ if (oldProgress != progress) {
+ runCallback()
+ }
+
+ var offset = 0.0f
+ var progress = this.progress
+ if (!linearProgress) {
+ val factor = 2.0f
+ offset =
+ (1.0f - (1.0f - this.progress / 360.0f).toDouble().pow((2.0f * factor).toDouble()))
+ .toFloat() * 360.0f
+ progress =
+ (1.0f - (1.0f - this.progress / 360.0f).toDouble().pow(factor.toDouble())).toFloat() *
+ 360.0f
+ }
+
+ if (isInEditMode) {
+ progress = 360f
+ }
+
+ canvas.drawArc(circleBounds, offset - 90, progress, false, barPaint)
+ }
+
+ if (mustInvalidate) {
+ invalidate()
+ }
+ }
+
+ override fun onVisibilityChanged(changedView: View, visibility: Int) {
+ super.onVisibilityChanged(changedView, visibility)
+
+ if (visibility == VISIBLE) {
+ lastTimeAnimated = SystemClock.uptimeMillis()
+ }
+ }
+
+ public override fun onSaveInstanceState(): Parcelable {
+ val superState = super.onSaveInstanceState()
+
+ val ss = WheelSavedState(superState)
+
+ ss.mProgress = this.progress
+ ss.mTargetProgress = this.targetProgress
+ ss.isSpinning = this.isSpinning
+ ss.spinSpeed = this.spinSpeed
+ ss.barWidth = this.barWidth
+ ss.barColor = this.barColor
+ ss.rimWidth = this.rimWidth
+ ss.rimColor = this.rimColor
+ ss.circleRadius = this.circleRadius
+ ss.linearProgress = this.linearProgress
+ ss.fillRadius = this.fillRadius
+
+ return ss
+ }
+
+ public override fun onRestoreInstanceState(state: Parcelable) {
+ if (state !is WheelSavedState) {
+ super.onRestoreInstanceState(state)
+ return
+ }
+
+ super.onRestoreInstanceState(state.superState)
+
+ this.progress = state.mProgress
+ this.targetProgress = state.mTargetProgress
+ this.isSpinning = state.isSpinning
+ this.spinSpeed = state.spinSpeed
+ this.barWidth = state.barWidth
+ this.barColor = state.barColor
+ this.rimWidth = state.rimWidth
+ this.rimColor = state.rimColor
+ this.circleRadius = state.circleRadius
+ this.linearProgress = state.linearProgress
+ this.fillRadius = state.fillRadius
+
+ this.lastTimeAnimated = SystemClock.uptimeMillis()
+ }
+
+ fun resetCount() {
+ progress = 0.0f
+ targetProgress = 0.0f
+ invalidate()
+ }
+
+ fun stopSpinning() {
+ isSpinning = false
+ progress = 0.0f
+ targetProgress = 0.0f
+ invalidate()
+ }
+
+ fun spin() {
+ lastTimeAnimated = SystemClock.uptimeMillis()
+ isSpinning = true
+ invalidate()
+ }
+
+ fun setInstantProgress(update: Float) {
+ var progressUpdate = update
+ if (isSpinning) {
+ progress = 0.0f
+ isSpinning = false
+ }
+
+ if (progressUpdate > 1.0f) {
+ progressUpdate -= 1.0f
+ } else if (progressUpdate < 0) {
+ progressUpdate = 0f
+ }
+
+ if (progressUpdate == targetProgress) {
+ return
+ }
+
+ targetProgress = (progressUpdate * 360.0f).coerceAtMost(360.0f)
+ progress = targetProgress
+ lastTimeAnimated = SystemClock.uptimeMillis()
+ invalidate()
+ }
+
+ fun getProgress(): Float {
+ return if (isSpinning) -1f else progress / 360.0f
+ }
+
+ fun setProgress(update: Float) {
+ var progress = update
+ if (isSpinning) {
+ this.progress = 0.0f
+ isSpinning = false
+
+ runCallback()
+ }
+
+ if (progress > 1.0f) {
+ progress -= 1.0f
+ } else if (progress < 0) {
+ progress = 0f
+ }
+
+ if (progress == targetProgress) {
+ return
+ }
+
+ if (this.progress == targetProgress) {
+ lastTimeAnimated = SystemClock.uptimeMillis()
+ }
+
+ targetProgress = (progress * 360.0f).coerceAtMost(360.0f)
+
+ invalidate()
+ }
+
+ fun setLinearProgress(isLinear: Boolean) {
+ linearProgress = isLinear
+ if (!isSpinning) {
+ invalidate()
+ }
+ }
+
+ fun getCircleRadius() = circleRadius
+
+ fun setCircleRadius(circleRadius: Int) {
+ this.circleRadius = circleRadius
+ if (!isSpinning) {
+ invalidate()
+ }
+ }
+
+ fun getBarWidth() = barWidth
+
+ fun setBarWidth(barWidth: Int) {
+ this.barWidth = barWidth
+ if (!isSpinning) {
+ invalidate()
+ }
+ }
+
+ fun getBarColor() = barColor
+
+ fun setBarColor(barColor: Int) {
+ this.barColor = barColor
+ setupPaints()
+ if (!isSpinning) {
+ invalidate()
+ }
+ }
+
+ fun getRimColor(): Int {
+ return rimColor
+ }
+
+ fun setRimColor(rimColor: Int) {
+ this.rimColor = rimColor
+ setupPaints()
+ if (!isSpinning) {
+ invalidate()
+ }
+ }
+
+ fun getSpinSpeed() = spinSpeed / 360.0f
+
+ fun setSpinSpeed(spinSpeed: Float) {
+ this.spinSpeed = spinSpeed * 360.0f
+ }
+
+ fun getRimWidth() = rimWidth
+
+ fun setRimWidth(rimWidth: Int) {
+ this.rimWidth = rimWidth
+ if (!isSpinning) {
+ invalidate()
+ }
+ }
+
+ fun setCallback(progressCallback: ProgressCallback) {
+ callback = progressCallback
+
+ if (!isSpinning) {
+ runCallback()
+ }
+ }
+
+ private fun setAnimationEnabled() {
+ val currentApiVersion = VERSION.SDK_INT
+
+ val animationValue =
+ if (currentApiVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ Settings.Global.getFloat(
+ context.contentResolver,
+ Settings.Global.ANIMATOR_DURATION_SCALE,
+ 1f
+ )
+ } else {
+ Settings.System.getFloat(
+ context.contentResolver,
+ Settings.System.ANIMATOR_DURATION_SCALE,
+ 1f
+ )
+ }
+
+ shouldAnimate = animationValue != 0f
+ }
+
+ private fun setupBounds(layoutWidth: Int, layoutHeight: Int) {
+ val paddingTop = paddingTop
+ val paddingBottom = paddingBottom
+ val paddingLeft = paddingLeft
+ val paddingRight = paddingRight
+
+ if (!fillRadius) {
+ val minValue =
+ (layoutWidth - paddingLeft - paddingRight).coerceAtMost(
+ layoutHeight - paddingBottom - paddingTop
+ )
+
+ val circleDiameter = minValue.coerceAtMost(circleRadius * 2 - barWidth * 2)
+
+ val xOffset = (layoutWidth - paddingLeft - paddingRight - circleDiameter) / 2 + paddingLeft
+ val yOffset = (layoutHeight - paddingTop - paddingBottom - circleDiameter) / 2 + paddingTop
+
+ circleBounds =
+ RectF(
+ (xOffset + barWidth).toFloat(),
+ (yOffset + barWidth).toFloat(),
+ (xOffset + circleDiameter - barWidth).toFloat(),
+ (yOffset + circleDiameter - barWidth).toFloat()
+ )
+ } else {
+ circleBounds =
+ RectF(
+ (paddingLeft + barWidth).toFloat(),
+ (paddingTop + barWidth).toFloat(),
+ (layoutWidth - paddingRight - barWidth).toFloat(),
+ (layoutHeight - paddingBottom - barWidth).toFloat()
+ )
+ }
+ }
+
+ private fun parseAttributes(a: TypedArray) {
+ val metrics = context.resources.displayMetrics
+ barWidth =
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, barWidth.toFloat(), metrics).toInt()
+ rimWidth =
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rimWidth.toFloat(), metrics).toInt()
+ circleRadius =
+ TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, circleRadius.toFloat(), metrics)
+ .toInt()
+
+ circleRadius =
+ a.getDimension(R.styleable.FbProgress_fbp_circleRadius, circleRadius.toFloat()).toInt()
+
+ fillRadius = a.getBoolean(R.styleable.FbProgress_fbp_fillRadius, false)
+
+ barWidth = a.getDimension(R.styleable.FbProgress_fbp_barWidth, barWidth.toFloat()).toInt()
+
+ rimWidth = a.getDimension(R.styleable.FbProgress_fbp_rimWidth, rimWidth.toFloat()).toInt()
+
+ val baseSpinSpeed = a.getFloat(R.styleable.FbProgress_fbp_spinSpeed, spinSpeed / 360.0f)
+ spinSpeed = baseSpinSpeed * 360
+
+ barSpinCycleTime =
+ a.getInt(R.styleable.FbProgress_fbp_barSpinCycleTime, barSpinCycleTime.toInt()).toDouble()
+
+ barColor = a.getColor(R.styleable.FbProgress_fbp_barColor, barColor)
+
+ rimColor = a.getColor(R.styleable.FbProgress_fbp_rimColor, rimColor)
+
+ linearProgress = a.getBoolean(R.styleable.FbProgress_fbp_linearProgress, false)
+
+ if (a.getBoolean(R.styleable.FbProgress_fbp_progressIndeterminate, false)) {
+ spin()
+ }
+
+ a.recycle()
+ }
+
+ private fun setupPaints() {
+ barPaint.color = barColor
+ barPaint.isAntiAlias = true
+ barPaint.style = Paint.Style.STROKE
+ barPaint.strokeWidth = barWidth.toFloat()
+
+ rimPaint.color = rimColor
+ rimPaint.isAntiAlias = true
+ rimPaint.style = Paint.Style.STROKE
+ rimPaint.strokeWidth = rimWidth.toFloat()
+ }
+
+ private fun updateBarLength(deltaTimeInMilliSeconds: Long) {
+ if (pausedTimeWithoutGrowing >= pauseGrowingTime) {
+ timeStartGrowing += deltaTimeInMilliSeconds.toDouble()
+
+ if (timeStartGrowing > barSpinCycleTime) {
+ timeStartGrowing -= barSpinCycleTime
+ pausedTimeWithoutGrowing = 0
+ barGrowingFromFront = !barGrowingFromFront
+ }
+
+ val distance = cos((timeStartGrowing / barSpinCycleTime + 1) * Math.PI).toFloat() / 2 + 0.5f
+ val destLength = (barMaxLength - barLength).toFloat()
+
+ if (barGrowingFromFront) {
+ barExtraLength = distance * destLength
+ } else {
+ val newLength = destLength * (1 - distance)
+ progress += barExtraLength - newLength
+ barExtraLength = newLength
+ }
+ } else {
+ pausedTimeWithoutGrowing += deltaTimeInMilliSeconds
+ }
+ }
+
+ private fun runCallback(value: Float) {
+ if (callback != null) {
+ callback!!.onProgressUpdate(value)
+ }
+ }
+
+ private fun runCallback() {
+ if (callback != null) {
+ val normalizedProgress = (progress * 100 / 360.0f).roundToInt().toFloat() / 100
+ callback!!.onProgressUpdate(normalizedProgress)
+ }
+ }
+
+ interface ProgressCallback {
+ fun onProgressUpdate(progress: Float)
+ }
+
+ internal class WheelSavedState : View.BaseSavedState {
+ var mProgress: Float = 0.toFloat()
+ var mTargetProgress: Float = 0.toFloat()
+ var isSpinning: Boolean = false
+ var spinSpeed: Float = 0.toFloat()
+ var barWidth: Int = 0
+ var barColor: Int = 0
+ var rimWidth: Int = 0
+ var rimColor: Int = 0
+ var circleRadius: Int = 0
+ var linearProgress: Boolean = false
+ var fillRadius: Boolean = false
+
+ constructor(superState: Parcelable?) : super(superState)
+
+ private constructor(`in`: Parcel) : super(`in`) {
+ this.mProgress = `in`.readFloat()
+ this.mTargetProgress = `in`.readFloat()
+ this.isSpinning = `in`.readByte().toInt() != 0
+ this.spinSpeed = `in`.readFloat()
+ this.barWidth = `in`.readInt()
+ this.barColor = `in`.readInt()
+ this.rimWidth = `in`.readInt()
+ this.rimColor = `in`.readInt()
+ this.circleRadius = `in`.readInt()
+ this.linearProgress = `in`.readByte().toInt() != 0
+ this.fillRadius = `in`.readByte().toInt() != 0
+ }
+
+ override fun writeToParcel(out: Parcel, flags: Int) {
+ super.writeToParcel(out, flags)
+ out.writeFloat(this.mProgress)
+ out.writeFloat(this.mTargetProgress)
+ out.writeByte((if (isSpinning) 1 else 0).toByte())
+ out.writeFloat(this.spinSpeed)
+ out.writeInt(this.barWidth)
+ out.writeInt(this.barColor)
+ out.writeInt(this.rimWidth)
+ out.writeInt(this.rimColor)
+ out.writeInt(this.circleRadius)
+ out.writeByte((if (linearProgress) 1 else 0).toByte())
+ out.writeByte((if (fillRadius) 1 else 0).toByte())
+ }
+
+ companion object {
+ @Suppress("unused")
+ @JvmField
+ val CREATOR: Parcelable.Creator =
+ object : Parcelable.Creator {
+ override fun createFromParcel(`in`: Parcel): WheelSavedState {
+ return WheelSavedState(`in`)
+ }
+
+ override fun newArray(size: Int): Array {
+ return newArray(size)
+ }
+ }
+ }
+ }
+}
diff --git a/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/ShadowView.kt b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/ShadowView.kt
new file mode 100644
index 0000000000..0becdab337
--- /dev/null
+++ b/subprojects/flashbar/src/main/java/com/itsaky/androidide/flashbar/view/ShadowView.kt
@@ -0,0 +1,33 @@
+package com.itsaky.androidide.flashbar.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import androidx.annotation.DrawableRes
+import androidx.core.content.ContextCompat
+import com.itsaky.androidide.flashbar.R
+import com.itsaky.androidide.flashbar.view.ShadowView.ShadowType.BOTTOM
+import com.itsaky.androidide.flashbar.view.ShadowView.ShadowType.TOP
+
+internal class ShadowView
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
+ View(context, attrs, defStyleAttr) {
+
+ internal fun applyShadow(type: ShadowType) {
+ when (type) {
+ TOP -> setShadow(R.drawable.shadow_top)
+ BOTTOM -> setShadow(R.drawable.shadow_bottom)
+ }
+ }
+
+ private fun setShadow(@DrawableRes id: Int) {
+ val shadow = ContextCompat.getDrawable(context, id)
+ this.background = shadow
+ }
+
+ enum class ShadowType {
+ TOP,
+ BOTTOM
+ }
+}
diff --git a/subprojects/flashbar/src/main/res/drawable/fb_button_background_selector.xml b/subprojects/flashbar/src/main/res/drawable/fb_button_background_selector.xml
new file mode 100644
index 0000000000..5660a9bd97
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/drawable/fb_button_background_selector.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/drawable/ic_info.png b/subprojects/flashbar/src/main/res/drawable/ic_info.png
new file mode 100644
index 0000000000..2b609265df
Binary files /dev/null and b/subprojects/flashbar/src/main/res/drawable/ic_info.png differ
diff --git a/subprojects/flashbar/src/main/res/drawable/shadow_bottom.xml b/subprojects/flashbar/src/main/res/drawable/shadow_bottom.xml
new file mode 100644
index 0000000000..c68c6f8bc4
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/drawable/shadow_bottom.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/drawable/shadow_top.xml b/subprojects/flashbar/src/main/res/drawable/shadow_top.xml
new file mode 100644
index 0000000000..1b041c9d67
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/drawable/shadow_top.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/layout/flash_bar_view.xml b/subprojects/flashbar/src/main/res/layout/flash_bar_view.xml
new file mode 100644
index 0000000000..6b8b80ae9f
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/layout/flash_bar_view.xml
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/values/attrs.xml b/subprojects/flashbar/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..3bfa26a2a6
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/values/attrs.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/values/colors.xml b/subprojects/flashbar/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..7787818905
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #8e8e8e
+ #fff
+ #94444444
+ #22000000
+ #80272727
+ #FF333333
+ #FFEB3B
+
diff --git a/subprojects/flashbar/src/main/res/values/dimens.xml b/subprojects/flashbar/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..95445d6c60
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/values/dimens.xml
@@ -0,0 +1,17 @@
+
+
+ 16dp
+ 16sp
+ 14sp
+ 2dp
+ 28dp
+ 16dp
+ 16sp
+ 16dp
+ 30dp
+ 20dp
+ 12dp
+ 12dp
+ 20dp
+
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/values/integers.xml b/subprojects/flashbar/src/main/res/values/integers.xml
new file mode 100644
index 0000000000..55e8aefbdb
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/values/integers.xml
@@ -0,0 +1,4 @@
+
+
+ 250
+
\ No newline at end of file
diff --git a/subprojects/flashbar/src/main/res/values/styles.xml b/subprojects/flashbar/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..deda1a838d
--- /dev/null
+++ b/subprojects/flashbar/src/main/res/values/styles.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.java
index 6ff4ad9bcb..1d1aa3ab92 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.java
@@ -1,9 +1,9 @@
package com.google.googlejavaformat.java;
import com.google.googlejavaformat.Input;
-import com.sun.source.tree.AnnotationTree;
+import openjdk.source.tree.AnnotationTree;
-import javax.annotation.processing.Generated;
+import jdkx.annotation.processing.Generated;
@Generated("com.google.auto.value.processor.AutoOneOfProcessor")
final class AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier {
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations.java
index 9ed00aac64..3d25c7867a 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations.java
@@ -1,9 +1,9 @@
package com.google.googlejavaformat.java;
import com.google.common.collect.ImmutableList;
-import com.sun.source.tree.AnnotationTree;
+import openjdk.source.tree.AnnotationTree;
-import javax.annotation.processing.Generated;
+import jdkx.annotation.processing.Generated;
@Generated("com.google.auto.value.processor.AutoValueProcessor")
final class AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java
index 40690b7af4..7abd914b81 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java
@@ -15,11 +15,11 @@
package com.google.googlejavaformat.java;
import com.google.common.collect.ImmutableList;
-import com.sun.source.tree.AnnotatedTypeTree;
-import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.ArrayTypeTree;
-import com.sun.source.tree.Tree;
-import com.sun.tools.javac.tree.JCTree;
+import openjdk.source.tree.AnnotatedTypeTree;
+import openjdk.source.tree.AnnotationTree;
+import openjdk.source.tree.ArrayTypeTree;
+import openjdk.source.tree.Tree;
+import openjdk.tools.javac.tree.JCTree;
import java.util.ArrayDeque;
import java.util.ArrayList;
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Formatter.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Formatter.java
index 737ed78ac1..5ba6130895 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Formatter.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Formatter.java
@@ -33,13 +33,13 @@
import com.google.googlejavaformat.Newlines;
import com.google.googlejavaformat.Op;
import com.google.googlejavaformat.OpsBuilder;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.parser.JavacParser;
-import com.sun.tools.javac.parser.ParserFactory;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Options;
+import openjdk.tools.javac.file.JavacFileManager;
+import openjdk.tools.javac.parser.JavacParser;
+import openjdk.tools.javac.parser.ParserFactory;
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Log;
+import openjdk.tools.javac.util.Options;
import java.io.IOError;
import java.io.IOException;
@@ -49,12 +49,12 @@
import java.util.Collection;
import java.util.List;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardLocation;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.DiagnosticCollector;
+import jdkx.tools.DiagnosticListener;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.SimpleJavaFileObject;
+import jdkx.tools.StandardLocation;
/**
* This is google-java-format, a new Java formatter that follows the Google Java Style Guide quite
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/FormatterException.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/FormatterException.java
index 595ec9d763..2ebc4c0fec 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/FormatterException.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/FormatterException.java
@@ -22,8 +22,8 @@
import java.util.List;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.JavaFileObject;
/** Checked exception class for formatter errors. */
public final class FormatterException extends Exception {
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java
index 5e3d31d30e..b7d57f0f6b 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java
@@ -25,7 +25,7 @@
import com.google.googlejavaformat.Newlines;
import com.google.googlejavaformat.java.JavaFormatterOptions.Style;
import com.google.googlejavaformat.java.JavaInput.Tok;
-import com.sun.tools.javac.parser.Tokens.TokenKind;
+import openjdk.tools.javac.parser.Tokens.TokenKind;
import java.util.ArrayList;
import java.util.Comparator;
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInput.java
index 1155415957..bcf8f837fb 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInput.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInput.java
@@ -33,13 +33,13 @@
import com.google.googlejavaformat.Input;
import com.google.googlejavaformat.Newlines;
import com.google.googlejavaformat.java.JavacTokens.RawTok;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.parser.Tokens.TokenKind;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
-import com.sun.tools.javac.util.Options;
+import openjdk.tools.javac.file.JavacFileManager;
+import openjdk.tools.javac.parser.Tokens.TokenKind;
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Log;
+import openjdk.tools.javac.util.Log.DeferredDiagnosticHandler;
+import openjdk.tools.javac.util.Options;
import java.io.IOException;
import java.net.URI;
@@ -48,12 +48,12 @@
import java.util.Iterator;
import java.util.List;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.DiagnosticCollector;
+import jdkx.tools.DiagnosticListener;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.JavaFileObject.Kind;
+import jdkx.tools.SimpleJavaFileObject;
/** {@code JavaInput} extends {@link Input} to represent a Java input document. */
public final class JavaInput extends Input {
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java
index 642562e028..cc90a6cf0d 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java
@@ -29,18 +29,18 @@
import static com.google.googlejavaformat.java.Trees.operatorName;
import static com.google.googlejavaformat.java.Trees.precedence;
import static com.google.googlejavaformat.java.Trees.skipParen;
-import static com.sun.source.tree.Tree.Kind.ANNOTATION;
-import static com.sun.source.tree.Tree.Kind.ARRAY_ACCESS;
-import static com.sun.source.tree.Tree.Kind.ASSIGNMENT;
-import static com.sun.source.tree.Tree.Kind.BLOCK;
-import static com.sun.source.tree.Tree.Kind.EXTENDS_WILDCARD;
-import static com.sun.source.tree.Tree.Kind.IF;
-import static com.sun.source.tree.Tree.Kind.METHOD_INVOCATION;
-import static com.sun.source.tree.Tree.Kind.NEW_ARRAY;
-import static com.sun.source.tree.Tree.Kind.NEW_CLASS;
-import static com.sun.source.tree.Tree.Kind.STRING_LITERAL;
-import static com.sun.source.tree.Tree.Kind.UNION_TYPE;
-import static com.sun.source.tree.Tree.Kind.VARIABLE;
+import static openjdk.source.tree.Tree.Kind.ANNOTATION;
+import static openjdk.source.tree.Tree.Kind.ARRAY_ACCESS;
+import static openjdk.source.tree.Tree.Kind.ASSIGNMENT;
+import static openjdk.source.tree.Tree.Kind.BLOCK;
+import static openjdk.source.tree.Tree.Kind.EXTENDS_WILDCARD;
+import static openjdk.source.tree.Tree.Kind.IF;
+import static openjdk.source.tree.Tree.Kind.METHOD_INVOCATION;
+import static openjdk.source.tree.Tree.Kind.NEW_ARRAY;
+import static openjdk.source.tree.Tree.Kind.NEW_CLASS;
+import static openjdk.source.tree.Tree.Kind.STRING_LITERAL;
+import static openjdk.source.tree.Tree.Kind.UNION_TYPE;
+import static openjdk.source.tree.Tree.Kind.VARIABLE;
import static java.util.stream.Collectors.toList;
import com.google.auto.value.AutoOneOf;
@@ -77,73 +77,73 @@
import com.google.googlejavaformat.Output.BreakTag;
import com.google.googlejavaformat.java.DimensionHelpers.SortedDims;
import com.google.googlejavaformat.java.DimensionHelpers.TypeWithDims;
-import com.sun.source.tree.AnnotatedTypeTree;
-import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.ArrayTypeTree;
-import com.sun.source.tree.AssertTree;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.BlockTree;
-import com.sun.source.tree.BreakTree;
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.CatchTree;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.CompoundAssignmentTree;
-import com.sun.source.tree.ConditionalExpressionTree;
-import com.sun.source.tree.ContinueTree;
-import com.sun.source.tree.DirectiveTree;
-import com.sun.source.tree.DoWhileLoopTree;
-import com.sun.source.tree.EmptyStatementTree;
-import com.sun.source.tree.EnhancedForLoopTree;
-import com.sun.source.tree.ExportsTree;
-import com.sun.source.tree.ExpressionStatementTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.ForLoopTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.IfTree;
-import com.sun.source.tree.ImportTree;
-import com.sun.source.tree.InstanceOfTree;
-import com.sun.source.tree.IntersectionTypeTree;
-import com.sun.source.tree.LabeledStatementTree;
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ModifiersTree;
-import com.sun.source.tree.ModuleTree;
-import com.sun.source.tree.NewArrayTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.OpensTree;
-import com.sun.source.tree.ParameterizedTypeTree;
-import com.sun.source.tree.ParenthesizedTree;
-import com.sun.source.tree.PrimitiveTypeTree;
-import com.sun.source.tree.ProvidesTree;
-import com.sun.source.tree.RequiresTree;
-import com.sun.source.tree.ReturnTree;
-import com.sun.source.tree.StatementTree;
-import com.sun.source.tree.SwitchTree;
-import com.sun.source.tree.SynchronizedTree;
-import com.sun.source.tree.ThrowTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TryTree;
-import com.sun.source.tree.TypeCastTree;
-import com.sun.source.tree.TypeParameterTree;
-import com.sun.source.tree.UnaryTree;
-import com.sun.source.tree.UnionTypeTree;
-import com.sun.source.tree.UsesTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.tree.WhileLoopTree;
-import com.sun.source.tree.WildcardTree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.TreeScanner;
+import openjdk.source.tree.AnnotatedTypeTree;
+import openjdk.source.tree.AnnotationTree;
+import openjdk.source.tree.ArrayAccessTree;
+import openjdk.source.tree.ArrayTypeTree;
+import openjdk.source.tree.AssertTree;
+import openjdk.source.tree.AssignmentTree;
+import openjdk.source.tree.BinaryTree;
+import openjdk.source.tree.BlockTree;
+import openjdk.source.tree.BreakTree;
+import openjdk.source.tree.CaseTree;
+import openjdk.source.tree.CatchTree;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.CompoundAssignmentTree;
+import openjdk.source.tree.ConditionalExpressionTree;
+import openjdk.source.tree.ContinueTree;
+import openjdk.source.tree.DirectiveTree;
+import openjdk.source.tree.DoWhileLoopTree;
+import openjdk.source.tree.EmptyStatementTree;
+import openjdk.source.tree.EnhancedForLoopTree;
+import openjdk.source.tree.ExportsTree;
+import openjdk.source.tree.ExpressionStatementTree;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.ForLoopTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.IfTree;
+import openjdk.source.tree.ImportTree;
+import openjdk.source.tree.InstanceOfTree;
+import openjdk.source.tree.IntersectionTypeTree;
+import openjdk.source.tree.LabeledStatementTree;
+import openjdk.source.tree.LambdaExpressionTree;
+import openjdk.source.tree.LiteralTree;
+import openjdk.source.tree.MemberReferenceTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.ModifiersTree;
+import openjdk.source.tree.ModuleTree;
+import openjdk.source.tree.NewArrayTree;
+import openjdk.source.tree.NewClassTree;
+import openjdk.source.tree.OpensTree;
+import openjdk.source.tree.ParameterizedTypeTree;
+import openjdk.source.tree.ParenthesizedTree;
+import openjdk.source.tree.PrimitiveTypeTree;
+import openjdk.source.tree.ProvidesTree;
+import openjdk.source.tree.RequiresTree;
+import openjdk.source.tree.ReturnTree;
+import openjdk.source.tree.StatementTree;
+import openjdk.source.tree.SwitchTree;
+import openjdk.source.tree.SynchronizedTree;
+import openjdk.source.tree.ThrowTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.TryTree;
+import openjdk.source.tree.TypeCastTree;
+import openjdk.source.tree.TypeParameterTree;
+import openjdk.source.tree.UnaryTree;
+import openjdk.source.tree.UnionTypeTree;
+import openjdk.source.tree.UsesTree;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.tree.WhileLoopTree;
+import openjdk.source.tree.WildcardTree;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.tools.javac.code.Flags;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCMethodDecl;
+import openjdk.tools.javac.tree.TreeScanner;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -161,7 +161,7 @@
import java.util.regex.Pattern;
import java.util.stream.Stream;
-import javax.lang.model.element.Name;
+import jdkx.lang.model.element.Name;
/**
* An AST visitor that builds a stream of {@link Op}s to format from the given {@link
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavacTokens.java
index 593e4ebcd8..ab4cc5e3e6 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavacTokens.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/JavacTokens.java
@@ -18,15 +18,15 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-import com.sun.tools.javac.parser.JavaTokenizer;
-import com.sun.tools.javac.parser.Scanner;
-import com.sun.tools.javac.parser.ScannerFactory;
-import com.sun.tools.javac.parser.Tokens.Comment;
-import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
-import com.sun.tools.javac.parser.Tokens.Token;
-import com.sun.tools.javac.parser.Tokens.TokenKind;
-import com.sun.tools.javac.parser.UnicodeReader;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.parser.JavaTokenizer;
+import openjdk.tools.javac.parser.Scanner;
+import openjdk.tools.javac.parser.ScannerFactory;
+import openjdk.tools.javac.parser.Tokens.Comment;
+import openjdk.tools.javac.parser.Tokens.Comment.CommentStyle;
+import openjdk.tools.javac.parser.Tokens.Token;
+import openjdk.tools.javac.parser.Tokens.TokenKind;
+import openjdk.tools.javac.parser.UnicodeReader;
+import openjdk.tools.javac.util.Context;
import java.util.Set;
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java
index 206ef5f60c..386b88c471 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java
@@ -23,7 +23,7 @@
import com.google.common.collect.TreeRangeMap;
import com.google.googlejavaformat.Input.Tok;
import com.google.googlejavaformat.Input.Token;
-import com.sun.tools.javac.parser.Tokens.TokenKind;
+import openjdk.tools.javac.parser.Tokens.TokenKind;
import java.util.ArrayList;
import java.util.Collection;
@@ -33,7 +33,7 @@
import java.util.Map;
import java.util.Map.Entry;
-import javax.lang.model.element.Modifier;
+import jdkx.lang.model.element.Modifier;
/** Fixes sequences of modifiers to be in JLS order. */
final class ModifierOrderer {
@@ -112,7 +112,7 @@ private static void addTrivia(StringBuilder replacement, ImmutableList extends
}
/**
- * Returns the given token as a {@link javax.lang.model.element.Modifier}, or {@code null} if it
+ * Returns the given token as a {@link jdkx.lang.model.element.Modifier}, or {@code null} if it
* is not a modifier.
*/
private static Modifier asModifier(Token token) {
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java
index 9695f3b1e9..f01903de43 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java
@@ -30,30 +30,30 @@
import com.google.common.collect.TreeRangeMap;
import com.google.common.collect.TreeRangeSet;
import com.google.googlejavaformat.Newlines;
-import com.sun.source.doctree.DocCommentTree;
-import com.sun.source.doctree.ReferenceTree;
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.ImportTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.DocTreePath;
-import com.sun.source.util.DocTreePathScanner;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.TreeScanner;
-import com.sun.tools.javac.api.JavacTrees;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.parser.JavacParser;
-import com.sun.tools.javac.parser.ParserFactory;
-import com.sun.tools.javac.tree.DCTree;
-import com.sun.tools.javac.tree.DCTree.DCReference;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
-import com.sun.tools.javac.tree.JCTree.JCIdent;
-import com.sun.tools.javac.tree.JCTree.JCImport;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Options;
+import openjdk.source.doctree.DocCommentTree;
+import openjdk.source.doctree.ReferenceTree;
+import openjdk.source.tree.CaseTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.ImportTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.DocTreePath;
+import openjdk.source.util.DocTreePathScanner;
+import openjdk.source.util.TreePathScanner;
+import openjdk.source.util.TreeScanner;
+import openjdk.tools.javac.api.JavacTrees;
+import openjdk.tools.javac.file.JavacFileManager;
+import openjdk.tools.javac.parser.JavacParser;
+import openjdk.tools.javac.parser.ParserFactory;
+import openjdk.tools.javac.tree.DCTree;
+import openjdk.tools.javac.tree.DCTree.DCReference;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit;
+import openjdk.tools.javac.tree.JCTree.JCFieldAccess;
+import openjdk.tools.javac.tree.JCTree.JCIdent;
+import openjdk.tools.javac.tree.JCTree.JCImport;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Log;
+import openjdk.tools.javac.util.Options;
import java.io.IOError;
import java.io.IOException;
@@ -64,12 +64,12 @@
import java.util.Map;
import java.util.Set;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardLocation;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.DiagnosticCollector;
+import jdkx.tools.DiagnosticListener;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.SimpleJavaFileObject;
+import jdkx.tools.StandardLocation;
/**
* Removes unused imports from a source file. Imports that are only used in javadoc are also
@@ -303,7 +303,7 @@ private void scanJavadoc() {
// scan javadoc comments, checking for references to imported types
class DocTreeScanner extends DocTreePathScanner {
@Override
- public Void visitIdentifier(com.sun.source.doctree.IdentifierTree node, Void aVoid) {
+ public Void visitIdentifier(openjdk.source.doctree.IdentifierTree node, Void aVoid) {
return null;
}
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/StringWrapper.java
index ce99cf220a..61a960ea95 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/StringWrapper.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/StringWrapper.java
@@ -26,21 +26,21 @@
import com.google.common.collect.Range;
import com.google.common.collect.TreeRangeMap;
import com.google.googlejavaformat.Newlines;
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.parser.JavacParser;
-import com.sun.tools.javac.parser.ParserFactory;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Options;
-import com.sun.tools.javac.util.Position;
+import openjdk.source.tree.BinaryTree;
+import openjdk.source.tree.LiteralTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.Tree.Kind;
+import openjdk.source.util.TreePath;
+import openjdk.source.util.TreePathScanner;
+import openjdk.tools.javac.file.JavacFileManager;
+import openjdk.tools.javac.parser.JavacParser;
+import openjdk.tools.javac.parser.ParserFactory;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Log;
+import openjdk.tools.javac.util.Options;
+import openjdk.tools.javac.util.Position;
import java.io.IOException;
import java.io.UncheckedIOException;
@@ -54,12 +54,12 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardLocation;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.DiagnosticCollector;
+import jdkx.tools.DiagnosticListener;
+import jdkx.tools.JavaFileObject;
+import jdkx.tools.SimpleJavaFileObject;
+import jdkx.tools.StandardLocation;
/** Wraps string literals that exceed the column limit. */
public final class StringWrapper {
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Trees.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Trees.java
index 1926541a43..8feecaa112 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Trees.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/Trees.java
@@ -14,23 +14,23 @@
package com.google.googlejavaformat.java;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompoundAssignmentTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.ParenthesizedTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.TreePath;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.Pretty;
-import com.sun.tools.javac.tree.TreeInfo;
+import openjdk.source.tree.ClassTree;
+import openjdk.source.tree.CompoundAssignmentTree;
+import openjdk.source.tree.ExpressionTree;
+import openjdk.source.tree.IdentifierTree;
+import openjdk.source.tree.MemberSelectTree;
+import openjdk.source.tree.MethodInvocationTree;
+import openjdk.source.tree.ParenthesizedTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.util.TreePath;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.Pretty;
+import openjdk.tools.javac.tree.TreeInfo;
import java.io.IOError;
import java.io.IOException;
-import javax.lang.model.element.Name;
+import jdkx.lang.model.element.Name;
/** Utilities for working with {@link Tree}s. */
class Trees {
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java
index eaaf349c7c..6add6a5479 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java
@@ -22,12 +22,12 @@
import java.io.IOException;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.Messager;
-import javax.lang.model.element.Element;
-import javax.tools.FileObject;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
+import jdkx.annotation.processing.Filer;
+import jdkx.annotation.processing.Messager;
+import jdkx.lang.model.element.Element;
+import jdkx.tools.FileObject;
+import jdkx.tools.JavaFileManager;
+import jdkx.tools.JavaFileObject;
/**
* A decorating {@link Filer} implementation which formats Java source files with a {@link
diff --git a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java
index ebd8410cbb..4050c746b9 100644
--- a/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java
+++ b/subprojects/google-java-format/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java
@@ -26,10 +26,10 @@
import java.io.IOException;
import java.io.Writer;
-import javax.annotation.processing.Messager;
-import javax.tools.Diagnostic;
-import javax.tools.ForwardingJavaFileObject;
-import javax.tools.JavaFileObject;
+import jdkx.annotation.processing.Messager;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.ForwardingJavaFileObject;
+import jdkx.tools.JavaFileObject;
/** A {@link JavaFileObject} decorator which {@linkplain Formatter formats} source code. */
final class FormattingJavaFileObject extends ForwardingJavaFileObject {
diff --git a/subprojects/javac-services/build.gradle.kts b/subprojects/javac-services/build.gradle.kts
index 72e51d8020..8e6ff692f3 100644
--- a/subprojects/javac-services/build.gradle.kts
+++ b/subprojects/javac-services/build.gradle.kts
@@ -1,3 +1,5 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
plugins {
id("com.android.library")
id("kotlin-android")
@@ -19,6 +21,10 @@ android {
}
}
+tasks.withType {
+ kotlinOptions.jvmTarget = "1.8"
+}
+
dependencies {
implementation(libs.common.kotlin)
implementation(libs.common.utilcode)
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelAbort.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelAbort.java
index 99daa27326..bdccfed743 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelAbort.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelAbort.java
@@ -36,7 +36,7 @@
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.util.Abort;
+import openjdk.tools.javac.util.Abort;
/**
* @author Tomas Zezula
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelService.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelService.java
index 2f4f867208..dc37f8acea 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelService.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/CancelService.java
@@ -36,7 +36,7 @@
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.util.Context;
/**
* @author Tomas Zezula
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBAttr.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBAttr.java
index 4624d96080..98033c92d1 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBAttr.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBAttr.java
@@ -35,20 +35,20 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.comp.Attr;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCBlock;
-import com.sun.tools.javac.tree.JCTree.JCCatch;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
+import openjdk.tools.javac.code.Type;
+import openjdk.tools.javac.comp.Attr;
+import openjdk.tools.javac.comp.AttrContext;
+import openjdk.tools.javac.comp.Env;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCBlock;
+import openjdk.tools.javac.tree.JCTree.JCCatch;
+import openjdk.tools.javac.tree.JCTree.JCClassDecl;
+import openjdk.tools.javac.tree.JCTree.JCExpression;
+import openjdk.tools.javac.tree.JCTree.JCMethodDecl;
+import openjdk.tools.javac.tree.JCTree.JCVariableDecl;
+import openjdk.tools.javac.tree.TreeMaker;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.List;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassFinder.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassFinder.java
index 18ea350608..dfad771f7a 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassFinder.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassFinder.java
@@ -35,19 +35,19 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.ClassFinder;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds.Kind;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symbol.Completer;
-import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.JCDiagnostic;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticInfo;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
-import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Names;
+import openjdk.tools.javac.code.ClassFinder;
+import openjdk.tools.javac.code.Flags;
+import openjdk.tools.javac.code.Kinds.Kind;
+import openjdk.tools.javac.code.Symbol;
+import openjdk.tools.javac.code.Symbol.Completer;
+import openjdk.tools.javac.code.Symbol.CompletionFailure;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.JCDiagnostic;
+import openjdk.tools.javac.util.JCDiagnostic.DiagnosticInfo;
+import openjdk.tools.javac.util.JCDiagnostic.DiagnosticType;
+import openjdk.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
+import openjdk.tools.javac.util.Log;
+import openjdk.tools.javac.util.Names;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -56,7 +56,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.tools.JavaFileObject;
+import jdkx.tools.JavaFileObject;
/**
* @author lahvac
@@ -85,7 +85,7 @@ public NBClassFinder(Context context) {
public Completer getCompleter() {
if (completer == null) {
try {
- Class.forName("com.sun.tools.javac.model.LazyTreeLoader");
+ Class.forName("openjdk.tools.javac.model.LazyTreeLoader");
// patched nb-javac, handles missing java.lang itself:
completer = super.getCompleter();
} catch (ClassNotFoundException e) {
@@ -99,7 +99,7 @@ public Completer getCompleter() {
sym.flags_field |= Flags.EXISTS;
try {
Class> dcfhClass =
- Class.forName("com.sun.tools.javac.code.DeferredCompletionFailureHandler");
+ Class.forName("openjdk.tools.javac.code.DeferredCompletionFailureHandler");
Constructor constr =
CompletionFailure.class.getDeclaredConstructor(
Symbol.class, Supplier.class, dcfhClass);
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassReader.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassReader.java
index ad7451635b..901ebd68e1 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassReader.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassReader.java
@@ -35,21 +35,21 @@
*/
package com.itsaky.androidide.javac.services;
-import static com.sun.tools.javac.jvm.ClassFile.Version.V45_3;
+import static openjdk.tools.javac.jvm.ClassFile.Version.V45_3;
import android.text.TextUtils;
import com.itsaky.androidide.utils.ILogger;
-import com.sun.tools.javac.code.ClassFinder.BadClassFile;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.jvm.ClassFile;
-import com.sun.tools.javac.jvm.ClassFile.Version;
-import com.sun.tools.javac.jvm.ClassReader;
-import com.sun.tools.javac.resources.CompilerProperties.Warnings;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Name;
+import openjdk.tools.javac.code.ClassFinder.BadClassFile;
+import openjdk.tools.javac.code.Symbol;
+import openjdk.tools.javac.code.Symbol.ClassSymbol;
+import openjdk.tools.javac.jvm.ClassFile;
+import openjdk.tools.javac.jvm.ClassFile.Version;
+import openjdk.tools.javac.jvm.ClassReader;
+import openjdk.tools.javac.resources.CompilerProperties.Warnings;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Log;
+import openjdk.tools.javac.util.Name;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -59,8 +59,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.tools.ForwardingJavaFileObject;
-import javax.tools.JavaFileObject;
+import jdkx.tools.ForwardingJavaFileObject;
+import jdkx.tools.JavaFileObject;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassWriter.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassWriter.java
index afb426f8a8..d42c1149d9 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassWriter.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBClassWriter.java
@@ -35,9 +35,9 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.jvm.ClassWriter;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.code.Types;
+import openjdk.tools.javac.jvm.ClassWriter;
+import openjdk.tools.javac.util.Context;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBEnter.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBEnter.java
index 8829cb680e..1d04649fca 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBEnter.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBEnter.java
@@ -35,16 +35,16 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.Symbol.TypeSymbol;
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Enter;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.code.Symbol.TypeSymbol;
+import openjdk.tools.javac.code.Symtab;
+import openjdk.tools.javac.comp.AttrContext;
+import openjdk.tools.javac.comp.Enter;
+import openjdk.tools.javac.comp.Env;
+import openjdk.tools.javac.main.JavaCompiler;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCClassDecl;
+import openjdk.tools.javac.tree.TreeInfo;
+import openjdk.tools.javac.util.Context;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavaCompiler.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavaCompiler.java
index 43fee2f11e..568edfea8a 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavaCompiler.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavaCompiler.java
@@ -35,13 +35,13 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Pair;
+import openjdk.tools.javac.comp.AttrContext;
+import openjdk.tools.javac.comp.Env;
+import openjdk.tools.javac.main.JavaCompiler;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.List;
+import openjdk.tools.javac.util.Pair;
import java.util.Collection;
import java.util.Collections;
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavacTrees.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavacTrees.java
index 8729ad4b76..20510052d7 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavacTrees.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBJavacTrees.java
@@ -35,21 +35,21 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.TreePath;
-import com.sun.tools.javac.api.JavacTrees;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.Context;
+import openjdk.source.tree.VariableTree;
+import openjdk.source.util.TreePath;
+import openjdk.tools.javac.api.JavacTrees;
+import openjdk.tools.javac.code.Flags;
+import openjdk.tools.javac.code.Symbol;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCVariableDecl;
+import openjdk.tools.javac.tree.TreeInfo;
+import openjdk.tools.javac.tree.TreeMaker;
+import openjdk.tools.javac.util.Context;
import java.util.HashMap;
import java.util.Map;
-import javax.lang.model.element.Element;
+import jdkx.lang.model.element.Element;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBLog.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBLog.java
index 5eaf6a8849..686c75ee5b 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBLog.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBLog.java
@@ -35,10 +35,10 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.JCDiagnostic;
-import com.sun.tools.javac.util.Log;
+import openjdk.tools.javac.code.Symbol;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.JCDiagnostic;
+import openjdk.tools.javac.util.Log;
import java.io.PrintWriter;
import java.net.URI;
@@ -49,8 +49,8 @@
import java.util.Map;
import java.util.Set;
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.JavaFileObject;
/**
* @author Tomas Zezula
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBMemberEnter.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBMemberEnter.java
index c405a97391..d222832f7d 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBMemberEnter.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBMemberEnter.java
@@ -35,14 +35,14 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.source.util.TreePath;
-import com.sun.tools.javac.api.JavacTrees;
-import com.sun.tools.javac.comp.MemberEnter;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.tree.JCTree.JCImport;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.util.Context;
+import openjdk.source.util.TreePath;
+import openjdk.tools.javac.api.JavacTrees;
+import openjdk.tools.javac.comp.MemberEnter;
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit;
+import openjdk.tools.javac.tree.JCTree.JCImport;
+import openjdk.tools.javac.tree.JCTree.JCMethodDecl;
+import openjdk.tools.javac.tree.JCTree.JCVariableDecl;
+import openjdk.tools.javac.util.Context;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBNames.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBNames.java
index 73fb80b60f..5d18993f8a 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBNames.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBNames.java
@@ -35,9 +35,9 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Name;
-import com.sun.tools.javac.util.Names;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Name;
+import openjdk.tools.javac.util.Names;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java
index 770b28f678..7479097080 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBParserFactory.java
@@ -35,24 +35,24 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.parser.JavacParser;
-import com.sun.tools.javac.parser.Lexer;
-import com.sun.tools.javac.parser.ParserFactory;
-import com.sun.tools.javac.parser.ScannerFactory;
-import com.sun.tools.javac.parser.Tokens.Comment;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCStatement;
-import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Name;
-import com.sun.tools.javac.util.Names;
-import com.sun.tools.javac.util.Position;
+import openjdk.tools.javac.parser.JavacParser;
+import openjdk.tools.javac.parser.Lexer;
+import openjdk.tools.javac.parser.ParserFactory;
+import openjdk.tools.javac.parser.ScannerFactory;
+import openjdk.tools.javac.parser.Tokens.Comment;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCClassDecl;
+import openjdk.tools.javac.tree.JCTree.JCEnhancedForLoop;
+import openjdk.tools.javac.tree.JCTree.JCExpression;
+import openjdk.tools.javac.tree.JCTree.JCModifiers;
+import openjdk.tools.javac.tree.JCTree.JCStatement;
+import openjdk.tools.javac.tree.JCTree.JCTypeParameter;
+import openjdk.tools.javac.tree.TreeInfo;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.List;
+import openjdk.tools.javac.util.Name;
+import openjdk.tools.javac.util.Names;
+import openjdk.tools.javac.util.Position;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBResolve.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBResolve.java
index e19ac823e0..92e1fcd39d 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBResolve.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBResolve.java
@@ -35,13 +35,13 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symbol.TypeSymbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.comp.Resolve;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.code.Symbol;
+import openjdk.tools.javac.code.Symbol.TypeSymbol;
+import openjdk.tools.javac.code.Type;
+import openjdk.tools.javac.comp.AttrContext;
+import openjdk.tools.javac.comp.Env;
+import openjdk.tools.javac.comp.Resolve;
+import openjdk.tools.javac.util.Context;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBTreeMaker.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBTreeMaker.java
index 2b53369809..a01ef556df 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBTreeMaker.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/NBTreeMaker.java
@@ -35,12 +35,12 @@
*/
package com.itsaky.androidide.javac.services;
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Names;
+import openjdk.tools.javac.code.Symtab;
+import openjdk.tools.javac.code.Types;
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit;
+import openjdk.tools.javac.tree.TreeMaker;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Names;
/**
* @author lahvac
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/JavacFlowListener.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/JavacFlowListener.java
index b93cb5ff06..18b170f0b7 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/JavacFlowListener.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/JavacFlowListener.java
@@ -19,9 +19,9 @@
import androidx.annotation.NonNull;
-import com.sun.tools.javac.util.Context;
+import openjdk.tools.javac.util.Context;
-import javax.tools.JavaFileObject;
+import jdkx.tools.JavaFileObject;
/**
* @author Akash Yadav
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableBorrow.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableBorrow.kt
index 41c52546e3..62e454e516 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableBorrow.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableBorrow.kt
@@ -16,12 +16,14 @@
*/
package com.itsaky.androidide.javac.services.compiler
-import com.itsaky.androidide.javac.services.util.JavacTaskUtil
-import com.sun.tools.javac.api.JavacTaskImpl
+import openjdk.tools.javac.api.JavacTaskImpl
/** @author Akash Yadav */
-class ReusableBorrow internal constructor(private val reusableCompiler: ReusableCompiler, @JvmField val task: JavacTaskImpl) :
- AutoCloseable {
+class ReusableBorrow
+internal constructor(
+ private val reusableCompiler: ReusableCompiler,
+ @JvmField val task: JavacTaskImpl
+) : AutoCloseable {
private var closed = false
@@ -32,7 +34,7 @@ class ReusableBorrow internal constructor(private val reusableCompiler: Reusable
// not returning the context to the pool if task crashes with an exception
// the task/context may be in a broken state
reusableCompiler.currentContext!!.clear()
- JavacTaskUtil.cleanup(task)
+ task.cleanup()
reusableCompiler.checkedOut = false
closed = true
}
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableCompiler.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableCompiler.kt
index 0df960eeba..1fd79f5fa0 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableCompiler.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableCompiler.kt
@@ -18,13 +18,11 @@
package com.itsaky.androidide.javac.services.compiler
import com.itsaky.androidide.javac.services.CancelService
-import com.itsaky.androidide.utils.ILogger
-import com.sun.tools.javac.api.JavacTaskImpl
-import com.sun.tools.javac.api.JavacTool
-import java.util.stream.*
-import javax.tools.DiagnosticListener
-import javax.tools.JavaFileManager
-import javax.tools.JavaFileObject
+import openjdk.tools.javac.api.JavacTaskImpl
+import openjdk.tools.javac.api.JavacTool
+import jdkx.tools.DiagnosticListener
+import jdkx.tools.JavaFileManager
+import jdkx.tools.JavaFileObject
/**
* A pool of reusable JavacTasks. When a task is no valid anymore, it is returned to the pool, and
@@ -52,28 +50,28 @@ import javax.tools.JavaFileObject
*/
class ReusableCompiler {
private val systemProvider = JavacTool.create()
- private val currentOptions: MutableList = java.util.ArrayList()
+ private val currentOptions = mutableListOf()
@JvmField var currentContext: ReusableContext? = null
-
+
internal var checkedOut = false
/**
- * Creates a new task as if by [javax.tools.JavaCompiler.getTask] and runs the provided worker
+ * Creates a new task as if by [jdkx.tools.JavaCompiler.getTask] and runs the provided worker
* with it. The task is only valid while the worker is running. The internal structures may be
* reused from some previous compilation.
*
* @param fileManager a file manager; if `null` use the compiler's standard filemanager
* @param diagnosticListener a diagnostic listener; if `null` use the compiler's default method
- * for reporting diagnostics
+ * for reporting diagnostics
* @param options compiler options, `null` means no options
* @param classes names of classes to be processed by annotation processing, `null` means no class
- * names
+ * names
* @param compilationUnits the compilation units to compile, `null` means no compilation units
* @return an object representing the compilation
* @throws RuntimeException if an unrecoverable error occurred in a user supplied component. The
- * [cause][Throwable.cause] will be the error in user code.
+ * [cause][Throwable.cause] will be the error in user code.
* @throws IllegalArgumentException if any of the options are invalid, or if any of the given
- * compilation units are of other kind than [source][JavaFileObject.Kind.SOURCE]
+ * compilation units are of other kind than [source][JavaFileObject.Kind.SOURCE]
*/
fun getTask(
fileManager: JavaFileManager?,
@@ -112,7 +110,6 @@ class ReusableCompiler {
}
companion object {
- private val log = ILogger.newInstance(ReusableCompiler::class.java.simpleName)
private val cancelService: CancelService = CancelServiceImpl()
}
}
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt
index d7330f8b81..6be568e416 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableContext.kt
@@ -31,33 +31,33 @@ import com.itsaky.androidide.javac.services.fs.CacheFSInfoSingleton
import com.itsaky.androidide.javac.services.fs.JarPackageProviderImpl
import com.itsaky.androidide.utils.VMUtils
import com.itsaky.androidide.zipfs2.JarPackageProvider
-import com.sun.source.util.JavacTask
-import com.sun.source.util.TaskEvent
-import com.sun.source.util.TaskEvent.Kind.ANALYZE
-import com.sun.source.util.TaskListener
-import com.sun.tools.javac.api.JavacTrees
-import com.sun.tools.javac.api.MultiTaskListener
-import com.sun.tools.javac.code.Types
-import com.sun.tools.javac.comp.Annotate
-import com.sun.tools.javac.comp.Check
-import com.sun.tools.javac.comp.CompileStates
-import com.sun.tools.javac.comp.Enter
-import com.sun.tools.javac.comp.Modules
-import com.sun.tools.javac.file.CacheFSInfo
-import com.sun.tools.javac.file.FSInfo
-import com.sun.tools.javac.main.Arguments
-import com.sun.tools.javac.main.JavaCompiler
-import com.sun.tools.javac.model.JavacElements
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit
-import com.sun.tools.javac.util.Context
-import com.sun.tools.javac.util.DefinedBy
-import com.sun.tools.javac.util.DefinedBy.Api.COMPILER_TREE
-import com.sun.tools.javac.util.Log
+import openjdk.source.util.JavacTask
+import openjdk.source.util.TaskEvent
+import openjdk.source.util.TaskEvent.Kind.ANALYZE
+import openjdk.source.util.TaskListener
+import openjdk.tools.javac.api.JavacTrees
+import openjdk.tools.javac.api.MultiTaskListener
+import openjdk.tools.javac.code.Types
+import openjdk.tools.javac.comp.Annotate
+import openjdk.tools.javac.comp.Check
+import openjdk.tools.javac.comp.CompileStates
+import openjdk.tools.javac.comp.Enter
+import openjdk.tools.javac.comp.Modules
+import openjdk.tools.javac.file.CacheFSInfo
+import openjdk.tools.javac.file.FSInfo
+import openjdk.tools.javac.main.Arguments
+import openjdk.tools.javac.main.JavaCompiler
+import openjdk.tools.javac.model.JavacElements
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit
+import openjdk.tools.javac.util.Context
+import openjdk.tools.javac.util.DefinedBy
+import openjdk.tools.javac.util.DefinedBy.Api.COMPILER_TREE
+import openjdk.tools.javac.util.Log
import java.io.PrintWriter
import java.net.URI
-import javax.tools.DiagnosticListener
-import javax.tools.JavaFileManager
-import javax.tools.JavaFileObject
+import jdkx.tools.DiagnosticListener
+import jdkx.tools.JavaFileManager
+import jdkx.tools.JavaFileObject
/**
* Reusable [Context] for [ReusableCompiler].
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt
index 93025a1fbd..9dd5fad086 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableJavaCompiler.kt
@@ -18,8 +18,8 @@
package com.itsaky.androidide.javac.services.compiler
import com.itsaky.androidide.javac.services.NBJavaCompiler
-import com.sun.tools.javac.main.JavaCompiler
-import com.sun.tools.javac.util.Context
+import openjdk.tools.javac.main.JavaCompiler
+import openjdk.tools.javac.util.Context
/**
* Reusable JavaCompiler; exposes a method to clean up the component from leftovers associated
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableLog.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableLog.kt
index 09534846f5..7b102f6321 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableLog.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/compiler/ReusableLog.kt
@@ -17,14 +17,14 @@
package com.itsaky.androidide.javac.services.compiler
import com.itsaky.androidide.javac.services.NBLog
-import com.sun.tools.javac.util.Context
-import com.sun.tools.javac.util.DefinedBy
-import com.sun.tools.javac.util.DefinedBy.Api.COMPILER
-import com.sun.tools.javac.util.Log
+import openjdk.tools.javac.util.Context
+import openjdk.tools.javac.util.DefinedBy
+import openjdk.tools.javac.util.DefinedBy.Api.COMPILER
+import openjdk.tools.javac.util.Log
import java.io.PrintWriter
-import javax.tools.Diagnostic
-import javax.tools.DiagnosticListener
-import javax.tools.JavaFileObject
+import jdkx.tools.Diagnostic
+import jdkx.tools.DiagnosticListener
+import jdkx.tools.JavaFileObject
/**
* Reusable Log; exposes a method to clean up the component from leftovers associated with
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CacheFSInfoSingleton.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CacheFSInfoSingleton.kt
index 438fda11bf..904daf2742 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CacheFSInfoSingleton.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CacheFSInfoSingleton.kt
@@ -18,7 +18,7 @@
package com.itsaky.androidide.javac.services.fs
import com.itsaky.androidide.utils.VMUtils
-import com.sun.tools.javac.file.CacheFSInfo
+import openjdk.tools.javac.file.CacheFSInfo
import java.nio.file.Path
/**
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CachedJarFileSystem.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CachedJarFileSystem.kt
index da0d178cdb..be24bda86c 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CachedJarFileSystem.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/CachedJarFileSystem.kt
@@ -19,10 +19,10 @@ package com.itsaky.androidide.javac.services.fs
import com.itsaky.androidide.zipfs2.ZipFileSystem
import com.itsaky.androidide.zipfs2.ZipFileSystemProvider
-import com.sun.tools.javac.file.RelativePath.RelativeDirectory
+import openjdk.tools.javac.file.RelativePath.RelativeDirectory
import java.io.IOException
import java.nio.file.Path
-import javax.lang.model.SourceVersion
+import jdkx.lang.model.SourceVersion
/**
* A cached file system for JAR files.
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/JarPackageProviderImpl.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/JarPackageProviderImpl.kt
index 3cfaf45442..8bbe8fdb43 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/JarPackageProviderImpl.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/fs/JarPackageProviderImpl.kt
@@ -19,7 +19,7 @@ package com.itsaky.androidide.javac.services.fs
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.zipfs2.JarPackageProvider
-import com.sun.tools.javac.file.RelativePath.RelativeDirectory
+import openjdk.tools.javac.file.RelativePath.RelativeDirectory
import java.nio.file.Path
/**
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/CompilationInfo.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/CompilationInfo.kt
index 6b0a5566cb..cf109a6f12 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/CompilationInfo.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/CompilationInfo.kt
@@ -17,11 +17,11 @@
package com.itsaky.androidide.javac.services.partial
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.tools.javac.api.JavacTaskImpl
-import com.sun.tools.javac.api.JavacTrees
-import javax.tools.DiagnosticListener
-import javax.tools.JavaFileObject
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.tools.javac.api.JavacTaskImpl
+import openjdk.tools.javac.api.JavacTrees
+import jdkx.tools.DiagnosticListener
+import jdkx.tools.JavaFileObject
/**
* Information about a compilation.
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/DiagnosticListenerImpl.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/DiagnosticListenerImpl.java
index a41203bb88..f781c0c05c 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/DiagnosticListenerImpl.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/DiagnosticListenerImpl.java
@@ -19,8 +19,8 @@
import androidx.annotation.Nullable;
-import com.sun.tools.javac.api.ClientCodeWrapper;
-import com.sun.tools.javac.util.JCDiagnostic;
+import openjdk.tools.javac.api.ClientCodeWrapper;
+import openjdk.tools.javac.util.JCDiagnostic;
import java.util.ArrayList;
import java.util.Arrays;
@@ -34,9 +34,9 @@
import java.util.SortedMap;
import java.util.TreeMap;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticListener;
-import javax.tools.JavaFileObject;
+import jdkx.tools.Diagnostic;
+import jdkx.tools.DiagnosticListener;
+import jdkx.tools.JavaFileObject;
/**
* @author Akash Yadav
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparser.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparser.kt
index a50c012134..b2210e33cb 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparser.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparser.kt
@@ -17,7 +17,7 @@
package com.itsaky.androidide.javac.services.partial
-import com.sun.source.util.TreePath
+import openjdk.source.util.TreePath
/**
* A parser reparser parses part of code.
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparserImpl.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparserImpl.kt
index 3bf2c77eab..8fe22362ba 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparserImpl.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/PartialReparserImpl.kt
@@ -22,38 +22,38 @@ import com.itsaky.androidide.javac.services.util.ReparserUtils
import com.itsaky.androidide.javac.services.visitors.FindAnonymousVisitor
import com.itsaky.androidide.javac.services.visitors.TranslateMethodPositionsVisitor
import com.itsaky.androidide.utils.ILogger
-import com.sun.source.tree.BlockTree
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.CompilationUnitTree
-import com.sun.source.tree.Tree.Kind.BLOCK
-import com.sun.source.tree.Tree.Kind.METHOD
-import com.sun.source.util.TreePath
-import com.sun.tools.javac.api.JavacScope
-import com.sun.tools.javac.api.JavacTrees
-import com.sun.tools.javac.code.Flags
-import com.sun.tools.javac.code.Symbol
-import com.sun.tools.javac.code.Symtab
-import com.sun.tools.javac.comp.Attr
-import com.sun.tools.javac.comp.AttrContext
-import com.sun.tools.javac.comp.Enter
-import com.sun.tools.javac.comp.Env
-import com.sun.tools.javac.comp.Flow
-import com.sun.tools.javac.parser.JavacParser
-import com.sun.tools.javac.parser.LazyDocCommentTable.Entry
-import com.sun.tools.javac.parser.ScannerFactory
-import com.sun.tools.javac.tree.DocCommentTable
-import com.sun.tools.javac.tree.EndPosTable
-import com.sun.tools.javac.tree.JCTree
-import com.sun.tools.javac.tree.JCTree.JCBlock
-import com.sun.tools.javac.tree.JCTree.JCClassDecl
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl
-import com.sun.tools.javac.tree.TreeInfo
-import com.sun.tools.javac.tree.TreeMaker
-import com.sun.tools.javac.util.Context
-import com.sun.tools.javac.util.List
-import com.sun.tools.javac.util.Log
-import com.sun.tools.javac.util.Names
+import openjdk.source.tree.BlockTree
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.CompilationUnitTree
+import openjdk.source.tree.Tree.Kind.BLOCK
+import openjdk.source.tree.Tree.Kind.METHOD
+import openjdk.source.util.TreePath
+import openjdk.tools.javac.api.JavacScope
+import openjdk.tools.javac.api.JavacTrees
+import openjdk.tools.javac.code.Flags
+import openjdk.tools.javac.code.Symbol
+import openjdk.tools.javac.code.Symtab
+import openjdk.tools.javac.comp.Attr
+import openjdk.tools.javac.comp.AttrContext
+import openjdk.tools.javac.comp.Enter
+import openjdk.tools.javac.comp.Env
+import openjdk.tools.javac.comp.Flow
+import openjdk.tools.javac.parser.JavacParser
+import openjdk.tools.javac.parser.LazyDocCommentTable.Entry
+import openjdk.tools.javac.parser.ScannerFactory
+import openjdk.tools.javac.tree.DocCommentTable
+import openjdk.tools.javac.tree.EndPosTable
+import openjdk.tools.javac.tree.JCTree
+import openjdk.tools.javac.tree.JCTree.JCBlock
+import openjdk.tools.javac.tree.JCTree.JCClassDecl
+import openjdk.tools.javac.tree.JCTree.JCCompilationUnit
+import openjdk.tools.javac.tree.JCTree.JCMethodDecl
+import openjdk.tools.javac.tree.TreeInfo
+import openjdk.tools.javac.tree.TreeMaker
+import openjdk.tools.javac.util.Context
+import openjdk.tools.javac.util.List
+import openjdk.tools.javac.util.Log
+import openjdk.tools.javac.util.Names
import java.nio.CharBuffer
import java.util.*
@@ -330,7 +330,7 @@ class PartialReparserImpl : PartialReparser {
// generated one.
log.error(
tree.body.stats.head.pos(),
- com.sun.tools.javac.util.JCDiagnostic.Error(
+ openjdk.tools.javac.util.JCDiagnostic.Error(
"compiler",
"call.to.super.not.allowed.in.enum.ctor",
env.enclClass.sym
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/RichDiagnostic.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/RichDiagnostic.java
index 8975fd5ff3..061c24676e 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/RichDiagnostic.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/partial/RichDiagnostic.java
@@ -17,12 +17,12 @@
package com.itsaky.androidide.javac.services.partial;
-import com.sun.tools.javac.api.DiagnosticFormatter;
-import com.sun.tools.javac.util.JCDiagnostic;
+import openjdk.tools.javac.api.DiagnosticFormatter;
+import openjdk.tools.javac.util.JCDiagnostic;
import java.util.Locale;
-import javax.tools.Diagnostic;
+import jdkx.tools.Diagnostic;
/**
* @author Akash Yadav
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavaDiagnosticUtils.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavaDiagnosticUtils.kt
index 1fd6824756..cfe66a06fd 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavaDiagnosticUtils.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavaDiagnosticUtils.kt
@@ -17,10 +17,10 @@
package com.itsaky.androidide.javac.services.util
-import com.sun.tools.javac.api.ClientCodeWrapper
-import com.sun.tools.javac.util.JCDiagnostic
-import javax.tools.Diagnostic
-import javax.tools.JavaFileObject
+import openjdk.tools.javac.api.ClientCodeWrapper
+import openjdk.tools.javac.util.JCDiagnostic
+import jdkx.tools.Diagnostic
+import jdkx.tools.JavaFileObject
/** @author Akash Yadav */
class JavaDiagnosticUtils {
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavacTaskUtil.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavacTaskUtil.java
deleted file mode 100644
index 269faaf864..0000000000
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/JavacTaskUtil.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.androidide.javac.services.util;
-
-import androidx.annotation.NonNull;
-
-import com.itsaky.androidide.utils.ILogger;
-import com.itsaky.androidide.utils.VMUtils;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.tools.javac.api.JavacTaskImpl;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.lang.model.element.Element;
-import javax.tools.JavaFileObject;
-
-/**
- * @author Akash Yadav
- */
-public class JavacTaskUtil {
-
- private static final ILogger LOG = ILogger.newInstance("JavacTaskUtil");
-
- public static void cleanup(JavacTaskImpl task) {
- if (VMUtils.isJvm()) {
- jvmCleanup(task);
- } else {
- task.cleanup();
- }
- }
-
- public static void jvmCleanup(@NonNull JavacTaskImpl task) {
- try {
- final Class> klass = JavacTaskImpl.class;
- final Method method = klass.getDeclaredMethod("cleanup");
- if (!method.isAccessible()) {
- method.setAccessible(true);
- }
- method.invoke(task);
- } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
- LOG.error("Unable to cleanup JavacTaskImpl", e);
- throw new RuntimeException(e);
- }
- }
-
- public static Iterable extends CompilationUnitTree> parse(
- JavacTaskImpl task, JavaFileObject... sources) throws IOException {
-
- if (!VMUtils.isJvm()) {
- return task.parse(sources);
- }
-
- // No method JavacTaskImpl.parse(JavaFileObject[]) in jdk
- return task.parse();
- }
-
- public static Iterable extends Element> enterTrees(
- JavacTaskImpl task, Iterable extends CompilationUnitTree> trees) throws IOException {
-
- if (!VMUtils.isJvm()) {
- return task.enterTrees(trees);
- }
-
- // No method JavacTaskImpl.enterTrees(Iterable) in jdk
- return task.enter(trees);
- }
-
- public static Iterable extends Element> analyze(
- JavacTaskImpl task, Iterable extends Element> elements) {
- // No difference in method signature defined in nb-javac-android and jdk
- return task.analyze(elements);
- }
-}
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/ReparserUtils.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/ReparserUtils.java
index eb40ec748f..4d79c69cf9 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/ReparserUtils.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/util/ReparserUtils.java
@@ -22,13 +22,13 @@
import com.itsaky.androidide.javac.services.visitors.UnEnter;
import com.itsaky.androidide.utils.ILogger;
import com.itsaky.androidide.utils.VMUtils;
-import com.sun.tools.javac.comp.Enter;
-import com.sun.tools.javac.parser.JavacParser;
-import com.sun.tools.javac.parser.LazyDocCommentTable;
-import com.sun.tools.javac.tree.DocCommentTable;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Position;
+import openjdk.tools.javac.comp.Enter;
+import openjdk.tools.javac.parser.JavacParser;
+import openjdk.tools.javac.parser.LazyDocCommentTable;
+import openjdk.tools.javac.tree.DocCommentTable;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.util.Context;
+import openjdk.tools.javac.util.Position;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -155,7 +155,7 @@ private static void initIfNecessary() {
if (lineMapBuild == null) {
lineMapBuild =
tryReflectMethod(
- "com.sun.tools.javac.util.Position$LineMapImpl", "build", char[].class, int.class);
+ "openjdk.tools.javac.util.Position$LineMapImpl", "build", char[].class, int.class);
}
if (lazyDocCommentsTable == null) {
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/ErrorAwareTreeScanner.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/ErrorAwareTreeScanner.kt
index 8f6510494d..bd062afb6d 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/ErrorAwareTreeScanner.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/ErrorAwareTreeScanner.kt
@@ -17,8 +17,8 @@
package com.itsaky.androidide.javac.services.visitors
-import com.sun.source.tree.ErroneousTree
-import com.sun.source.util.TreeScanner
+import openjdk.source.tree.ErroneousTree
+import openjdk.source.util.TreeScanner
/** @author Akash Yadav */
open class ErrorAwareTreeScanner : TreeScanner() {
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/FindAnonymousVisitor.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/FindAnonymousVisitor.kt
index 33cfc59111..9e4d66ab40 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/FindAnonymousVisitor.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/FindAnonymousVisitor.kt
@@ -19,10 +19,10 @@ package com.itsaky.androidide.javac.services.visitors
import com.itsaky.androidide.javac.services.visitors.FindAnonymousVisitor.Mode.CHECK
import com.itsaky.androidide.javac.services.visitors.FindAnonymousVisitor.Mode.COLLECT
-import com.sun.source.tree.ClassTree
-import com.sun.source.tree.MethodTree
-import com.sun.source.tree.Tree
-import com.sun.source.tree.VariableTree
+import openjdk.source.tree.ClassTree
+import openjdk.source.tree.MethodTree
+import openjdk.source.tree.Tree
+import openjdk.source.tree.VariableTree
/**
* Partial reparse helper visitor. Finds anonymous and local classes in given method tree.
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/TranslateMethodPositionsVisitor.java b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/TranslateMethodPositionsVisitor.java
index 122e6d1da0..55b0cb5c86 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/TranslateMethodPositionsVisitor.java
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/TranslateMethodPositionsVisitor.java
@@ -17,13 +17,13 @@
package com.itsaky.androidide.javac.services.visitors;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import com.sun.tools.javac.tree.EndPosTable;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import openjdk.source.tree.CompilationUnitTree;
+import openjdk.source.tree.MethodTree;
+import openjdk.source.tree.Tree;
+import openjdk.source.tree.VariableTree;
+import openjdk.tools.javac.tree.EndPosTable;
+import openjdk.tools.javac.tree.JCTree;
+import openjdk.tools.javac.tree.JCTree.JCVariableDecl;
/** Helper visitor for partial reparse. Updates tree positions by the given delta. */
public class TranslateMethodPositionsVisitor extends ErrorAwareTreeScanner {
diff --git a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/UnEnter.kt b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/UnEnter.kt
index 73e49a7615..ab60bc0cf0 100644
--- a/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/UnEnter.kt
+++ b/subprojects/javac-services/src/main/java/com/itsaky/androidide/javac/services/visitors/UnEnter.kt
@@ -17,10 +17,10 @@
package com.itsaky.androidide.javac.services.visitors
import com.blankj.utilcode.util.ReflectUtils
-import com.sun.tools.javac.code.Symbol.ModuleSymbol
-import com.sun.tools.javac.comp.Enter
-import com.sun.tools.javac.tree.JCTree.JCClassDecl
-import com.sun.tools.javac.tree.TreeScanner
+import openjdk.tools.javac.code.Symbol.ModuleSymbol
+import openjdk.tools.javac.comp.Enter
+import openjdk.tools.javac.tree.JCTree.JCClassDecl
+import openjdk.tools.javac.tree.TreeScanner
/**
* `Enter.unenter` method is not available in JDK 11. This visitor does the same thing as calling
diff --git a/subprojects/javac/build.gradle.kts b/subprojects/javac/build.gradle.kts
index adabae9fa8..87ef432aa1 100644
--- a/subprojects/javac/build.gradle.kts
+++ b/subprojects/javac/build.gradle.kts
@@ -33,7 +33,8 @@ configurations.all {
dependencies {
- api (libs.androidide.javac) {
- isChanging = true
- }
+ api(files("libs/nb-javac-17.0.0.4-android.jar"))
+// api (libs.androidide.javac) {
+// isChanging = true
+// }
}
\ No newline at end of file
diff --git a/subprojects/javac/libs/nb-javac-17.0.0.4-android.jar b/subprojects/javac/libs/nb-javac-17.0.0.4-android.jar
new file mode 100644
index 0000000000..687fbbb96e
Binary files /dev/null and b/subprojects/javac/libs/nb-javac-17.0.0.4-android.jar differ
diff --git a/subprojects/jdt/src/main/java/org/eclipse/jdt/core/compiler/CharOperation.java b/subprojects/jdt/src/main/java/org/eclipse/jdt/core/compiler/CharOperation.java
index fc7ecde910..89b26a3155 100755
--- a/subprojects/jdt/src/main/java/org/eclipse/jdt/core/compiler/CharOperation.java
+++ b/subprojects/jdt/src/main/java/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -30,7 +30,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Luiz-Otavio Zorzella - Improve CamelCase algorithm
- * Gábor Kövesdán - Contribution for Bug 350000 - [content assist] Include non-prefix matches in auto-complete suggestions
+ * Gabor Kovesdan - Contribution for Bug 350000 - [content assist] Include non-prefix matches in auto-complete suggestions
* Stefan Xenos (Google) - Bug 501283 - Lots of hash collisions during indexing
*******************************************************************************/
package org.eclipse.jdt.core.compiler;
diff --git a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CancelChecker.java b/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CancelChecker.java
deleted file mode 100644
index 670a6d93f4..0000000000
--- a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CancelChecker.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2016 TypeFox and others.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- ******************************************************************************/
-package org.eclipse.lsp4j.jsonrpc;
-
-import java.util.concurrent.CancellationException;
-
-/** Used for processing requests with cancellation support. */
-public interface CancelChecker {
-
- /** Check for cancellation without throwing an exception. */
- default boolean isCanceled() {
- try {
- checkCanceled();
- } catch (CancellationException ce) {
- return true;
- }
- return false;
- }
-
- /** Throw a {@link CancellationException} if the currently processed request has been canceled. */
- void checkCanceled();
-}
diff --git a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java b/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java
deleted file mode 100644
index 3a0e842ab2..0000000000
--- a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/CompletableFutures.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2016 TypeFox and others.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- ******************************************************************************/
-package org.eclipse.lsp4j.jsonrpc;
-
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Executor;
-import java.util.function.Function;
-
-public final class CompletableFutures {
- private CompletableFutures() {}
-
- /**
- * A utility method to create a {@link CompletableFuture} with cancellation support.
- *
- * @param code a function that accepts a {@link CancelChecker} and returns the to be computed
- * value
- * @return a future
- */
- public static CompletableFuture computeAsync(Function code) {
- CompletableFuture start = new CompletableFuture<>();
- CompletableFuture result = start.thenApplyAsync(code);
- start.complete(new FutureCancelChecker(result));
- return result;
- }
-
- /**
- * A utility method to create a {@link CompletableFuture} with cancellation support.
- *
- * @param code a function that accepts a {@link CancelChecker} and returns the to be computed
- * value
- * @return a future
- */
- public static CompletableFuture computeAsync(
- Executor executor, Function code) {
- CompletableFuture start = new CompletableFuture<>();
- CompletableFuture result = start.thenApplyAsync(code, executor);
- start.complete(new FutureCancelChecker(result));
- return result;
- }
-
- public static class FutureCancelChecker implements CancelChecker {
-
- private final CompletableFuture> future;
-
- public FutureCancelChecker(CompletableFuture> future) {
- this.future = future;
- }
-
- @Override
- public boolean isCanceled() {
- return future.isCancelled();
- }
-
- @Override
- public void checkCanceled() {
- if (future.isCancelled()) throw new CancellationException();
- }
- }
-}
diff --git a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Endpoint.java b/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Endpoint.java
deleted file mode 100644
index 5a95e452f2..0000000000
--- a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Endpoint.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2016 TypeFox and others.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- ******************************************************************************/
-package org.eclipse.lsp4j.jsonrpc;
-
-import java.util.concurrent.CompletableFuture;
-
-/** An endpoint is a generic interface that accepts jsonrpc requests and notifications. */
-public interface Endpoint {
-
- CompletableFuture> request(String method, Object parameter);
-
- void notify(String method, Object parameter);
-}
diff --git a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/JsonRpcException.java b/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/JsonRpcException.java
deleted file mode 100644
index 91c3f430a1..0000000000
--- a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/JsonRpcException.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2018 TypeFox and others.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- ******************************************************************************/
-package org.eclipse.lsp4j.jsonrpc;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.SocketException;
-import java.nio.channels.ClosedChannelException;
-
-/** An exception thrown when accessing the JSON-RPC communication channel fails. */
-public class JsonRpcException extends RuntimeException {
-
- private static final long serialVersionUID = -7952794305289314670L;
-
- public JsonRpcException(Throwable cause) {
- super(cause);
- }
-
- /** Whether the given exception indicates that the currently accessed stream has been closed. */
- public static boolean indicatesStreamClosed(Throwable thr) {
- return thr instanceof InterruptedIOException
- || thr instanceof ClosedChannelException
- || thr instanceof IOException && "Pipe closed".equals(thr.getMessage())
- || thr instanceof SocketException
- && ("Connection reset".equals(thr.getMessage())
- || "Socket closed".equals(thr.getMessage())
- || "Broken pipe (Write failed)".equals(thr.getMessage()))
- || thr instanceof JsonRpcException && indicatesStreamClosed(thr.getCause());
- }
-}
diff --git a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java b/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java
deleted file mode 100644
index 4966ab7db4..0000000000
--- a/subprojects/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/Launcher.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2016-2018 TypeFox and others.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0,
- * or the Eclipse Distribution License v. 1.0 which is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- ******************************************************************************/
-package org.eclipse.lsp4j.jsonrpc;
-
-import com.google.gson.GsonBuilder;
-
-import org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor;
-import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
-import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethodProvider;
-import org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler;
-import org.eclipse.lsp4j.jsonrpc.json.StreamMessageConsumer;
-import org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer;
-import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
-import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
-import org.eclipse.lsp4j.jsonrpc.validation.ReflectiveMessageValidator;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * This is the entry point for applications that use LSP4J. A Launcher does all the wiring that is
- * necessary to connect your endpoint via an input stream and an output stream.
- *
- * @param remote service interface type
- */
-public interface Launcher {
-
- /**
- * Create a new Launcher for a given local service object, a given remote interface and an input
- * and output stream.
- *
- * @param localService - the object that receives method calls from the remote service
- * @param remoteInterface - an interface on which RPC methods are looked up
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- */
- static Launcher createLauncher(
- Object localService, Class remoteInterface, InputStream in, OutputStream out) {
- return new Builder()
- .setLocalService(localService)
- .setRemoteInterface(remoteInterface)
- .setInput(in)
- .setOutput(out)
- .create();
- }
-
- /**
- * Create a new Launcher for a given local service object, a given remote interface and an input
- * and output stream, and set up message validation and tracing.
- *
- * @param localService - the object that receives method calls from the remote service
- * @param remoteInterface - an interface on which RPC methods are looked up
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- * @param validate - whether messages should be validated with the {@link
- * ReflectiveMessageValidator}
- * @param trace - a writer to which incoming and outgoing messages are traced, or {@code null} to
- * disable tracing
- */
- static Launcher createLauncher(
- Object localService,
- Class remoteInterface,
- InputStream in,
- OutputStream out,
- boolean validate,
- PrintWriter trace) {
- return new Builder()
- .setLocalService(localService)
- .setRemoteInterface(remoteInterface)
- .setInput(in)
- .setOutput(out)
- .validateMessages(validate)
- .traceMessages(trace)
- .create();
- }
-
- /**
- * Create a new Launcher for a given local service object, a given remote interface and an input
- * and output stream. Threads are started with the given executor service. The wrapper function is
- * applied to the incoming and outgoing message streams so additional message handling such as
- * validation and tracing can be included.
- *
- * @param localService - the object that receives method calls from the remote service
- * @param remoteInterface - an interface on which RPC methods are looked up
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- * @param executorService - the executor service used to start threads
- * @param wrapper - a function for plugging in additional message consumers
- */
- static Launcher createLauncher(
- Object localService,
- Class remoteInterface,
- InputStream in,
- OutputStream out,
- ExecutorService executorService,
- Function wrapper) {
- return createIoLauncher(localService, remoteInterface, in, out, executorService, wrapper);
- }
-
- /**
- * Create a new Launcher for a given local service object, a given remote interface and an input
- * and output stream. Threads are started with the given executor service. The wrapper function is
- * applied to the incoming and outgoing message streams so additional message handling such as
- * validation and tracing can be included.
- *
- * @param localService - the object that receives method calls from the remote service
- * @param remoteInterface - an interface on which RPC methods are looked up
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- * @param executorService - the executor service used to start threads
- * @param wrapper - a function for plugging in additional message consumers
- */
- static Launcher createIoLauncher(
- Object localService,
- Class remoteInterface,
- InputStream in,
- OutputStream out,
- ExecutorService executorService,
- Function wrapper) {
- return new Builder()
- .setLocalService(localService)
- .setRemoteInterface(remoteInterface)
- .setInput(in)
- .setOutput(out)
- .setExecutorService(executorService)
- .wrapMessages(wrapper)
- .create();
- }
-
- /**
- * Create a new Launcher for a given local service object, a given remote interface and an input
- * and output stream. Threads are started with the given executor service. The wrapper function is
- * applied to the incoming and outgoing message streams so additional message handling such as
- * validation and tracing can be included. The {@code configureGson} function can be used to
- * register additional type adapters in the {@link GsonBuilder} in order to support protocol
- * classes that cannot be handled by Gson's reflective capabilities.
- *
- * @param localService - the object that receives method calls from the remote service
- * @param remoteInterface - an interface on which RPC methods are looked up
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- * @param executorService - the executor service used to start threads
- * @param wrapper - a function for plugging in additional message consumers
- * @param configureGson - a function for Gson configuration
- */
- static Launcher createIoLauncher(
- Object localService,
- Class remoteInterface,
- InputStream in,
- OutputStream out,
- ExecutorService executorService,
- Function wrapper,
- Consumer configureGson) {
- return new Builder()
- .setLocalService(localService)
- .setRemoteInterface(remoteInterface)
- .setInput(in)
- .setOutput(out)
- .setExecutorService(executorService)
- .wrapMessages(wrapper)
- .configureGson(configureGson)
- .create();
- }
-
- /**
- * Create a new Launcher for a given local service object, a given remote interface and an input
- * and output stream. Threads are started with the given executor service. The wrapper function is
- * applied to the incoming and outgoing message streams so additional message handling such as
- * validation and tracing can be included. The {@code configureGson} function can be used to
- * register additional type adapters in the {@link GsonBuilder} in order to support protocol
- * classes that cannot be handled by Gson's reflective capabilities.
- *
- * @param localService - the object that receives method calls from the remote service
- * @param remoteInterface - an interface on which RPC methods are looked up
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- * @param validate - whether messages should be validated with the {@link
- * ReflectiveMessageValidator}
- * @param executorService - the executor service used to start threads
- * @param wrapper - a function for plugging in additional message consumers
- * @param configureGson - a function for Gson configuration
- */
- static Launcher createIoLauncher(
- Object localService,
- Class remoteInterface,
- InputStream in,
- OutputStream out,
- boolean validate,
- ExecutorService executorService,
- Function wrapper,
- Consumer configureGson) {
- return new Builder()
- .setLocalService(localService)
- .setRemoteInterface(remoteInterface)
- .setInput(in)
- .setOutput(out)
- .validateMessages(validate)
- .setExecutorService(executorService)
- .wrapMessages(wrapper)
- .configureGson(configureGson)
- .create();
- }
-
- /**
- * Create a new Launcher for a collection of local service objects, a collection of remote
- * interfaces and an input and output stream. Threads are started with the given executor service.
- * The wrapper function is applied to the incoming and outgoing message streams so additional
- * message handling such as validation and tracing can be included. The {@code configureGson}
- * function can be used to register additional type adapters in the {@link GsonBuilder} in order
- * to support protocol classes that cannot be handled by Gson's reflective capabilities.
- *
- * @param localServices - the objects that receive method calls from the remote services
- * @param remoteInterfaces - interfaces on which RPC methods are looked up
- * @param classLoader - a class loader that is able to resolve all given interfaces
- * @param in - input stream to listen for incoming messages
- * @param out - output stream to send outgoing messages
- * @param executorService - the executor service used to start threads
- * @param wrapper - a function for plugging in additional message consumers
- * @param configureGson - a function for Gson configuration
- */
- static Launcher