Retain optional expected annotations when compiling platform code
After this change, optional expected annotations will be compiled to
physical class files on JVM, and stored to metadata on other platforms,
to allow their usages from dependent platform modules. For example:
@OptionalExpectation
expect annotation class A
When compiling this code on JVM, A.class will be produced as if the
class A did neither have the 'expect' modifier, nor had it been
annotated with OptionalExpectation. Note that if there's no actual
annotation class for A, then usages (which can only be usages as
annotation entries) are simply skipped.
Class A will be public from Kotlin's point of view (since it should
be possible to use it in Kotlin sources), but _package-private_ in Java
to disallow its usages outside of the declaring module.
#KT-18882 Fixed
#KT-24617 Fixed
This commit is contained in:
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.types.FlexibleType;
|
||||
@@ -300,7 +301,10 @@ public abstract class AnnotationCodegen {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (classDescriptor.isExpect()) {
|
||||
// We do not generate annotations whose classes are optional (annotated with `@OptionalExpectation`) because if an annotation entry
|
||||
// is resolved to the expected declaration, this means that annotation has no actual class, and thus should not be generated.
|
||||
// (Otherwise we would've resolved the entry to the actual annotation class.)
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(classDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
@@ -278,6 +279,9 @@ public class AsmUtil {
|
||||
if (descriptor instanceof SyntheticClassDescriptorForLambda) {
|
||||
return getVisibilityAccessFlagForAnonymous(descriptor);
|
||||
}
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
if (descriptor.getVisibility() == Visibilities.PUBLIC ||
|
||||
descriptor.getVisibility() == Visibilities.PROTECTED ||
|
||||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
|
||||
|
||||
Reference in New Issue
Block a user