[klib] Don't print 'final' modality
This commit is contained in:
@@ -29,21 +29,6 @@ import org.jetbrains.kotlin.utils.Printer
|
|||||||
class KlibPrinter(out: Appendable) {
|
class KlibPrinter(out: Appendable) {
|
||||||
|
|
||||||
val printer = Printer(out, 1, " ")
|
val printer = Printer(out, 1, " ")
|
||||||
val renderer = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
|
||||||
modifiers = DescriptorRendererModifier.ALL
|
|
||||||
overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE
|
|
||||||
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY
|
|
||||||
excludedAnnotationClasses += setOf(KotlinBuiltIns.FQ_NAMES.suppress)
|
|
||||||
|
|
||||||
classWithPrimaryConstructor = true
|
|
||||||
renderConstructorKeyword = true
|
|
||||||
includePropertyConstant = true
|
|
||||||
|
|
||||||
unitReturnType = false
|
|
||||||
withDefinedIn = false
|
|
||||||
renderDefaultVisibility = false
|
|
||||||
secondaryConstructorsAsPrimary = false
|
|
||||||
}
|
|
||||||
|
|
||||||
val DeclarationDescriptorWithVisibility.isPublicOrProtected: Boolean
|
val DeclarationDescriptorWithVisibility.isPublicOrProtected: Boolean
|
||||||
get() = visibility == Visibilities.PUBLIC || visibility == Visibilities.PROTECTED
|
get() = visibility == Visibilities.PUBLIC || visibility == Visibilities.PROTECTED
|
||||||
@@ -64,6 +49,27 @@ class KlibPrinter(out: Appendable) {
|
|||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ClassDescriptor.render(): String {
|
||||||
|
val renderer = when (modality) {
|
||||||
|
// Don't render 'final' modality
|
||||||
|
Modality.FINAL -> Renderers.WITHOUT_MODALITY
|
||||||
|
else -> Renderers.DEFAULT
|
||||||
|
}
|
||||||
|
return renderer.render(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CallableMemberDescriptor.render(): String {
|
||||||
|
val containingDeclaration = containingDeclaration
|
||||||
|
val renderer = when {
|
||||||
|
// Don't render modality for non-override final methods and interface methods.
|
||||||
|
containingDeclaration is ClassDescriptor && containingDeclaration.kind == ClassKind.INTERFACE ||
|
||||||
|
modality == Modality.FINAL && overriddenDescriptors.isEmpty() ->
|
||||||
|
Renderers.WITHOUT_MODALITY
|
||||||
|
else -> Renderers.DEFAULT
|
||||||
|
}
|
||||||
|
return renderer.render(this)
|
||||||
|
}
|
||||||
|
|
||||||
fun print(module: ModuleDescriptor) {
|
fun print(module: ModuleDescriptor) {
|
||||||
module.accept(PrinterVisitor(), Unit)
|
module.accept(PrinterVisitor(), Unit)
|
||||||
}
|
}
|
||||||
@@ -89,7 +95,7 @@ class KlibPrinter(out: Appendable) {
|
|||||||
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) {
|
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) {
|
||||||
val children = descriptor.unsubstitutedMemberScope.getContributedDescriptors().filter { it.shouldBePrinted }
|
val children = descriptor.unsubstitutedMemberScope.getContributedDescriptors().filter { it.shouldBePrinted }
|
||||||
val constructors = descriptor.constructors.filter { !it.isPrimary && it.shouldBePrinted }
|
val constructors = descriptor.constructors.filter { !it.isPrimary && it.shouldBePrinted }
|
||||||
val header = renderer.render(descriptor)
|
val header = descriptor.render()
|
||||||
if (children.isNotEmpty() || constructors.isNotEmpty()) {
|
if (children.isNotEmpty() || constructors.isNotEmpty()) {
|
||||||
printer.printBody(header) {
|
printer.printBody(header) {
|
||||||
constructors.forEach { it.accept(this, data) }
|
constructors.forEach { it.accept(this, data) }
|
||||||
@@ -102,15 +108,36 @@ class KlibPrinter(out: Appendable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) {
|
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) {
|
||||||
printer.println(renderer.render(descriptor))
|
printer.println(descriptor.render())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) {
|
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) {
|
||||||
printer.println(renderer.render(descriptor))
|
printer.println(descriptor.render())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: Unit) {
|
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) {
|
||||||
printer.println(renderer.render(constructorDescriptor))
|
printer.println(descriptor.render())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Renderers {
|
||||||
|
val DEFAULT = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
||||||
|
modifiers = DescriptorRendererModifier.ALL
|
||||||
|
overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE
|
||||||
|
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY
|
||||||
|
excludedAnnotationClasses += setOf(KotlinBuiltIns.FQ_NAMES.suppress)
|
||||||
|
|
||||||
|
classWithPrimaryConstructor = true
|
||||||
|
renderConstructorKeyword = true
|
||||||
|
includePropertyConstant = true
|
||||||
|
|
||||||
|
unitReturnType = false
|
||||||
|
withDefinedIn = false
|
||||||
|
renderDefaultVisibility = false
|
||||||
|
secondaryConstructorsAsPrimary = false
|
||||||
|
}
|
||||||
|
val WITHOUT_MODALITY = DEFAULT.withOptions {
|
||||||
|
modifiers -= DescriptorRendererModifier.MODALITY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,8 +143,7 @@ class Library(val name: String, val requestedRepository: String?, val target: St
|
|||||||
|
|
||||||
fun contents(output: Appendable = out) {
|
fun contents(output: Appendable = out) {
|
||||||
val reader = LibraryReaderImpl(libraryInRepoOrCurrentDir(repository, name), currentAbiVersion)
|
val reader = LibraryReaderImpl(libraryInRepoOrCurrentDir(repository, name), currentAbiVersion)
|
||||||
// TODO: Should the klib tool have arguments like compilerVersion or apiVersion?
|
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
|
||||||
val versionSpec = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE)
|
|
||||||
val module = reader.moduleDescriptor(versionSpec)
|
val module = reader.moduleDescriptor(versionSpec)
|
||||||
val defaultModules = mutableListOf<ModuleDescriptorImpl>()
|
val defaultModules = mutableListOf<ModuleDescriptorImpl>()
|
||||||
if (!module.isStdlib()) {
|
if (!module.isStdlib()) {
|
||||||
@@ -169,6 +168,8 @@ class Library(val name: String, val requestedRepository: String?, val target: St
|
|||||||
|
|
||||||
// TODO: need to do something here.
|
// TODO: need to do something here.
|
||||||
val currentAbiVersion = 1
|
val currentAbiVersion = 1
|
||||||
|
val currentLanguageVersion = LanguageVersion.LATEST_STABLE
|
||||||
|
val currentApiVersion = ApiVersion.LATEST_STABLE
|
||||||
|
|
||||||
fun libraryInRepo(repository: File, name: String): File {
|
fun libraryInRepo(repository: File, name: String): File {
|
||||||
val resolver = KonanLibrarySearchPathResolver(
|
val resolver = KonanLibrarySearchPathResolver(
|
||||||
|
|||||||
@@ -26,10 +26,13 @@ class ContentsTest {
|
|||||||
|
|
||||||
private fun testLibrary(name: String) = LIBRARY_DIRECTORY.resolve("$name.klib").toFile().absolutePath
|
private fun testLibrary(name: String) = LIBRARY_DIRECTORY.resolve("$name.klib").toFile().absolutePath
|
||||||
|
|
||||||
private fun klibContents(library: String, expected: () -> String) {
|
private fun klibContents(library: String, printOutput: Boolean = false, expected: () -> String) {
|
||||||
val output = StringBuilder()
|
val output = StringBuilder()
|
||||||
val lib = Library(library, null, "host")
|
val lib = Library(library, null, "host")
|
||||||
lib.contents(output)
|
lib.contents(output)
|
||||||
|
if (printOutput) {
|
||||||
|
println(output.trim().toString())
|
||||||
|
}
|
||||||
assertEquals(expected(), output.trim().toString(), "klib contents test failed for library: $library")
|
assertEquals(expected(), output.trim().toString(), "klib contents test failed for library: $library")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,9 +62,9 @@ class ContentsTest {
|
|||||||
inline fun <reified T> t4(x: T)
|
inline fun <reified T> t4(x: T)
|
||||||
fun <T : Number> t5(x: T)
|
fun <T : Number> t5(x: T)
|
||||||
fun Foo.e()
|
fun Foo.e()
|
||||||
final annotation class A constructor() : Annotation
|
annotation class A constructor() : Annotation
|
||||||
final annotation class B constructor() : Annotation
|
annotation class B constructor() : Annotation
|
||||||
final class Foo constructor()
|
class Foo constructor()
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
@@ -70,11 +73,11 @@ class ContentsTest {
|
|||||||
fun constructors() = klibContents(testLibrary("Constructors")) {
|
fun constructors() = klibContents(testLibrary("Constructors")) {
|
||||||
"""
|
"""
|
||||||
package <root> {
|
package <root> {
|
||||||
final annotation class A constructor() : Annotation
|
annotation class A constructor() : Annotation
|
||||||
final class Bar @A constructor(x: Int)
|
class Bar @A constructor(x: Int)
|
||||||
final class Baz private constructor(x: Int)
|
class Baz private constructor(x: Int)
|
||||||
|
|
||||||
final class Foo constructor(x: Int) {
|
class Foo constructor(x: Int) {
|
||||||
constructor()
|
constructor()
|
||||||
constructor(x: Double)
|
constructor(x: Double)
|
||||||
constructor(x: Double, y: Int)
|
constructor(x: Double, y: Int)
|
||||||
@@ -82,9 +85,9 @@ class ContentsTest {
|
|||||||
@A constructor(x: Foo)
|
@A constructor(x: Foo)
|
||||||
}
|
}
|
||||||
|
|
||||||
final class Qux protected constructor(x: Int)
|
class Qux protected constructor(x: Int)
|
||||||
|
|
||||||
final class Typed<T> constructor(x: Int) {
|
class Typed<T> constructor(x: Int) {
|
||||||
constructor()
|
constructor()
|
||||||
constructor(x: Double)
|
constructor(x: Double)
|
||||||
constructor(x: Double, y: Int)
|
constructor(x: Double, y: Int)
|
||||||
@@ -102,25 +105,25 @@ class ContentsTest {
|
|||||||
package <root> {
|
package <root> {
|
||||||
|
|
||||||
object A {
|
object A {
|
||||||
final fun a()
|
fun a()
|
||||||
}
|
}
|
||||||
|
|
||||||
final class B constructor() {
|
class B constructor() {
|
||||||
|
|
||||||
object C {
|
object C {
|
||||||
final fun c()
|
fun c()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
final fun b()
|
fun b()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final class D constructor() {
|
class D constructor() {
|
||||||
|
|
||||||
companion object E {
|
companion object E {
|
||||||
final fun e()
|
fun e()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -134,54 +137,54 @@ class ContentsTest {
|
|||||||
"""
|
"""
|
||||||
package <root> {
|
package <root> {
|
||||||
|
|
||||||
final class A constructor() {
|
class A constructor() {
|
||||||
final val aVal: Int = 0
|
val aVal: Int = 0
|
||||||
final var aVar: String
|
var aVar: String
|
||||||
final fun aFun()
|
fun aFun()
|
||||||
|
|
||||||
final inner class B constructor() {
|
inner class B constructor() {
|
||||||
final val bVal: Int = 0
|
val bVal: Int = 0
|
||||||
final var bVar: String
|
var bVar: String
|
||||||
final fun bFun()
|
fun bFun()
|
||||||
|
|
||||||
final inner class C constructor() {
|
inner class C constructor() {
|
||||||
final val cVal: Int = 0
|
val cVal: Int = 0
|
||||||
final var cVar: String
|
var cVar: String
|
||||||
final fun cFun()
|
fun cFun()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final class E constructor() {
|
class E constructor() {
|
||||||
final val eVal: Int = 0
|
val eVal: Int = 0
|
||||||
final var eVar: String
|
var eVar: String
|
||||||
final fun eFun()
|
fun eFun()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final data class F constructor(fVal: Int, fVar: String) {
|
data class F constructor(fVal: Int, fVar: String) {
|
||||||
final val fVal: Int
|
val fVal: Int
|
||||||
final var fVar: String
|
var fVar: String
|
||||||
final operator fun component1(): Int
|
operator fun component1(): Int
|
||||||
final operator fun component2(): String
|
operator fun component2(): String
|
||||||
final fun copy(fVal: Int = ..., fVar: String = ...): F
|
fun copy(fVal: Int = ..., fVar: String = ...): F
|
||||||
override fun equals(other: Any?): Boolean
|
override fun equals(other: Any?): Boolean
|
||||||
final fun fFun()
|
fun fFun()
|
||||||
override fun hashCode(): Int
|
override fun hashCode(): Int
|
||||||
override fun toString(): String
|
override fun toString(): String
|
||||||
}
|
}
|
||||||
|
|
||||||
final class FinalImpl constructor() : OpenImpl {
|
class FinalImpl constructor() : OpenImpl {
|
||||||
override val iVal: Int = 0
|
override val iVal: Int = 0
|
||||||
override var iVar: String
|
override var iVar: String
|
||||||
override fun iFun()
|
override fun iFun()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Interface {
|
interface Interface {
|
||||||
abstract val iVal: Int
|
val iVal: Int
|
||||||
abstract var iVar: String
|
var iVar: String
|
||||||
abstract fun iFun()
|
fun iFun()
|
||||||
}
|
}
|
||||||
|
|
||||||
open class OpenImpl constructor() : Interface {
|
open class OpenImpl constructor() : Interface {
|
||||||
@@ -194,13 +197,61 @@ class ContentsTest {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun methodModality() = klibContents(testLibrary("MethodModality")) {
|
||||||
|
"""
|
||||||
|
package <root> {
|
||||||
|
|
||||||
|
abstract class AbstractClass constructor() : Interface {
|
||||||
|
abstract fun abstractFun()
|
||||||
|
override fun interfaceFun()
|
||||||
|
}
|
||||||
|
|
||||||
|
class FinalClass constructor() : OpenClass {
|
||||||
|
override fun openFun1()
|
||||||
|
final override fun openFun2()
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Interface {
|
||||||
|
fun interfaceFun()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class OpenClass constructor() : AbstractClass {
|
||||||
|
override fun abstractFun()
|
||||||
|
fun finalFun()
|
||||||
|
open fun openFun1()
|
||||||
|
open fun openFun2()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun functionModifiers() = klibContents(testLibrary("FunctionModifiers")) {
|
||||||
|
"""
|
||||||
|
package <root> {
|
||||||
|
|
||||||
|
class Foo constructor() {
|
||||||
|
fun f1()
|
||||||
|
infix fun f2(x: Int)
|
||||||
|
suspend fun f3()
|
||||||
|
tailrec fun f4()
|
||||||
|
fun f5(vararg x: Int)
|
||||||
|
operator fun plus(x: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore // TODO: Do we need to print the overridden method in the C entry?
|
@Ignore // TODO: Do we need to print the overridden method in the C entry?
|
||||||
fun enum() = klibContents(testLibrary("Enum")) {
|
fun enum() = klibContents(testLibrary("Enum")) {
|
||||||
"""
|
"""
|
||||||
package <root> {
|
package <root> {
|
||||||
|
|
||||||
final enum class E private constructor(x: Int = ...) : Enum<E> {
|
enum class E private constructor(x: Int = ...) : Enum<E> {
|
||||||
enum entry A
|
enum entry A
|
||||||
enum entry B
|
enum entry B
|
||||||
|
|
||||||
@@ -208,9 +259,9 @@ class ContentsTest {
|
|||||||
override fun enumFun(): Int
|
override fun enumFun(): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
final val enumVal: Int = 0
|
val enumVal: Int = 0
|
||||||
final var enumVar: String
|
var enumVar: String
|
||||||
final val x: Int
|
val x: Int
|
||||||
open fun enumFun(): Int
|
open fun enumFun(): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class Foo {
|
||||||
|
fun f1() {}
|
||||||
|
infix fun f2(x: Int) {}
|
||||||
|
suspend fun f3() {}
|
||||||
|
operator fun plus(x: Int) {}
|
||||||
|
tailrec fun f4() {}
|
||||||
|
fun f5(vararg x: Int) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
interface Interface {
|
||||||
|
fun interfaceFun()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractClass: Interface {
|
||||||
|
override fun interfaceFun() {}
|
||||||
|
abstract fun abstractFun()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class OpenClass: AbstractClass() {
|
||||||
|
override fun abstractFun() {}
|
||||||
|
open fun openFun1() {}
|
||||||
|
open fun openFun2() {}
|
||||||
|
fun finalFun() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FinalClass: OpenClass() {
|
||||||
|
override fun openFun1() {}
|
||||||
|
final override fun openFun2() {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user