Drop @inline from tests and incremental compilation

This commit is contained in:
Alexey Tsvetkov
2015-10-19 19:16:23 +03:00
parent df8066b1e4
commit d87ce33458
3 changed files with 89 additions and 29 deletions
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2015 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.kotlin.inline
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
public fun inlineFunctionsJvmNames(bytes: ByteArray): Set<String> {
val header = readKotlinHeader(bytes)
val annotationData = header.annotationData
val strings = header.strings
if (annotationData == null || strings == null) return emptySet()
return when (header.kind) {
KotlinClassHeader.Kind.CLASS -> {
val classData = JvmProtoBufUtil.readClassDataFrom(BitEncoding.decodeBytes(annotationData), strings)
inlineFunctionsJvmNames(classData.classProto.functionList, classData.nameResolver, classData.classProto.typeTable)
}
KotlinClassHeader.Kind.FILE_FACADE,
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
val packageData = JvmProtoBufUtil.readPackageDataFrom(BitEncoding.decodeBytes(annotationData), strings)
inlineFunctionsJvmNames(packageData.packageProto.functionList, packageData.nameResolver, packageData.packageProto.typeTable)
}
else -> emptySet<String>()
}
}
private fun inlineFunctionsJvmNames(functions: List<ProtoBuf.Function>, nameResolver: NameResolver, protoTypeTable: ProtoBuf.TypeTable): Set<String> {
val typeTable = TypeTable(protoTypeTable)
val inlineFunctions = functions.filter { Flags.IS_INLINE.get(it.flags) }
val jvmNames = inlineFunctions.map {
JvmProtoBufUtil.getJvmMethodSignature(it, nameResolver, typeTable)
}
return jvmNames.filterNotNull().toSet()
}
private fun readKotlinHeader(bytes: ByteArray): KotlinClassHeader {
var header: KotlinClassHeader? = null
FileBasedKotlinClass.create(bytes) { className, classHeader, innerClasses ->
header = classHeader
null
}
if (header == null) throw AssertionError("Could not read kotlin header from byte array")
return header!!
}
@@ -17,10 +17,10 @@
package org.jetbrains.kotlin.codegen;
import org.jetbrains.kotlin.backend.common.output.OutputFile
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
@@ -32,7 +32,6 @@ import kotlin.properties.Delegates
public object InlineTestUtil {
public val INLINE_ANNOTATION_CLASS: String = "kotlin/inline"
private val KOTLIN_PACKAGE_DESC = "L" + AsmUtil.internalNameByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE) + ";"
private val KOTLIN_MULTIFILE_CLASS_DESC = "L" + AsmUtil.internalNameByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS) + ";"
@@ -62,27 +61,28 @@ public object InlineTestUtil {
val classHeaders = hashMapOf<String, KotlinClassHeader>()
for (file in files) {
val cr = ClassReader(file.asByteArray())
val bytes = file.asByteArray()
val cr = ClassReader(bytes)
val inlineFunctions = inlineFunctionsJvmNames(bytes)
if (inlineFunctions.isEmpty()) continue
val classVisitor = object : ClassVisitorWithName() {
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor {
return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
public override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor {
val type = Type.getType(desc)
val annotationClass = type.getInternalName()
if (INLINE_ANNOTATION_CLASS == annotationClass) {
override fun visitEnd() {
if (name + desc in inlineFunctions) {
inlineMethods.add(MethodInfo(className, name, this.desc))
}
return super.visitAnnotation(desc, visible)
}
}
}
}
cr.accept(classVisitor, 0)
cr.accept(classVisitor, 0)
classHeaders.put(classVisitor.className, getClassHeader(file))
}
return InlineInfo(inlineMethods, classHeaders)
}