diff options
author | Sorin Basca <sorinbasca@google.com> | 2022-05-11 21:28:29 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-05-11 21:28:29 +0000 |
commit | 5976f804d3240917471369f179c1b15fdebd563b (patch) | |
tree | 81372424da9be7970fe78f49a7f39646d70b3400 | |
parent | 845305798a7e45e04d9931512cc8fdc21978b63b (diff) | |
parent | 41407b062fb2048a2c16e51d520362fe755f9fbb (diff) | |
download | jarjar-5976f804d3240917471369f179c1b15fdebd563b.tar.gz |
Add option to strip annotations from jar am: 47f189c1e4 am: 18e65b195a am: 41407b062f
Original change: https://android-review.googlesource.com/c/platform/external/jarjar/+/2092603
Change-Id: I57bc8b8f6993d61502d965fff15b0ae0b11354c2
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
5 files changed, 171 insertions, 0 deletions
diff --git a/res/com/tonicsystems/jarjar/help.txt b/res/com/tonicsystems/jarjar/help.txt index 8410909..6f14db6 100644 --- a/res/com/tonicsystems/jarjar/help.txt +++ b/res/com/tonicsystems/jarjar/help.txt @@ -49,6 +49,7 @@ Rules file format: rule <pattern> <result> zap <pattern> keep <pattern> + strip-annotations <annotation> The standard rule ("rule") is used to rename classes. All references to the renamed classes will also be updated. If a class name is @@ -73,3 +74,6 @@ Rules file format: via dependency analysis are discarded when writing the output jar. This is the last step in the process, after renaming and zapping. + The "strip-annotations" rule will remove all the references to a certain + annotation from a jar file. As no pattern matching is performed, the + annotations have to be provided as one per line. diff --git a/src/android/com/android/jarjar/StripAnnotation.java b/src/android/com/android/jarjar/StripAnnotation.java new file mode 100644 index 0000000..debd469 --- /dev/null +++ b/src/android/com/android/jarjar/StripAnnotation.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jarjar; + +import com.tonicsystems.jarjar.PatternElement; + +/** + * Configuration element for stripping annotations in a jar file. + */ +public class StripAnnotation extends PatternElement +{ +} diff --git a/src/android/com/android/jarjar/StripAnnotationsJarTransformer.java b/src/android/com/android/jarjar/StripAnnotationsJarTransformer.java new file mode 100644 index 0000000..260cb30 --- /dev/null +++ b/src/android/com/android/jarjar/StripAnnotationsJarTransformer.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jarjar; + +import com.tonicsystems.jarjar.util.JarTransformer; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * A transformer that strips annotations from all classes based on custom rules. + */ +public final class StripAnnotationsJarTransformer extends JarTransformer { + + private static int ASM_VERSION = Opcodes.ASM7; + + private final List<String> stripAnnotationList; + + public StripAnnotationsJarTransformer(List<StripAnnotation> stripAnnotationList) { + this.stripAnnotationList = getAnnotationList(stripAnnotationList); + } + + private static List<String> getAnnotationList(List<StripAnnotation> stripAnnotationList) { + return stripAnnotationList.stream().map(el -> getClassName(el)).collect(Collectors.toList()); + } + + private static String getClassName(StripAnnotation element) { + return "L" + element.getPattern().replace('.', '/') + ";"; + } + + @Override + protected ClassVisitor transform(ClassVisitor classVisitor) { + return new AnnotationRemover(classVisitor); + } + + private class AnnotationRemover extends ClassVisitor { + + AnnotationRemover(ClassVisitor cv) { + super(ASM_VERSION, cv); + } + + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitAnnotation(descriptor, visible)); + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, + Object value) { + FieldVisitor superVisitor = + super.visitField(access, name, descriptor, signature, value); + return new FieldVisitor(ASM_VERSION, superVisitor) { + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitAnnotation(descriptor, visible)); + + } + }; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, + String signature, String[] exceptions) { + MethodVisitor superVisitor = + super.visitMethod(access, name, descriptor, signature, exceptions); + return new MethodVisitor(ASM_VERSION, superVisitor) { + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitAnnotation(descriptor, visible)); + } + + @Override + public AnnotationVisitor visitParameterAnnotation(int parameter, + String descriptor, boolean visible) { + return visitAnnotationCommon(descriptor, + () -> super.visitParameterAnnotation(parameter, descriptor, visible)); + } + }; + } + + /** + * Create an {@link AnnotationVisitor} that removes any annotations from {@link + * #stripAnnotationList}. + */ + private AnnotationVisitor visitAnnotationCommon(String annotation, + Supplier<AnnotationVisitor> defaultVisitorSupplier) { + if (stripAnnotationList.contains(annotation)) { + return null; + } + // Only get() the default AnnotationVisitor if the annotation is to be included. + // Invoking super.visitAnnotation(descriptor, visible) causes the annotation to be + // included in the output even if the resulting AnnotationVisitor is not returned or + // used. + return defaultVisitorSupplier.get(); + } + } +} diff --git a/src/main/com/tonicsystems/jarjar/MainProcessor.java b/src/main/com/tonicsystems/jarjar/MainProcessor.java index 2778cc5..a0ef4c7 100644 --- a/src/main/com/tonicsystems/jarjar/MainProcessor.java +++ b/src/main/com/tonicsystems/jarjar/MainProcessor.java @@ -16,12 +16,14 @@ package com.tonicsystems.jarjar; +import com.android.jarjar.StripAnnotation; import com.tonicsystems.jarjar.util.*; import java.io.File; import java.io.IOException; import java.util.*; import com.android.jarjar.RemoveAndroidCompatAnnotationsJarTransformer; +import com.android.jarjar.StripAnnotationsJarTransformer; class MainProcessor implements JarProcessor { @@ -42,6 +44,9 @@ class MainProcessor implements JarProcessor List<Zap> zapList = new ArrayList<Zap>(); List<Rule> ruleList = new ArrayList<Rule>(); List<Keep> keepList = new ArrayList<Keep>(); + // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs + List<StripAnnotation> stripAnnotationList = new ArrayList<StripAnnotation>(); + // ANDROID-END: b/222743634 Strip annotations from system module stubs for (PatternElement pattern : patterns) { if (pattern instanceof Zap) { zapList.add((Zap) pattern); @@ -49,7 +54,11 @@ class MainProcessor implements JarProcessor ruleList.add((Rule) pattern); } else if (pattern instanceof Keep) { keepList.add((Keep) pattern); + // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs + } else if (pattern instanceof StripAnnotation) { + stripAnnotationList.add((StripAnnotation) pattern); } + // ANDROID-END: b/222743634 Strip annotations from system module stubs } PackageRemapper pr = new PackageRemapper(ruleList, verbose); @@ -65,6 +74,11 @@ class MainProcessor implements JarProcessor if (removeAndroidCompatAnnotations) processors.add(new RemoveAndroidCompatAnnotationsJarTransformer(pr)); // ANDROID-END: b/146418363 Add an Android-specific transformer to strip compat annotation + // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs + if (!stripAnnotationList.isEmpty()) { + processors.add(new StripAnnotationsJarTransformer(stripAnnotationList)); + } + // ANDROID-END: b/222743634 Strip annotations from system module stubs processors.add(new JarTransformerChain(new RemappingClassTransformer[]{ new RemappingClassTransformer(pr) })); processors.add(new ResourceProcessor(pr)); chain = new JarProcessorChain(processors.toArray(new JarProcessor[processors.size()])); diff --git a/src/main/com/tonicsystems/jarjar/RulesFileParser.java b/src/main/com/tonicsystems/jarjar/RulesFileParser.java index f54f3b9..c8c6ea4 100644 --- a/src/main/com/tonicsystems/jarjar/RulesFileParser.java +++ b/src/main/com/tonicsystems/jarjar/RulesFileParser.java @@ -16,6 +16,8 @@ package com.tonicsystems.jarjar; +import com.android.jarjar.StripAnnotation; + import java.io.*; import java.util.*; @@ -62,6 +64,10 @@ class RulesFileParser element = new Zap(); } else if (type.equals("keep")) { element = new Keep(); + // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs + } else if (type.equals("strip-annotation")) { + element = new StripAnnotation(); + // ANDROID-END: b/222743634 Strip annotations from system module stubs } else { error(c, parts); } |