blob: 2280955e0ccf849033de9613bcc5ff9c59127494 [file] [log] [blame]
// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.
import java.io.FileOutputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* GenKeepForCompile creates a jarfile containing a class definition that has the KeepForCOmpile
* attribute.
*/
public class GenKeepForCompile implements Opcodes {
public static void main(String[] args) throws Exception {
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(args[0]))) {
jos.putNextEntry(new ZipEntry("functions/car/CarInlineUtilsKt.class"));
jos.write(dump());
jos.closeEntry();
}
}
public static byte[] dump() throws Exception {
ClassWriter classWriter = new ClassWriter(0);
MethodVisitor methodVisitor;
AnnotationVisitor annotationVisitor0;
classWriter.visit(
V1_8,
ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
"functions/car/CarInlineUtilsKt",
null,
"java/lang/Object",
null);
classWriter.visitSource("CarInlineUtils.kt", null);
{
annotationVisitor0 = classWriter.visitAnnotation("Lkotlin/Metadata;", true);
annotationVisitor0.visit("mv", new int[] {1, 1, 11});
annotationVisitor0.visit("bv", new int[] {1, 0, 2});
annotationVisitor0.visit("k", Integer.valueOf(2));
{
AnnotationVisitor annotationVisitor1 = annotationVisitor0.visitArray("d1");
annotationVisitor1.visit(
null,
"\u0000\u0014\n\u0000\n\u0002\u0010\u000e\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u0008\u001a!\u0010\u0000\u001a\u00020\u0001*\u00020\u00022\u0012\u0010\u0003\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00010\u0004H\u0086\u0008");
annotationVisitor1.visitEnd();
}
{
AnnotationVisitor annotationVisitor1 = annotationVisitor0.visitArray("d2");
annotationVisitor1.visit(null, "customName");
annotationVisitor1.visit(null, "");
annotationVisitor1.visit(null, "Lfunctions/car/Car;");
annotationVisitor1.visit(null, "formatYear");
annotationVisitor1.visit(null, "Lkotlin/Function1;");
annotationVisitor1.visit(null, "");
annotationVisitor1.visitEnd();
}
annotationVisitor0.visitEnd();
}
{ // Private method to make sure ijar doesn't ignore those
methodVisitor =
classWriter.visitMethod(
ACC_PRIVATE | ACC_FINAL | ACC_STATIC,
"customName",
"(Lfunctions/car/Car;Lkotlin/jvm/functions/Function1;)Ljava/lang/String;",
"(Lfunctions/car/Car;Lkotlin/jvm/functions/Function1<-Ljava/lang/Integer;Ljava/lang/String;>;)Ljava/lang/String;",
null);
methodVisitor.visitParameter("$receiver", ACC_MANDATED);
methodVisitor.visitParameter("formatYear", 0);
{
annotationVisitor0 =
methodVisitor.visitAnnotation("Lorg/jetbrains/annotations/NotNull;", false);
annotationVisitor0.visitEnd();
}
methodVisitor.visitAnnotableParameterCount(2, false);
{
annotationVisitor0 =
methodVisitor.visitParameterAnnotation(0, "Lorg/jetbrains/annotations/NotNull;", false);
annotationVisitor0.visitEnd();
}
{
annotationVisitor0 =
methodVisitor.visitParameterAnnotation(1, "Lorg/jetbrains/annotations/NotNull;", false);
annotationVisitor0.visitEnd();
}
// ATTRIBUTE com.google.devtools.ijar.KeepForCompile
// ASM-ifier doesn't emit attributes it does not know about :( - emitting by hand here.
methodVisitor.visitAttribute(
new Attribute("com.google.devtools.ijar.KeepForCompile") {
@Override
public ByteVector write(
ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
// nothing to write, just get the attribute's name in the file.
return new ByteVector();
}
});
methodVisitor.visitCode();
Label label0 = new Label();
methodVisitor.visitLabel(label0);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitLdcInsn("$receiver");
methodVisitor.visitMethodInsn(
INVOKESTATIC,
"kotlin/jvm/internal/Intrinsics",
"checkParameterIsNotNull",
"(Ljava/lang/Object;Ljava/lang/String;)V",
false);
methodVisitor.visitVarInsn(ALOAD, 1);
methodVisitor.visitLdcInsn("formatYear");
methodVisitor.visitMethodInsn(
INVOKESTATIC,
"kotlin/jvm/internal/Intrinsics",
"checkParameterIsNotNull",
"(Ljava/lang/Object;Ljava/lang/String;)V",
false);
Label label1 = new Label();
methodVisitor.visitLabel(label1);
methodVisitor.visitLineNumber(3, label1);
methodVisitor.visitTypeInsn(NEW, "java/lang/StringBuilder");
methodVisitor.visitInsn(DUP);
methodVisitor.visitMethodInsn(
INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
methodVisitor.visitVarInsn(ALOAD, 1);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "functions/car/Car", "getYear", "()I", false);
methodVisitor.visitMethodInsn(
INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
methodVisitor.visitMethodInsn(
INVOKEINTERFACE,
"kotlin/jvm/functions/Function1",
"invoke",
"(Ljava/lang/Object;)Ljava/lang/Object;",
true);
methodVisitor.visitTypeInsn(CHECKCAST, "java/lang/String");
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
"append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;",
false);
methodVisitor.visitIntInsn(BIPUSH, 32);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
"append",
"(C)Ljava/lang/StringBuilder;",
false);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL, "functions/car/Car", "getMake", "()Ljava/lang/String;", false);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
"append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;",
false);
methodVisitor.visitIntInsn(BIPUSH, 32);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
"append",
"(C)Ljava/lang/StringBuilder;",
false);
methodVisitor.visitVarInsn(ALOAD, 0);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL, "functions/car/Car", "getModel", "()Ljava/lang/String;", false);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
"append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;",
false);
methodVisitor.visitMethodInsn(
INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
methodVisitor.visitInsn(ARETURN);
Label label2 = new Label();
methodVisitor.visitLabel(label2);
methodVisitor.visitLocalVariable("$receiver", "Lfunctions/car/Car;", null, label0, label2, 0);
methodVisitor.visitLocalVariable(
"formatYear", "Lkotlin/jvm/functions/Function1;", null, label0, label2, 1);
methodVisitor.visitLocalVariable("$i$f$customName", "I", null, label0, label2, 2);
methodVisitor.visitMaxs(3, 3);
methodVisitor.visitEnd();
}
classWriter.visitEnd();
return classWriter.toByteArray();
}
}