mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
feat(projects): implement project deserialization and transformation (2/2)
This commit is contained in:
@@ -67,7 +67,7 @@ class QuickRunAction(context: Context) : BaseBuildAction() {
|
||||
return@execTasks
|
||||
}
|
||||
|
||||
val (_, main) = foundVariant.get()
|
||||
val main = foundVariant.get().mainArtifact
|
||||
val outputListingFile = main.assembleTaskOutputListingFile
|
||||
if (outputListingFile == null) {
|
||||
log.error("No output listing file provided with project model")
|
||||
|
||||
@@ -44,8 +44,8 @@ class FindInProjectAction() : EditorActivityAction() {
|
||||
return
|
||||
}
|
||||
|
||||
val root = ProjectManager.rootProject
|
||||
if (root == null || root.subModules.isEmpty()) {
|
||||
val project = ProjectManager.rootProject
|
||||
if (project == null || project.subProjects.isEmpty()) {
|
||||
markInvisible()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -457,6 +457,7 @@ abstract class BaseEditorActivity :
|
||||
}
|
||||
|
||||
private fun onBuildStatusChanged() {
|
||||
log.debug("onBuildStatusChanged: isInitializing: ${viewModel.isInitializing}, isBuildInProgress: ${viewModel.isBuildInProgress}")
|
||||
val visible = viewModel.isBuildInProgress || viewModel.isInitializing
|
||||
binding.buildProgressIndicator.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
invalidateOptionsMenu()
|
||||
|
||||
@@ -44,7 +44,7 @@ import com.itsaky.androidide.projects.ProjectManager.projectInitialized
|
||||
import com.itsaky.androidide.projects.ProjectManager.projectPath
|
||||
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.api.GradleProject
|
||||
import com.itsaky.androidide.projects.builder.BuildService
|
||||
import com.itsaky.androidide.services.builder.GradleBuildService
|
||||
import com.itsaky.androidide.services.builder.GradleBuildServiceConnnection
|
||||
@@ -214,7 +214,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
|
||||
override fun initializeProject() {
|
||||
val projectDir = File(projectPath)
|
||||
if (!projectDir.exists()) {
|
||||
log.error("Project directory does not exist. Cannot initialize project")
|
||||
log.error("GradleProject directory does not exist. Cannot initialize project")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
|
||||
// In this case, we should not start another project initialization
|
||||
log.debug("Using cached initialize result as the project is already initialized")
|
||||
CompletableFuture.supplyAsync {
|
||||
log.warn("Project has already been initialized. Skipping initialization process.")
|
||||
log.warn("GradleProject has already been initialized. Skipping initialization process.")
|
||||
cachedInitResult
|
||||
}
|
||||
}
|
||||
@@ -336,7 +336,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
|
||||
|
||||
val moduleDirs =
|
||||
try {
|
||||
rootProject!!.subModules.stream().map(Project::projectDir).collect(Collectors.toList())
|
||||
rootProject!!.subProjects.stream().map(GradleProject::projectDir).collect(Collectors.toList())
|
||||
} catch (e: Throwable) {
|
||||
flashError(getString(string.msg_no_modules))
|
||||
emptyList()
|
||||
@@ -429,13 +429,13 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler {
|
||||
private fun initialSetup() {
|
||||
lastOpenedProject = getProjectDirPath()
|
||||
try {
|
||||
val rootProject = rootProject
|
||||
if (rootProject == null) {
|
||||
log.warn("Project not initialized. Skipping initial setup...")
|
||||
val project = rootProject
|
||||
if (project == null) {
|
||||
log.warn("GradleProject not initialized. Skipping initial setup...")
|
||||
return
|
||||
}
|
||||
|
||||
var projectName = rootProject.name
|
||||
var projectName = project.rootProject.name
|
||||
if (projectName.isEmpty()) {
|
||||
projectName = File(getProjectDirPath()).name
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.itsaky.androidide.adapters.RunTasksListAdapter.VH
|
||||
import com.itsaky.androidide.databinding.LayoutRunTaskItemBinding
|
||||
import com.itsaky.androidide.models.Checkable
|
||||
import com.itsaky.androidide.tooling.api.model.GradleTask
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
|
||||
/**
|
||||
* Adapter for showing tasks list in [RunTaskDialogFragment]
|
||||
|
||||
@@ -49,7 +49,7 @@ import com.itsaky.androidide.projects.ProjectManager
|
||||
import com.itsaky.androidide.projects.builder.BuildService
|
||||
import com.itsaky.androidide.resources.R
|
||||
import com.itsaky.androidide.tasks.executeAsync
|
||||
import com.itsaky.androidide.tooling.api.model.GradleTask
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.SingleTextWatcher
|
||||
import com.itsaky.androidide.utils.doOnApplyWindowInsets
|
||||
@@ -183,10 +183,11 @@ class RunTasksDialogFragment : BottomSheetDialogFragment() {
|
||||
viewModel.displayedChild = CHILD_LOADING
|
||||
|
||||
executeAsync({
|
||||
val project = ProjectManager.rootProject
|
||||
val rootProject =
|
||||
ProjectManager.rootProject ?: return@executeAsync emptyList<Checkable<GradleTask>>()
|
||||
project?.rootProject ?: return@executeAsync emptyList<Checkable<GradleTask>>()
|
||||
val tasks = rootProject.tasks.map { Checkable(false, it) }.toMutableList()
|
||||
tasks.addAll(rootProject.subModules.flatMap { it.tasks }.map { Checkable(false, it) })
|
||||
tasks.addAll(project.subProjects.flatMap { it.tasks }.map { Checkable(false, it) })
|
||||
return@executeAsync tasks
|
||||
}) { tasks ->
|
||||
viewModel.tasks = tasks ?: emptyList()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package com.itsaky.androidide.models
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import com.itsaky.androidide.tooling.api.model.GradleTask
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
|
||||
/** @author Akash Yadav */
|
||||
data class RunTasksCategory(@StringRes val title: Int, val tasks: List<Checkable<GradleTask>>)
|
||||
|
||||
@@ -220,7 +220,7 @@ public class GradleBuildService extends Service implements BuildService, IToolin
|
||||
this.server = server;
|
||||
Lookup.getDefault().update(BuildService.KEY_PROJECT_PROXY, projectProxy);
|
||||
this.isToolingServerStarted = true;
|
||||
ProjectManager.INSTANCE.setupProject(projectProxy);
|
||||
ProjectManager.INSTANCE.setupProject(projectProxy, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -72,7 +72,7 @@ internal class ToolingServerRunner(
|
||||
"java.base/java.io=ALL-UNNAMED", // The JAR file to run
|
||||
"-jar", Environment.TOOLING_API_JAR.absolutePath)
|
||||
|
||||
val launcher = ToolingApiLauncher.newClientLauncher(observer?.getClient(),
|
||||
val launcher = ToolingApiLauncher.newClientLauncher(observer!!.getClient(),
|
||||
serverStreams.`in`, serverStreams.out)
|
||||
|
||||
val future = launcher.startListening()
|
||||
|
||||
@@ -22,7 +22,7 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.itsaky.androidide.models.Checkable
|
||||
import com.itsaky.androidide.tooling.api.model.GradleTask
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
|
||||
/** @author Akash Yadav */
|
||||
class RunTasksViewModel : ViewModel() {
|
||||
|
||||
+2
-1
@@ -21,8 +21,9 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.itsaky.androidide.eventbus.events.project.ProjectInitializedEvent;
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
import com.itsaky.androidide.projects.api.GradleProject;
|
||||
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
@@ -52,8 +52,9 @@ import com.itsaky.androidide.lsp.models.SignatureHelpParams;
|
||||
import com.itsaky.androidide.models.Range;
|
||||
import com.itsaky.androidide.progress.ICancelChecker;
|
||||
import com.itsaky.androidide.projects.ProjectManager;
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
import com.itsaky.androidide.projects.api.GradleProject;
|
||||
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ import com.itsaky.androidide.progress.ICancelChecker;
|
||||
import com.itsaky.androidide.projects.FileManager;
|
||||
import com.itsaky.androidide.projects.ProjectManager;
|
||||
import com.itsaky.androidide.projects.api.ModuleProject;
|
||||
import com.itsaky.androidide.projects.api.GradleProject;
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
import com.itsaky.androidide.utils.DocumentUtils;
|
||||
import com.itsaky.androidide.utils.ILogger;
|
||||
@@ -164,7 +165,7 @@ public class JavaLanguageServer implements ILanguageServer {
|
||||
JavaCompilerProvider.getInstance().destroy();
|
||||
|
||||
// Cache classpath locations
|
||||
for (final Project subModule : project.getSubModules()) {
|
||||
for (final GradleProject subModule : project.getSubProjects()) {
|
||||
if (!(subModule instanceof ModuleProject)) {
|
||||
continue;
|
||||
}
|
||||
@@ -284,7 +285,7 @@ public class JavaLanguageServer implements ILanguageServer {
|
||||
return JavaCompilerService.NO_MODULE_COMPILER;
|
||||
}
|
||||
|
||||
final Project root = ProjectManager.INSTANCE.getRootProject();
|
||||
final var root = ProjectManager.INSTANCE.getRootProject();
|
||||
if (root == null) {
|
||||
return JavaCompilerService.NO_MODULE_COMPILER;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.itsaky.androidide.models.Range;
|
||||
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.tooling.api.ProjectType;
|
||||
import com.itsaky.androidide.utils.ClassTrie;
|
||||
import com.itsaky.androidide.utils.SourceClassTrie;
|
||||
import com.itsaky.androidide.utils.StopWatch;
|
||||
@@ -150,7 +151,7 @@ public class CompileBatch implements AutoCloseable {
|
||||
|
||||
// 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) {
|
||||
if (this.parent.module != null && this.parent.module.getType() == ProjectType.Android) {
|
||||
setLatestSourceVersion(SourceVersion.RELEASE_8);
|
||||
setLatestSupportedSourceVersion(SourceVersion.RELEASE_11);
|
||||
disableModules();
|
||||
|
||||
@@ -44,8 +44,8 @@ import com.itsaky.androidide.lsp.xml.providers.CodeFormatProvider;
|
||||
import com.itsaky.androidide.lsp.xml.providers.XmlCompletionProvider;
|
||||
import com.itsaky.androidide.models.Range;
|
||||
import com.itsaky.androidide.progress.ICancelChecker;
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
|
||||
import com.itsaky.androidide.projects.api.Project;
|
||||
import com.itsaky.androidide.utils.DocumentUtils;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
-1
@@ -22,7 +22,6 @@ import java.io.Serializable
|
||||
|
||||
/** @author Akash Yadav */
|
||||
class DefaultJavaCompileOptions : IJavaCompilerSettings(), JavaCompileOptions, Serializable {
|
||||
private val serialVersionUID = 1L
|
||||
override var encoding: String = ""
|
||||
override var isCoreLibraryDesugaringEnabled: Boolean = false
|
||||
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ package com.itsaky.androidide.builder.model
|
||||
abstract class IJavaCompilerSettings {
|
||||
|
||||
private val gsonType: String = javaClass.name
|
||||
private val serialVersionUID = 1L
|
||||
|
||||
/** Source java version. */
|
||||
abstract val javaSourceVersion: String
|
||||
|
||||
+14
-11
@@ -35,16 +35,16 @@ import com.itsaky.androidide.tooling.api.messages.result.InitializeResult
|
||||
import com.itsaky.androidide.utils.DocumentUtils
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.flashError
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode.ASYNC
|
||||
import org.greenrobot.eventbus.ThreadMode.BACKGROUND
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.pathString
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode.ASYNC
|
||||
import org.greenrobot.eventbus.ThreadMode.BACKGROUND
|
||||
|
||||
/**
|
||||
* Manages projects in AndroidIDE.
|
||||
@@ -52,6 +52,7 @@ import org.greenrobot.eventbus.ThreadMode.BACKGROUND
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
object ProjectManager : EventReceiver {
|
||||
|
||||
private val log = ILogger.newInstance(javaClass.simpleName)
|
||||
lateinit var projectPath: String
|
||||
|
||||
@@ -62,12 +63,14 @@ object ProjectManager : EventReceiver {
|
||||
var cachedInitResult: InitializeResult? = null
|
||||
|
||||
@JvmOverloads
|
||||
fun setupProject(project: IProject = Lookup.getDefault().lookup(BuildService.KEY_PROJECT_PROXY)!!) {
|
||||
val caching = CachingProject(project)
|
||||
this.rootProject = ProjectTransformer().transform(caching)
|
||||
fun setupProject(
|
||||
project: IProject = Lookup.getDefault().lookup(BuildService.KEY_PROJECT_PROXY)!!,
|
||||
isInitialized: Boolean = true
|
||||
) {
|
||||
this.rootProject = if (isInitialized) ProjectTransformer().transform(CachingProject(project)) else null
|
||||
if (this.rootProject != null) {
|
||||
this.app = this.rootProject!!.findFirstAndroidAppModule()
|
||||
this.rootProject!!.subModules.filterIsInstance(ModuleProject::class.java).forEach {
|
||||
this.rootProject!!.subProjects.filterIsInstance(ModuleProject::class.java).forEach {
|
||||
it.indexSourcesAndClasspaths()
|
||||
if (it is AndroidModule) {
|
||||
it.readResources()
|
||||
@@ -155,7 +158,7 @@ object ProjectManager : EventReceiver {
|
||||
executeAsync {
|
||||
if (rootProject != null) {
|
||||
// Update the source file index
|
||||
rootProject!!.subModules.forEach {
|
||||
rootProject!!.subProjects.forEach {
|
||||
if (it is ModuleProject) {
|
||||
it.indexSources()
|
||||
}
|
||||
@@ -191,7 +194,7 @@ object ProjectManager : EventReceiver {
|
||||
return false
|
||||
}
|
||||
|
||||
for (module in this.rootProject!!.subModules) {
|
||||
for (module in this.rootProject!!.subProjects) {
|
||||
if (module !is ModuleProject) {
|
||||
continue
|
||||
}
|
||||
@@ -212,7 +215,7 @@ object ProjectManager : EventReceiver {
|
||||
return true
|
||||
}
|
||||
|
||||
log.warn("Project is not initialized yet!")
|
||||
log.warn("GradleProject is not initialized yet!")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -32,7 +32,6 @@ import com.itsaky.androidide.builder.model.DefaultSourceSetContainer
|
||||
import com.itsaky.androidide.builder.model.DefaultViewBindingOptions
|
||||
import com.itsaky.androidide.builder.model.UNKNOWN_PACKAGE
|
||||
import com.itsaky.androidide.projects.ProjectManager
|
||||
import com.itsaky.androidide.tooling.api.IAndroidProject
|
||||
import com.itsaky.androidide.tooling.api.ProjectType.Android
|
||||
import com.itsaky.androidide.tooling.api.models.BasicAndroidVariantMetadata
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
@@ -47,7 +46,7 @@ import java.io.File
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* A [Project] model implementation for Android modules which is exposed to other modules and
|
||||
* A [GradleProject] model implementation for Android modules which is exposed to other modules and
|
||||
* provides additional helper methods.
|
||||
*
|
||||
* @param name The display name of the project.
|
||||
@@ -190,11 +189,11 @@ open class AndroidModule( // Class must be open because BaseXMLTest mocks this..
|
||||
}
|
||||
|
||||
override fun getCompileClasspaths(): Set<File> {
|
||||
val root = ProjectManager.rootProject ?: return emptySet()
|
||||
val project = ProjectManager.rootProject ?: return emptySet()
|
||||
val result = mutableSetOf<File>()
|
||||
result.addAll(getModuleClasspaths())
|
||||
|
||||
collectLibraries(root, this.libraries, result)
|
||||
collectLibraries(project, this.libraries, result)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
+54
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.projects.api
|
||||
|
||||
import com.android.builder.model.v2.ide.ProjectType.APPLICATION
|
||||
import com.itsaky.androidide.tooling.api.ProjectType
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
/**
|
||||
* A Gradle project model which is identical to [IGradleProject][com.itsaky.androidide.tooling.api.IGradleProject]. This project module caches all the data
|
||||
* from an [IGradleProject][com.itsaky.androidide.tooling.api.IGradleProject] eliminating the use of [CompletableFuture] s.
|
||||
*
|
||||
* @param name The display name of the project.
|
||||
* @param description The project description.
|
||||
* @param path The project path (same as Gradle project paths). For example, `:app`,
|
||||
* `:module:submodule`, etc. Root project is always represented by path `:`.
|
||||
* @param projectDir The project directory.
|
||||
* @param buildDir The build directory of the project.
|
||||
* @param buildScript The Gradle buildscript file of the project.
|
||||
* @param tasks The tasks of the project.
|
||||
* @param subModules The submodules of the project.
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
open class GradleProject(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val path: String,
|
||||
val projectDir: File,
|
||||
val buildDir: File,
|
||||
val buildScript: File,
|
||||
val tasks: List<GradleTask>
|
||||
) {
|
||||
|
||||
var type: ProjectType = ProjectType.Gradle
|
||||
protected set
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import com.itsaky.androidide.tooling.api.models.JavaModuleDependency
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* A [Project] model implementation for Java library modules which is exposed to other modules and
|
||||
* A [GradleProject] model implementation for Java library modules which is exposed to other modules and
|
||||
* provides additional helper methods.
|
||||
*
|
||||
* @param name The display name of the project.
|
||||
|
||||
+1
-2
@@ -23,7 +23,6 @@ import com.itsaky.androidide.javac.services.fs.CacheFSInfoSingleton
|
||||
import com.itsaky.androidide.lookup.Lookup
|
||||
import com.itsaky.androidide.projects.classpath.JarFsClasspathReader
|
||||
import com.itsaky.androidide.projects.util.BootClasspathProvider
|
||||
import com.itsaky.androidide.tooling.api.IModuleProject
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
import com.itsaky.androidide.utils.ClassTrie
|
||||
import com.itsaky.androidide.utils.DocumentUtils
|
||||
@@ -49,7 +48,7 @@ abstract class ModuleProject(
|
||||
buildScript: File,
|
||||
tasks: List<GradleTask>
|
||||
) :
|
||||
Project(name, description, path, projectDir, buildDir, buildScript, tasks) {
|
||||
GradleProject(name, description, path, projectDir, buildDir, buildScript, tasks) {
|
||||
|
||||
private val log = ILogger.newInstance(javaClass.simpleName)
|
||||
|
||||
|
||||
@@ -17,55 +17,29 @@
|
||||
|
||||
package com.itsaky.androidide.projects.api
|
||||
|
||||
import com.android.builder.model.v2.ide.ProjectType.APPLICATION
|
||||
import com.itsaky.androidide.tooling.api.IProject
|
||||
import com.itsaky.androidide.tooling.api.ProjectType
|
||||
import com.itsaky.androidide.tooling.api.models.GradleTask
|
||||
import com.android.builder.model.v2.ide.ProjectType
|
||||
import com.itsaky.androidide.builder.model.DefaultProjectSyncIssues
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.*
|
||||
|
||||
/**
|
||||
* A Gradle project model which is identical to [IProject]. This project module caches all the data
|
||||
* from an [IProject] eliminating the use of [CompletableFuture] s.
|
||||
* Model for representing the whole project that is opened in the IDE (including the root project).
|
||||
*
|
||||
* @param name The display name of the project.
|
||||
* @param description The project description.
|
||||
* @param path The project path (same as Gradle project paths). For example, `:app`,
|
||||
* `:module:submodule`, etc. Root project is always represented by path `:`.
|
||||
* @param projectDir The project directory.
|
||||
* @param buildDir The build directory of the project.
|
||||
* @param buildScript The Gradle buildscript file of the project.
|
||||
* @param parentPath The parent project path. Always `null` for root project.
|
||||
* @param tasks The tasks of the project.
|
||||
* @param subModules The submodules of the project.
|
||||
* @property rootProject The root Gradle project.
|
||||
* @property subProjects List of all project that are included the project.
|
||||
* @property syncIssues The issues that occurred while syncing the project.
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
open class Project(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val path: String,
|
||||
val projectDir: File,
|
||||
val buildDir: File,
|
||||
val buildScript: File,
|
||||
val tasks: List<GradleTask>,
|
||||
val subModules: List<Project> = mutableListOf()
|
||||
) {
|
||||
|
||||
var type: ProjectType = ProjectType.Gradle
|
||||
protected set
|
||||
data class Project(val rootProject: GradleProject, val subProjects: List<GradleProject>,
|
||||
val syncIssues: Map<String, DefaultProjectSyncIssues>) {
|
||||
|
||||
/**
|
||||
* Finds the project by the given path.
|
||||
*
|
||||
* @return The project with the given path or `null` if no project is available with that path.
|
||||
*/
|
||||
fun findByPath(path: String): Project? {
|
||||
if (path == this.path) {
|
||||
return this
|
||||
}
|
||||
|
||||
return this.subModules.find { it.path == path }
|
||||
fun findByPath(path: String): GradleProject? {
|
||||
return this.subProjects.find { it.path == path }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,10 +49,7 @@ open class Project(
|
||||
* @return The first Android module.
|
||||
*/
|
||||
fun findFirstAndroidModule(): AndroidModule? {
|
||||
if (this is AndroidModule) {
|
||||
return this
|
||||
}
|
||||
val android = this.subModules.find { it is AndroidModule }
|
||||
val android = this.subProjects.find { it is AndroidModule }
|
||||
if (android != null) {
|
||||
return android as AndroidModule
|
||||
}
|
||||
@@ -93,10 +64,7 @@ open class Project(
|
||||
* @return The first Android module.
|
||||
*/
|
||||
fun findFirstAndroidAppModule(): AndroidModule? {
|
||||
if (this is AndroidModule && this.projectType == APPLICATION) {
|
||||
return this
|
||||
}
|
||||
val app = this.subModules.find { it is AndroidModule && it.projectType == APPLICATION }
|
||||
val app = this.subProjects.find { it is AndroidModule && it.projectType == ProjectType.APPLICATION }
|
||||
|
||||
if (app != null) {
|
||||
return app as AndroidModule
|
||||
@@ -111,12 +79,7 @@ open class Project(
|
||||
* @return The list of android modules.
|
||||
*/
|
||||
fun findAndroidModules(): List<AndroidModule> {
|
||||
val androidModules = this.subModules.filterIsInstance(AndroidModule::class.java).toMutableList()
|
||||
|
||||
if (this is AndroidModule) {
|
||||
androidModules.add(0, this)
|
||||
}
|
||||
return androidModules
|
||||
return subProjects.filterIsInstance(AndroidModule::class.java).toMutableList()
|
||||
}
|
||||
|
||||
fun findModuleForFile(file: Path): ModuleProject? {
|
||||
@@ -134,7 +97,7 @@ open class Project(
|
||||
var longestPath = ""
|
||||
var moduleWithLongestPath: ModuleProject? = null
|
||||
|
||||
for (module in subModules) {
|
||||
for (module in subProjects) {
|
||||
if (module !is ModuleProject) {
|
||||
continue
|
||||
}
|
||||
@@ -152,4 +115,4 @@ open class Project(
|
||||
|
||||
return moduleWithLongestPath
|
||||
}
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.projects.api
|
||||
|
||||
import com.itsaky.androidide.tooling.api.messages.result.SimpleModuleData
|
||||
|
||||
/**
|
||||
* Any project model which contains
|
||||
* [com.itsaky.androidide.tooling.api.messages.result.SimpleModuleData].
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
interface WithModuleData {
|
||||
|
||||
/** The module data. */
|
||||
var moduleData: SimpleModuleData?
|
||||
}
|
||||
+30
-23
@@ -18,9 +18,11 @@
|
||||
package com.itsaky.androidide.projects.util
|
||||
|
||||
import com.itsaky.androidide.projects.api.AndroidModule
|
||||
import com.itsaky.androidide.projects.api.GradleProject
|
||||
import com.itsaky.androidide.projects.api.JavaModule
|
||||
import com.itsaky.androidide.projects.api.Project
|
||||
import com.itsaky.androidide.tooling.api.IAndroidProject
|
||||
import com.itsaky.androidide.tooling.api.IGradleProject
|
||||
import com.itsaky.androidide.tooling.api.IJavaProject
|
||||
import com.itsaky.androidide.tooling.api.IProject
|
||||
import com.itsaky.androidide.tooling.api.ProjectType
|
||||
@@ -49,32 +51,36 @@ class ProjectTransformer {
|
||||
}
|
||||
|
||||
val rootProject = when (project.getType().get()) {
|
||||
ProjectType.Gradle -> project.asGradleProject()
|
||||
ProjectType.Android -> project.asGradleProject()
|
||||
ProjectType.Gradle -> transform(project.asGradleProject())
|
||||
ProjectType.Android -> transform(project.asAndroidProject())
|
||||
else -> throw IllegalStateException(
|
||||
"Root project must be either an Android project or a Gradle project")
|
||||
}
|
||||
|
||||
val metadata = rootProject.getMetadata().get()
|
||||
return Project(
|
||||
name = metadata.name ?: IProject.PROJECT_UNKNOWN,
|
||||
description = metadata.description ?: "",
|
||||
path = metadata.projectPath,
|
||||
projectDir = metadata.projectDir,
|
||||
buildDir = metadata.buildDir,
|
||||
buildScript = metadata.buildScript,
|
||||
|
||||
// As these lists will never change, we could make these thread-safe with
|
||||
// CopyOnWriteArrayList
|
||||
tasks = CopyOnWriteArrayList(rootProject.getTasks().get() ?: listOf()),
|
||||
subModules = CopyOnWriteArrayList(transform(allProjects, project))
|
||||
)
|
||||
return Project(rootProject, CopyOnWriteArrayList(transform(allProjects, project)),
|
||||
project.getProjectSyncIssues().get())
|
||||
} catch (error: Throwable) {
|
||||
log.error("Unable to transform project", error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun transform(rootProject: IGradleProject): GradleProject {
|
||||
val metadata = rootProject.getMetadata().get()
|
||||
return GradleProject(
|
||||
name = metadata.name ?: IProject.PROJECT_UNKNOWN,
|
||||
description = metadata.description ?: "",
|
||||
path = metadata.projectPath,
|
||||
projectDir = metadata.projectDir,
|
||||
buildDir = metadata.buildDir,
|
||||
buildScript = metadata.buildScript,
|
||||
|
||||
// The list will never change, we could make these thread-safe with
|
||||
// CopyOnWriteArrayList
|
||||
tasks = CopyOnWriteArrayList(rootProject.getTasks().get() ?: listOf()),
|
||||
)
|
||||
}
|
||||
|
||||
private fun transform(
|
||||
project: IAndroidProject
|
||||
): AndroidModule {
|
||||
@@ -109,7 +115,7 @@ class ProjectTransformer {
|
||||
}
|
||||
|
||||
private fun transform(project: IJavaProject): JavaModule {
|
||||
val metadata = project.getMetadata() as JavaProjectMetadata
|
||||
val metadata = project.getMetadata().get() as JavaProjectMetadata
|
||||
return JavaModule(
|
||||
name = metadata.name ?: IProject.PROJECT_UNKNOWN,
|
||||
description = metadata.description ?: "",
|
||||
@@ -125,15 +131,15 @@ class ProjectTransformer {
|
||||
)
|
||||
}
|
||||
|
||||
private fun transform(modules: List<BasicProjectMetadata>, root: IProject): List<Project> {
|
||||
return mutableListOf<Project>().apply {
|
||||
private fun transform(modules: List<BasicProjectMetadata>, root: IProject): List<GradleProject> {
|
||||
return mutableListOf<GradleProject>().apply {
|
||||
for (module in modules) {
|
||||
add(createProject(module, root))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createProject(moduleMetadata: BasicProjectMetadata, root: IProject): Project {
|
||||
private fun createProject(moduleMetadata: BasicProjectMetadata, root: IProject): GradleProject {
|
||||
val selectionResult = root.selectProject(StringParameter(moduleMetadata.projectPath)).get()
|
||||
check(selectionResult.isSuccessful) {
|
||||
"Selection failed for project '${moduleMetadata.projectPath}' but it is included in all projects."
|
||||
@@ -143,9 +149,10 @@ class ProjectTransformer {
|
||||
|
||||
return when (type) {
|
||||
ProjectType.Gradle,
|
||||
ProjectType.Unknown -> transform(project)!!
|
||||
ProjectType.Android -> transform(project as IAndroidProject)
|
||||
ProjectType.Java -> transform(project as IJavaProject)
|
||||
ProjectType.Unknown -> transform(root.asGradleProject())
|
||||
|
||||
ProjectType.Android -> transform(root.asAndroidProject())
|
||||
ProjectType.Java -> transform(root.asJavaProject())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-13
@@ -24,6 +24,7 @@ import com.itsaky.androidide.eventbus.events.file.FileRenameEvent
|
||||
import com.itsaky.androidide.lookup.Lookup
|
||||
import com.itsaky.androidide.projects.ProjectManager
|
||||
import com.itsaky.androidide.projects.builder.BuildService
|
||||
import com.itsaky.androidide.tooling.api.IAndroidProject
|
||||
import com.itsaky.androidide.tooling.api.messages.InitializeProjectMessage
|
||||
import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher
|
||||
import com.itsaky.androidide.utils.FileProvider
|
||||
@@ -51,15 +52,20 @@ class ModuleProjectTest {
|
||||
|
||||
verifyProjectManagerAPIs()
|
||||
|
||||
val root = ProjectManager.rootProject
|
||||
assertThat(project).isNotNull()
|
||||
|
||||
val rootProject = ProjectManager.rootProject
|
||||
assertThat(rootProject).isNotNull()
|
||||
|
||||
val root = rootProject!!.rootProject
|
||||
assertThat(root).isNotNull()
|
||||
assertThat(root!!.name).isEqualTo("TestApp")
|
||||
assertThat(root.name).isEqualTo("TestApp")
|
||||
|
||||
val rootDir = root.projectDir
|
||||
assertThat(rootDir).isNotNull()
|
||||
assertThat(Files.isSameFile(rootDir.toPath(), FileProvider.testProjectRoot())).isTrue()
|
||||
|
||||
val app = root.findByPath(":app")
|
||||
val app = rootProject.findByPath(":app")
|
||||
assertThat(app).isNotNull()
|
||||
assertThat(app).isInstanceOf(AndroidModule::class.java)
|
||||
|
||||
@@ -75,7 +81,7 @@ class ModuleProjectTest {
|
||||
assertThat(app.compilerSettings.javaBytecodeVersion)
|
||||
.isEqualTo(app.compilerSettings.targetCompatibility)
|
||||
|
||||
val anotherAndroidLib = root.findByPath(":another-android-library")
|
||||
val anotherAndroidLib = rootProject.findByPath(":another-android-library")
|
||||
assertThat(anotherAndroidLib).isNotNull()
|
||||
assertThat(anotherAndroidLib).isInstanceOf(AndroidModule::class.java)
|
||||
|
||||
@@ -90,11 +96,11 @@ class ModuleProjectTest {
|
||||
.containsAtLeast(
|
||||
File(
|
||||
anotherAndroidLibDir,
|
||||
"build/${com.itsaky.androidide.tooling.api.model.AndroidModule.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar"
|
||||
"build/${IAndroidProject.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar"
|
||||
),
|
||||
File(
|
||||
anotherAndroidLibDir,
|
||||
"build/${com.itsaky.androidide.tooling.api.model.AndroidModule.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar"
|
||||
"build/${IAndroidProject.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar"
|
||||
)
|
||||
)
|
||||
assertThat(
|
||||
@@ -129,15 +135,15 @@ class ModuleProjectTest {
|
||||
.containsAtLeast(
|
||||
File(
|
||||
anotherAndroidLibDir,
|
||||
"build/${com.itsaky.androidide.tooling.api.model.AndroidModule.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar"
|
||||
"build/${IAndroidProject.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar"
|
||||
),
|
||||
File(
|
||||
app.projectDir,
|
||||
"build/${com.itsaky.androidide.tooling.api.model.AndroidModule.FD_INTERMEDIATES}/compile_and_runtime_not_namespaced_r_class_jar/debug/R.jar"
|
||||
"build/${IAndroidProject.FD_INTERMEDIATES}/compile_and_runtime_not_namespaced_r_class_jar/debug/R.jar"
|
||||
),
|
||||
File(
|
||||
anotherAndroidLibDir,
|
||||
"build/${com.itsaky.androidide.tooling.api.model.AndroidModule.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar"
|
||||
"build/${IAndroidProject.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar"
|
||||
)
|
||||
)
|
||||
assertThat(
|
||||
@@ -150,7 +156,7 @@ class ModuleProjectTest {
|
||||
.hasSize(3)
|
||||
}
|
||||
|
||||
val javaLibrary = root.findByPath(":java-library")
|
||||
val javaLibrary = rootProject.findByPath(":java-library")
|
||||
assertThat(javaLibrary).isNotNull()
|
||||
assertThat(javaLibrary).isInstanceOf(JavaModule::class.java)
|
||||
|
||||
@@ -172,7 +178,7 @@ class ModuleProjectTest {
|
||||
assertThat(classes.map { it::class.java })
|
||||
.containsExactly(SourceNode::class.java, SourceNode::class.java)
|
||||
|
||||
root.findByPath(":another-java-library").run {
|
||||
rootProject.findByPath(":another-java-library").run {
|
||||
assertThat(this).isInstanceOf(JavaModule::class.java)
|
||||
assertThat((this as JavaModule).compilerSettings).isNotNull()
|
||||
assertThat(compilerSettings.javaSourceVersion).isEqualTo("1.8")
|
||||
@@ -199,13 +205,16 @@ class ModuleProjectTest {
|
||||
|
||||
ProjectManager.setupProject()
|
||||
|
||||
val root = ProjectManager.rootProject
|
||||
val rootProject = ProjectManager.rootProject
|
||||
assertThat(rootProject).isNotNull()
|
||||
|
||||
val root = rootProject?.rootProject
|
||||
assertThat(root).isNotNull()
|
||||
assertThat(root!!.path).isEqualTo(":")
|
||||
|
||||
val source =
|
||||
root.projectDir.toPath().resolve("app/src/main/java/com/itsaky/test/app/MainActivity.java")
|
||||
val module = root.findModuleForFile(source)
|
||||
val module = rootProject.findModuleForFile(source)
|
||||
assertThat(module).isNotNull()
|
||||
assertThat(module!!.path).isEqualTo(":app")
|
||||
assertThat(module.projectDir.path).isEqualTo(File(root.projectDir, "app").path)
|
||||
|
||||
+7
-10
@@ -17,7 +17,6 @@
|
||||
|
||||
package com.itsaky.androidide.tooling.impl
|
||||
|
||||
import com.itsaky.androidide.builder.model.DefaultProjectSyncIssues
|
||||
import com.itsaky.androidide.tooling.api.IProject
|
||||
import com.itsaky.androidide.tooling.api.IToolingApiClient
|
||||
import com.itsaky.androidide.tooling.api.IToolingApiServer
|
||||
@@ -34,7 +33,6 @@ import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Fai
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.BUILD_FAILED
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.CONNECTION_CLOSED
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.CONNECTION_ERROR
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.PROJECT_NOT_FOUND
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.UNKNOWN
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.UNSUPPORTED_BUILD_ARGUMENT
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.UNSUPPORTED_CONFIGURATION
|
||||
@@ -55,7 +53,8 @@ import org.gradle.tooling.UnsupportedVersionException
|
||||
import org.gradle.tooling.exceptions.UnsupportedBuildArgumentException
|
||||
import org.gradle.tooling.exceptions.UnsupportedOperationConfigurationException
|
||||
import java.io.File
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.CompletionException
|
||||
|
||||
/**
|
||||
* Implementation for the Gradle Tooling API server.
|
||||
@@ -104,21 +103,19 @@ internal class ToolingApiServerImpl(private val project: ProjectImpl) :
|
||||
val connection = this.connector!!.connect()
|
||||
stopWatch.lapFromLast("Project connection established")
|
||||
|
||||
val issues: MutableMap<String, DefaultProjectSyncIssues> = mutableMapOf()
|
||||
val project = RootModelBuilder.build(connection to "debug") as? ProjectImpl?
|
||||
project ?: throw ModelBuilderException("Failed to build project model")
|
||||
|
||||
this.project.rootProject = project.rootProject
|
||||
this.project.projects = project.projects
|
||||
stopWatch.lapFromLast("Project read successful")
|
||||
|
||||
connection.close()
|
||||
stopWatch.log()
|
||||
|
||||
this.project.rootProject = project.rootProject
|
||||
this.project.projects = project.projects
|
||||
initialized = true
|
||||
|
||||
notifyBuildSuccess(emptyList())
|
||||
return@computeAsync InitializeResult(issues)
|
||||
return@computeAsync InitializeResult(emptyMap())
|
||||
} catch (err: Throwable) {
|
||||
log.error(err)
|
||||
notifyBuildFailure(emptyList())
|
||||
@@ -151,10 +148,10 @@ internal class ToolingApiServerImpl(private val project: ProjectImpl) :
|
||||
projectPath = IProject.ROOT_PROJECT_PATH
|
||||
}
|
||||
|
||||
val project = this.project!!.run {
|
||||
val project = this.project.run {
|
||||
selectProject(StringParameter(projectPath)).get()
|
||||
asGradleProject()
|
||||
} ?: return@computeAsync TaskExecutionResult(false, PROJECT_NOT_FOUND)
|
||||
}
|
||||
|
||||
this.connector!!.forProjectDirectory(project.getMetadata().get().projectDir)
|
||||
setupConnectorForGradleInstallation(this.connector!!, message.gradleInstallation)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import java.util.concurrent.CompletableFuture
|
||||
/**
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
internal open class GradleProjectImpl(
|
||||
internal open class GradleProjectImpl (
|
||||
protected val gradleProject: GradleProject
|
||||
) : IGradleProject, Serializable {
|
||||
|
||||
|
||||
+9
-2
@@ -106,7 +106,10 @@ internal class JavaProjectImpl(
|
||||
}
|
||||
|
||||
private fun getClassesJar(): File {
|
||||
val metadata = getMetadata().get()
|
||||
return getClassesJar(getMetadata().get())
|
||||
}
|
||||
|
||||
private fun getClassesJar(metadata: ProjectMetadata): File {
|
||||
var jar = File(metadata.buildDir, "libs/${metadata.name}.jar")
|
||||
if (jar.exists()) {
|
||||
return jar
|
||||
@@ -128,7 +131,11 @@ internal class JavaProjectImpl(
|
||||
override fun getMetadata(): CompletableFuture<ProjectMetadata> {
|
||||
return CompletableFuture.supplyAsync {
|
||||
val base = super.getMetadata().get()
|
||||
return@supplyAsync JavaProjectMetadata(base, compilerSettings, getClassesJar())
|
||||
|
||||
// do not call getClassesJar() here
|
||||
// it'll try to fetch metadata which will in return call this method
|
||||
// this will result in an infinite loop
|
||||
return@supplyAsync JavaProjectMetadata(base, compilerSettings, getClassesJar(base))
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -40,5 +40,6 @@ data class AndroidArtifactMetadata(
|
||||
val compileTaskName: String,
|
||||
val targetSdkVersionOverride: Int
|
||||
) : Serializable {
|
||||
private val gsonType: String = javaClass.name
|
||||
private val serialVersionUID = 1L
|
||||
}
|
||||
-1
@@ -21,7 +21,6 @@ import com.itsaky.androidide.builder.model.DefaultAndroidGradlePluginProjectFlag
|
||||
import com.itsaky.androidide.builder.model.DefaultJavaCompileOptions
|
||||
import com.itsaky.androidide.builder.model.DefaultViewBindingOptions
|
||||
import com.itsaky.androidide.tooling.api.ProjectType
|
||||
import com.itsaky.androidide.tooling.api.models.result.IModuleMetadata
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
|
||||
+1
-3
@@ -30,6 +30,4 @@ open class AndroidVariantMetadata(
|
||||
name: String,
|
||||
mainArtifact: AndroidArtifactMetadata,
|
||||
val otherArtifacts: Map<String, AndroidArtifactMetadata>
|
||||
) : BasicAndroidVariantMetadata(name, mainArtifact), Serializable {
|
||||
private val serialVersionUID = 1L
|
||||
}
|
||||
) : BasicAndroidVariantMetadata(name, mainArtifact)
|
||||
+1
-1
@@ -37,5 +37,5 @@ open class BasicProjectMetadata(
|
||||
) : Serializable {
|
||||
|
||||
protected val gsonType: String = javaClass.name
|
||||
private val serialVersionUID = 1L
|
||||
protected val serialVersionUID = 1L
|
||||
}
|
||||
+7
-2
@@ -17,10 +17,15 @@
|
||||
|
||||
package com.itsaky.androidide.tooling.api.models
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
* Represents a Gradle dependency artifact.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
data class GradleArtifact(val group: String, val name: String, val version: String) :
|
||||
java.io.Serializable
|
||||
data class GradleArtifact(val group: String, val name: String, val version: String) : Serializable {
|
||||
|
||||
private val gsonType: String = javaClass.name
|
||||
private val serialVersionUID = 1L
|
||||
}
|
||||
+1
-1
@@ -37,4 +37,4 @@ open class GradleTask(
|
||||
displayName: String?,
|
||||
isPublic: Boolean?,
|
||||
val projectPath: String?
|
||||
) : Launchable(displayName, isPublic ?: false), Serializable
|
||||
) : Launchable(displayName, isPublic ?: false)
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.tooling.api.models.result
|
||||
package com.itsaky.androidide.tooling.api.models
|
||||
|
||||
import java.io.File
|
||||
|
||||
-2
@@ -29,8 +29,6 @@ class JavaModuleCompilerSettings(
|
||||
override val javaBytecodeVersion: String
|
||||
) : IJavaCompilerSettings(), java.io.Serializable {
|
||||
|
||||
private val serialVersionUID = 1L
|
||||
|
||||
// IMPORTANT
|
||||
// Do not use javax.lang.model.SourceVersion reference here
|
||||
// When running on Android, this class is preset as jdkx.lang.model.SourceVersion
|
||||
|
||||
+1
-1
@@ -37,4 +37,4 @@ class JavaModuleProjectDependency(
|
||||
|
||||
/** Whether the dependency is exported. */
|
||||
exported: Boolean
|
||||
) : JavaModuleDependency(null, scope, exported), Serializable {}
|
||||
) : JavaModuleDependency(null, scope, exported), Serializable
|
||||
|
||||
+2
-2
@@ -19,7 +19,6 @@ package com.itsaky.androidide.tooling.api.models
|
||||
|
||||
import com.itsaky.androidide.builder.model.IJavaCompilerSettings
|
||||
import com.itsaky.androidide.tooling.api.ProjectType
|
||||
import com.itsaky.androidide.tooling.api.models.result.IModuleMetadata
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
@@ -38,7 +37,8 @@ class JavaProjectMetadata(
|
||||
type: ProjectType,
|
||||
val compilerSettings: IJavaCompilerSettings,
|
||||
override val classesJar: File?
|
||||
) : ProjectMetadata(name, path, projectDir, buildDir, description, buildScript, type), IModuleMetadata {
|
||||
) : ProjectMetadata(name, path, projectDir, buildDir, description, buildScript, type),
|
||||
IModuleMetadata {
|
||||
|
||||
constructor(base: ProjectMetadata, compilerSettings: IJavaCompilerSettings, classesJar: File?) :
|
||||
this(
|
||||
|
||||
+4
-1
@@ -25,4 +25,7 @@ import java.io.Serializable
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class JavaSourceDirectory(val directory: File, val isGenerated: Boolean) : Serializable {}
|
||||
class JavaSourceDirectory(val directory: File, val isGenerated: Boolean) : Serializable {
|
||||
private val gsonType: String = javaClass.name
|
||||
private val serialVersionUID = 1L
|
||||
}
|
||||
|
||||
+3
-3
@@ -196,11 +196,11 @@ object ToolingApiLauncher {
|
||||
}
|
||||
|
||||
private fun <T> GsonBuilder.runtimeTypeAdapter(baseClass: Class<T>,
|
||||
vararg subtype: Class<out T>) {
|
||||
vararg subtypes: Class<out T>) {
|
||||
registerTypeAdapterFactory(
|
||||
RuntimeTypeAdapterFactory.of(baseClass, "gsonType", true)
|
||||
.registerSubtype(baseClass).also { factory ->
|
||||
subtype.forEach { subtype ->
|
||||
.registerSubtype(baseClass, baseClass.name).also { factory ->
|
||||
subtypes.forEach { subtype ->
|
||||
factory.registerSubtype(subtype, subtype.name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ private fun generateTemplateProject(name: String, languages: Array<Language>,
|
||||
for (language in languages) {
|
||||
val packageName = "com.itsaky.androidide.template.${language.lang}"
|
||||
run {
|
||||
val projectName = "${name}Project${language.name}WithoutKts"
|
||||
val projectName = "${name}GradleProject${language.name}WithoutKts"
|
||||
|
||||
File(testProjectsDir, projectName).apply {
|
||||
if (exists()) deleteRecursively()
|
||||
@@ -108,7 +108,7 @@ private fun generateTemplateProject(name: String, languages: Array<Language>,
|
||||
}
|
||||
|
||||
run {
|
||||
val projectName = "${name}Project${language.name}WithKts"
|
||||
val projectName = "${name}GradleProject${language.name}WithKts"
|
||||
|
||||
File(testProjectsDir, projectName).apply {
|
||||
if (exists()) deleteRecursively()
|
||||
|
||||
@@ -93,7 +93,7 @@ fun processXmlFile(file: File, expectedType: AaptResourceType): Pair<XmlProcesso
|
||||
}
|
||||
|
||||
if (ProjectManager.rootProject == null) {
|
||||
throw InflateException("Project is not initialized!")
|
||||
throw InflateException("GradleProject is not initialized!")
|
||||
}
|
||||
|
||||
val module =
|
||||
|
||||
@@ -228,7 +228,7 @@ class LayoutInflaterTest {
|
||||
}
|
||||
|
||||
private fun layoutFile(name: String): File {
|
||||
val app = ProjectManager.app ?: throw IllegalStateException("Project is not initialized")
|
||||
val app = ProjectManager.app ?: throw IllegalStateException("GradleProject is not initialized")
|
||||
return File(app.projectDir, "src/main/res/layout/$name.xml")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user