Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ Capture:
Flags:
- ways to disable class count and resource count (--no-class-count on task)

Generation
- Fetch resource artifact from AGP to reference resources from other modules
- Two-pass resource generation so menu resources can be generated with code references
- Implement random raw resource generation. Also implement random java resource generation and asset generation.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
*/
package com.android.gradle.replicator.codegen

import kotlin.reflect.KClass

data class FieldModel(
val name: String,
override val classModel: ClassModel<*>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.android.gradle.replicator.codegen

import com.android.gradle.replicator.resourceModel.ResourceModel
import java.io.File
import java.lang.reflect.Modifier
import java.net.URLClassLoader
Expand All @@ -39,20 +40,25 @@ class GeneratorDriver(
/**
* Generate a single class
*
* @param moduleName the root package for the module (where the R class is located).
* @param packageName the package name for the class to generate.
* @param className the class name to generate.
* @param printStream the [PrettyPrintStream] to use to generate the code.
* @param listeners optional list of code generation listeners to further customize generated code.
*/
override fun generateClass(
moduleName: String,
packageName: String,
className: String,
printStream: PrettyPrintStream,
listeners: List<CodeGenerationListener>) {
listeners: List<CodeGenerationListener>,
resourceModel: ResourceModel) {
SingleClassGenerator(
generator = generatorAllocator(printStream, listeners),
moduleName = moduleName,
packageName = packageName,
className = className,
resourceModel = resourceModel,
random = random,
apiClassPicker = apiImportClassPicker,
implClassPicker = implementationImportClassPicker,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ open class ImportClassPicker(
return classModel
}

/**
* find a specific class in the class loader by name.
*
* @param className the name of the class.
* @return the class or null if it could not be found.
*/
fun getClassByName(className: String): ClassModel<*>? {
return isClassEligible(loadClass(className))
}

/**
* Loads a class from the classloader.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@
*/
package com.android.gradle.replicator.codegen

import com.android.gradle.replicator.model.AndroidResourcesInfo
import com.android.gradle.replicator.model.FilesWithSizeMetadataInfo
import com.android.gradle.replicator.model.internal.AndroidResourcesAdapter
import com.android.gradle.replicator.model.internal.DefaultAndroidResourcesInfo
import com.android.gradle.replicator.model.internal.DefaultFilesWithSizeMetadataInfo
import com.android.gradle.replicator.model.internal.FilesWithSizeMetadataAdapter
import com.android.gradle.replicator.parsing.ArgsParser
import com.android.gradle.replicator.resourceModel.ResourceModel
import com.android.gradle.replicator.resourceModel.ResourceModelAdapter
import com.google.gson.stream.JsonReader
import java.io.File
import java.io.PrintStream
import java.nio.file.Files

fun main(args: Array<String>) {
val main= Main()
Expand All @@ -34,6 +44,7 @@ class Main {
val parser = ArgsParser()

val pathToArgumentsFileOption = parser.option(longName = "argsFile", shortName = "i", argc = 1)
val resourceModelFileOption = parser.option(longName = "resModel", shortName = "rm", argc = 1)
val outputFolderOption = parser.option(longName = "outputFolder", shortName = "o", argc = 1)
val moduleOption = parser.option(longName = "module", shortName = "m", argc = 1)
val implClasspathElementOption = parser.option(
Expand Down Expand Up @@ -61,11 +72,19 @@ class Main {
parser.parseArgs(args)

val parametersBuilder = CodeGenerationParameters.Builder()
val pathToArgumentsFile = pathToArgumentsFileOption.orNull?.first
if (pathToArgumentsFile!=null
&& File(pathToArgumentsFile).exists()) {
parser.parsePropertyFile(File(pathToArgumentsFile))
val pathToArgumentsFile = pathToArgumentsFileOption.orNull?.asFile
if (pathToArgumentsFile != null
&& pathToArgumentsFile.exists()) {
parser.parsePropertyFile(pathToArgumentsFile)
}
val resourceModelFile = resourceModelFileOption.orNull?.asFile
val resourceModel =
if (resourceModelFile != null
&& resourceModelFile.exists()) {
loadResourceModel(resourceModelFile)
} else {
ResourceModel()
}
buildParameters(
parametersBuilder,
apiOption.orNull?.argv,
Expand All @@ -80,7 +99,7 @@ class Main {
val kotlinGenerator: GeneratorType = GeneratorType.Kotlin
val javaGenerator = GeneratorType.Java

val outputFolder = File(checkNotNull(outputFolderOption.orNull?.first))
val outputFolder = outputFolderOption.asFile
outputFolder.deleteRecursively()
outputFolder.mkdirs()
println("Generating in $outputFolder")
Expand All @@ -94,6 +113,7 @@ class Main {
javaGenerator,
arguments,
moduleName,
resourceModel,
outputFolder
)
}
Expand All @@ -103,6 +123,7 @@ class Main {
kotlinGenerator,
arguments,
moduleName,
resourceModel,
outputFolder
)
}
Expand All @@ -113,6 +134,7 @@ class Main {
generatorType: GeneratorType,
parameters: CodeGenerationParameters,
moduleName: String,
resourceModel: ResourceModel,
outputFolder: File) {
val generator = generatorType.initialize(parameters)
repeat(numberOfSources) { count ->
Expand All @@ -124,14 +146,27 @@ class Main {
println("Generating ${generatorType.name} source ${outputFile.absolutePath}")
PrintStream(outputFile).use {
generator.generateClass(
moduleName = "com.android.example.${moduleName}",
packageName = "com.android.example.${moduleName}",
className = className,
printStream = PrettyPrintStream(it),
listeners = listOf())
listeners = listOf(),
resourceModel = resourceModel)
}
}
}

// read generated android resource model
private fun loadResourceModel(resourceModelFile: File): ResourceModel {
var resourceModel: ResourceModel

with(JsonReader(Files.newBufferedReader(resourceModelFile.toPath()))) {
resourceModel = ResourceModelAdapter().read(this)
}

return resourceModel
}

private fun buildParameters(
parametersBuilder: CodeGenerationParameters.Builder,
apiClasspath: List<String>?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.android.gradle.replicator.codegen

import com.android.gradle.replicator.resourceModel.ResourceModel
import java.lang.reflect.Modifier
import kotlin.random.Random
import kotlin.reflect.*
Expand All @@ -28,17 +29,21 @@ import kotlin.reflect.jvm.kotlinFunction
class SingleClassGenerator(
generator: ClassGenerator,
private val params: ClassGenerationParameters,
private val moduleName: String,
private val packageName: String,
private val className: String,
private val apiClassPicker: ImportClassPicker,
private val implClassPicker: ImportClassPicker,
private val resourceModel: ResourceModel,
private val random: Random
) {

private val classGenerator = ModelBuilderClassGenerator(generator)

private var currentBlockDepth: Int = 0;

private val rClassName = "$moduleName.R"

/**
* Generate a single class using the provided generation parameters.
*/
Expand Down Expand Up @@ -222,6 +227,10 @@ class SingleClassGenerator(
}
}

private fun addResourceReferenceAndMethodCall() {
// To be implemented
}

private fun findMethodReturning(desiredReturnType: KType): MethodCall? {
return findMethodReturning(classGenerator.getMethodParametersVariables(), desiredReturnType)
?: findMethodReturning(classGenerator.getLocalVariables(), desiredReturnType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package com.android.gradle.replicator.codegen

import com.android.gradle.replicator.resourceModel.ResourceModel

/**
* A SourceGenerator is capable of generating various types of source files for a particular language.
*
Expand All @@ -24,15 +26,18 @@ package com.android.gradle.replicator.codegen
interface SourceGenerator {
/**
* Generate a class
* @param moduleName the root package for the module (where the R class is located).
* @param packageName the class package.
* @param className the class name.
* @param printStream the stream to write the source code to.
* @param listeners listeners for code generation events.
*/
fun generateClass(
moduleName: String,
packageName: String,
className: String,
printStream: PrettyPrintStream,
listeners: List<CodeGenerationListener> = listOf()
listeners: List<CodeGenerationListener> = listOf(),
resourceModel: ResourceModel
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class ArgsParser {
get() = argv[0]
val orNull
get() = if (isPresent) this else null
val asFile
get() = File(argv[0])
}

private val longNameOpts = mutableMapOf<String, Option>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ package com.android.gradle.replicator.resgen
import com.android.gradle.replicator.model.internal.filedata.AbstractAndroidResourceProperties
import com.android.gradle.replicator.model.internal.filedata.DefaultAndroidResourceProperties
import com.android.gradle.replicator.model.internal.filedata.ResourcePropertyType
import com.android.gradle.replicator.resgen.resourceModel.ResourceData
import com.android.gradle.replicator.resourceModel.ResourceData
import com.android.gradle.replicator.resgen.util.FileTypes
import com.android.gradle.replicator.resgen.util.VectorDrawableGenerator
import com.android.gradle.replicator.resgen.util.copyResourceFile
import com.android.gradle.replicator.resgen.util.getFileType
import com.android.gradle.replicator.resgen.util.getResourceClosestToSize
import com.android.gradle.replicator.resourceModel.ResourceTypes
import com.google.common.annotations.VisibleForTesting
import java.io.File

Expand Down Expand Up @@ -60,7 +61,7 @@ class DrawableResourceGenerator (params: ResourceGenerationParams): ResourceGene
params.resourceModel.resourceList.add(ResourceData(
pkg = "",
name = fileName,
type = "drawable",
type = ResourceTypes.DRAWABLE,
extension = properties.extension,
qualifiers = properties.splitQualifiers))
}
Expand All @@ -72,7 +73,7 @@ class DrawableResourceGenerator (params: ResourceGenerationParams): ResourceGene
params.resourceModel.resourceList.add(ResourceData(
pkg = "",
name = fileName,
type = "drawable",
type = ResourceTypes.DRAWABLE,
extension = properties.extension,
qualifiers = properties.splitQualifiers))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package com.android.gradle.replicator.resgen
import com.android.gradle.replicator.model.internal.filedata.AbstractAndroidResourceProperties
import com.android.gradle.replicator.model.internal.filedata.DefaultAndroidResourceProperties
import com.android.gradle.replicator.model.internal.filedata.ResourcePropertyType
import com.android.gradle.replicator.resgen.resourceModel.ResourceData
import com.android.gradle.replicator.resourceModel.ResourceData
import com.android.gradle.replicator.resgen.util.copyResourceFile
import com.android.gradle.replicator.resgen.util.getFileType
import com.android.gradle.replicator.resgen.util.getResourceClosestToSize
import com.android.gradle.replicator.resourceModel.ResourceTypes
import java.io.File

class FontResourceGenerator(params: ResourceGenerationParams): ResourceGenerator(params) {
Expand Down Expand Up @@ -40,7 +41,7 @@ class FontResourceGenerator(params: ResourceGenerationParams): ResourceGenerator
ResourceData(
pkg = "",
name = fileName,
type = "font",
type = ResourceTypes.FONT,
extension = properties.extension,
qualifiers = properties.splitQualifiers)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.android.gradle.replicator.resgen

import com.android.gradle.replicator.model.internal.filedata.AbstractAndroidResourceProperties
import com.android.gradle.replicator.resgen.resourceModel.ResourceModel
import com.android.gradle.replicator.resourceModel.ResourceModel
import com.android.gradle.replicator.resgen.util.ResgenConstants
import com.android.gradle.replicator.resgen.util.UniqueIdGenerator
import java.io.File
Expand Down
Loading