Exclude local and private classes from ABI classes
This commit is contained in:
+37
@@ -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)
|
||||
}
|
||||
}
|
||||
+10
@@ -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
|
||||
Reference in New Issue
Block a user