Skip to content

Commit

Permalink
Merge pull request #3 from 2BAB/dev
Browse files Browse the repository at this point in the history
release 0.2.0
  • Loading branch information
2BAB committed Mar 18, 2023
2 parents 8d461ad + 3851935 commit 50096c7
Show file tree
Hide file tree
Showing 45 changed files with 1,001 additions and 168 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/maven-central-publish.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {

// 1. Determine the type of publication
val publishType = project.properties["me.2bab.maven.publish.type"] as String
println("publishType: $publishType")
//println("publishType: $publishType")


// 2. Signing and ossrh secrets setup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package me.xx2bab.caliper.ksp
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.*
import com.google.devtools.ksp.validate
import com.squareup.javapoet.TypeName
import com.squareup.kotlinpoet.javapoet.KotlinPoetJavaPoetPreview
import com.squareup.kotlinpoet.javapoet.toJTypeName
import com.squareup.kotlinpoet.ksp.toTypeName
Expand Down Expand Up @@ -153,7 +154,10 @@ class CaliperProxyRulesAggregationProcessor(
val className = currClass.qualifiedName!!.asString()
logger.info("className = $className")

val functionReturnType = function.returnType?.toTypeName()?.toJTypeName()
var functionReturnType = function.returnType?.toTypeName()?.toJTypeName()
if (functionReturnType == null || functionReturnType.toString() == "kotlin.Unit") {
functionReturnType = TypeName.VOID
}
logger.info("functionReturnType = $functionReturnType")

val functionParameters = function.parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.squareup.javapoet.ClassName
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.ParameterSpec
import com.squareup.javapoet.TypeName
import com.squareup.javapoet.TypeSpec
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
Expand All @@ -29,15 +30,16 @@ class CaliperWrapperGenerator(
fun generate() {
val proxiedMetaData = ProxiedMetaData()
metadataMap.forEach { (className, metadata) ->
val fullClassNameBySlash = className.replace(".", "/")
val simpleClassName = className.split(".").last()
val wrapperSimpleClassName = simpleClassName.toCaliperWrapperSimpleName()
val wrapperFullClassNameBySlash = simpleClassName.toCaliperWrapperFullNameBySlash()

if (metadata.targetClass != null) {
proxiedMetaData.proxiedClasses.add(
ProxiedClass(
className = metadata.targetClass!!,
replacedClassName = className.replace(".", "/")
targetClassName = metadata.targetClass!!.replace(".", "/"),
newClassName = fullClassNameBySlash
)
)

Expand Down Expand Up @@ -66,20 +68,24 @@ class CaliperWrapperGenerator(
proxyMethod.targetType == CaliperMethodProxy::class.simpleName
if (isAnnotatedWithProxyMethod) {
val pm = ProxiedMethod(
className = proxyMethod.targetClassName,
methodName = proxyMethod.targetElementName,
opcode = proxyMethod.targetOpcode,
replacedClassName = wrapperFullClassNameBySlash,
replacedMethodName = proxyMethod.methodName
targetClassName = proxyMethod.targetClassName,
targetMethodName = proxyMethod.targetElementName,
targetOpcode = proxyMethod.targetOpcode,
newClassName = fullClassNameBySlash,
newMethodName = proxyMethod.methodName,
wrapperClassName = wrapperFullClassNameBySlash,
wrapperMethodName = proxyMethod.methodName
)
proxiedMetaData.proxiedMethods.add(pm)
} else {
val pf = ProxiedField(
className = proxyMethod.targetClassName,
fieldName = proxyMethod.targetElementName,
opcode = proxyMethod.targetOpcode,
replacedClassName = wrapperFullClassNameBySlash,
replacedMethodName = proxyMethod.methodName
targetClassName = proxyMethod.targetClassName,
targetFieldName = proxyMethod.targetElementName,
targetOpcode = proxyMethod.targetOpcode,
newClassName = fullClassNameBySlash,
newMethodName = proxyMethod.methodName,
wrapperClassName = wrapperFullClassNameBySlash,
wrapperMethodName = proxyMethod.methodName
)
proxiedMetaData.proxiedFields.add(pf)
}
Expand All @@ -103,8 +109,10 @@ class CaliperWrapperGenerator(
}
logger.lifecycle(proxyMethod.targetClassName)
val caliperClass = ClassName.get("me.xx2bab.caliper.runtime", "Caliper")
MethodSpec.methodBuilder(proxyMethod.methodName).returns(proxyMethod.returnType)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC).addParameters(inputParams)
MethodSpec.methodBuilder(proxyMethod.methodName)
.returns(proxyMethod.returnType)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameters(inputParams)
.addStatement(
"\$T.log(\""
+ proxyMethod.targetClassName.replace(
Expand All @@ -115,7 +123,8 @@ class CaliperWrapperGenerator(
+ "$paramNameArray, "
+ "$paramInstanceArray)", caliperClass
)
.addStatement("return $className.${proxyMethod.methodName}($invokeParams)")
.addStatement((if (proxyMethod.returnType != null && proxyMethod.returnType != TypeName.VOID) "return " else "")
+ "$className.${proxyMethod.methodName}($invokeParams)")
.build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class ClassProxyWrapperGenTest {
package me.xx2bab.caliper.test;
import me.xx2bab.caliper.anno.CaliperClassProxy
@CaliperClassProxy(className = "java.lang.Thread")
open class ThreadClassProxyWrittenInJava(name: String) : Thread(name + "mockedNameSuffix") {}
open class ThreadClassProxyWrittenInKotlin(name: String) : Thread(name + "mockedNameSuffix") {}
"""
)

Expand All @@ -101,7 +101,7 @@ class ClassProxyWrapperGenTest {
kspGenDir,
"resources/app.caliper.json"
).readText()
val expectJson = File("src/test/resources/thread.caliper.json").readText()
val expectJson = File("src/test/resources/thread-kt.caliper.json").readText()
assertThat(expectJson, equalToCompressingWhiteSpace(generatedJson))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"proxiedMethods":[],"proxiedFields":[{"className":"android/provider/Settings$Secure","fieldName":"SERIAL","opcode":178,"replacedClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInKtForFieldReplacement_CaliperWrapper","replacedMethodName":"getString"}],"proxiedClasses":[]}
{"proxiedMethods":[],"proxiedFields":[{"targetClassName":"android/provider/Settings$Secure","targetFieldName":"SERIAL","targetOpcode":178,"newClassName":"me/xx2bab/caliper/test/ProxyWrittenInKtForFieldReplacement","newMethodName":"getString","wrapperClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInKtForFieldReplacement_CaliperWrapper","wrapperMethodName":"getString"}],"proxiedClasses":[]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"proxiedMethods":[],"proxiedFields":[{"className":"android/provider/Settings$Secure","fieldName":"SERIAL","opcode":178,"replacedClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInJavaForFieldReplacement_CaliperWrapper","replacedMethodName":"getString"}],"proxiedClasses":[]}
{"proxiedMethods":[],"proxiedFields":[{"targetClassName":"android/provider/Settings$Secure","targetFieldName":"SERIAL","targetOpcode":178,"newClassName":"me/xx2bab/caliper/test/ProxyWrittenInJavaForFieldReplacement","newMethodName":"getString","wrapperClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInJavaForFieldReplacement_CaliperWrapper","wrapperMethodName":"getString"}],"proxiedClasses":[]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"proxiedMethods":[{"className":"android/provider/Settings$Secure","methodName":"getString","opcode":184,"replacedClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInKtForMethodReplacement_CaliperWrapper","replacedMethodName":"getString"}],"proxiedFields":[],"proxiedClasses":[]}
{"proxiedMethods":[{"targetClassName":"android/provider/Settings$Secure","targetMethodName":"getString","targetOpcode":184,"newClassName":"me/xx2bab/caliper/test/ProxyWrittenInKtForMethodReplacement","newMethodName":"getString","wrapperClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInKtForMethodReplacement_CaliperWrapper","wrapperMethodName":"getString"}],"proxiedFields":[],"proxiedClasses":[]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"proxiedMethods":[{"className":"android/provider/Settings$Secure","methodName":"getString","opcode":184,"replacedClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInJavaForMethodReplacement_CaliperWrapper","replacedMethodName":"getString"}],"proxiedFields":[],"proxiedClasses":[]}
{"proxiedMethods":[{"targetClassName":"android/provider/Settings$Secure","targetMethodName":"getString","targetOpcode":184,"newClassName":"me/xx2bab/caliper/test/ProxyWrittenInJavaForMethodReplacement","newMethodName":"getString","wrapperClassName":"me/xx2bab/caliper/runtime/wrapper/ProxyWrittenInJavaForMethodReplacement_CaliperWrapper","wrapperMethodName":"getString"}],"proxiedFields":[],"proxiedClasses":[]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"proxiedMethods":[],"proxiedFields":[],"proxiedClasses":[{"targetClassName":"java/lang/Thread","newClassName":"me/xx2bab/caliper/test/ThreadClassProxyWrittenInKotlin"}]}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"proxiedMethods":[],"proxiedFields":[],"proxiedClasses":[{"className":"java.lang.Thread","replacedClassName":"me/xx2bab/caliper/test/ThreadClassProxyWrittenInJava"}]}
{"proxiedMethods":[],"proxiedFields":[],"proxiedClasses":[{"targetClassName":"java/lang/Thread","newClassName":"me/xx2bab/caliper/test/ThreadClassProxyWrittenInJava"}]}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ import kotlinx.serialization.Serializable

@Serializable
data class ProxiedMethod(
val className: String,
val methodName: String,
val opcode: Int,
val replacedClassName: String,
val replacedMethodName: String
val targetClassName: String,
val targetMethodName: String,
val targetOpcode: Int,
val newClassName: String,
val newMethodName: String,
val wrapperClassName: String,
val wrapperMethodName: String
)

@Serializable
data class ProxiedField(
val className: String,
val fieldName: String,
val opcode: Int,
val replacedClassName: String,
val replacedMethodName: String
val targetClassName: String,
val targetFieldName: String,
val targetOpcode: Int,
val newClassName: String,
val newMethodName: String,
val wrapperClassName: String,
val wrapperMethodName: String
)

@Serializable
data class ProxiedClass(
val className: String,
val replacedClassName: String
val targetClassName: String,
val newClassName: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.xx2bab.caliper.sample.customproxy

import me.xx2bab.caliper.anno.ASMOpcodes
import me.xx2bab.caliper.anno.CaliperMethodProxy
import me.xx2bab.caliper.sample.library.LibrarySampleClass

object CustomProxy {

@CaliperMethodProxy(
className = "me/xx2bab/caliper/sample/library/LibrarySampleClass",
methodName = "commonMethodReturnsString",
opcode = ASMOpcodes.INVOKEVIRTUAL
)
@JvmStatic
fun commonMethodReturnsString(lib: LibrarySampleClass) = "CustomProxy"

}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.xx2bab.caliper.gradle.core
package me.xx2bab.caliper.gradle

import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package me.xx2bab.caliper
package me.xx2bab.caliper.gradle

import me.xx2bab.caliper.gradle.CaliperExtension
import org.gradle.testfixtures.ProjectBuilder
import org.hamcrest.MatcherAssert.assertThat
import org.junit.jupiter.api.Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package me.xx2bab.caliper.gradle.core

import io.mockk.spyk
import me.xx2bab.caliper.anno.ASMOpcodes
import me.xx2bab.caliper.common.ProxiedMethod
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.containsInAnyOrder
import org.hamcrest.Matchers.`is`
import org.junit.jupiter.api.Test
import java.io.File

class CaliperProxyConfigCollectorTest {

private val kLogger = spyk(
object : KLogger {
override fun lifecycle(message: String) {}
override fun info(message: String) {}
override fun warn(message: String) {}
override fun error(message: String) {}
override fun debug(message: String) {}
})

@Test
fun `doCollect() aggregates metadata from local project successfully`() {
val config = CaliperProxyConfigCollector(kLogger)
val localResJar = File(
"src/fixtures/gen-metadata/local-res-jar" +
"/build/intermediates/library_java_res/debug/res.jar"
)
val result = config.doCollect(setOf(localResJar))
assertThat(result.proxiedMethods.size, `is`(1))
assertThat(result.proxiedMethods.first().targetMethodName, `is`("commonMethodReturnsString"))
assertThat(
result.proxiedMethods.first().targetClassName,
`is`("me/xx2bab/caliper/sample/library/LibrarySampleClass")
)
assertThat(result.proxiedMethods.first().targetOpcode, `is`(ASMOpcodes.INVOKEVIRTUAL))
assertThat(
result.proxiedMethods.first().wrapperMethodName,
`is`("commonMethodReturnsString")
)
assertThat(
result.proxiedMethods.first().wrapperClassName,
`is`("me/xx2bab/caliper/runtime/wrapper/CustomProxy_CaliperWrapper")
)
}

@Test
fun `doCollect() aggregates metadata from remote artifact successfully`() {
val config = CaliperProxyConfigCollector(kLogger)
val remoteClassJar = File(
"src/fixtures/gen-metadata/remote-class-jar" +
"/classes.jar"
)
val result = config.doCollect(setOf(remoteClassJar))

assertThat(result.proxiedMethods.size, `is`(3))
assertThat(result.proxiedMethods, containsInAnyOrder(
ProxiedMethod(
"android/os/Build",
"getSerial",
ASMOpcodes.INVOKESTATIC,
"me/xx2bab/caliper/privacy/AndroidOSBuildProxy",
"getSerial",
"me/xx2bab/caliper/runtime/wrapper/AndroidOSBuildProxy_CaliperWrapper",
"getSerial"
),
ProxiedMethod(
"android/provider/Settings\$Secure",
"getString",
ASMOpcodes.INVOKESTATIC,
"me/xx2bab/caliper/privacy/SettingsSecureProxy",
"getString",
"me/xx2bab/caliper/runtime/wrapper/SettingsSecureProxy_CaliperWrapper",
"getString"
),
ProxiedMethod(
"android/app/Activity",
"requestPermissions",
ASMOpcodes.INVOKEVIRTUAL,
"me/xx2bab/caliper/privacy/ActivityProxy",
"requestPermissions",
"me/xx2bab/caliper/runtime/wrapper/ActivityProxy_CaliperWrapper",
"requestPermissions"
)
))

assertThat(result.proxiedFields.size, `is`(1))
assertThat(result.proxiedFields.first().targetFieldName, `is`("SERIAL"))
assertThat(result.proxiedFields.first().targetClassName, `is`("android/os/Build"))
assertThat(result.proxiedFields.first().targetOpcode, `is`(ASMOpcodes.GETSTATIC))
assertThat(result.proxiedFields.first().wrapperMethodName, `is`("getSerialField"))
assertThat(
result.proxiedFields.first().wrapperClassName,
`is`("me/xx2bab/caliper/runtime/wrapper/AndroidOSBuildProxy_CaliperWrapper")
)
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package me.xx2bab.caliper.proxy
package me.xx2bab.caliper.gradle.core.proxy

import com.tschuchort.compiletesting.KotlinCompilation
import com.tschuchort.compiletesting.SourceFile
import me.xx2bab.caliper.common.ProxiedClass
import me.xx2bab.caliper.gradle.core.ASMManipulator
import me.xx2bab.caliper.gradle.ASMManipulator
import me.xx2bab.caliper.gradle.core.CaliperClassVisitor
import me.xx2bab.caliper.gradle.core.ProxyConfig
import me.xx2bab.caliper.tool.invokeMethod
import me.xx2bab.caliper.proxy.getCompiledFileByName
import me.xx2bab.caliper.proxy.printAll
import me.xx2bab.caliper.gradle.tool.invokeMethod
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -74,8 +76,8 @@ class ClassProxyTest {
config = ProxyConfig(
proxiedClasses = mutableListOf(
ProxiedClass(
className = "java/lang/Thread",
replacedClassName = "NamedThread"
targetClassName = "java/lang/Thread",
newClassName = "NamedThread"
)
)
)
Expand Down

0 comments on commit 50096c7

Please sign in to comment.