Skip to content

Commit

Permalink
添加增量编译支持, 优化gradle plugin的编译速度
Browse files Browse the repository at this point in the history
  • Loading branch information
shinvi committed May 19, 2021
1 parent 1dbb3bc commit e51c930
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 51 deletions.
21 changes: 20 additions & 1 deletion component-gradle-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'java-library'
id 'kotlin'
id 'com.github.dcendents.android-maven'
// id 'maven'
}
group = 'com.github.qstumn'

Expand All @@ -15,6 +16,7 @@ dependencies {
implementation "com.android.tools.build:gradle:4.1.2"
implementation gradleApi()
implementation project(":component-annotation-compiler")
// implementation 'com.github.qstumn.ComponentHepler:component-annotation-compiler:1.1.0'
}
task sourceJar(type: Jar) {
classifier = 'sources'
Expand All @@ -25,4 +27,21 @@ artifacts {

tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
}

//uploadArchives {
// repositories {
// mavenDeployer {
// repository(url: 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath)
//
// pom.project {
// version '1.1.0-dev5'
// artifactId 'component-gradle-plugin'
// groupId 'com.github.qstumn.dev.ComponentHepler'
// packaging = 'jar'
// description = 'component-gradle-plugin'
// }
// }
//
// }
//}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package q.rorbin.component.gradle.plugin.transform

import com.android.build.api.transform.Format
import com.android.build.api.transform.QualifiedContent
import com.android.build.api.transform.Transform
import com.android.build.api.transform.TransformInvocation
import com.android.build.api.transform.*
import com.android.utils.FileUtils
import org.apache.commons.codec.digest.DigestUtils
import q.rorbin.component.ComponentInitializatorManager
Expand All @@ -28,24 +25,38 @@ class ComponentTransform : Transform() {
QualifiedContent.Scope.EXTERNAL_LIBRARIES
)

override fun isIncremental(): Boolean = false
override fun isIncremental(): Boolean = true

override fun transform(transformInvocation: TransformInvocation?) {
super.transform(transformInvocation)
transformInvocation ?: return

val serviceHelpers = mutableListOf<String>()
val initializatorHelpers = mutableListOf<String>()
var serviceHelperManager: File? = null
var initializatorHelperManager: File? = null

val inputs = transformInvocation.inputs
val outputProvider = transformInvocation.outputProvider

if (!transformInvocation.isIncremental) {
outputProvider.deleteAll()
}

val servicePackage = "${ComponentService::class.java.`package`.name}."
val initializatorPackage = "${ComponentInitializator::class.java.`package`.name}."

inputs.forEach { input ->
//遍历所有的文件夹收集serviceHelpers和initializatorHelpers
input.directoryInputs.forEach { dirInput ->
dirInput.file.traverse(
val inputDir = dirInput.file
val destDir = outputProvider.getContentLocation(
dirInput.name,
dirInput.contentTypes,
dirInput.scopes,
Format.DIRECTORY
)
inputDir.traverse(
{ file -> file.extension == "class" },
FileType.FILE
) { file ->
Expand All @@ -57,23 +68,23 @@ class ComponentTransform : Transform() {
initializatorHelpers.add("$initializatorPackage$name")
}
}
val dest = outputProvider.getContentLocation(
dirInput.name,
dirInput.contentTypes,
dirInput.scopes,
Format.DIRECTORY
)
FileUtils.copyDirectory(dirInput.file, dest)
if (transformInvocation.isIncremental) {
for ((file, status) in dirInput.changedFiles) {
val destFile =
File(destDir, FileUtils.relativePossiblyNonExistingPath(file, inputDir))
when (status) {
Status.ADDED, Status.CHANGED -> FileUtils.copyFile(file, destFile)
Status.REMOVED -> FileUtils.delete(destFile)
}
}
} else {
FileUtils.copyDirectory(inputDir, destDir)
}
}
//遍历所有的jar文件收集serviceHelpers和initializatorHelpers, 并记录当前serviceHelperManager或initializatorHelperManager是否在这个jar中
input.jarInputs.forEach { jarInput ->
var jarName = jarInput.name
val md5 = DigestUtils.md5Hex(jarInput.file.absolutePath)
if (jarName.endsWith(".jar")) {
jarName = jarName.substring(0, jarName.length - 4)
}
val dest = outputProvider.getContentLocation(
jarName + md5,
jarInput.name,
jarInput.contentTypes,
jarInput.scopes,
Format.JAR
Expand Down Expand Up @@ -103,7 +114,14 @@ class ComponentTransform : Transform() {
}
}
}
FileUtils.copyFile(jarInput.file, dest)
if (transformInvocation.isIncremental) {
when (jarInput.status) {
Status.ADDED, Status.CHANGED -> FileUtils.copyFile(jarInput.file, dest)
Status.REMOVED -> FileUtils.delete(dest)
}
} else {
FileUtils.copyFile(jarInput.file, dest)
}
}
}
println("serviceHelpers gather result : $serviceHelpers, serviceHelperManager : $serviceHelperManager")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,42 @@ import q.rorbin.component.ComponentInitializatorManager
/**
* @author changhai.qiu
*/
class ComponentInitializatorManagerClassVisitor(private val classVisitor: ClassVisitor, private val helpers: MutableList<String>) : ClassVisitor(Opcodes.ASM5, classVisitor) {
class ComponentInitializatorManagerClassVisitor(
private val classVisitor: ClassVisitor,
private val helpers: MutableList<String>
) : ClassVisitor(Opcodes.ASM5, classVisitor) {

override fun visitMethod(
access: Int,
name: String,
descriptor: String,
signature: String?,
exceptions: Array<out String>?
access: Int,
name: String,
descriptor: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor {
var methodVisitor = classVisitor.visitMethod(access, name, descriptor, signature, exceptions)
var methodVisitor =
classVisitor.visitMethod(access, name, descriptor, signature, exceptions)
if (name == "addAllInitializator") {
methodVisitor = AddAllInitializatorMethodAdapter(methodVisitor, access, name, descriptor)
methodVisitor = AddAllInitializatorMethodAdapter(methodVisitor)
}
return methodVisitor
}

private inner class AddAllInitializatorMethodAdapter(mv: MethodVisitor, access: Int, private val name: String?, desc: String?)
: AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) {
private inner class AddAllInitializatorMethodAdapter(val visitor: MethodVisitor) :
MethodVisitor(Opcodes.ASM5) {

override fun onMethodEnter() {
super.onMethodEnter()
override fun visitCode() {
for (helper in helpers) {
mv.visitVarInsn(Opcodes.ALOAD, 0)
mv.visitLdcInsn(helper)
mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(ComponentInitializatorManager::class.java),
"addInitializator", "(Ljava/lang/String;)V", false)
visitor.visitVarInsn(Opcodes.ALOAD, 0)
visitor.visitLdcInsn(helper)
visitor.visitMethodInsn(
Opcodes.INVOKESPECIAL,
Type.getInternalName(ComponentInitializatorManager::class.java),
"addInitializator",
"(Ljava/lang/String;)V",
false
)
}
visitor.visitInsn(Opcodes.RETURN)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,29 @@ class ComponentServiceManagerClassVisitor(
descriptor: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor {
): MethodVisitor? {
var methodVisitor =
classVisitor.visitMethod(access, name, descriptor, signature, exceptions)
if (name == "initServices") {
methodVisitor = InitServicesMethodAdapter(methodVisitor, access, name, descriptor)
methodVisitor = InitServicesMethodAdapter(methodVisitor)
}
return methodVisitor
}

private inner class InitServicesMethodAdapter(
mv: MethodVisitor,
access: Int,
name: String?,
desc: String?
) : AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) {

override fun onMethodEnter() {
super.onMethodEnter()
private inner class InitServicesMethodAdapter(val visitor: MethodVisitor) :
MethodVisitor(Opcodes.ASM5) {
override fun visitCode() {
for (helper in helpers) {
mv.visitVarInsn(Opcodes.ALOAD, 0)
mv.visitLdcInsn(helper)
mv.visitMethodInsn(
visitor.visitVarInsn(Opcodes.ALOAD, 0)
visitor.visitLdcInsn(helper)
visitor.visitMethodInsn(
Opcodes.INVOKESPECIAL, Type.getInternalName(
ComponentServiceManager::class.java
),
"initServiceByHelper", "(Ljava/lang/String;)V", false
)
}
visitor.visitInsn(Opcodes.RETURN)
}
}
}

0 comments on commit e51c930

Please sign in to comment.