diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 0034de2f5..9c8b297a9 100755 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -11,6 +11,7 @@ + diff --git a/app/src/main/assets/data/common/tooling-api-all.jar b/app/src/main/assets/data/common/tooling-api-all.jar index e2d64dec5..51d779cf9 100644 Binary files a/app/src/main/assets/data/common/tooling-api-all.jar and b/app/src/main/assets/data/common/tooling-api-all.jar differ diff --git a/app/src/main/java/com/itsaky/androidide/EditorActivity.java b/app/src/main/java/com/itsaky/androidide/EditorActivity.java index 4cb974d72..c25e65018 100755 --- a/app/src/main/java/com/itsaky/androidide/EditorActivity.java +++ b/app/src/main/java/com/itsaky/androidide/EditorActivity.java @@ -76,6 +76,7 @@ import com.itsaky.androidide.adapters.DiagnosticsAdapter; import com.itsaky.androidide.adapters.EditorBottomSheetTabAdapter; import com.itsaky.androidide.adapters.SearchListAdapter; import com.itsaky.androidide.app.StudioActivity; +import com.itsaky.androidide.app.StudioApp; import com.itsaky.androidide.databinding.ActivityEditorBinding; import com.itsaky.androidide.databinding.LayoutDiagnosticInfoBinding; import com.itsaky.androidide.databinding.LayoutSearchProjectBinding; @@ -98,8 +99,9 @@ import com.itsaky.androidide.models.LogLine; import com.itsaky.androidide.models.SaveResult; import com.itsaky.androidide.models.SearchResult; import com.itsaky.androidide.models.SheetOption; -import com.itsaky.androidide.project.AndroidProject; -import com.itsaky.androidide.project.IDEProject; +import com.itsaky.androidide.projects.AndroidProject; +import com.itsaky.androidide.projects.IDEProject; +import com.itsaky.androidide.projects.ProjectManager; import com.itsaky.androidide.services.GradleBuildService; import com.itsaky.androidide.services.LogReceiver; import com.itsaky.androidide.shell.ShellServer; @@ -119,6 +121,7 @@ import com.itsaky.androidide.views.SymbolInputView; import com.itsaky.androidide.views.editor.CodeEditorView; import com.itsaky.androidide.views.editor.IDEEditor; import com.itsaky.inflater.values.ValuesTableFactory; +import com.itsaky.lsp.java.JavaLanguageServer; import com.itsaky.lsp.java.models.JavaServerSettings; import com.itsaky.lsp.models.DiagnosticItem; import com.itsaky.lsp.models.InitializeParams; @@ -846,8 +849,7 @@ public class EditorActivity extends StudioActivity if (result.gradleSaved) { notifySyncNeeded(); } - - + // TODO Notify language servers about changed XML files // Maybe use a file watcher to do these kind of things. @@ -1290,25 +1292,9 @@ public class EditorActivity extends StudioActivity protected void onProjectInitialized(IdeGradleProject root) { mRootProject = root; - CompletableFuture.runAsync( - () -> { - // final var app = - // mBuildService.findFirstAndroidModule(root); - // if (app == null) { - // LOG.error( - // "No Android application module - // is present in root project:", - // root.getName()); - // return; - // } - }) - .whenComplete( - (result, error) -> { - if (error != null) { - LOG.error("Post initialize task failed", error); - } - }); - + ProjectManager.INSTANCE.setRootProject(mRootProject); + ProjectManager.INSTANCE.notifyProjectUpdate( + ((JavaLanguageServer) StudioApp.getInstance().getJavaLanguageServer())); ThreadUtils.runOnUiThread(() -> mBinding.buildProgressIndicator.setVisibility(View.GONE)); } diff --git a/app/src/main/java/com/itsaky/androidide/MainActivity.java b/app/src/main/java/com/itsaky/androidide/MainActivity.java index d6b2b6f73..497bace4d 100755 --- a/app/src/main/java/com/itsaky/androidide/MainActivity.java +++ b/app/src/main/java/com/itsaky/androidide/MainActivity.java @@ -39,7 +39,7 @@ import com.itsaky.androidide.managers.PreferenceManager; import com.itsaky.androidide.models.ConstantsBridge; import com.itsaky.androidide.models.NewProjectDetails; import com.itsaky.androidide.models.ProjectTemplate; -import com.itsaky.androidide.project.AndroidProject; +import com.itsaky.androidide.projects.AndroidProject; import com.itsaky.androidide.tasks.TaskExecutor; import com.itsaky.androidide.tasks.callables.ProjectCreatorCallable; import com.itsaky.androidide.utils.DialogUtils; diff --git a/app/src/main/java/com/itsaky/androidide/adapters/ProjectsListAdapter.java b/app/src/main/java/com/itsaky/androidide/adapters/ProjectsListAdapter.java index 3db235826..1e5322e26 100755 --- a/app/src/main/java/com/itsaky/androidide/adapters/ProjectsListAdapter.java +++ b/app/src/main/java/com/itsaky/androidide/adapters/ProjectsListAdapter.java @@ -34,7 +34,7 @@ import com.bumptech.glide.Glide; import com.itsaky.androidide.R; import com.itsaky.androidide.app.StudioApp; import com.itsaky.androidide.databinding.LayoutProjectsItemBinding; -import com.itsaky.androidide.project.AndroidProject; +import com.itsaky.androidide.projects.AndroidProject; import com.itsaky.androidide.tasks.TaskExecutor; import com.itsaky.toaster.Toaster; diff --git a/app/src/main/java/com/itsaky/androidide/app/StudioApp.java b/app/src/main/java/com/itsaky/androidide/app/StudioApp.java index c69d141c9..53ddb7fcd 100755 --- a/app/src/main/java/com/itsaky/androidide/app/StudioApp.java +++ b/app/src/main/java/com/itsaky/androidide/app/StudioApp.java @@ -24,7 +24,7 @@ import androidx.annotation.NonNull; import com.blankj.utilcode.util.ThrowableUtils; import com.itsaky.androidide.CrashHandlerActivity; import com.itsaky.androidide.R; -import com.itsaky.androidide.project.ProjectResourceTable; +import com.itsaky.androidide.projects.ProjectResourceTable; import com.itsaky.androidide.utils.ILogger; import com.itsaky.apiinfo.ApiInfo; import com.itsaky.attrinfo.AttrInfo; diff --git a/app/src/main/java/com/itsaky/androidide/fragments/FileTreeFragment.java b/app/src/main/java/com/itsaky/androidide/fragments/FileTreeFragment.java index e7022e722..7982ee9f4 100755 --- a/app/src/main/java/com/itsaky/androidide/fragments/FileTreeFragment.java +++ b/app/src/main/java/com/itsaky/androidide/fragments/FileTreeFragment.java @@ -40,7 +40,7 @@ import com.itsaky.androidide.R; import com.itsaky.androidide.adapters.viewholders.FileTreeViewHolder; import com.itsaky.androidide.app.StudioApp; import com.itsaky.androidide.databinding.LayoutEditorFileTreeBinding; -import com.itsaky.androidide.project.AndroidProject; +import com.itsaky.androidide.projects.AndroidProject; import com.itsaky.androidide.tasks.TaskExecutor; import com.itsaky.androidide.tasks.callables.FileTreeCallable; import com.itsaky.androidide.utils.Environment; diff --git a/app/src/main/java/com/itsaky/androidide/handlers/IDEHandler.java b/app/src/main/java/com/itsaky/androidide/handlers/IDEHandler.java index 8a27d015f..f08331b79 100755 --- a/app/src/main/java/com/itsaky/androidide/handlers/IDEHandler.java +++ b/app/src/main/java/com/itsaky/androidide/handlers/IDEHandler.java @@ -18,8 +18,8 @@ package com.itsaky.androidide.handlers; import com.itsaky.androidide.EditorActivity; -import com.itsaky.androidide.project.AndroidProject; -import com.itsaky.androidide.project.IDEProject; +import com.itsaky.androidide.projects.AndroidProject; +import com.itsaky.androidide.projects.IDEProject; import com.itsaky.androidide.utils.ILogger; /** diff --git a/app/src/main/java/com/itsaky/androidide/project/AndroidProject.java b/app/src/main/java/com/itsaky/androidide/projects/AndroidProject.java old mode 100755 new mode 100644 similarity index 99% rename from app/src/main/java/com/itsaky/androidide/project/AndroidProject.java rename to app/src/main/java/com/itsaky/androidide/projects/AndroidProject.java index 1cc0f2876..b39d34b98 --- a/app/src/main/java/com/itsaky/androidide/project/AndroidProject.java +++ b/app/src/main/java/com/itsaky/androidide/projects/AndroidProject.java @@ -18,7 +18,7 @@ * **************************************************************************************/ -package com.itsaky.androidide.project; +package com.itsaky.androidide.projects; import android.os.Parcel; import android.os.Parcelable; diff --git a/app/src/main/java/com/itsaky/androidide/project/IDEModule.java b/app/src/main/java/com/itsaky/androidide/projects/IDEModule.java old mode 100755 new mode 100644 similarity index 98% rename from app/src/main/java/com/itsaky/androidide/project/IDEModule.java rename to app/src/main/java/com/itsaky/androidide/projects/IDEModule.java index 0eabfd116..b2171079a --- a/app/src/main/java/com/itsaky/androidide/project/IDEModule.java +++ b/app/src/main/java/com/itsaky/androidide/projects/IDEModule.java @@ -15,7 +15,7 @@ * along with AndroidIDE. If not, see . * **************************************************************************************/ -package com.itsaky.androidide.project; +package com.itsaky.androidide.projects; import com.google.gson.annotations.SerializedName; diff --git a/app/src/main/java/com/itsaky/androidide/project/IDEProject.java b/app/src/main/java/com/itsaky/androidide/projects/IDEProject.java old mode 100755 new mode 100644 similarity index 98% rename from app/src/main/java/com/itsaky/androidide/project/IDEProject.java rename to app/src/main/java/com/itsaky/androidide/projects/IDEProject.java index 05aef2b9a..c00012236 --- a/app/src/main/java/com/itsaky/androidide/project/IDEProject.java +++ b/app/src/main/java/com/itsaky/androidide/projects/IDEProject.java @@ -15,7 +15,7 @@ * along with AndroidIDE. If not, see . * **************************************************************************************/ -package com.itsaky.androidide.project; +package com.itsaky.androidide.projects; import com.google.gson.annotations.SerializedName; diff --git a/app/src/main/java/com/itsaky/androidide/project/IDETask.java b/app/src/main/java/com/itsaky/androidide/projects/IDETask.java old mode 100755 new mode 100644 similarity index 97% rename from app/src/main/java/com/itsaky/androidide/project/IDETask.java rename to app/src/main/java/com/itsaky/androidide/projects/IDETask.java index c66e80dbb..1d3809d33 --- a/app/src/main/java/com/itsaky/androidide/project/IDETask.java +++ b/app/src/main/java/com/itsaky/androidide/projects/IDETask.java @@ -15,7 +15,7 @@ * along with AndroidIDE. If not, see . * **************************************************************************************/ -package com.itsaky.androidide.project; +package com.itsaky.androidide.projects; import com.google.gson.annotations.SerializedName; diff --git a/app/src/main/java/com/itsaky/androidide/project/ProjectFileObserver.java b/app/src/main/java/com/itsaky/androidide/projects/ProjectFileObserver.java similarity index 96% rename from app/src/main/java/com/itsaky/androidide/project/ProjectFileObserver.java rename to app/src/main/java/com/itsaky/androidide/projects/ProjectFileObserver.java index 8739f9469..1e2a345c8 100644 --- a/app/src/main/java/com/itsaky/androidide/project/ProjectFileObserver.java +++ b/app/src/main/java/com/itsaky/androidide/projects/ProjectFileObserver.java @@ -15,7 +15,7 @@ * along with AndroidIDE. If not, see . */ -package com.itsaky.androidide.project; +package com.itsaky.androidide.projects; import android.os.FileObserver; diff --git a/app/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt b/app/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt new file mode 100644 index 000000000..b2189a611 --- /dev/null +++ b/app/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt @@ -0,0 +1,172 @@ +/* + * 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 . + */ + +/* + * 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.projects + +import com.android.builder.model.v2.ide.LibraryType.ANDROID_LIBRARY +import com.android.builder.model.v2.ide.LibraryType.JAVA_LIBRARY +import com.android.builder.model.v2.ide.LibraryType.PROJECT +import com.itsaky.androidide.tooling.api.model.IdeAndroidModule +import com.itsaky.androidide.tooling.api.model.IdeGradleProject +import com.itsaky.androidide.tooling.api.model.IdeJavaModule +import com.itsaky.androidide.tooling.api.model.IdeModule +import com.itsaky.lsp.java.JavaLanguageServer +import com.itsaky.lsp.java.models.JavaServerConfiguration +import java.io.File +import java.nio.file.Path + +/** + * Manages projects in AndroidIDE. + * + * @author Akash Yadav + */ +object ProjectManager { + private val log = com.itsaky.androidide.utils.ILogger.newInstance(javaClass.simpleName) + var rootProject: IdeGradleProject? = null + + fun notifyProjectUpdate(server: JavaLanguageServer) { + val sourceDirs = collectApplicationSourceDirs(rootProject!!) + val classPaths = collectApplicationClassPaths(rootProject!!) + val configuration = JavaServerConfiguration(sourceDirs, classPaths) + server.configurationChanged(configuration) + } + + private fun collectApplicationClassPaths(rootProject: IdeGradleProject): Set { + val app = getApplicationModule(rootProject) + val libraries = app.variantDependencies["debug"]!!.libraries + val paths = mutableSetOf() + + for (value in libraries.values) { + if (value.type == ANDROID_LIBRARY || value.type == JAVA_LIBRARY) { + paths.add(value.artifact!!.toPath()) + } else { + val project = rootProject.findByPath(value.projectInfo!!.projectPath)!! as IdeModule + paths.add(project.getGeneratedJar("debug").toPath()) + + if (project is IdeAndroidModule) { + // R.jar and maybe other JARs + paths.addAll( + project.variants + .first { it.name == "debug" } + .mainArtifact.classesFolders + .filter { it.name.endsWith(".jar") } + .map { it.toPath() }) + } + } + } + + return paths + } + + private fun collectApplicationSourceDirs(rootProject: IdeGradleProject): Set { + val app = getApplicationModule(rootProject) + val sources = app.mainSourceSet ?: return emptySet() + val javaDirs = sources.sourceProvider.javaDirectories + val sourcePaths = javaDirs.toMutableSet() + val projectSources = collectSourceDirs(collectProjectDependencies(rootProject, app)) + sourcePaths.addAll(projectSources) + return sourcePaths.map { it.toPath() }.toSet() + } + + private fun getApplicationModule(rootProject: IdeGradleProject): IdeAndroidModule { + return rootProject.findFirstAndroidModule() + ?: throw UnsupportedOperationException( + "No application module found in project ${rootProject.name} (${rootProject.projectPath})") + } + + fun collectProjectDependencies( + project: IdeGradleProject, + app: IdeAndroidModule + ): List { + + return app.variantDependencies["debug"]!! + .libraries.values + .filter { it.type == PROJECT } + .mapNotNull { project.findByPath(it.projectInfo!!.projectPath) } + .filterIsInstance(IdeModule::class.java) + } + + fun collectSourceDirs(projects: List): Set { + val sources = mutableSetOf() + for (project in projects) { + if (project is IdeJavaModule) { + sources.addAll(collectSources(project)) + } else if (project is IdeAndroidModule) { + sources.addAll(collectSources(project)) + } + } + + return sources + } + + fun collectSourceDirs(vararg projects: IdeModule): List { + val sources = mutableListOf() + for (project in projects) { + if (project is IdeJavaModule) { + sources.addAll(collectSources(project)) + } else if (project is IdeAndroidModule) { + sources.addAll(collectSources(project)) + } + } + + return sources + } + + fun collectSources(java: IdeJavaModule): List { + val sources = mutableListOf() + for (root in java.contentRoots) { + sources.addAll(root.sourceDirectories.map { it.directory }) + } + + return sources + } + + fun collectSources(android: IdeAndroidModule): List { + if (android.mainSourceSet == null) { + return mutableListOf() + } + + // src/main/java + val sources = android.mainSourceSet!!.sourceProvider.javaDirectories.toMutableList() + + // src/main/kotlin + sources.addAll(android.mainSourceSet!!.sourceProvider.kotlinDirectories) + + // build/generated/** + // AIDL, ViewBinding, Renderscript, BuildConfig i.e every generated source sources + sources.addAll( + android.variants.first { it.name == "debug" }.mainArtifact.generatedSourceFolders) + return sources + } +} diff --git a/app/src/main/java/com/itsaky/androidide/project/ProjectResourceTable.java b/app/src/main/java/com/itsaky/androidide/projects/ProjectResourceTable.java similarity index 99% rename from app/src/main/java/com/itsaky/androidide/project/ProjectResourceTable.java rename to app/src/main/java/com/itsaky/androidide/projects/ProjectResourceTable.java index bc42ab62d..7781b1bd2 100644 --- a/app/src/main/java/com/itsaky/androidide/project/ProjectResourceTable.java +++ b/app/src/main/java/com/itsaky/androidide/projects/ProjectResourceTable.java @@ -15,7 +15,7 @@ * along with AndroidIDE. If not, see . * */ -package com.itsaky.androidide.project; +package com.itsaky.androidide.projects; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/BuildListener.java b/app/src/main/java/com/itsaky/androidide/services/builder/BuildListener.java index 739c8c702..fb34f6cf5 100755 --- a/app/src/main/java/com/itsaky/androidide/services/builder/BuildListener.java +++ b/app/src/main/java/com/itsaky/androidide/services/builder/BuildListener.java @@ -17,8 +17,8 @@ **************************************************************************************/ package com.itsaky.androidide.services.builder; -import com.itsaky.androidide.project.IDEModule; -import com.itsaky.androidide.project.IDEProject; +import com.itsaky.androidide.projects.IDEModule; +import com.itsaky.androidide.projects.IDEProject; import com.itsaky.androidide.tasks.GradleTask; import java.util.Optional; diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/IDEService.java b/app/src/main/java/com/itsaky/androidide/services/builder/IDEService.java index a560b9a49..6794b8ce9 100755 --- a/app/src/main/java/com/itsaky/androidide/services/builder/IDEService.java +++ b/app/src/main/java/com/itsaky/androidide/services/builder/IDEService.java @@ -30,8 +30,8 @@ import com.google.gson.Gson; import com.itsaky.androidide.R; import com.itsaky.androidide.app.StudioApp; import com.itsaky.androidide.managers.PreferenceManager; -import com.itsaky.androidide.project.IDEModule; -import com.itsaky.androidide.project.IDEProject; +import com.itsaky.androidide.projects.IDEModule; +import com.itsaky.androidide.projects.IDEProject; import com.itsaky.androidide.shell.IProcessExecutor; import com.itsaky.androidide.shell.IProcessExitListener; import com.itsaky.androidide.shell.ProcessExecutorFactory; diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/MainThreadBuildListener.java b/app/src/main/java/com/itsaky/androidide/services/builder/MainThreadBuildListener.java index ebbc9aeca..07ebc3762 100755 --- a/app/src/main/java/com/itsaky/androidide/services/builder/MainThreadBuildListener.java +++ b/app/src/main/java/com/itsaky/androidide/services/builder/MainThreadBuildListener.java @@ -20,8 +20,8 @@ package com.itsaky.androidide.services.builder; import androidx.annotation.NonNull; import com.blankj.utilcode.util.ThreadUtils; -import com.itsaky.androidide.project.IDEModule; -import com.itsaky.androidide.project.IDEProject; +import com.itsaky.androidide.projects.IDEModule; +import com.itsaky.androidide.projects.IDEProject; import com.itsaky.androidide.tasks.GradleTask; import java.util.Objects; diff --git a/app/src/main/java/com/itsaky/androidide/utils/ProjectFinder.java b/app/src/main/java/com/itsaky/androidide/utils/ProjectFinder.java index 741b3cc86..6bcbbfd3b 100755 --- a/app/src/main/java/com/itsaky/androidide/utils/ProjectFinder.java +++ b/app/src/main/java/com/itsaky/androidide/utils/ProjectFinder.java @@ -23,7 +23,7 @@ package com.itsaky.androidide.utils; import android.text.TextUtils; import com.blankj.utilcode.util.FileIOUtils; -import com.itsaky.androidide.project.AndroidProject; +import com.itsaky.androidide.projects.AndroidProject; import org.json.JSONException; import org.json.JSONObject; diff --git a/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.java b/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.java index 7c0b150a5..5e6bf7991 100644 --- a/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.java +++ b/app/src/main/java/com/itsaky/androidide/viewmodel/EditorViewModel.java @@ -25,8 +25,8 @@ import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModel; -import com.itsaky.androidide.project.AndroidProject; -import com.itsaky.androidide.project.IDEProject; +import com.itsaky.androidide.projects.AndroidProject; +import com.itsaky.androidide.projects.IDEProject; import java.io.File; import java.util.ArrayList; diff --git a/build-tools/project/.gitignore b/build-tools/project/.gitignore deleted file mode 100644 index 42afabfd2..000000000 --- a/build-tools/project/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/build-tools/project/build.gradle b/build-tools/project/build.gradle deleted file mode 100644 index 0cecf7100..000000000 --- a/build-tools/project/build.gradle +++ /dev/null @@ -1,58 +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 . - */ - -plugins { - id 'com.android.library' - id 'kotlin-android' -} - -android { - compileSdkVersion rootProject.ext.compileSdk - buildToolsVersion rootProject.ext.buildTools - - defaultConfig { - minSdkVersion rootProject.ext.minSdk - targetSdkVersion rootProject.ext.targetSdk - } - - buildFeatures.viewBinding true - - compileOptions { - sourceCompatibility rootProject.ext.javaSourceVersion - targetCompatibility rootProject.ext.javaTargetVersion - } - - buildTypes { - release { - minifyEnabled true - } - } -} - -dependencies { - implementation "androidx.core:core-ktx:1.7.0" - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - - implementation project (path: ':build-tools:tooling-api-model') - implementation project (path: ':lsp:api') - implementation project (path: ':lsp:java') - implementation project (path: ':lsp:xml') - - testImplementation tests.junit - testImplementation tests.google_truth - testImplementation tests.robolectric -} \ No newline at end of file diff --git a/build-tools/project/consumer-rules.pro b/build-tools/project/consumer-rules.pro deleted file mode 100644 index e69de29bb..000000000 diff --git a/build-tools/project/proguard-rules.pro b/build-tools/project/proguard-rules.pro deleted file mode 100644 index 481bb4348..000000000 --- a/build-tools/project/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# 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/build-tools/project/src/androidTest/java/com/itsaky/projects/ExampleInstrumentedTest.java b/build-tools/project/src/androidTest/java/com/itsaky/projects/ExampleInstrumentedTest.java deleted file mode 100644 index 627716996..000000000 --- a/build-tools/project/src/androidTest/java/com/itsaky/projects/ExampleInstrumentedTest.java +++ /dev/null @@ -1,43 +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.projects; - -import android.content.Context; - -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext () { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getInstrumentation ().getTargetContext (); - assertEquals ("com.itsaky.projects.test", appContext.getPackageName ()); - } -} \ No newline at end of file diff --git a/build-tools/project/src/main/AndroidManifest.xml b/build-tools/project/src/main/AndroidManifest.xml deleted file mode 100644 index 399cb52f6..000000000 --- a/build-tools/project/src/main/AndroidManifest.xml +++ /dev/null @@ -1,17 +0,0 @@ - - \ No newline at end of file diff --git a/build-tools/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ProjectReader.java b/build-tools/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ProjectReader.java index 3f79e8120..1aa5aa5a5 100644 --- a/build-tools/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ProjectReader.java +++ b/build-tools/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/util/ProjectReader.java @@ -96,6 +96,12 @@ public class ProjectReader { final var basicAndroid = androidModel(connection, BasicAndroidProject.class); final var module = buildAndroidModuleProject(gradle, android, basicAndroid.getProjectType()); + module.setBoothclasspaths(basicAndroid.getBootClasspath()); + module.setMainSourceSet( + basicAndroid.getMainSourceSet() == null + ? null + : AndroidModulePropertyCopier.INSTANCE.copy( + basicAndroid.getMainSourceSet())); readDependencies(connection, module); final var issues = readSyncIssues(connection); diff --git a/build-tools/tooling-api-impl/src/test/test-home/.androidide/init/model.jar b/build-tools/tooling-api-impl/src/test/test-home/.androidide/init/model.jar index 8a9cc354a..539f8f180 100644 Binary files a/build-tools/tooling-api-impl/src/test/test-home/.androidide/init/model.jar and b/build-tools/tooling-api-impl/src/test/test-home/.androidide/init/model.jar differ diff --git a/build-tools/tooling-api-impl/src/test/test-project/android-library/build.gradle b/build-tools/tooling-api-impl/src/test/test-project/android-library/build.gradle new file mode 100644 index 000000000..f0bd462af --- /dev/null +++ b/build-tools/tooling-api-impl/src/test/test-project/android-library/build.gradle @@ -0,0 +1,39 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion rootProject.ext.compileSdk + buildToolsVersion rootProject.ext.buildTools + + defaultConfig { + minSdkVersion rootProject.ext.minSdk + targetSdkVersion rootProject.ext.targetSdk + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + lintOptions { + abortOnError false + } +} + +dependencies { + implementation 'io.github.itsaky:nb-javac-android:17.0.0.0' +} + +repositories { + mavenCentral () +} \ No newline at end of file diff --git a/build-tools/tooling-api-impl/src/test/test-project/android-library/src/main/AndroidManifest.xml b/build-tools/tooling-api-impl/src/test/test-project/android-library/src/main/AndroidManifest.xml new file mode 100644 index 000000000..4586e7b8d --- /dev/null +++ b/build-tools/tooling-api-impl/src/test/test-project/android-library/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build-tools/tooling-api-impl/src/test/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/build-tools/tooling-api-impl/src/test/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java new file mode 100644 index 000000000..bf5dd7e72 --- /dev/null +++ b/build-tools/tooling-api-impl/src/test/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java @@ -0,0 +1,7 @@ +package com.itsaky.androidide.tooling.test; + +public class Main { + public static void main (String[] args) { + + } +} \ No newline at end of file diff --git a/build-tools/tooling-api-impl/src/test/test-project/app/build.gradle b/build-tools/tooling-api-impl/src/test/test-project/app/build.gradle index f1efcd349..f6c265b97 100644 --- a/build-tools/tooling-api-impl/src/test/test-project/app/build.gradle +++ b/build-tools/tooling-api-impl/src/test/test-project/app/build.gradle @@ -34,5 +34,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' + implementation project (path: ':java-library') + implementation project (path: ':android-library') } diff --git a/build-tools/tooling-api-impl/src/test/test-project/build.gradle b/build-tools/tooling-api-impl/src/test/test-project/build.gradle index d71f1a95f..04738b975 100644 --- a/build-tools/tooling-api-impl/src/test/test-project/build.gradle +++ b/build-tools/tooling-api-impl/src/test/test-project/build.gradle @@ -17,9 +17,7 @@ buildscript { maven { url 'https://maven.aliyun.com/repository/public/' } maven { url 'https://maven.aliyun.com/repository/google/' } maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' } - maven { url 'https://dl.bintray.com/ppartisan/maven/' } maven { url "https://clojars.org/repo/" } - maven { url "https://jitpack.io" } google() mavenLocal() mavenCentral() @@ -34,9 +32,7 @@ allprojects { maven { url 'https://maven.aliyun.com/repository/public/' } maven { url 'https://maven.aliyun.com/repository/google/' } maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' } - maven { url 'https://dl.bintray.com/ppartisan/maven/' } maven { url "https://clojars.org/repo/" } - maven { url "https://jitpack.io" } mavenLocal() mavenCentral() google() diff --git a/build-tools/tooling-api-impl/src/test/test-project/settings.gradle b/build-tools/tooling-api-impl/src/test/test-project/settings.gradle index bbb5b589e..c6be97d4e 100644 --- a/build-tools/tooling-api-impl/src/test/test-project/settings.gradle +++ b/build-tools/tooling-api-impl/src/test/test-project/settings.gradle @@ -1,3 +1,4 @@ include ':app' include ':java-library' +include ':android-library' rootProject.name = "TestApp" \ No newline at end of file diff --git a/build-tools/project/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/HasDependencies.kt similarity index 54% rename from build-tools/project/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt rename to build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/HasDependencies.kt index 560562a80..dd5d39414 100644 --- a/build-tools/project/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/HasDependencies.kt @@ -15,26 +15,9 @@ * along with AndroidIDE. If not, see . */ -package com.itsaky.androidide.projects +package com.itsaky.androidide.tooling.api.model -import com.itsaky.androidide.tooling.api.model.IdeGradleProject -import com.itsaky.lsp.java.JavaLanguageServer -import java.nio.file.Path - -/** - * Manages projects in AndroidIDE. - * - * @author Akash Yadav - */ -object ProjectManager { - var rootProject: IdeGradleProject? = null - - fun notifyProjectUpdate(server: JavaLanguageServer) { - val sourceDirs = collectSourceDirs(rootProject!!) - } - - private fun collectSourceDirs(rootProject: IdeGradleProject): List { - val list = mutableListOf() - return list - } +/** @author Akash Yadav */ +interface HasDependencies { + fun getDependencies(): List } diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeAndroidModule.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeAndroidModule.kt index 6a8894a0a..91d09df0e 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeAndroidModule.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeAndroidModule.kt @@ -21,6 +21,7 @@ import com.android.builder.model.v2.models.AndroidProject import com.itsaky.androidide.tooling.api.model.internal.DefaultAndroidGradlePluginProjectFlags import com.itsaky.androidide.tooling.api.model.internal.DefaultJavaCompileOptions import com.itsaky.androidide.tooling.api.model.internal.DefaultModelSyncFile +import com.itsaky.androidide.tooling.api.model.internal.DefaultSourceSetContainer import com.itsaky.androidide.tooling.api.model.internal.DefaultVariant import com.itsaky.androidide.tooling.api.model.internal.DefaultVariantDependencies import com.itsaky.androidide.tooling.api.model.internal.DefaultViewBindingOptions @@ -51,8 +52,11 @@ class IdeAndroidModule( override val modelSyncFiles: List ) : IdeGradleProject(name, description, path, projectDir, buildDir, buildScript, parent, tasks), + IdeModule, AndroidProject { + var boothclasspaths: Collection = emptyList() + var mainSourceSet: DefaultSourceSetContainer? = null var variantDependencies: MutableMap = mutableMapOf() fun copy(): IdeAndroidModule { @@ -76,6 +80,12 @@ class IdeAndroidModule( modelSyncFiles) } + override fun getGeneratedJar(variant: String): File { + return File( + buildDir, + "${AndroidProject.FD_INTERMEDIATES}/compile_library_classes_jar/$variant/classes.jar") + } + override fun toString(): String { return "IdeAndroidModule(dynamicFeatures=$dynamicFeatures, flags=$flags, javaCompileOptions=$javaCompileOptions, resourcePrefix=$resourcePrefix, variants=$variants, viewBindingOptions=$viewBindingOptions, lintChecksJars=$lintChecksJars, modelSyncFiles=$modelSyncFiles, variantDependencies=$variantDependencies, androidTestNamespace=$androidTestNamespace, namespace='$namespace', testFixturesNamespace=$testFixturesNamespace)" } diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeGradleProject.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeGradleProject.kt index 7ae670aca..bdadf2b1e 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeGradleProject.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeGradleProject.kt @@ -45,6 +45,14 @@ open class IdeGradleProject( return getModules().firstOrNull { it.projectPath == path } } + fun findAndroidModules(): List { + return getModules().filterIsInstance(IdeAndroidModule::class.java) + } + + fun findFirstAndroidModule(): IdeAndroidModule? { + return findAndroidModules().firstOrNull() + } + override fun toString(): String { return "IdeGradleProject(name=$name, description=$description, projectPath=$projectPath, projectDir=$projectDir, buildDir=$buildDir, buildScript=$buildScript, parent=$parent, subprojects=$moduleProjects, tasks=$tasks, gsonType='$gsonType')" } diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeJavaModule.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeJavaModule.kt index 1d505f44d..0950a3057 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeJavaModule.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeJavaModule.kt @@ -39,5 +39,26 @@ class IdeJavaModule( val contentRoots: List, /** Dependencies of this project. */ - val dependencies: List -) : IdeGradleProject(name, description, path, projectDir, buildDir, buildScript, parent, tasks) {} + val javaDependencies: List +) : + IdeGradleProject(name, description, path, projectDir, buildDir, buildScript, parent, tasks), + IdeModule, + HasDependencies { + + override fun getDependencies() = javaDependencies + + override fun getGeneratedJar(variant: String): File { + var jar = File(buildDir, "libs/$name.jar") + if (jar.exists()) { + return jar + } + + jar = + File(buildDir, "libs").listFiles()?.first { + it.name.startsWith(this.name ?: this.projectPath?.substring(1) ?: "") + } + ?: File("i-do-not-exist.jar") + + return jar + } +} diff --git a/build-tools/project/src/test/java/com/itsaky/projects/ExampleUnitTest.java b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeModule.kt similarity index 65% rename from build-tools/project/src/test/java/com/itsaky/projects/ExampleUnitTest.java rename to build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeModule.kt index b547a1b43..beb857c38 100644 --- a/build-tools/project/src/test/java/com/itsaky/projects/ExampleUnitTest.java +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeModule.kt @@ -15,20 +15,21 @@ * along with AndroidIDE. If not, see . */ -package com.itsaky.projects; +package com.itsaky.androidide.tooling.api.model -import org.junit.Test; - -import static org.junit.Assert.*; +import java.io.File /** - * Example local unit test, which will execute on the development machine (host). + * A module in a Gradle project. * - * @see Testing documentation + * @author Akash Yadav */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect () { - assertEquals (4, 2 + 2); - } -} \ No newline at end of file +interface IdeModule { + + /** + * Get the generated JAR file for this module. + * + * @param variant The build variant name. NOT application for [IdeJavaModule]. + */ + fun getGeneratedJar(variant: String): File +} diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/AndroidModulePropertyCopier.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/AndroidModulePropertyCopier.kt index 5b903e0d9..7b089c211 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/AndroidModulePropertyCopier.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/AndroidModulePropertyCopier.kt @@ -92,6 +92,7 @@ object AndroidModulePropertyCopier { module.buildScript, module.parent, module.tasks, + module.projectType, module.dynamicFeatures, copy(module.flags), copy(module.javaCompileOptions), diff --git a/settings.gradle b/settings.gradle index 92d677368..1fec28dac 100755 --- a/settings.gradle +++ b/settings.gradle @@ -16,6 +16,8 @@ include ':lsp:xml' include ':lsp:testing' include ':build-tools' +include ':build-tools:builder-api' +include ':build-tools:builder-model' include ':build-tools:framework-stubs' include ':build-tools:google-java-format' include ':build-tools:javac' @@ -25,6 +27,3 @@ include ':build-tools:tooling-api' include ':build-tools:tooling-api-impl' include ':build-tools:tooling-api-model' include ':build-tools:xml-formatter' -include ':build-tools:builder-api' -include ':build-tools:builder-model' -include ':build-tools:project'