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.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
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.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.modules.TargetId
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
@@ -53,13 +60,43 @@ class JvmAbiAnalysisHandlerExtension(
|
|||||||
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
|
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
|
||||||
|
|
||||||
val outputDir = compilerConfiguration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)!!
|
val outputDir = compilerConfiguration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)!!
|
||||||
|
val outputFiles = arrayListOf<File>()
|
||||||
generationState.factory.writeAll(
|
generationState.factory.writeAll(
|
||||||
outputDir,
|
outputDir,
|
||||||
fun(file: OutputFile, sources: List<File>, output: File) {
|
fun(file: OutputFile, sources: List<File>, output: File) {
|
||||||
// todo report
|
// 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
|
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/");
|
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")
|
@TestMetadata("topLevelPrivateMembers")
|
||||||
public void testTopLevelPrivateMembers() throws Exception {
|
public void testTopLevelPrivateMembers() throws Exception {
|
||||||
runTest("plugins/jvm-abi-gen/testData/compare/topLevelPrivateMembers/");
|
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