diff --git a/.idea/compiler.xml b/.idea/compiler.xml index e42ed4b08..cc16c8451 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 679144a1d..08b035cd0 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/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java b/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java index eddf3c0d6..2f5f1625c 100644 --- a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java +++ b/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/MessageJsonHandler.java @@ -13,12 +13,14 @@ package org.eclipse.lsp4j.jsonrpc.json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.InstanceCreator; import com.google.gson.JsonIOException; import com.google.gson.JsonParseException; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.MalformedJsonException; import com.itsaky.androidide.tooling.api.model.IdeProject; +import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject; import org.eclipse.lsp4j.jsonrpc.MessageIssueException; import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter; @@ -31,7 +33,6 @@ import org.eclipse.lsp4j.jsonrpc.messages.CancelParams; import org.eclipse.lsp4j.jsonrpc.messages.Message; import org.eclipse.lsp4j.jsonrpc.messages.MessageIssue; import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode; -import org.eclipse.lsp4j.jsonrpc.utils.IdeProjectInstanceCreator; import java.io.IOException; import java.io.Reader; @@ -70,7 +71,9 @@ public class MessageJsonHandler { .registerTypeAdapterFactory(new TupleTypeAdapters.TwoTypeAdapterFactory()) .registerTypeAdapterFactory(new EnumTypeAdapter.Factory()) .registerTypeAdapterFactory(new MessageTypeAdapter.Factory(this)) - .registerTypeAdapter(IdeProject.class, new IdeProjectInstanceCreator()); + .registerTypeAdapter( + IdeProject.class, + (InstanceCreator) type -> new DefaultIdeProject()); } /** diff --git a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java b/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java index f2afb9eda..19986abc0 100644 --- a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java +++ b/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/json/adapters/MessageTypeAdapter.java @@ -26,8 +26,6 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import com.google.gson.stream.MalformedJsonException; -import com.itsaky.androidide.tooling.api.model.IdeProject; -import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject; import org.eclipse.lsp4j.jsonrpc.MessageIssueException; import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod; @@ -45,7 +43,6 @@ import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage; import java.io.EOFException; import java.io.IOException; -import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Iterator; @@ -97,13 +94,9 @@ public class MessageTypeAdapter extends TypeAdapter { } else { out.name("result"); Object result = responseMessage.getResult(); - if (result == null) writeNullValue(out); - else { - if (Proxy.isProxyClass(result.getClass())) { - LOG.debug("Copying IdeProject instance..."); - result = copyProject((IdeProject) result); - } - + if (result == null) { + writeNullValue(out); + } else { gson.toJson(result, result.getClass(), out); } } @@ -214,14 +207,6 @@ public class MessageTypeAdapter extends TypeAdapter { out.setSerializeNulls(previousSerializeNulls); } - private Object copyProject(IdeProject result) { - final var project = new DefaultIdeProject(); - project.setProjectDir(result.getProjectDir()); - project.setDisplayName(result.getDisplayName()); - project.setPath(result.getPath()); - return project; - } - /** * Convert the json input into the result object corresponding to the call made by id. * diff --git a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/utils/IdeProjectCopier.java b/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/utils/IdeProjectCopier.java deleted file mode 100644 index 778c4024d..000000000 --- a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/utils/IdeProjectCopier.java +++ /dev/null @@ -1,49 +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 org.eclipse.lsp4j.jsonrpc.utils; - -import com.itsaky.androidide.tooling.api.model.IdeProject; -import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject; - -/** - * Copies an {@link IdeProject}. - * - *

Why do we need this class?
- *
The actual {@link IdeProject} instance is created in the AndroidIDEToolingApiPlugin - * class, which is NOT executed in the same JVM instance as the JSONRpc classes. As a result, the - * object we get from the plugin is a {@link java.lang.reflect.Proxy Proxy}. Gson is not capable of - * serializing proxy classes. So, before writing messages to the remote endpoint, we first check if - * the object we are writing is a proxy or not. If it is, then the data being written to - * the remote endpoint is definitely an {@link IdeProject}. So we use this class to copy the data - * stored in that proxy object to create a new instance of the project object. - * - *

Why we cannot create a copy() function in {@link IdeProject} class itself?
- * I tried to do the same and found that the new project object created is also a proxy. - * - * @author Akash Yadav - */ -public class IdeProjectCopier { - - public static IdeProject copy(IdeProject project) { - final var copy = new DefaultIdeProject(); - copy.setPath(project.getPath()); - copy.setProjectDir(project.getProjectDir()); - copy.setDisplayName(project.getDisplayName()); - return copy; - } -} diff --git a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/utils/IdeProjectInstanceCreator.java b/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/utils/IdeProjectInstanceCreator.java deleted file mode 100644 index 3a7005966..000000000 --- a/build-tools/jsonrpc/src/main/java/org/eclipse/lsp4j/jsonrpc/utils/IdeProjectInstanceCreator.java +++ /dev/null @@ -1,54 +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 . - */ - -/* - * 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 org.eclipse.lsp4j.jsonrpc.utils; - -import com.google.gson.InstanceCreator; -import com.itsaky.androidide.tooling.api.model.IdeProject; -import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject; - -import java.lang.reflect.Type; - -/** - * As {@link IdeProject} is an interface, we need to implement an {@link InstanceCreator}. - * - * @author Akash Yadav - */ -public class IdeProjectInstanceCreator implements InstanceCreator { - - @Override - public IdeProject createInstance(Type type) { - return new DefaultIdeProject(); - } -} diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeProject.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeProject.kt index 47fbba674..0d90c1cec 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeProject.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/IdeProject.kt @@ -28,24 +28,26 @@ import java.io.Serializable * @author Akash Yadav */ interface IdeProject : Serializable { - /** - * Get the path of this project. For example: ':app'. - * - * @return The path of this project. - */ + /** The path of this project. For example: ':app'. */ val path: String? - /** - * Get the display name of this project. - * - * @return The display name of this project. - */ + /** The display name of this project. */ val displayName: String? - /** - * Get the project directory of this project. - * - * @return The directory of this project. - */ + /** The project directory of this project. */ val projectDir: File? + + /** Get the build directory of this project. */ + val buildDir: File? + + /** The buildscript file (build.gradle) of this project. */ + val buildFile: File? + + /** Subprojects of this project. */ + val subProjects: List + + /** + * Dependencies of this project. + */ + val dependencies: List } diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectDependency.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectDependency.kt index 2fb33ec19..bfade8d25 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectDependency.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectDependency.kt @@ -23,14 +23,15 @@ import java.io.File * A project dependency. Holds data about the jar, sources and javadoc files of a dependency. Also * some other useful metadata. * + * If you do any changes here, please update IdeProjectCopier too. + * * @author Akash Yadav */ -class ProjectDependency( - private val group: String, - private val artifact: String, - private val version: String, - private val jar: File -) { - private val sourcesJar: File? = null - private val javadocJar: File? = null +class ProjectDependency { + var group: String? = null + var artifact: String? = null + var version: String? = null + var jar: File? = null + var sourcesJar: File? = null + var javadocJar: File? = null } diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectTask.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectTask.kt new file mode 100644 index 000000000..fb574f6a9 --- /dev/null +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/ProjectTask.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 + +/** + * A task in an [IdeProject]. + * + * @author Akash Yadav + */ +class ProjectTask { + + ////////////////////////////////////////////////////////////////////////// + //// Any changes made here must be reflected in IdeProjectCopier too //// + //////////////////////////////////////////////////////////////////////// + + var path: String? = null + var name: String? = null + var group: String? = null + var description: String? = null +} diff --git a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/internal/DefaultIdeProject.kt b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/internal/DefaultIdeProject.kt index 4bd055996..4bff8e8f5 100644 --- a/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/internal/DefaultIdeProject.kt +++ b/build-tools/tooling-api-model/src/main/java/com/itsaky/androidide/tooling/api/model/internal/DefaultIdeProject.kt @@ -18,12 +18,16 @@ package com.itsaky.androidide.tooling.api.model.internal import com.itsaky.androidide.tooling.api.model.IdeProject +import com.itsaky.androidide.tooling.api.model.ProjectDependency import java.io.File /** @author Akash Yadav */ class DefaultIdeProject : IdeProject { - override var path: String? = null override var displayName: String? = null override var projectDir: File? = null + override var buildDir: File? = null + override var buildFile: File? = null + override var subProjects: MutableList = mutableListOf() + override var dependencies: MutableList = mutableListOf() } diff --git a/build-tools/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java b/build-tools/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java index 0f83bb547..b63d7d542 100644 --- a/build-tools/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java +++ b/build-tools/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java @@ -18,11 +18,15 @@ package com.itsaky.androidide.tooling.plugin; import com.itsaky.androidide.tooling.api.model.IdeProject; +import com.itsaky.androidide.tooling.api.model.ProjectDependency; import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject; import org.gradle.api.Project; import org.gradle.tooling.provider.model.ToolingModelBuilder; +import java.util.ArrayList; +import java.util.List; + /** * @author Akash Yadav */ @@ -44,5 +48,25 @@ public class IdeProjectModelBuilder implements ToolingModelBuilder { ideProject.setPath(project.getPath()); ideProject.setDisplayName(project.getDisplayName()); ideProject.setProjectDir(project.getProjectDir()); + ideProject.setBuildDir(project.getBuildDir()); + ideProject.setBuildFile(project.getBuildFile()); + ideProject.setDependencies(getDependencies(project)); + ideProject.setSubProjects(getSubProjects(project)); + } + + private List getDependencies(Project project) { + return null; + } + + private List getSubProjects(Project project) { + final var projects = new ArrayList(); + project.getSubprojects() + .forEach( + sub -> { + final var subProject = new DefaultIdeProject(); + fillProjectDetails(sub, subProject); + projects.add(subProject); + }); + return projects; } } diff --git a/settings.gradle b/settings.gradle index 8f72be906..cb25ec9e0 100755 --- a/settings.gradle +++ b/settings.gradle @@ -22,6 +22,5 @@ include ':build-tools:javac' include ':build-tools:logger' include ':build-tools:tooling-api' include ':build-tools:tooling-api-impl' -include ':build-tools:tooling-api-plugin' include ':build-tools:tooling-api-model' include ':build-tools:jsonrpc'