Do not include $DefaultImpls inner classes in public API when they do not contain any public members (i.e. used only as a container to hold synthetic methods with annotations for properties or typealiases)
This commit is contained in:
+2
-2
@@ -41,7 +41,7 @@ fun getBinaryAPI(classStreams: Sequence<InputStream>, visibilityMap: Map<String,
|
||||
it.isEffectivelyPublic(classAccess, classVisibility)
|
||||
}
|
||||
|
||||
ClassBinarySignature(name, superName, outerClassName, supertypes, memberSignatures, classAccess, isEffectivelyPublic(classVisibility), isFileOrMultipartFacade())
|
||||
ClassBinarySignature(name, superName, outerClassName, supertypes, memberSignatures, classAccess, isEffectivelyPublic(classVisibility), isFileOrMultipartFacade() || isDefaultImpls())
|
||||
}}
|
||||
.asIterable()
|
||||
.sortedBy { it.name }
|
||||
@@ -74,7 +74,7 @@ fun List<ClassBinarySignature>.filterOutNonPublic(): List<ClassBinarySignature>
|
||||
|
||||
return filter { it.isPublicAndAccessible() }
|
||||
.map { it.flattenNonPublicBases() }
|
||||
.filterNot { it.isFileOrMultipartFacade && it.memberSignatures.isEmpty()}
|
||||
.filterNot { it.isNotUsedWhenEmpty && it.memberSignatures.isEmpty()}
|
||||
}
|
||||
|
||||
fun List<ClassBinarySignature>.dump() = dump(to = System.out)
|
||||
|
||||
+4
-1
@@ -23,7 +23,7 @@ data class ClassBinarySignature(
|
||||
val memberSignatures: List<MemberBinarySignature>,
|
||||
val access: AccessFlags,
|
||||
val isEffectivelyPublic: Boolean,
|
||||
val isFileOrMultipartFacade: Boolean) {
|
||||
val isNotUsedWhenEmpty: Boolean) {
|
||||
|
||||
val signature: String
|
||||
get() = "${access.getModifierString()} class $name" + if (supertypes.isEmpty()) "" else " : ${supertypes.joinToString()}"
|
||||
@@ -121,6 +121,7 @@ fun ClassNode.isEffectivelyPublic(classVisibility: ClassVisibility?) =
|
||||
|
||||
val ClassNode.innerClassNode: InnerClassNode? get() = innerClasses.singleOrNull { it.name == name }
|
||||
fun ClassNode.isLocal() = innerClassNode?.run { innerName == null && outerName == null} ?: false
|
||||
fun ClassNode.isInner() = innerClassNode != null
|
||||
fun ClassNode.isWhenMappings() = isSynthetic(access) && name.endsWith("\$WhenMappings")
|
||||
|
||||
val ClassNode.effectiveAccess: Int get() = innerClassNode?.access ?: access
|
||||
@@ -134,12 +135,14 @@ fun FieldNode.isInlineExposed() = hasAnnotation(inlineExposedAnnotationName, inc
|
||||
|
||||
private object KotlinClassKind {
|
||||
const val FILE = 2
|
||||
const val SYNTHETIC_CLASS = 3
|
||||
const val MULTIPART_FACADE = 4
|
||||
|
||||
val FILE_OR_MULTIPART_FACADE_KINDS = listOf(FILE, MULTIPART_FACADE)
|
||||
}
|
||||
|
||||
fun ClassNode.isFileOrMultipartFacade() = kotlinClassKind.let { it != null && it in KotlinClassKind.FILE_OR_MULTIPART_FACADE_KINDS }
|
||||
fun ClassNode.isDefaultImpls() = isInner() && name.endsWith("\$DefaultImpls") && kotlinClassKind == KotlinClassKind.SYNTHETIC_CLASS
|
||||
|
||||
|
||||
val ClassNode.kotlinClassKind: Int?
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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 cases.interfaces
|
||||
|
||||
public interface EmptyImpls {
|
||||
@SinceKotlin("1.1")
|
||||
val property: String
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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 cases.interfaces
|
||||
|
||||
public interface BaseWithImpl {
|
||||
fun foo() = 42
|
||||
}
|
||||
|
||||
public interface DerivedWithImpl : BaseWithImpl {
|
||||
override fun foo(): Int {
|
||||
return super.foo() + 1
|
||||
}
|
||||
}
|
||||
|
||||
public interface DerivedWithoutImpl : BaseWithImpl
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
public abstract interface class cases/interfaces/BaseWithImpl {
|
||||
public abstract fun foo ()I
|
||||
}
|
||||
|
||||
public final class cases/interfaces/BaseWithImpl$DefaultImpls {
|
||||
public static fun foo (Lcases/interfaces/BaseWithImpl;)I
|
||||
}
|
||||
|
||||
public abstract interface class cases/interfaces/DerivedWithImpl : cases/interfaces/BaseWithImpl {
|
||||
public abstract fun foo ()I
|
||||
}
|
||||
|
||||
public final class cases/interfaces/DerivedWithImpl$DefaultImpls {
|
||||
public static fun foo (Lcases/interfaces/DerivedWithImpl;)I
|
||||
}
|
||||
|
||||
public abstract interface class cases/interfaces/DerivedWithoutImpl : cases/interfaces/BaseWithImpl {
|
||||
}
|
||||
|
||||
public final class cases/interfaces/DerivedWithoutImpl$DefaultImpls {
|
||||
public static fun foo (Lcases/interfaces/DerivedWithoutImpl;)I
|
||||
}
|
||||
|
||||
public abstract interface class cases/interfaces/EmptyImpls {
|
||||
public abstract fun getProperty ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
+2
@@ -20,6 +20,8 @@ class CasesPublicAPITest {
|
||||
|
||||
@Test fun inline() { snapshotAPIAndCompare(testName.methodName) }
|
||||
|
||||
@Test fun interfaces() { snapshotAPIAndCompare(testName.methodName) }
|
||||
|
||||
@Test fun internal() { snapshotAPIAndCompare(testName.methodName) }
|
||||
|
||||
@Test fun java() { snapshotAPIAndCompare(testName.methodName) }
|
||||
|
||||
Reference in New Issue
Block a user