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 23402b9cf..7f46319e8 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 437d42e6c..f000a1465 100755 --- a/app/src/main/java/com/itsaky/androidide/EditorActivity.java +++ b/app/src/main/java/com/itsaky/androidide/EditorActivity.java @@ -105,13 +105,13 @@ import com.itsaky.androidide.services.GradleBuildService; import com.itsaky.androidide.services.LogReceiver; import com.itsaky.androidide.shell.ShellServer; import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult; -import com.itsaky.androidide.tooling.api.model.IdeAndroidModule; import com.itsaky.androidide.tooling.api.model.IdeGradleProject; import com.itsaky.androidide.utils.DialogUtils; import com.itsaky.androidide.utils.EditorActivityActions; import com.itsaky.androidide.utils.EditorBottomSheetBehavior; import com.itsaky.androidide.utils.Environment; import com.itsaky.androidide.utils.ILogger; +import com.itsaky.androidide.utils.JSONUtility; import com.itsaky.androidide.utils.LSPUtils; import com.itsaky.androidide.utils.RecursiveFileSearcher; import com.itsaky.androidide.utils.Symbols; @@ -121,7 +121,6 @@ import com.itsaky.androidide.views.SymbolInputView; import com.itsaky.androidide.views.editor.CodeEditorView; import com.itsaky.androidide.views.editor.IDEEditor; import com.itsaky.inflater.values.ValuesTableFactory; -import com.itsaky.lsp.java.models.JavaServerConfiguration; import com.itsaky.lsp.java.models.JavaServerSettings; import com.itsaky.lsp.models.DiagnosticItem; import com.itsaky.lsp.models.InitializeParams; @@ -139,7 +138,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.function.Consumer; @@ -955,43 +953,43 @@ public class EditorActivity extends StudioActivity @NonNull String variantName) { return task -> { if (task != null) { - // TODO Handle multiple application modules - final var app = mRootProject.findFirstApplicationModule(); - if (app == null) { - LOG.error("No application module found in root project. Cannot install APKs"); - return; - } - - final var variants = app.getVariants(); - final var foundVariant = - variants.stream() - .filter(variant -> variant.getName().equals(variantName)) - .findFirst(); - - if (foundVariant.isPresent()) { - final var variant = foundVariant.get(); - final var main = variant.getMainArtifact(); - final var outputListingFile = main.getAssembleTaskOutputListingFile(); - if (outputListingFile == null) { - LOG.error("No output listing file provided with project model"); - return; - } - - final var apkFile = ApkMetadata.findApkFile(outputListingFile); - if (apkFile == null) { - LOG.error( - "No apk file specified in output listing file:", outputListingFile); - return; - } - - install(apkFile); - } else { - LOG.error( - "No", - variantName, - "variant found in application module", - app.getProjectPath()); - } +// // TODO Handle multiple application modules +// final var app = mRootProject.findFirstApplicationModule(); +// if (app == null) { +// LOG.error("No application module found in root project. Cannot install APKs"); +// return; +// } +// +// final var variants = app.getVariants(); +// final var foundVariant = +// variants.stream() +// .filter(variant -> variant.getName().equals(variantName)) +// .findFirst(); +// +// if (foundVariant.isPresent()) { +// final var variant = foundVariant.get(); +// final var main = variant.getMainArtifact(); +// final var outputListingFile = main.getAssembleTaskOutputListingFile(); +// if (outputListingFile == null) { +// LOG.error("No output listing file provided with project model"); +// return; +// } +// +// final var apkFile = ApkMetadata.findApkFile(outputListingFile); +// if (apkFile == null) { +// LOG.error( +// "No apk file specified in output listing file:", outputListingFile); +// return; +// } +// +// install(apkFile); +// } else { +// LOG.error( +// "No", +// variantName, +// "variant found in application module", +// app.getProjectPath()); +// } } }; } @@ -1295,27 +1293,13 @@ public class EditorActivity extends StudioActivity 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; - } - - // Notify Java language server about updated dependencies - // TODO Java language server must also be notified about updated source - // paths - final var debugDependencies = - app.getVariantDependencyJars().get("debug"); - getApp().getJavaLanguageServer() - .configurationChanged( - new JavaServerConfiguration( - debugDependencies.stream() - .filter(File::exists) - .map(File::toPath) - .collect(Collectors.toSet()), - collectSourcePaths(app))); +// 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) -> { @@ -1327,17 +1311,6 @@ public class EditorActivity extends StudioActivity ThreadUtils.runOnUiThread(() -> mBinding.buildProgressIndicator.setVisibility(View.GONE)); } - private Set collectSourcePaths(IdeAndroidModule app) { - final var paths = new HashSet(); - final var mainSourceProvider = app.getMainSourceSet().getSourceProvider(); - paths.addAll( - mainSourceProvider.getJavaDirectories().stream() - .map(File::toPath) - .collect(Collectors.toList())); - - return paths; - } - private void setupDrawerToggle() { ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( diff --git a/app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java b/app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java index 511a78876..e5884ee0e 100644 --- a/app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java +++ b/app/src/main/java/com/itsaky/androidide/services/GradleBuildService.java @@ -238,31 +238,31 @@ public class GradleBuildService extends Service implements BuildService, IToolin public boolean isBuildInProgress() { return isBuildInProgress; } - - /** - * Find the first direct subproject of the given root project that is an {@link - * IdeAndroidModule}. - * - * @param root The project whose subprojects will be searched. - * @return The found {@link IdeAndroidModule} or null. - */ - @Nullable - public IdeAndroidModule findFirstAndroidModule(IdeGradleProject root) { - return root.findFirstApplicationModule(); - } - - /** - * Find all the direct children of the given root project that are {@link IdeAndroidModule} and - * their projectType is {@link - * com.android.builder.model.v2.ide.ProjectType#APPLICATION APPLICATION} - * - * @param root The project whose subprojects will be searched. - * @return The found application modules. Never null. - */ - @NonNull - public List findAndroidModules(@NonNull IdeGradleProject root) { - return root.findApplicationModules(); - } +// +// /** +// * Find the first direct subproject of the given root project that is an {@link +// * IdeAndroidModule}. +// * +// * @param root The project whose subprojects will be searched. +// * @return The found {@link IdeAndroidModule} or null. +// */ +// @Nullable +// public IdeAndroidModule findFirstAndroidModule(IdeGradleProject root) { +// return root.findFirstApplicationModule(); +// } +// +// /** +// * Find all the direct children of the given root project that are {@link IdeAndroidModule} and +// * their projectType is {@link +// * com.android.builder.model.v2.ide.ProjectType#APPLICATION APPLICATION} +// * +// * @param root The project whose subprojects will be searched. +// * @return The found application modules. Never null. +// */ +// @NonNull +// public List findAndroidModules(@NonNull IdeGradleProject root) { +// return root.findApplicationModules(); +// } public void startToolingServer(@Nullable OnServerStartListener listener) { if (toolingServerThread != null && toolingServerThread.isAlive()) { diff --git a/build-tools/project/.gitignore b/build-tools/project/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/build-tools/project/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/build-tools/project/build.gradle b/build-tools/project/build.gradle new file mode 100644 index 000000000..0cecf7100 --- /dev/null +++ b/build-tools/project/build.gradle @@ -0,0 +1,58 @@ +/* + * 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 new file mode 100644 index 000000000..e69de29bb diff --git a/build-tools/project/proguard-rules.pro b/build-tools/project/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/build-tools/project/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/build-tools/project/src/androidTest/java/com/itsaky/projects/ExampleInstrumentedTest.java b/build-tools/project/src/androidTest/java/com/itsaky/projects/ExampleInstrumentedTest.java new file mode 100644 index 000000000..627716996 --- /dev/null +++ b/build-tools/project/src/androidTest/java/com/itsaky/projects/ExampleInstrumentedTest.java @@ -0,0 +1,43 @@ +/* + * 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 new file mode 100644 index 000000000..399cb52f6 --- /dev/null +++ b/build-tools/project/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + \ No newline at end of file diff --git a/build-tools/project/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt b/build-tools/project/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt new file mode 100644 index 000000000..d2489d9cc --- /dev/null +++ b/build-tools/project/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt @@ -0,0 +1,34 @@ +/* + * 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.itsaky.androidide.tooling.api.model.IdeGradleProject +import com.itsaky.lsp.java.JavaLanguageServer + +/** + * Manages projects in AndroidIDE. + * + * @author Akash Yadav + */ +object ProjectManager { + var rootProject: IdeGradleProject? = null + + fun notifyProjectUpdate (server: JavaLanguageServer) { + rootProject!! + } +} \ No newline at end of file diff --git a/build-tools/project/src/test/java/com/itsaky/projects/ExampleUnitTest.java b/build-tools/project/src/test/java/com/itsaky/projects/ExampleUnitTest.java new file mode 100644 index 000000000..b547a1b43 --- /dev/null +++ b/build-tools/project/src/test/java/com/itsaky/projects/ExampleUnitTest.java @@ -0,0 +1,34 @@ +/* + * 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 org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect () { + assertEquals (4, 2 + 2); + } +} \ 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 76adccbd8..5edadbe55 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 @@ -26,6 +26,12 @@ import com.android.builder.model.v2.models.VariantDependencies; import com.itsaky.androidide.tooling.api.model.IdeAndroidModule; import com.itsaky.androidide.tooling.api.model.IdeGradleProject; import com.itsaky.androidide.tooling.api.model.IdeGradleTask; +import com.itsaky.androidide.tooling.api.model.IdeJavaModule; +import com.itsaky.androidide.tooling.api.model.JavaContentRoot; +import com.itsaky.androidide.tooling.api.model.JavaModuleDependency; +import com.itsaky.androidide.tooling.api.model.JavaModuleExternalDependency; +import com.itsaky.androidide.tooling.api.model.JavaModuleProjectDependency; +import com.itsaky.androidide.tooling.api.model.JavaSourceDirectory; import com.itsaky.androidide.tooling.api.model.internal.DefaultProjectSyncIssues; import com.itsaky.androidide.tooling.api.model.internal.DefaultVariant; import com.itsaky.androidide.tooling.api.model.util.AndroidModulePropertyCopier; @@ -39,8 +45,15 @@ import org.gradle.tooling.ProjectConnection; import org.gradle.tooling.UnknownModelException; import org.gradle.tooling.model.GradleProject; import org.gradle.tooling.model.GradleTask; +import org.gradle.tooling.model.idea.IdeaDependency; +import org.gradle.tooling.model.idea.IdeaModule; +import org.gradle.tooling.model.idea.IdeaModuleDependency; +import org.gradle.tooling.model.idea.IdeaProject; +import org.gradle.tooling.model.idea.IdeaSingleEntryLibraryDependency; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Map; /** @@ -52,48 +65,48 @@ public class ProjectReader { public static IdeGradleProject read( ProjectConnection connection, Map outIssues) { - final var modelBuilder = connection.model(GradleProject.class); - configureBuilder(modelBuilder); + final var watch = new StopWatch("Create basic models"); + LOG.debug("Creating Idea project model..."); + final var ideaProject = connection.getModel(IdeaProject.class); + watch.lapFromLast("Idea project model created"); - final var gradleModel = modelBuilder.get(); - if (gradleModel == null) { - return null; - } - - return buildProjectModel(connection, gradleModel, outIssues); + return buildGradleProjectModel(ideaProject, outIssues); } - private static IdeGradleProject buildProjectModel( + private static IdeGradleProject buildModuleProject( ProjectConnection connection, - GradleProject gradleModel, + IdeaModule ideaModule, Map outIssues) { + + final var gradle = ideaModule.getGradleProject(); + final var modelBuilder = connection.model(AndroidProject.class); + addProperty(modelBuilder, AndroidProject.PROPERTY_BUILD_MODEL_ONLY, true); + addProperty(modelBuilder, AndroidProject.PROPERTY_INVOKED_FROM_IDE, true); + try { - final var modelBuilder = connection.model(AndroidProject.class); - configureBuilder(modelBuilder); - addProperty(modelBuilder, AndroidProject.PROPERTY_BUILD_MODEL_ONLY, true); - addProperty(modelBuilder, AndroidProject.PROPERTY_INVOKED_FROM_IDE, true); final var android = modelBuilder.get(); if (android == null) { throw new UnknownModelException( - "Project " + gradleModel.getPath() + " is not an Android project."); + "Project " + gradle.getPath() + " is not an Android project."); } - final var module = buildAndroidProjectModel(gradleModel, android, outIssues); + final var module = buildAndroidModuleProject(gradle, android); readDependencies(connection, module); final var issues = readSyncIssues(connection); - outIssues.put(gradleModel.getPath(), issues); + outIssues.put(gradle.getPath(), issues); return module; } catch (Throwable error) { try { - LOG.info("Building IdeGradleProject model for project:", gradleModel.getPath()); + LOG.info("Building IdeGradleProject model for project:", gradle.getPath()); if (!(error instanceof UnknownModelException)) { // If the error is something else than UnknownModelException, we should log it LOG.error(error); } - return buildGradleProjectModel(gradleModel, outIssues); + + return buildJavaModuleProject(gradle, ideaModule); } catch (Throwable e) { LOG.error("Unable to create model for project", e); return null; @@ -101,6 +114,69 @@ public class ProjectReader { } } + private static IdeJavaModule buildJavaModuleProject(GradleProject gradle, IdeaModule idea) { + + final var builder = new ProjectBuilder(); + builder.setName(gradle.getName()); + builder.setDescription(gradle.getDescription()); + builder.setPath(gradle.getPath()); + builder.setProjectDir(gradle.getProjectDirectory()); + builder.setBuildDir(gradle.getBuildDirectory()); + builder.setBuildScript(gradle.getBuildScript().getSourceFile()); + builder.setContentRoots (collectContentRoots(idea)); + builder.setJavaDependencies(collectJavaDependencies(idea)); + + final var project = builder.buildJavaModule(); + addTasks(gradle, project); + return project; + } + + private static List collectJavaDependencies(IdeaModule idea) { + final var list = new ArrayList(); + for (IdeaDependency dependency : idea.getDependencies()) { + // TODO There might be unresolved dependencies here. We need to handle them too. + if (dependency instanceof IdeaSingleEntryLibraryDependency) { + final var external = (IdeaSingleEntryLibraryDependency) dependency; + // There might be multiple entries of same dependency, but with different scope + // So we only add dependencies with 'RUNTIME' scope + if (external.getScope().getScope().equals("RUNTIME")) { + list.add( + new JavaModuleExternalDependency( + external.getFile(), + external.getSource(), + external.getJavadoc())); + } + } else if (dependency instanceof IdeaModuleDependency) { + final var project = ((IdeaModuleDependency) dependency); + list.add(new JavaModuleProjectDependency(project.getTargetModuleName())); + } + } + return list; + } + + private static List collectContentRoots(IdeaModule module) { + final var list = new ArrayList(); + for (var contentRoot : module.getContentRoots()) { + final var thisRoot = new JavaContentRoot(); + for (var sourceDir : contentRoot.getSourceDirectories()) { + thisRoot.getSourceDirectories() + .add( + new JavaSourceDirectory( + sourceDir.getDirectory(), sourceDir.isGenerated())); + } + + for (var testDir : contentRoot.getTestDirectories()) { + thisRoot.getTestDirectories() + .add( + new JavaSourceDirectory( + testDir.getDirectory(), testDir.isGenerated())); + } + + list.add(thisRoot); + } + return list; + } + private static DefaultProjectSyncIssues readSyncIssues(ProjectConnection connection) { final var builder = connection.model(ProjectSyncIssues.class); addProperty(builder, AndroidProject.PROPERTY_BUILD_MODEL_ONLY, true); @@ -130,7 +206,6 @@ public class ProjectReader { addProperty(modelFinder, AndroidProject.PROPERTY_BUILD_MODEL_ONLY, true); addProperty(modelFinder, AndroidProject.PROPERTY_INVOKED_FROM_IDE, true); modelFinder.addProgressListener(new LoggingProgressListener()); - configureBuilder(modelFinder); final var variantDependencies = AndroidModulePropertyCopier.INSTANCE.copy(modelFinder.run()); android.getVariantDependencies().put(name, variantDependencies); @@ -141,10 +216,8 @@ public class ProjectReader { launcher.addArguments(String.format("-P%s=%s", property, value)); } - private static IdeAndroidModule buildAndroidProjectModel( - GradleProject gradle, - AndroidProject android, - Map outIssues) { + private static IdeAndroidModule buildAndroidModuleProject( + GradleProject gradle, AndroidProject android) { LOG.debug("Building IdeAndroidModule for project:", gradle.getPath()); final var builder = new ProjectBuilder(); final var copier = AndroidModulePropertyCopier.INSTANCE; @@ -164,14 +237,25 @@ public class ProjectReader { builder.setLintChecksJars(android.getLintChecksJars()); final var module = builder.buildAndroidModule(); - addSubprojects(gradle, module, outIssues); addTasks(gradle, module); return module; } private static IdeGradleProject buildGradleProjectModel( - GradleProject gradle, Map outIssues) { + IdeaProject ideaProject, Map outIssues) { + final var hasGradle = + ideaProject.getModules().stream() + .map(IdeaModule::getGradleProject) + .filter(it -> it.getPath().equals(":")) + .findAny(); + + if (hasGradle.isEmpty()) { + throw new IllegalArgumentException( + "No GradleProject model is associated with project path: " + ":"); + } + + final var gradle = hasGradle.get(); final var builder = new ProjectBuilder(); builder.setName(gradle.getName()); builder.setDescription(gradle.getDescription()); @@ -181,7 +265,7 @@ public class ProjectReader { builder.setBuildScript(gradle.getBuildScript().getSourceFile()); final var project = builder.buildGradleProject(); - addSubprojects(gradle, project, outIssues); + addModules(ideaProject, project, outIssues); addTasks(gradle, project); return project; @@ -193,18 +277,24 @@ public class ProjectReader { } } - private static void addSubprojects( - GradleProject gradle, + private static void addModules( + IdeaProject ideaProject, IdeGradleProject project, Map outIssues) { - for (final var subGradle : gradle.getChildren()) { + for (final var module : ideaProject.getModules()) { + final var gradle = module.getGradleProject(); + if (gradle.getPath().equals(":")) { + // Do not try to add the root project again + continue; + } + final var connection = GradleConnector.newConnector() - .forProjectDirectory(subGradle.getProjectDirectory()) + .forProjectDirectory(gradle.getProjectDirectory()) .connect(); - final var sub = buildProjectModel(connection, subGradle, outIssues); + final var sub = buildModuleProject(connection, module, outIssues); if (sub != null) { - project.getSubprojects().add(sub); + project.getModules().add(sub); } } } @@ -219,6 +309,4 @@ public class ProjectReader { task.isPublic(), project.getProjectPath()); } - - private static void configureBuilder(ConfigurableLauncher launcher) {} } diff --git a/build-tools/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ToolingApiImplTest.kt b/build-tools/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ToolingApiImplTest.kt index 6101b977a..7c1dbc9bd 100644 --- a/build-tools/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ToolingApiImplTest.kt +++ b/build-tools/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ToolingApiImplTest.kt @@ -17,9 +17,9 @@ package com.itsaky.androidide.tooling.impl -import com.android.builder.model.v2.ide.ProjectType import com.google.common.truth.Truth.assertThat import com.google.gson.GsonBuilder +import com.itsaky.androidide.models.LogLine import com.itsaky.androidide.tooling.api.IToolingApiClient import com.itsaky.androidide.tooling.api.IToolingApiServer import com.itsaky.androidide.tooling.api.messages.InitializeProjectMessage @@ -27,13 +27,13 @@ import com.itsaky.androidide.tooling.api.model.IdeAndroidModule import com.itsaky.androidide.tooling.api.model.IdeGradleProject import com.itsaky.androidide.tooling.api.util.ToolingApiLauncher import com.itsaky.androidide.utils.ILogger +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 import java.io.BufferedReader import java.io.File import java.io.InputStream import java.io.InputStreamReader -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 /** @author Akash Yadav */ @RunWith(JUnit4::class) @@ -49,7 +49,6 @@ class ToolingApiImplTest { val result = server.initialize(InitializeProjectMessage(getTestProject().absolutePath)).get() val project = result.project - log.debug(result.syncIssues.asJson()) assertThat(project).isNotNull() assertThat(project!!).isInstanceOf(IdeGradleProject::class.java) @@ -69,7 +68,6 @@ class ToolingApiImplTest { } private fun assertAndroidModule(android: IdeAndroidModule) { - assertThat(android.projectType).isEqualTo(ProjectType.APPLICATION) assertThat(android.viewBindingOptions).isNotNull() assertThat(android.viewBindingOptions!!.isEnabled).isFalse() } @@ -110,6 +108,13 @@ class ToolingApiImplTest { private class TestClient : IToolingApiClient { private val log = ILogger.newInstance(javaClass.simpleName) + override fun logMessage(line: LogLine) { + log.log(ILogger.priority(line.priorityChar), line.formattedTagAndMessage()) + } + override fun logOutput(line: String) {} + override fun prepareBuild() {} + override fun onBuildSuccessful(tasks: List) {} + override fun onBuildFailed(tasks: List) {} } private class Reader(val input: InputStream) : Runnable { 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 f2069bd6d..60c3669ab 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/build.gradle b/build-tools/tooling-api-impl/src/test/test-project/build.gradle index 882249c79..d71f1a95f 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 @@ -1,6 +1,6 @@ buildscript { ext { - build_gradle_version = '7.0.2' + build_gradle_version = '7.2.0-rc01' } project.ext { diff --git a/build-tools/tooling-api-impl/src/test/test-project/gradle/wrapper/gradle-wrapper.properties b/build-tools/tooling-api-impl/src/test/test-project/gradle/wrapper/gradle-wrapper.properties index e750102e0..41dfb8790 100644 --- a/build-tools/tooling-api-impl/src/test/test-project/gradle/wrapper/gradle-wrapper.properties +++ b/build-tools/tooling-api-impl/src/test/test-project/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/build-tools/tooling-api-impl/src/test/test-project/java-library/build.gradle b/build-tools/tooling-api-impl/src/test/test-project/java-library/build.gradle index 63af8f060..316ec08a4 100644 --- a/build-tools/tooling-api-impl/src/test/test-project/java-library/build.gradle +++ b/build-tools/tooling-api-impl/src/test/test-project/java-library/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java-library' + id 'idea' } java { @@ -7,6 +8,11 @@ java { targetCompatibility = JavaVersion.VERSION_11 } +dependencies { + implementation 'io.github.itsaky:nb-javac-android:17.0.0.0' + compileOnly 'com.google.android.material:material:1.5.0' +} + repositories { mavenCentral () } \ No newline at end of file diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/HasModules.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/HasModules.kt new file mode 100644 index 000000000..5d768a004 --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/HasModules.kt @@ -0,0 +1,29 @@ +/* + * 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.tooling.api.model + +/** + * Any project that has modules. + * + * @author Akash Yadav + */ +interface HasModules { + + /** Get the modules. */ + fun getModules(): 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 d4675e640..335a95d6d 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 @@ -38,7 +38,6 @@ class IdeAndroidModule( buildDir: File?, buildScript: File?, parent: IdeGradleProject?, - subprojects: List, tasks: List, override var dynamicFeatures: Collection?, override var flags: DefaultAndroidGradlePluginProjectFlags, @@ -49,8 +48,7 @@ class IdeAndroidModule( override val lintChecksJars: List, override val modelSyncFiles: List ) : - IdeGradleProject( - name, description, path, projectDir, buildDir, buildScript, parent, subprojects, tasks), + IdeGradleProject(name, description, path, projectDir, buildDir, buildScript, parent, tasks), AndroidProject { var variantDependencies: MutableMap = mutableMapOf() @@ -64,7 +62,6 @@ class IdeAndroidModule( buildDir, buildScript, parent, - subprojects, tasks, dynamicFeatures, flags, 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 5334e2d79..7ae670aca 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 @@ -19,7 +19,7 @@ package com.itsaky.androidide.tooling.api.model import java.io.File /** - * Default implementation for [IdeGradleProject]. + * A root Gradle project. * @author Akash Yadav */ open class IdeGradleProject( @@ -30,34 +30,22 @@ open class IdeGradleProject( val buildDir: File?, val buildScript: File?, val parent: IdeGradleProject?, - val subprojects: List, val tasks: List, -) { +) : HasModules { - protected val gsonType: String = javaClass.name + private val gsonType: String = javaClass.name + private val moduleProjects: MutableList = mutableListOf() + override fun getModules(): List = moduleProjects fun findByPath(path: String): IdeGradleProject? { if (path == this.projectPath) { return this } - for (sub in subprojects) { - val subSub = sub.findByPath(path) - if (subSub != null) { - return subSub - } - } - - return null + return getModules().firstOrNull { it.projectPath == path } } - // TODO Filter by application modules - fun findApplicationModules(): List = - this.subprojects.filterIsInstance(IdeAndroidModule::class.java) - - fun findFirstApplicationModule(): IdeAndroidModule? = findApplicationModules().firstOrNull() - override fun toString(): String { - return "IdeGradleProject(name=$name, description=$description, projectPath=$projectPath, projectDir=$projectDir, buildDir=$buildDir, buildScript=$buildScript, parent=$parent, subprojects=$subprojects, tasks=$tasks, gsonType='$gsonType')" + 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 new file mode 100644 index 000000000..1d505f44d --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeJavaModule.kt @@ -0,0 +1,43 @@ +/* + * 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.tooling.api.model + +import java.io.File + +/** + * A java library model. Modules represented by this model does not apply any of the Android + * plugins. + * + * @author Akash Yadav + */ +class IdeJavaModule( + name: String?, + path: String?, + description: String?, + projectDir: File?, + buildDir: File?, + buildScript: File?, + parent: IdeGradleProject?, + tasks: List, + + /** * Source directories of this project. */ + val contentRoots: List, + + /** Dependencies of this project. */ + val dependencies: List +) : IdeGradleProject(name, description, path, projectDir, buildDir, buildScript, parent, tasks) {} diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaContentRoot.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaContentRoot.kt new file mode 100644 index 000000000..f67be7b5f --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaContentRoot.kt @@ -0,0 +1,24 @@ +/* + * 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.tooling.api.model + +/** @author Akash Yadav */ +class JavaContentRoot { + val sourceDirectories: List = mutableListOf() + val testDirectories: List = mutableListOf() +} \ No newline at end of file diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleDependency.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleDependency.kt new file mode 100644 index 000000000..5f1a6a4c0 --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleDependency.kt @@ -0,0 +1,29 @@ +/* + * 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.tooling.api.model + +import java.io.File + +/** + * Dependency of an [IdeJavaModule]. + * + * @author Akash Yadav + */ +abstract class JavaModuleDependency(val jarFile: File?) { + private val gsonType = javaClass.name +} diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleExternalDependency.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleExternalDependency.kt new file mode 100644 index 000000000..5455ae5ce --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleExternalDependency.kt @@ -0,0 +1,35 @@ +/* + * 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.tooling.api.model + +import java.io.File + +/** + * An external dependency of an [IdeJavaModule]. + * + * @author Akash Yadav + */ +class JavaModuleExternalDependency( + jar: File, + + /** `sources.jar` for this dependency. */ + val sources: File? = null, + + /** `javadoc.jar` for this dependency. */ + val javadoc: File? = null +) : JavaModuleDependency(jar) {} diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleProjectDependency.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleProjectDependency.kt new file mode 100644 index 000000000..3cd0521b7 --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaModuleProjectDependency.kt @@ -0,0 +1,29 @@ +/* + * 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.tooling.api.model + +/** + * A project dependency of an [IdeJavaModule]. More details about the project can be fetched by + * querying the [projectPath] in the root project. + * + * @author Akash Yadav + */ +class JavaModuleProjectDependency( + /** The name of the module project. */ + val moduleName: String +) : JavaModuleDependency(null) diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaSourceDirectory.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaSourceDirectory.kt new file mode 100644 index 000000000..d758c228d --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/JavaSourceDirectory.kt @@ -0,0 +1,27 @@ +/* + * 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.tooling.api.model + +import java.io.File + +/** + * A source directory of an [IdeJavaModule]. + * + * @author Akash Yadav + */ +class JavaSourceDirectory(val directory: File, val isGenerated: Boolean) {} 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 093776c2a..3eb677a5f 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 @@ -91,7 +91,6 @@ object AndroidModulePropertyCopier { module.buildDir, module.buildScript, module.parent, - module.subprojects, module.tasks, module.dynamicFeatures, copy(module.flags), diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/ProjectBuilder.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/ProjectBuilder.kt index 4eab6ffe6..9aa8448e2 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/ProjectBuilder.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/util/ProjectBuilder.kt @@ -19,6 +19,9 @@ package com.itsaky.androidide.tooling.api.model.util import com.itsaky.androidide.tooling.api.model.IdeAndroidModule import com.itsaky.androidide.tooling.api.model.IdeGradleProject import com.itsaky.androidide.tooling.api.model.IdeGradleTask +import com.itsaky.androidide.tooling.api.model.IdeJavaModule +import com.itsaky.androidide.tooling.api.model.JavaContentRoot +import com.itsaky.androidide.tooling.api.model.JavaModuleDependency 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 @@ -39,7 +42,7 @@ class ProjectBuilder { var buildDir: File? = null var buildScript: File? = null var parent: IdeGradleProject? = null - var subprojects: List = mutableListOf() + var modules: List = mutableListOf() var tasks: List = mutableListOf() var dynamicFeatures: Collection? = mutableListOf() var flags: DefaultAndroidGradlePluginProjectFlags = @@ -50,10 +53,26 @@ class ProjectBuilder { var viewBindingOptions: DefaultViewBindingOptions? = null var modelSyncFiles: List = emptyList() var lintChecksJars: List = mutableListOf() + var contentRoots: List = mutableListOf() + var javaDependencies: List = mutableListOf() fun buildGradleProject(): IdeGradleProject { return IdeGradleProject( - name, description, path, projectDir, buildDir, buildScript, parent, subprojects, tasks) + name, description, path, projectDir, buildDir, buildScript, parent, tasks) + } + + fun buildJavaModule(): IdeJavaModule { + return IdeJavaModule( + name, + path, + description, + projectDir, + buildDir, + buildScript, + parent, + tasks, + contentRoots, + javaDependencies) } fun buildAndroidModule(): IdeAndroidModule = @@ -65,7 +84,6 @@ class ProjectBuilder { buildDir, buildScript, parent, - subprojects, tasks, dynamicFeatures, flags, diff --git a/build-tools/tooling-api/src/main/java/com/itsaky/androidide/tooling/api/util/ToolingApiLauncher.java b/build-tools/tooling-api/src/main/java/com/itsaky/androidide/tooling/api/util/ToolingApiLauncher.java index cda34ec46..783826985 100644 --- a/build-tools/tooling-api/src/main/java/com/itsaky/androidide/tooling/api/util/ToolingApiLauncher.java +++ b/build-tools/tooling-api/src/main/java/com/itsaky/androidide/tooling/api/util/ToolingApiLauncher.java @@ -23,7 +23,11 @@ import com.itsaky.androidide.tooling.api.IToolingApiServer; import com.itsaky.androidide.tooling.api.model.IdeAndroidModule; import com.itsaky.androidide.tooling.api.model.IdeGradleProject; import com.itsaky.androidide.tooling.api.model.IdeGradleTask; +import com.itsaky.androidide.tooling.api.model.IdeJavaModule; import com.itsaky.androidide.tooling.api.model.IdeLaunchable; +import com.itsaky.androidide.tooling.api.model.JavaModuleDependency; +import com.itsaky.androidide.tooling.api.model.JavaModuleExternalDependency; +import com.itsaky.androidide.tooling.api.model.JavaModuleProjectDependency; import org.eclipse.lsp4j.jsonrpc.Launcher; @@ -56,11 +60,20 @@ public class ToolingApiLauncher { builder.registerTypeAdapterFactory( RuntimeTypeAdapterFactory.of(IdeGradleProject.class, "gsonType", true) .registerSubtype(IdeAndroidModule.class, IdeAndroidModule.class.getName()) + .registerSubtype(IdeJavaModule.class, IdeJavaModule.class.getName()) .registerSubtype(IdeGradleProject.class, IdeGradleProject.class.getName())); builder.registerTypeAdapterFactory( RuntimeTypeAdapterFactory.of(IdeLaunchable.class, "gsonType", true) .registerSubtype(IdeGradleTask.class, IdeGradleTask.class.getName()) .registerSubtype(IdeLaunchable.class, IdeLaunchable.class.getName())); + builder.registerTypeAdapterFactory( + RuntimeTypeAdapterFactory.of(JavaModuleDependency.class, "gsonType", true) + .registerSubtype( + JavaModuleExternalDependency.class, + JavaModuleExternalDependency.class.getName()) + .registerSubtype( + JavaModuleProjectDependency.class, + JavaModuleProjectDependency.class.getName())); } public static Launcher createServerLauncher( diff --git a/build.gradle b/build.gradle index 56960e472..f81601c06 100755 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ import java.nio.file.Paths import java.util.stream.Collectors buildscript { - ext.kotlin_version = '1.6.20' + ext.kotlin_version = '1.6.21' project.ext { compileSdk = 31 diff --git a/settings.gradle b/settings.gradle index 85e7134ec..92d677368 100755 --- a/settings.gradle +++ b/settings.gradle @@ -27,3 +27,4 @@ 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'