Exclude local and private classes from ABI classes

This commit is contained in:
Alexey Tsvetkov
2018-11-30 17:22:42 +03:00
parent 7c2f7cab9a
commit 1f5ca7274d
9 changed files with 98 additions and 0 deletions
@@ -16,7 +16,14 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
import org.jetbrains.kotlin.incremental.isClassFile
import org.jetbrains.kotlin.jvm.abi.asm.AbiClassBuilder
import org.jetbrains.kotlin.jvm.abi.asm.FilterInnerClassesVisitor
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingTrace
@@ -53,13 +60,43 @@ class JvmAbiAnalysisHandlerExtension(
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
val outputDir = compilerConfiguration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)!!
val outputFiles = arrayListOf<File>()
generationState.factory.writeAll(
outputDir,
fun(file: OutputFile, sources: List<File>, output: File) {
// todo report
outputFiles.add(output)
}
)
val classFiles = HashSet<File>()
val removedClasses = HashSet<String>()
for (file in outputFiles) {
if (!file.isClassFile()) continue
classFiles.add(file)
val localFileKotlinClass = LocalFileKotlinClass.create(file) ?: continue
val header = localFileKotlinClass.classHeader
if (header.kind == KotlinClassHeader.Kind.CLASS) {
val (_, classProto) = JvmProtoBufUtil.readClassDataFrom(header.data!!, header.strings!!)
val visibility = Flags.VISIBILITY.get(classProto.flags)
if (visibility == ProtoBuf.Visibility.PRIVATE || visibility == ProtoBuf.Visibility.LOCAL) {
file.delete()
classFiles.remove(file)
removedClasses.add(localFileKotlinClass.className.internalName)
}
}
}
for (file in classFiles) {
val reader = ClassReader(file.readBytes())
val writer = ClassWriter(reader, 0)
val visitor = FilterInnerClassesVisitor(removedClasses, Opcodes.ASM6, writer)
reader.accept(visitor, 0)
file.writeBytes(writer.toByteArray())
}
return null
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.jvm.abi.asm
import org.jetbrains.org.objectweb.asm.ClassVisitor
internal class FilterInnerClassesVisitor(
private val innerClassesToFilter: Set<String>,
api: Int,
cv: ClassVisitor
) : ClassVisitor(api, cv) {
override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) {
if (name in innerClassesToFilter) return
super.visitInnerClass(name, outerName, innerName, access)
}
}
@@ -44,6 +44,16 @@ public class CompareJvmAbiTestGenerated extends AbstractCompareJvmAbiTest {
runTest("plugins/jvm-abi-gen/testData/compare/inlineFunctionBody/");
}
@TestMetadata("localClass")
public void testLocalClass() throws Exception {
runTest("plugins/jvm-abi-gen/testData/compare/localClass/");
}
@TestMetadata("privateClass")
public void testPrivateClass() throws Exception {
runTest("plugins/jvm-abi-gen/testData/compare/privateClass/");
}
@TestMetadata("topLevelPrivateMembers")
public void testTopLevelPrivateMembers() throws Exception {
runTest("plugins/jvm-abi-gen/testData/compare/topLevelPrivateMembers/");
@@ -0,0 +1,7 @@
package test
class Class {
fun method() {
class MethodLocalClass
}
}
@@ -0,0 +1,5 @@
package test
fun function() {
class FunctionLocalClass
}
@@ -0,0 +1,6 @@
package test
class Class {
fun method() {
}
}
@@ -0,0 +1,4 @@
package test
fun function() {
}
@@ -0,0 +1,5 @@
package test
class PublicClass
internal class InternalClass
private class PrivateClass
@@ -0,0 +1,4 @@
package test
class PublicClass
internal class InternalClass