Created different classes for different types of projects and modules with their default implementations.

This commit is contained in:
Akash Yadav
2022-04-25 22:11:19 +05:30
parent 8b0843af21
commit 77c787073f
18 changed files with 498 additions and 105 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
<module name="AndroidIDE.build-tools.google-java-format" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel target="1.7">
<bytecodeTargetLevel target="1.8">
<module name="AndroidIDE.build-tools.tooling-api-plugin" target="11" />
<module name="AndroidIDE.google-java-format" target="1.8" />
<module name="AndroidIDE.gradle-tooling" target="1.8" />
+1 -1
View File
@@ -141,7 +141,7 @@
</option>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
Binary file not shown.
@@ -20,7 +20,7 @@ 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.IAndroidProject;
import com.itsaky.androidide.tooling.api.model.internal.DefaultAndroidProject;
import com.itsaky.androidide.tooling.api.model.internal.DefaultAndroidModule;
import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
import org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter;
@@ -70,10 +70,7 @@ public class MessageJsonHandler {
.registerTypeAdapterFactory(new EitherTypeAdapter.Factory())
.registerTypeAdapterFactory(new TupleTypeAdapters.TwoTypeAdapterFactory())
.registerTypeAdapterFactory(new EnumTypeAdapter.Factory())
.registerTypeAdapterFactory(new MessageTypeAdapter.Factory(this))
.registerTypeAdapter(
IAndroidProject.class,
(InstanceCreator<IAndroidProject>) type -> new DefaultAndroidProject ());
.registerTypeAdapterFactory(new MessageTypeAdapter.Factory(this));
}
/**
@@ -20,7 +20,6 @@ package com.itsaky.androidide.tooling.impl
import com.itsaky.androidide.tooling.api.IToolingApiClient
import com.itsaky.androidide.tooling.api.IToolingApiServer
import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
import com.itsaky.androidide.tooling.api.model.IAndroidProject
import com.itsaky.androidide.tooling.impl.util.InitScriptHandler
import com.itsaky.androidide.tooling.impl.util.ProjectReader
import com.itsaky.androidide.tooling.impl.util.StopWatch
@@ -0,0 +1,66 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.impl.util;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.itsaky.androidide.tooling.api.model.IGradleProject;
import java.lang.reflect.Type;
/**
* Gson (de)serializer for {@link IGradleProject}.
*
* @author Akash Yadav
*/
public class IGradleProjectTypeAdapter
implements JsonSerializer<IGradleProject>, JsonDeserializer<IGradleProject> {
public static final String className = "className";
public static final String classInst = "classInst";
@Override
public JsonElement serialize(
IGradleProject src, Type typeOfSrc, JsonSerializationContext context) {
final var obj = new JsonObject();
obj.addProperty(className, src.getClass().getName());
obj.add(classInst, context.serialize(obj));
return obj;
}
@Override
public IGradleProject deserialize(
JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
final var obj = json.getAsJsonObject();
final var name = obj.get(className).getAsString();
final Class<?> klass;
try {
klass = Class.forName(name);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
return context.deserialize(obj.get(classInst), klass);
}
}
@@ -20,11 +20,9 @@ package com.itsaky.androidide.tooling.impl.util;
import static com.itsaky.androidide.utils.ILogger.newInstance;
import com.android.builder.model.v2.models.AndroidProject;
import com.itsaky.androidide.tooling.api.model.IAndroidProject;
import com.itsaky.androidide.tooling.api.model.internal.DefaultAndroidProject;
import com.itsaky.androidide.tooling.api.model.IGradleProject;
import com.itsaky.androidide.utils.ILogger;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.model.GradleProject;
@@ -35,34 +33,24 @@ public class ProjectReader {
private static final ILogger LOG = newInstance("test");
public static IAndroidProject read(ProjectConnection connection) {
public static IGradleProject read(ProjectConnection connection) {
final var watch = new StopWatch("Read eclipse project from connection");
final var gradle = connection.getModel(GradleProject.class);
LOG.debug(System.getenv());
LOG.debug(System.getProperties());
for (var sub : gradle.getChildren()) {
var subConnection =
GradleConnector.newConnector()
.forProjectDirectory(sub.getProjectDirectory())
.connect();
final var modelBuilder =
subConnection
.model(AndroidProject.class)
.withArguments("-Pandroid.injected.build.model.v2=true");
final var project = modelBuilder.get();
LOG.debug(project);
if (gradle == null) {
LOG.error("Cannot build model for", GradleProject.class);
return null;
}
final var android =
connection
.model(AndroidProject.class)
.withArguments("-Pandroid.injected.build.model.v2=true")
.get();
LOG.debug(android);
watch.log();
// return read(project);
return null;
}
public static IAndroidProject read(AndroidProject android) {
final var project = new DefaultAndroidProject ();
LOG.debug(android);
return project;
}
public static IGradleProject read(AndroidProject android) {}
}
+14 -7
View File
@@ -21,9 +21,21 @@ plugins {
}
java {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
repositories {
maven {
url 'https://repo.gradle.org/gradle/libs-releases/'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation 'com.android.tools.build:builder-model:7.1.3'
}
task copyToTestDir (type: Copy) {
from "$project.buildDir.absolutePath/libs/tooling-api-model.jar"
into "${project.rootProject.findProject (":build-tools:tooling-api-impl").file ("src/test/test-home/.androidide/init").absolutePath}/"
@@ -41,9 +53,4 @@ project.tasks.jar {
outputs.upToDateWhen {
false
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}
@@ -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 <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model
import com.android.builder.model.v2.models.AndroidProject
/**
* A module in an [IAndroidProject].
*
* @author Akash Yadav
*/
interface IAndroidModule : IGradleProject, AndroidProject {}
@@ -1,53 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model
import java.io.File
import java.io.Serializable
/**
* Currently initialized project.
*
* The instance of this class is created from a [Proxy][java.lang.reflect.Proxy]. If you add any
* property to this class, make sure you update the [IAndroidProject.copy] method too.
*
* @author Akash Yadav
*/
interface IAndroidProject : Serializable {
/** The path of this project. For example: ':app'. */
val path: String?
/** The display name of this project. */
val displayName: String?
/** 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<IAndroidProject>
/**
* Dependencies of this project.
*/
val dependencies: List<ProjectDependency>
}
@@ -15,19 +15,33 @@
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model.internal
package com.itsaky.androidide.tooling.api.model
import com.itsaky.androidide.tooling.api.model.IAndroidProject
import com.itsaky.androidide.tooling.api.model.ProjectDependency
import java.io.File
import java.io.Serializable
/** @author Akash Yadav */
class DefaultAndroidProject : IAndroidProject {
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<IAndroidProject> = mutableListOf()
override var dependencies: MutableList<ProjectDependency> = mutableListOf()
/**
* An Gradle Project.
* @author Akash Yadav
*/
interface IGradleProject : Serializable {
val name: String
val description: String
val path: String
val projectDir: File
val buildDir: File
val buildScript: File
val parent: IGradleProject?
val subprojects: List<IGradleProject>
val tasks: List<IGradleTask>
val isAndroidModule: Boolean
/**
* Finds the project with the given project path.
*
* @return The found [IGradleProject] or `null`.
*/
fun findByPath(path: String): IGradleProject?
}
@@ -0,0 +1,31 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model
/**
* A task in an [IGradleProject].
* @author Akash Yadav
*/
interface IGradleTask : ILaunchable {
val name: String
val description: String
val group: String
val path: String
val project: IGradleProject
}
@@ -0,0 +1,28 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model
/**
* A launchable is an action that can be launched. For example, an [IGradleTask].
*
* @author Akash Yadav
*/
interface ILaunchable {
val displayName: String
val isPublic: Boolean
}
@@ -0,0 +1,99 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model.internal
import com.android.builder.model.v2.ide.AndroidGradlePluginProjectFlags
import com.android.builder.model.v2.ide.JavaCompileOptions
import com.android.builder.model.v2.ide.ProjectType
import com.android.builder.model.v2.ide.SourceSetContainer
import com.android.builder.model.v2.ide.Variant
import com.android.builder.model.v2.ide.ViewBindingOptions
import com.itsaky.androidide.tooling.api.model.IAndroidModule
import com.itsaky.androidide.tooling.api.model.IGradleProject
import com.itsaky.androidide.tooling.api.model.IGradleTask
import java.io.File
/**
* Default implementation of [IAndroidModule].
*
* @author Akash Yadav
*/
class DefaultAndroidModule(
override var name: String,
override var description: String,
override var path: String,
override var projectDir: File,
override var buildDir: File,
override var buildScript: File,
override var parent: IGradleProject?,
override var subprojects: List<IGradleProject>,
override var tasks: List<IGradleTask>,
override var androidTestNamespace: String?,
override var bootClasspath: Collection<File>,
override var buildFolder: File,
override var buildName: String,
override var buildTypeSourceSets: Collection<SourceSetContainer>,
override var dynamicFeatures: Collection<String>?,
override var flags: AndroidGradlePluginProjectFlags,
override var javaCompileOptions: JavaCompileOptions,
override var lintRuleJars: List<File>,
override var mainSourceSet: SourceSetContainer,
override var namespace: String,
override var productFlavorSourceSets: Collection<SourceSetContainer>,
override var projectType: ProjectType,
override var resourcePrefix: String?,
override var testFixturesNamespace: String?,
override var variants: Collection<Variant>,
override var viewBindingOptions: ViewBindingOptions?
) :
DefaultGradleProject(
name, description, path, projectDir, buildDir, buildScript, parent, subprojects, tasks),
IAndroidModule {
override val isAndroidModule: Boolean = true
fun copy(): IAndroidModule {
return DefaultAndroidModule(
name,
description,
path,
projectDir,
buildDir,
buildScript,
parent,
subprojects,
tasks,
androidTestNamespace,
bootClasspath,
buildFolder,
buildName,
buildTypeSourceSets,
dynamicFeatures,
flags,
javaCompileOptions,
lintRuleJars,
mainSourceSet,
namespace,
productFlavorSourceSets,
projectType,
resourcePrefix,
testFixturesNamespace,
variants,
viewBindingOptions)
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model.internal
import com.itsaky.androidide.tooling.api.model.IGradleProject
import com.itsaky.androidide.tooling.api.model.IGradleTask
import java.io.File
/**
* Default implementation for [IGradleProject].
* @author Akash Yadav
*/
open class DefaultGradleProject(
override val name: String,
override val description: String,
override val path: String,
override val projectDir: File,
override val buildDir: File,
override val buildScript: File,
override val parent: IGradleProject?,
override val subprojects: List<IGradleProject>,
override val tasks: List<IGradleTask>,
) : IGradleProject {
override val isAndroidModule: Boolean = false
override fun findByPath(path: String): IGradleProject? {
if (path == this.path) {
return this
}
for (sub in subprojects) {
val subSub = sub.findByPath(path)
if (subSub != null) {
return subSub
}
}
return null
}
}
@@ -0,0 +1,135 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.tooling.api.model.internal.util
import com.android.builder.model.v2.ide.AndroidGradlePluginProjectFlags
import com.android.builder.model.v2.ide.AndroidGradlePluginProjectFlags.BooleanFlag
import com.android.builder.model.v2.ide.JavaCompileOptions
import com.android.builder.model.v2.ide.ProjectType
import com.android.builder.model.v2.ide.ProjectType.APPLICATION
import com.android.builder.model.v2.ide.SourceProvider
import com.android.builder.model.v2.ide.SourceSetContainer
import com.android.builder.model.v2.ide.Variant
import com.android.builder.model.v2.ide.ViewBindingOptions
import com.itsaky.androidide.tooling.api.model.IAndroidModule
import com.itsaky.androidide.tooling.api.model.IGradleProject
import com.itsaky.androidide.tooling.api.model.IGradleTask
import com.itsaky.androidide.tooling.api.model.internal.DefaultAndroidModule
import com.itsaky.androidide.tooling.api.model.internal.DefaultGradleProject
import java.io.File
/**
* Builds instances of [IAndroidProject]
*
* @author Akash Yadav
*/
class ProjectBuilder {
private var name: String = ""
private var description: String = ""
private var path: String = ""
private var projectDir: File = File("<no_path>")
private var buildDir: File = File("<no_path>")
private var buildScript: File = File("<no_path>")
private var parent: IGradleProject? = null
private var subprojects: List<IGradleProject> = mutableListOf()
private var tasks: List<IGradleTask> = mutableListOf()
private var androidTestNamespace: String = ""
private var bootClasspath: Collection<File> = mutableListOf()
private var buildFolder: File = File("<no_path>")
private var buildName: String = ""
private var buildTypeSourceSets: Collection<SourceSetContainer> = mutableListOf()
private var dynamicFeatures: Collection<String>? = mutableListOf()
private var flags: AndroidGradlePluginProjectFlags = NoOpAndroidGradlePluginProjectFlags()
private var javaCompileOptions: JavaCompileOptions = DefaultJavaCompileOptions()
private var lintRuleJars: List<File> = mutableListOf()
private var mainSourceSet: SourceSetContainer = DefaultSourceSetContainer()
private var namespace: String = ""
private var productFlavorSourceSets: Collection<SourceSetContainer> = mutableListOf()
private var projectType: ProjectType = APPLICATION
private var resourcePrefix: String = ""
private var testFixturesNamespace: String = ""
private var variants: Collection<Variant> = mutableListOf()
private var viewBindingOptions: ViewBindingOptions? = null
fun buildGradleProject(): IGradleProject {
return DefaultGradleProject(
name, description, path, projectDir, buildDir, buildScript, parent, subprojects, tasks)
}
fun buildAndroidModule(): IAndroidModule =
DefaultAndroidModule(
name,
description,
path,
projectDir,
buildDir,
buildScript,
parent,
subprojects,
tasks,
androidTestNamespace,
bootClasspath,
buildFolder,
buildName,
buildTypeSourceSets,
dynamicFeatures,
flags,
javaCompileOptions,
lintRuleJars,
mainSourceSet,
namespace,
productFlavorSourceSets,
projectType,
resourcePrefix,
testFixturesNamespace,
variants,
viewBindingOptions)
class NoOpAndroidGradlePluginProjectFlags : AndroidGradlePluginProjectFlags {
override val booleanFlagMap: Map<BooleanFlag, Boolean> = mutableMapOf()
}
class DefaultJavaCompileOptions : JavaCompileOptions {
override val encoding: String = "UTF-8"
override val isCoreLibraryDesugaringEnabled: Boolean = false
override val sourceCompatibility: String = "11"
override val targetCompatibility: String = "11"
}
class DefaultSourceSetContainer : SourceSetContainer {
override val androidTestSourceProvider: SourceProvider? = null
override val sourceProvider: SourceProvider = DefaultSourceProvider()
override val testFixturesSourceProvider: SourceProvider? = null
override val unitTestSourceProvider: SourceProvider? = null
class DefaultSourceProvider : SourceProvider {
override val aidlDirectories: Collection<File>? = null
override val assetsDirectories: Collection<File>? = null
override val javaDirectories = mutableListOf<File>()
override val jniLibsDirectories: Collection<File> = mutableListOf()
override val kotlinDirectories: Collection<File> = mutableListOf()
override val manifestFile = File("<no_path>")
override val mlModelsDirectories: Collection<File>? = null
override val name: String = ""
override val renderscriptDirectories: Collection<File>? = null
override val resDirectories: Collection<File>? = null
override val resourcesDirectories: Collection<File> = mutableListOf()
override val shadersDirectories: Collection<File>? = null
}
}
}
@@ -18,7 +18,6 @@
package com.itsaky.androidide.tooling.api
import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams
import com.itsaky.androidide.tooling.api.model.IAndroidProject
import java.util.concurrent.*
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest
import org.eclipse.lsp4j.jsonrpc.services.JsonSegment