From be2f85767001f17e336ce04f57a0fcc24ca28cf9 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 14 Jan 2016 15:09:18 +0300 Subject: [PATCH] Introduce inline-only functions They have private visibility in bytecode --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 2 ++ .../codegen/context/CodegenContext.java | 3 +++ .../kotlin/resolve/AnnotationUtil.kt | 13 ++++++++---- .../codegen/bytecodeListing/inlineOnly.kt | 17 +++++++++++++++ .../codegen/bytecodeListing/inlineOnly.txt | 14 +++++++++++++ .../codegen/BytecodeListingTestGenerated.java | 6 ++++++ .../src/kotlin/jvm/internal/Annotations.kt | 21 +++++++++++++++++++ 7 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/inlineOnly.kt create mode 100644 compiler/testData/codegen/bytecodeListing/inlineOnly.txt create mode 100644 libraries/stdlib/src/kotlin/jvm/internal/Annotations.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index cc0655f9657..2b8b6e03ba8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -323,6 +323,8 @@ public class AsmUtil { DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration(); Visibility memberVisibility = memberDescriptor.getVisibility(); + if (AnnotationUtilKt.isInlineOnly(memberDescriptor)) return ACC_PRIVATE; + if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) { return ACC_PUBLIC; } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java index 6d0c298a0d6..fe150949aed 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.storage.NullableLazyValue; import org.jetbrains.kotlin.types.KotlinType; @@ -609,6 +610,8 @@ public abstract class CodegenContext { boolean withinInline, boolean isSuperCall ) { + if (AnnotationUtilKt.isInlineOnly(unwrappedDescriptor)) return false; + return isSuperCall && withinInline || (accessFlag & ACC_PRIVATE) != 0 || ((accessFlag & ACC_PROTECTED) != 0 && diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt index 45f2289e83d..8cb2c592882 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt @@ -16,9 +16,7 @@ package org.jetbrains.kotlin.resolve.annotations -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -62,4 +60,11 @@ fun AnnotationDescriptor.argumentValue(parameterName: String): Any? { return null return constant.value -} \ No newline at end of file +} + +private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.internal.InlineOnly") + +fun MemberDescriptor.isInlineOnly(): Boolean { + if (this !is FunctionDescriptor) return false + return typeParameters.any { it.isReified } || annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) +} diff --git a/compiler/testData/codegen/bytecodeListing/inlineOnly.kt b/compiler/testData/codegen/bytecodeListing/inlineOnly.kt new file mode 100644 index 00000000000..34006bfa683 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inlineOnly.kt @@ -0,0 +1,17 @@ +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.jvm.internal.InlineOnly +inline fun foo() { } + +inline fun bar() { } + +inline fun baz() {} + +class Foo { + @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") + @kotlin.jvm.internal.InlineOnly + inline fun foo() { } + + inline fun bar() { } + + inline fun baz() {} +} diff --git a/compiler/testData/codegen/bytecodeListing/inlineOnly.txt b/compiler/testData/codegen/bytecodeListing/inlineOnly.txt new file mode 100644 index 00000000000..d44965bde2d --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/inlineOnly.txt @@ -0,0 +1,14 @@ +@kotlin.jvm.internal.KotlinClass +public final class Foo { + public method (): void + public final method bar(): void + private final method baz(): void + private final @kotlin.jvm.internal.InlineOnly method foo(): void +} + +@kotlin.jvm.internal.KotlinFileFacade +public final class InlineOnlyKt { + public final static method bar(): void + private final static method baz(): void + private final static @kotlin.jvm.internal.InlineOnly method foo(): void +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index c6b78209071..36a2cea1d84 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -41,6 +41,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { doTest(fileName); } + @TestMetadata("inlineOnly.kt") + public void testInlineOnly() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/inlineOnly.kt"); + doTest(fileName); + } + @TestMetadata("compiler/testData/codegen/bytecodeListing/annotations") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/libraries/stdlib/src/kotlin/jvm/internal/Annotations.kt b/libraries/stdlib/src/kotlin/jvm/internal/Annotations.kt new file mode 100644 index 00000000000..b359890358d --- /dev/null +++ b/libraries/stdlib/src/kotlin/jvm/internal/Annotations.kt @@ -0,0 +1,21 @@ +/* + * 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 kotlin.jvm.internal + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.BINARY) +internal annotation class InlineOnly