Skip to content

Commit

Permalink
Use annotation instead of hardcode prefix (#3)
Browse files Browse the repository at this point in the history
* [WIP] Use annotation instead of hardcode package prefix

* [WIP] Use annotation instead of hardcode package prefix

* Refactor: Use annotation instead of hardcode package prefix

* Refactor: Use javassist instead of asm

* Fix: fix annotation collect

* Chore: require java 8

* Chore: clear code

* Chore: remove artifact prefix

* Chore: rename implementation class name

* Chore: clear code

* Chore: log transform jar

* Chore: log use Logger
  • Loading branch information
Kr328 authored Aug 29, 2021
1 parent 267a59b commit 7358c58
Show file tree
Hide file tree
Showing 18 changed files with 634 additions and 363 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build/
.idea/
.gradle/
local.properties
*.iml
84 changes: 84 additions & 0 deletions annotation/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import java.net.URI

plugins {
java
signing
`maven-publish`
}

group = extra["group"]!!
version = extra["version"]!!

val artifactName = "annotation"

java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

task("javadocJar", type = Jar::class) {
archiveClassifier.set("javadoc")
from(tasks["javadoc"])
}

task("sourcesJar", type = Jar::class) {
archiveClassifier.set("sources")
from(sourceSets.main.get().allSource)
}

publishing {
publications {
create("maven", type = MavenPublication::class) {
group = project.group.toString()
artifactId = artifactName
version = project.version.toString()

from(components["java"])

artifact(tasks["javadocJar"])
artifact(tasks["sourcesJar"])

pom {
name.set("HiddenApiRefine")
description.set("HiddenApiRefine")
url.set("https://github.com/RikkaApps/HiddenApiRefinePlugin")
licenses {
license {
name.set("MIT License")
url.set("https://github.com/RikkaApps/HiddenApiRefinePlugin/blob/main/LICENSE")
}
}
developers {
developer {
name.set("Kr328 & RikkaW")
}
}
scm {
connection.set("scm:git:https://github.com/RikkaApps/HiddenApiRefinePlugin.git")
url.set("https://github.com/RikkaApps/HiddenApiRefinePlugin")
}
}
}
}
repositories {
mavenLocal()
maven {
name = "ossrh"
url = URI("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2")
credentials(PasswordCredentials::class.java)
}
}
}

signing {
val signingKey = findProperty("signingKey") as? String
val signingPassword = findProperty("signingPassword") as? String
val secretKeyRingFile = findProperty("signing.secretKeyRingFile") as? String

if (secretKeyRingFile != null && file(secretKeyRingFile).exists()) {
sign(publishing.publications)
} else if (signingKey != null) {
useInMemoryPgpKeys(signingKey, signingPassword)
sign(publishing.publications)
}
}
12 changes: 12 additions & 0 deletions annotation/src/main/java/dev/rikka/tools/refine/RefineAs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dev.rikka.tools.refine;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE})
public @interface RefineAs {
Class<?> value();
}
15 changes: 15 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
buildscript {
repositories {
mavenCentral()
google()
}
}

allprojects {
extra["group"] = "dev.rikka.tools.refine"
extra["version"] = "2.0.0"
}

task("clean", type = Delete::class) {
delete(buildDir)
}
109 changes: 109 additions & 0 deletions gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import java.net.URI

plugins {
java
signing
`maven-publish`
`java-gradle-plugin`
}

group = extra["group"]!!
version = extra["version"]!!

val artifactName = "gradle-plugin"
val pluginId = "$group.$artifactName"
val pluginClass = "$group.RefinePlugin"

repositories {
mavenCentral()
google()
}

dependencies {
compileOnly(gradleApi())
compileOnly("com.android.tools.build:gradle:7.0.1")
implementation(project(":annotation"))
implementation("com.google.code.gson:gson:2.8.8")
implementation("org.javassist:javassist:3.28.0-GA")
}

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

gradlePlugin {
plugins {
create("HiddenApiRefine") {
id = pluginId
implementationClass = pluginClass
}
}
}

task("javadocJar", type = Jar::class) {
archiveClassifier.set("javadoc")
from(tasks["javadoc"])
}

task("sourcesJar", type = Jar::class) {
archiveClassifier.set("sources")
from(sourceSets.main.get().allSource)
}

publishing {
publications {
create("maven", type = MavenPublication::class) {
group = project.group.toString()
artifactId = artifactName
version = project.version.toString()

from(components["java"])

artifact(tasks["javadocJar"])
artifact(tasks["sourcesJar"])

pom {
name.set("HiddenApiRefine")
description.set("HiddenApiRefine")
url.set("https://github.com/RikkaApps/HiddenApiRefinePlugin")
licenses {
license {
name.set("MIT License")
url.set("https://github.com/RikkaApps/HiddenApiRefinePlugin/blob/main/LICENSE")
}
}
developers {
developer {
name.set("Kr328 & RikkaW")
}
}
scm {
connection.set("scm:git:https://github.com/RikkaApps/HiddenApiRefinePlugin.git")
url.set("https://github.com/RikkaApps/HiddenApiRefinePlugin")
}
}
}
}
repositories {
mavenLocal()
maven {
name = "ossrh"
url = URI("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2")
credentials(PasswordCredentials::class.java)
}
}
}

signing {
val signingKey = findProperty("signingKey") as? String
val signingPassword = findProperty("signingPassword") as? String
val secretKeyRingFile = findProperty("signing.secretKeyRingFile") as? String

if (secretKeyRingFile != null && file(secretKeyRingFile).exists()) {
sign(publishing.publications)
} else if (signingKey != null) {
useInMemoryPgpKeys(signingKey, signingPassword)
sign(publishing.publications)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.rikka.tools.refine;

import javassist.bytecode.ClassFile;

import java.io.*;
import java.util.Map;

public final class RefineApplier {
private final Map<String, String> refines;

public RefineApplier(Map<String, String> refines) {
this.refines = refines;
}

public void applyFor(InputStream in, OutputStream out) throws IOException {
final DataInputStream input = new DataInputStream(new BufferedInputStream(in));
final DataOutputStream output = new DataOutputStream(new BufferedOutputStream(out));
final ClassFile file = new ClassFile(input);
final String self = refines.remove(file.getName());

try {
file.renameClass(refines);
} finally {
if (self != null) {
refines.put(file.getName(), self);
}
}

file.write(output);
output.flush();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package dev.rikka.tools.refine;

import java.util.Map;

public class RefineCache {
private final Map<String, String> refines;

public RefineCache(Map<String, String> refines) {
this.refines = refines;
}

public Map<String, String> getRefines() {
return refines;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dev.rikka.tools.refine;

import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.AttributeInfo;
import javassist.bytecode.ClassFile;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.ClassMemberValue;
import javassist.bytecode.annotation.MemberValue;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.AbstractMap;
import java.util.Map;

public final class RefineCollector {
private static final String ANNOTATION_REFINE_AS_NAME = RefineAs.class.getName();
private static final String ANNOTATION_DEFAULT_VALUE = "value";

public static Map.Entry<String, String> collect(InputStream stream) throws IOException {
final DataInputStream in = new DataInputStream(new BufferedInputStream(stream));
final ClassFile file = new ClassFile(in);

for (AttributeInfo info : file.getAttributes()) {
if (info instanceof AnnotationsAttribute) {
final Annotation annotation = ((AnnotationsAttribute) info).getAnnotation(ANNOTATION_REFINE_AS_NAME);
if (annotation == null)
continue;

final MemberValue value = annotation.getMemberValue(ANNOTATION_DEFAULT_VALUE);
if (value instanceof ClassMemberValue) {
return new AbstractMap.SimpleEntry<>(
file.getName().replace('.', '/'),
((ClassMemberValue) value).getValue().replace('.', '/')
);
}
}
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.rikka.tools.refine;

import com.android.build.gradle.BaseExtension;
import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;

@SuppressWarnings("unused")
public class RefinePlugin implements Plugin<Project> {
@Override
public void apply(Project target) {
BaseExtension androidExtension = target.getExtensions().findByType(BaseExtension.class);
if (androidExtension == null)
throw new GradleException("Android extension not found");

androidExtension.registerTransform(new RefineTransform());
}
}
Loading

0 comments on commit 7358c58

Please sign in to comment.