From fa39bf03a023c34af4e31b1f8ee0d55f39d503f7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 12 Sep 2014 21:09:31 +0400 Subject: [PATCH] Extract abstract FileBasedKotlinClass out of VirtualFileKotlinClass Add another implementation of FileBasedKotlinClass which was indirectly used in jps-plugin (LocalFileKotlinClass) --- .../resolve/kotlin/FileBasedKotlinClass.java | 212 ++++++++++++++++++ .../kotlin/VirtualFileKotlinClass.java | 196 +--------------- .../jps/incremental/IncrementalCacheImpl.kt | 13 +- .../jps/incremental/LocalFileKotlinClass.kt | 46 ++++ .../jet/jps/build/classFilesComparison.kt | 8 +- 5 files changed, 278 insertions(+), 197 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/FileBasedKotlinClass.java create mode 100644 jps-plugin/src/org/jetbrains/jet/jps/incremental/LocalFileKotlinClass.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/FileBasedKotlinClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/FileBasedKotlinClass.java new file mode 100644 index 00000000000..6023256d467 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/FileBasedKotlinClass.java @@ -0,0 +1,212 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * 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 org.jetbrains.jet.lang.resolve.kotlin; + +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader; +import org.jetbrains.jet.lang.resolve.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.org.objectweb.asm.ClassReader; +import org.jetbrains.org.objectweb.asm.ClassVisitor; +import org.jetbrains.org.objectweb.asm.FieldVisitor; +import org.jetbrains.org.objectweb.asm.MethodVisitor; + +import static org.jetbrains.org.objectweb.asm.ClassReader.*; +import static org.jetbrains.org.objectweb.asm.Opcodes.ASM5; + +public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass { + private final JvmClassName className; + private final KotlinClassHeader classHeader; + + protected FileBasedKotlinClass(@NotNull JvmClassName className, @NotNull KotlinClassHeader classHeader) { + this.className = className; + this.classHeader = classHeader; + } + + @NotNull + protected abstract byte[] getFileContents(); + + @Nullable + public static Pair readClassNameAndHeader(@NotNull byte[] fileContents) { + final ReadKotlinClassHeaderAnnotationVisitor readHeaderVisitor = new ReadKotlinClassHeaderAnnotationVisitor(); + final Ref classNameRef = Ref.create(); + new ClassReader(fileContents).accept(new ClassVisitor(ASM5) { + @Override + public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) { + classNameRef.set(JvmClassName.byInternalName(name)); + } + + @Override + public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { + return convertAnnotationVisitor(readHeaderVisitor, desc); + } + + @Override + public void visitEnd() { + readHeaderVisitor.visitEnd(); + } + }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES); + + JvmClassName className = classNameRef.get(); + if (className == null) return null; + + KotlinClassHeader header = readHeaderVisitor.createHeader(); + if (header == null) return null; + + return Pair.create(className, header); + } + + @NotNull + @Override + public JvmClassName getClassName() { + return className; + } + + @NotNull + @Override + public KotlinClassHeader getClassHeader() { + return classHeader; + } + + @Override + public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor) { + new ClassReader(getFileContents()).accept(new ClassVisitor(ASM5) { + @Override + public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { + return convertAnnotationVisitor(annotationVisitor, desc); + } + + @Override + public void visitEnd() { + annotationVisitor.visitEnd(); + } + }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES); + } + + @Nullable + private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor(@NotNull AnnotationVisitor visitor, @NotNull String desc) { + AnnotationArgumentVisitor v = visitor.visitAnnotation(classNameFromAsmDesc(desc)); + return v == null ? null : convertAnnotationVisitor(v); + } + + @NotNull + private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor(@NotNull final AnnotationArgumentVisitor v) { + return new org.jetbrains.org.objectweb.asm.AnnotationVisitor(ASM5) { + @Override + public void visit(String name, @NotNull Object value) { + v.visit(name == null ? null : Name.identifier(name), value); + } + + @Override + public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitArray(String name) { + final AnnotationArrayArgumentVisitor arv = v.visitArray(Name.guess(name)); + return arv == null ? null : new org.jetbrains.org.objectweb.asm.AnnotationVisitor(ASM5) { + @Override + public void visit(String name, @NotNull Object value) { + arv.visit(value); + } + + @Override + public void visitEnum(String name, @NotNull String desc, @NotNull String value) { + arv.visitEnum(classNameFromAsmDesc(desc), Name.identifier(value)); + } + + @Override + public void visitEnd() { + arv.visitEnd(); + } + }; + } + + @Override + public void visitEnum(String name, @NotNull String desc, @NotNull String value) { + v.visitEnum(Name.identifier(name), classNameFromAsmDesc(desc), Name.identifier(value)); + } + + @Override + public void visitEnd() { + v.visitEnd(); + } + }; + } + + @Override + public void visitMembers(@NotNull final MemberVisitor memberVisitor) { + new ClassReader(getFileContents()).accept(new ClassVisitor(ASM5) { + @Override + public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) { + final AnnotationVisitor v = memberVisitor.visitField(Name.guess(name), desc, value); + if (v == null) return null; + + return new FieldVisitor(ASM5) { + @Override + public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { + return convertAnnotationVisitor(v, desc); + } + + @Override + public void visitEnd() { + v.visitEnd(); + } + }; + } + + @Override + public MethodVisitor visitMethod(int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions) { + final MethodAnnotationVisitor v = memberVisitor.visitMethod(Name.guess(name), desc); + if (v == null) return null; + + return new MethodVisitor(ASM5) { + @Override + public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { + return convertAnnotationVisitor(v, desc); + } + + @Override + public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) { + AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, classNameFromAsmDesc(desc)); + return av == null ? null : convertAnnotationVisitor(av); + } + + @Override + public void visitEnd() { + v.visitEnd(); + } + }; + } + }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES); + } + + @NotNull + private static JvmClassName classNameFromAsmDesc(@NotNull String desc) { + assert desc.startsWith("L") && desc.endsWith(";") : "Not a JVM descriptor: " + desc; + return JvmClassName.byInternalName(desc.substring(1, desc.length() - 1)); + } + + @Override + public abstract int hashCode(); + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract String toString(); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java index 114d545fd9b..755f762bc75 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 JetBrains s.r.o. + * Copyright 2010-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,64 +19,23 @@ package org.jetbrains.jet.lang.resolve.kotlin; import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader; -import org.jetbrains.jet.lang.resolve.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor; -import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.utils.UtilsPackage; -import org.jetbrains.org.objectweb.asm.ClassReader; -import org.jetbrains.org.objectweb.asm.ClassVisitor; -import org.jetbrains.org.objectweb.asm.FieldVisitor; -import org.jetbrains.org.objectweb.asm.MethodVisitor; -import static org.jetbrains.org.objectweb.asm.ClassReader.*; -import static org.jetbrains.org.objectweb.asm.Opcodes.ASM5; +import java.io.IOException; -public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { - private final static Logger LOG = Logger.getInstance(VirtualFileKotlinClass.class); +public final class VirtualFileKotlinClass extends FileBasedKotlinClass { + private final static Logger LOG = Logger.getInstance(FileBasedKotlinClass.class); private final VirtualFile file; - private final JvmClassName className; - private final KotlinClassHeader classHeader; private VirtualFileKotlinClass(@NotNull VirtualFile file, @NotNull JvmClassName className, @NotNull KotlinClassHeader classHeader) { + super(className, classHeader); this.file = file; - this.className = className; - this.classHeader = classHeader; - } - - @Nullable - public static Pair readClassNameAndHeader(@NotNull byte[] fileContents) { - final ReadKotlinClassHeaderAnnotationVisitor readHeaderVisitor = new ReadKotlinClassHeaderAnnotationVisitor(); - final Ref classNameRef = Ref.create(); - new ClassReader(fileContents).accept(new ClassVisitor(ASM5) { - @Override - public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) { - classNameRef.set(JvmClassName.byInternalName(name)); - } - - @Override - public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { - return convertAnnotationVisitor(readHeaderVisitor, desc); - } - - @Override - public void visitEnd() { - readHeaderVisitor.visitEnd(); - } - }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES); - - JvmClassName className = classNameRef.get(); - if (className == null) return null; - - KotlinClassHeader header = readHeaderVisitor.createHeader(); - if (header == null) return null; - - return Pair.create(className, header); } @Nullable @@ -85,9 +44,7 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { try { byte[] fileContents = file.contentsToByteArray(); Pair nameAndHeader = readClassNameAndHeader(fileContents); - if (nameAndHeader == null) { - return null; - } + if (nameAndHeader == null) return null; return new VirtualFileKotlinClass(file, nameAndHeader.first, nameAndHeader.second); } @@ -97,12 +54,6 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { } } - @Nullable - public static KotlinClassHeader readClassHeader(@NotNull byte[] fileContents) { - Pair pair = readClassNameAndHeader(fileContents); - return pair == null ? null : pair.second; - } - @NotNull public VirtualFile getFile() { return file; @@ -110,143 +61,18 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { @NotNull @Override - public JvmClassName getClassName() { - return className; - } - - @NotNull - @Override - public KotlinClassHeader getClassHeader() { - return classHeader; - } - - @Override - public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor) { + protected byte[] getFileContents() { try { - new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(ASM5) { - @Override - public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { - return convertAnnotationVisitor(annotationVisitor, desc); - } - - @Override - public void visitEnd() { - annotationVisitor.visitEnd(); - } - }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES); + return file.contentsToByteArray(); } - catch (Throwable e) { + catch (IOException e) { LOG.error(renderFileReadingErrorMessage(file), e); + // Seems to be a bug in IDEA inspection + //noinspection Contract throw UtilsPackage.rethrow(e); } } - @Nullable - private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor(@NotNull AnnotationVisitor visitor, @NotNull String desc) { - AnnotationArgumentVisitor v = visitor.visitAnnotation(classNameFromAsmDesc(desc)); - return v == null ? null : convertAnnotationVisitor(v); - } - - @NotNull - private static org.jetbrains.org.objectweb.asm.AnnotationVisitor convertAnnotationVisitor(@NotNull final AnnotationArgumentVisitor v) { - return new org.jetbrains.org.objectweb.asm.AnnotationVisitor(ASM5) { - @Override - public void visit(String name, @NotNull Object value) { - v.visit(name == null ? null : Name.identifier(name), value); - } - - @Override - public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitArray(String name) { - final AnnotationArrayArgumentVisitor arv = v.visitArray(Name.guess(name)); - return arv == null ? null : new org.jetbrains.org.objectweb.asm.AnnotationVisitor(ASM5) { - @Override - public void visit(String name, @NotNull Object value) { - arv.visit(value); - } - - @Override - public void visitEnum(String name, @NotNull String desc, @NotNull String value) { - arv.visitEnum(classNameFromAsmDesc(desc), Name.identifier(value)); - } - - @Override - public void visitEnd() { - arv.visitEnd(); - } - }; - } - - @Override - public void visitEnum(String name, @NotNull String desc, @NotNull String value) { - v.visitEnum(Name.identifier(name), classNameFromAsmDesc(desc), Name.identifier(value)); - } - - @Override - public void visitEnd() { - v.visitEnd(); - } - }; - } - - @Override - public void visitMembers(@NotNull final MemberVisitor memberVisitor) { - try { - new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(ASM5) { - @Override - public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) { - final AnnotationVisitor v = memberVisitor.visitField(Name.guess(name), desc, value); - if (v == null) return null; - - return new FieldVisitor(ASM5) { - @Override - public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { - return convertAnnotationVisitor(v, desc); - } - - @Override - public void visitEnd() { - v.visitEnd(); - } - }; - } - - @Override - public MethodVisitor visitMethod(int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions) { - final MethodAnnotationVisitor v = memberVisitor.visitMethod(Name.guess(name), desc); - if (v == null) return null; - - return new MethodVisitor(ASM5) { - @Override - public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) { - return convertAnnotationVisitor(v, desc); - } - - @Override - public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) { - AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, classNameFromAsmDesc(desc)); - return av == null ? null : convertAnnotationVisitor(av); - } - - @Override - public void visitEnd() { - v.visitEnd(); - } - }; - } - }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES); - } - catch (Throwable e) { - LOG.error(renderFileReadingErrorMessage(file), e); - throw UtilsPackage.rethrow(e); - } - } - - @NotNull - private static JvmClassName classNameFromAsmDesc(@NotNull String desc) { - assert desc.startsWith("L") && desc.endsWith(";") : "Not a JVM descriptor: " + desc; - return JvmClassName.byInternalName(desc.substring(1, desc.length() - 1)); - } - @NotNull private static String renderFileReadingErrorMessage(@NotNull VirtualFile file) { return "Could not read file: " + file.getPath() + "; " diff --git a/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt index 3700771d690..3987227e646 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt +++ b/jps-plugin/src/org/jetbrains/jet/jps/incremental/IncrementalCacheImpl.kt @@ -24,10 +24,8 @@ import com.intellij.util.io.IOUtil import java.io.DataInput import org.jetbrains.jet.lang.resolve.name.FqName import com.intellij.util.io.DataExternalizer -import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader import org.jetbrains.jet.descriptors.serialization.BitEncoding -import org.jetbrains.jet.utils.intellij.* import java.util.Arrays import org.jetbrains.org.objectweb.asm.* import com.intellij.util.io.EnumeratorStringDescriptor @@ -37,7 +35,6 @@ import java.util.HashSet import org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCache import java.util.HashMap import org.jetbrains.jet.lang.resolve.java.PackageClassUtils -import com.intellij.util.containers.MultiMap import com.intellij.openapi.util.io.FileUtil import java.security.MessageDigest import org.jetbrains.jps.incremental.storage.StorageOwner @@ -62,11 +59,13 @@ public class IncrementalCacheImpl(val baseDir: File): StorageOwner, IncrementalC private val maps = listOf(protoMap, constantsMap, inlineFunctionsMap, packagePartMap) public fun saveFileToCache(sourceFiles: Collection, classFile: File): RecompilationDecision { - val fileBytes = classFile.readBytes() - val classNameAndHeader = VirtualFileKotlinClass.readClassNameAndHeader(fileBytes) - if (classNameAndHeader == null) return DO_NOTHING + val kotlinClass = LocalFileKotlinClass.create(classFile) + if (kotlinClass == null) return DO_NOTHING + + val fileBytes = kotlinClass.getFileContents() + val className = kotlinClass.getClassName() + val header = kotlinClass.getClassHeader() - val (className, header) = classNameAndHeader val annotationDataEncoded = header.annotationData if (annotationDataEncoded != null) { val data = BitEncoding.decodeBytes(annotationDataEncoded) diff --git a/jps-plugin/src/org/jetbrains/jet/jps/incremental/LocalFileKotlinClass.kt b/jps-plugin/src/org/jetbrains/jet/jps/incremental/LocalFileKotlinClass.kt new file mode 100644 index 00000000000..a5d69cd4f64 --- /dev/null +++ b/jps-plugin/src/org/jetbrains/jet/jps/incremental/LocalFileKotlinClass.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * 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 org.jetbrains.jet.jps.incremental + +import org.jetbrains.jet.lang.resolve.kotlin.FileBasedKotlinClass +import org.jetbrains.jet.lang.resolve.java.JvmClassName +import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader +import java.io.File + +class LocalFileKotlinClass private( + private val file: File, + private val fileContents: ByteArray, + className: JvmClassName, + classHeader: KotlinClassHeader +) : FileBasedKotlinClass(className, classHeader) { + + class object { + fun create(file: File): LocalFileKotlinClass? { + val fileContents = file.readBytes() + val nameAndHeader = FileBasedKotlinClass.readClassNameAndHeader(fileContents) + if (nameAndHeader == null) return null + + return LocalFileKotlinClass(file, fileContents, nameAndHeader.first!!, nameAndHeader.second!!) + } + } + + public override fun getFileContents(): ByteArray = fileContents + + override fun hashCode(): Int = file.hashCode() + override fun equals(other: Any?): Boolean = other is LocalFileKotlinClass && file == other.file + override fun toString(): String = "$javaClass: $file" +} diff --git a/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt b/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt index 1bc2940535e..d5764a212d1 100644 --- a/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt +++ b/jps-plugin/test/org/jetbrains/jet/jps/build/classFilesComparison.kt @@ -35,7 +35,7 @@ import com.google.protobuf.ExtensionRegistry import java.io.ByteArrayInputStream import org.jetbrains.jet.descriptors.serialization.DebugProtoBuf import java.util.Arrays -import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass +import org.jetbrains.jet.jps.incremental.LocalFileKotlinClass // Set this to true if you want to dump all bytecode (test will fail in this case) val DUMP_ALL = System.getProperty("comparison.dump.all") == "true" @@ -116,12 +116,10 @@ fun assertEqualDirectories(expected: File, actual: File) { fun classFileToString(classFile: File): String { val out = StringWriter() - val classBytes = classFile.readBytes() - val traceVisitor = TraceClassVisitor(PrintWriter(out)) - ClassReader(classBytes).accept(traceVisitor, 0) + ClassReader(classFile.readBytes()).accept(traceVisitor, 0) - val classHeader = VirtualFileKotlinClass.readClassHeader(classBytes) + val classHeader = LocalFileKotlinClass.create(classFile)?.getClassHeader() val annotationDataEncoded = classHeader?.annotationData if (annotationDataEncoded != null) {