Introduce OptionalExpectation for annotations missing on some platforms

This commits adds a new annotation OptionalExpectation to the standard
library, which is experimental. To enable its usage, either pass
'-Xuse-experimental=kotlin.ExperimentalMultiplatform' as a compiler
argument, or '-Xuse-experimental=kotlin.Experimental' and also annotate
each usage with `@UseExperimental(ExperimentalMultiplatform::class)`

 #KT-18882 Fixed
This commit is contained in:
Alexander Udalov
2018-05-17 18:17:48 +02:00
parent ec5110e1f4
commit bf3419c3bd
31 changed files with 434 additions and 21 deletions
@@ -300,6 +300,10 @@ public abstract class AnnotationCodegen {
return null;
}
if (classDescriptor.isExpect()) {
return null;
}
innerClassConsumer.addInnerClassInfoFromAnnotation(classDescriptor);
String asmTypeDescriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
@@ -619,6 +619,9 @@ public interface Errors {
DiagnosticFactory2.create(ERROR, ACTUAL_DECLARATION_NAME);
DiagnosticFactory0<KtNamedDeclaration> ACTUAL_MISSING = DiagnosticFactory0.create(ERROR, ACTUAL_DECLARATION_NAME);
DiagnosticFactory0<PsiElement> OPTIONAL_EXPECTATION_NOT_ON_EXPECTED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Errors/warnings inside code blocks
@@ -284,6 +284,9 @@ public class DefaultErrorMessages {
NAME, IncompatibleExpectedActualClassScopesRenderer.TEXT);
MAP.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'");
MAP.put(OPTIONAL_EXPECTATION_NOT_ON_EXPECTED, "'@OptionalExpectation' can only be used on an expected annotation class");
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
MAP.put(NOTHING_TO_OVERRIDE, "''{0}'' overrides nothing", NAME);
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker;
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext;
import org.jetbrains.kotlin.resolve.checkers.PublishedApiUsageChecker;
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
import org.jetbrains.kotlin.resolve.checkers.*;
import java.util.Collection;
import java.util.List;
@@ -275,6 +272,7 @@ public class ModifiersChecker {
}
OperatorModifierChecker.INSTANCE.check(declaration, descriptor, trace, languageVersionSettings);
PublishedApiUsageChecker.INSTANCE.check(declaration, descriptor, trace);
OptionalExpectationTargetChecker.INSTANCE.check(declaration, descriptor, trace);
}
public void checkTypeParametersModifiers(@NotNull KtModifierListOwner modifierListOwner) {
@@ -100,7 +100,8 @@ private val DEFAULT_CALL_CHECKERS = listOf(
)
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker, MissingDependencyClassChecker.ClassifierUsage
DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker, MissingDependencyClassChecker.ClassifierUsage,
OptionalExpectationUsageChecker()
)
private val DEFAULT_ANNOTATION_CHECKERS = listOf<AdditionalAnnotationChecker>(
ExperimentalMarkerDeclarationAnnotationChecker
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.resolve.BindingContext
@@ -41,6 +42,8 @@ import org.jetbrains.kotlin.utils.ifEmpty
import java.io.File
object ExpectedActualDeclarationChecker : DeclarationChecker {
internal val OPTIONAL_EXPECTATION_FQ_NAME = FqName("kotlin.OptionalExpectation")
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return
@@ -67,6 +70,8 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
val compatibility = ExpectedActualResolver.findActualForExpected(descriptor, platformModule) ?: return
if (compatibility.allStrongIncompatibilities() && isOptionalAnnotationClass(descriptor)) return
val shouldReportError =
compatibility.allStrongIncompatibilities() ||
Compatible !in compatibility && compatibility.values.flatMapTo(hashSetOf()) { it }.all { actual ->
@@ -89,6 +94,10 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
}
}
internal fun isOptionalAnnotationClass(descriptor: DeclarationDescriptor): Boolean {
return descriptor.annotations.hasAnnotation(OPTIONAL_EXPECTATION_FQ_NAME)
}
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence<MemberDescriptor>) {
if (this is ExpectActualTracker.DoNothing) return
@@ -265,18 +265,6 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
}
}
private fun PsiElement.isUsageAsAnnotationOrImport(): Boolean {
val parent = parent
if (parent is KtUserType) {
return parent.parent is KtTypeReference &&
parent.parent.parent is KtConstructorCalleeExpression &&
parent.parent.parent.parent is KtAnnotationEntry
}
return parent is KtDotQualifiedExpression && parent.parent is KtImportDirective
}
private fun PsiElement.isUsageAsQualifier(): Boolean {
if (this is KtSimpleNameExpression) {
val qualifier = getTopmostParentQualifiedExpressionForSelector() ?: this
@@ -0,0 +1,30 @@
/*
* 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.resolve.checkers
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
object OptionalExpectationTargetChecker {
fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
trace: BindingTrace
) {
if (descriptor is MemberDescriptor && descriptor.isExpect) return
for (entry in declaration.annotationEntries) {
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
if (annotationDescriptor.fqName == ExpectedActualDeclarationChecker.OPTIONAL_EXPECTATION_FQ_NAME) {
trace.report(Errors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED.on(entry))
}
}
}
}
@@ -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.resolve.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
class OptionalExpectationUsageChecker : ClassifierUsageChecker {
override fun check(targetDescriptor: ClassifierDescriptor, element: PsiElement, context: ClassifierUsageCheckerContext) {
if (!ExpectedActualDeclarationChecker.isOptionalAnnotationClass(targetDescriptor)) return
if (!element.isUsageAsAnnotationOrImport()) {
context.trace.report(Errors.OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY.on(element))
}
}
}
@@ -0,0 +1,21 @@
/*
* 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.resolve.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.*
internal fun PsiElement.isUsageAsAnnotationOrImport(): Boolean {
val parent = parent
if (parent is KtUserType) {
return parent.parent is KtTypeReference &&
parent.parent.parent is KtConstructorCalleeExpression &&
parent.parent.parent.parent is KtAnnotationEntry
}
return parent is KtDotQualifiedExpression && parent.parent is KtImportDirective
}
+13
View File
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@JvmName("bar")
fun foo() {}
fun getJvmName(): JvmName? =
Class.forName("LoadJvmNameKt").declaredMethods.single { it.name == "bar" }.getAnnotation(JvmName::class.java)
fun box(): String {
// JvmName is binary-retained and should not be accessible via reflection
return if (getJvmName() == null) "OK" else "Fail"
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +MultiPlatformProjects
// !USE_EXPERIMENTAL: kotlin.ExperimentalMultiplatform
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FILE: common.kt
@OptionalExpectation
expect annotation class Anno(val s: String)
// FILE: jvm.kt
import java.lang.reflect.AnnotatedElement
@Anno("Foo")
class Foo @Anno("<init>") constructor(@Anno("x") x: Int) {
@Anno("bar")
fun bar() {}
@Anno("getX")
var x = x
@Anno("setX")
set
@Anno("Nested")
interface Nested
}
private fun check(element: AnnotatedElement) {
check(element.annotations)
}
private fun check(annotations: Array<Annotation>) {
val filtered = annotations.filterNot { it.annotationClass.java.name == "kotlin.Metadata" }
if (filtered.isNotEmpty()) {
throw AssertionError("Annotations should be empty: $filtered")
}
}
fun box(): String {
val foo = Foo::class.java
check(foo)
check(Foo.Nested::class.java)
check(foo.declaredMethods.single { it.name == "bar" })
check(foo.declaredMethods.single { it.name == "getX" })
check(foo.declaredMethods.single { it.name == "setX" })
check(foo.constructors.single())
check(foo.constructors.single().parameterAnnotations.single())
return "OK"
}
@@ -0,0 +1,21 @@
// !LANGUAGE: +MultiPlatformProjects
// !USE_EXPERIMENTAL: kotlin.ExperimentalMultiplatform
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@OptionalExpectation
expect annotation class Anno(val s: String)
@Anno("Foo")
class Foo @Anno("<init>") constructor(@Anno("x") x: Int) {
@Anno("bar")
fun bar() {}
@Anno("getX")
var x = x
@Anno("setX")
set
@Anno("Nested")
interface Nested
}
@@ -0,0 +1,15 @@
@kotlin.Metadata
public interface Foo$Nested {
inner class Foo$Nested
}
@kotlin.Metadata
public final class Foo {
private field x: int
inner class Foo$Nested
public method <init>(p0: int): void
public final method bar(): void
public final method getX(): int
public final method setX(p0: int): void
public synthetic deprecated static method x$annotations(): void
}
@@ -0,0 +1,10 @@
// WITH_RUNTIME
// ADDITIONAL_COMPILER_ARGUMENTS: -Xuse-experimental=kotlin.ExperimentalMultiplatform
@OptionalExpectation
expect annotation class A()
expect class C {
@A
fun f()
}
@@ -0,0 +1,3 @@
actual class C {
actual fun f() {}
}
@@ -0,0 +1,6 @@
actual annotation class A
actual class C {
@A
actual fun f() {}
}
@@ -0,0 +1,12 @@
-- Common --
Exit code: OK
Output:
-- JVM --
Exit code: OK
Output:
-- JS --
Exit code: OK
Output:
@@ -0,0 +1,20 @@
// WITH_RUNTIME
// ADDITIONAL_COMPILER_ARGUMENTS: -Xuse-experimental=kotlin.ExperimentalMultiplatform
@OptionalExpectation
expect annotation class A()
fun useInSignature(a: A) = a.toString()
@OptionalExpectation
expect class NotAnAnnotationClass
@OptionalExpectation
annotation class NotAnExpectedClass
annotation class InOtherAnnotation(val a: A)
@InOtherAnnotation(A())
fun useInOtherAnnotation() {}
@@ -0,0 +1,6 @@
fun useInReturnType(): A? = null
annotation class AnotherAnnotation(val a: A)
@AnotherAnnotation(A())
fun useInAnotherAnnotation() {}
@@ -0,0 +1,46 @@
-- Common --
Exit code: COMPILATION_ERROR
Output:
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:7:23: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
fun useInSignature(a: A) = a.toString()
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:9:1: error: this annotation is not applicable to target 'class'
@OptionalExpectation
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:12:1: error: '@OptionalExpectation' can only be used on an expected annotation class
@OptionalExpectation
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:17:43: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
annotation class InOtherAnnotation(val a: A)
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
@InOtherAnnotation(A())
^
-- JVM --
Exit code: COMPILATION_ERROR
Output:
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:7:23: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
fun useInSignature(a: A) = a.toString()
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:9:1: error: this annotation is not applicable to target 'class'
@OptionalExpectation
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:12:1: error: '@OptionalExpectation' can only be used on an expected annotation class
@OptionalExpectation
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:17:43: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
annotation class InOtherAnnotation(val a: A)
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
@InOtherAnnotation(A())
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:1:24: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
fun useInReturnType(): A? = null
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:3:43: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
annotation class AnotherAnnotation(val a: A)
^
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:5:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
@AnotherAnnotation(A())
^
@@ -12078,6 +12078,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/jvmName/functionName.kt");
}
@TestMetadata("loadJvmName.kt")
public void testLoadJvmName() throws Exception {
runTest("compiler/testData/codegen/box/jvmName/loadJvmName.kt");
}
@TestMetadata("multifileClass.kt")
public void testMultifileClass() throws Exception {
runTest("compiler/testData/codegen/box/jvmName/multifileClass.kt");
@@ -13440,6 +13445,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/multiplatform/noArgActualConstructor.kt");
}
@TestMetadata("optionalExpectation.kt")
public void testOptionalExpectation() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/optionalExpectation.kt");
}
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -12078,6 +12078,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/jvmName/functionName.kt");
}
@TestMetadata("loadJvmName.kt")
public void testLoadJvmName() throws Exception {
runTest("compiler/testData/codegen/box/jvmName/loadJvmName.kt");
}
@TestMetadata("multifileClass.kt")
public void testMultifileClass() throws Exception {
runTest("compiler/testData/codegen/box/jvmName/multifileClass.kt");
@@ -13440,6 +13445,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/multiplatform/noArgActualConstructor.kt");
}
@TestMetadata("optionalExpectation.kt")
public void testOptionalExpectation() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/optionalExpectation.kt");
}
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -286,6 +286,24 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
}
}
@TestMetadata("compiler/testData/codegen/bytecodeListing/multiplatform")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Multiplatform extends AbstractBytecodeListingTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInMultiplatform() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/multiplatform"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("optionalExpectation.kt")
public void testOptionalExpectation() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/multiplatform/optionalExpectation.kt");
}
}
@TestMetadata("compiler/testData/codegen/bytecodeListing/specialBridges")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -12078,6 +12078,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/jvmName/functionName.kt");
}
@TestMetadata("loadJvmName.kt")
public void testLoadJvmName() throws Exception {
runTest("compiler/testData/codegen/box/jvmName/loadJvmName.kt");
}
@TestMetadata("multifileClass.kt")
public void testMultifileClass() throws Exception {
runTest("compiler/testData/codegen/box/jvmName/multifileClass.kt");
@@ -13440,6 +13445,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/multiplatform/noArgActualConstructor.kt");
}
@TestMetadata("optionalExpectation.kt")
public void testOptionalExpectation() throws Exception {
runTest("compiler/testData/codegen/box/multiplatform/optionalExpectation.kt");
}
@TestMetadata("compiler/testData/codegen/box/multiplatform/defaultArguments")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -99,6 +99,16 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform
runTest("compiler/testData/multiplatform/missingOverload/");
}
@TestMetadata("optionalExpectation")
public void testOptionalExpectation() throws Exception {
runTest("compiler/testData/multiplatform/optionalExpectation/");
}
@TestMetadata("optionalExpectationIncorrectUse")
public void testOptionalExpectationIncorrectUse() throws Exception {
runTest("compiler/testData/multiplatform/optionalExpectationIncorrectUse/");
}
@TestMetadata("simple")
public void testSimple() throws Exception {
runTest("compiler/testData/multiplatform/simple/");
@@ -569,6 +579,32 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform
}
}
@TestMetadata("compiler/testData/multiplatform/optionalExpectation")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class OptionalExpectation extends AbstractMultiPlatformIntegrationTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInOptionalExpectation() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/multiplatform/optionalExpectation"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("compiler/testData/multiplatform/optionalExpectationIncorrectUse")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class OptionalExpectationIncorrectUse extends AbstractMultiPlatformIntegrationTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInOptionalExpectationIncorrectUse() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/multiplatform/optionalExpectationIncorrectUse"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
}
}
@TestMetadata("compiler/testData/multiplatform/regressions")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
+3 -2
View File
@@ -49,7 +49,8 @@ compileKotlinCommon {
compileKotlinCommon {
kotlinOptions {
freeCompilerArgs = [
"-module-name", project.name
"-module-name", project.name,
"-Xuse-experimental=kotlin.Experimental"
]
}
}
@@ -94,4 +95,4 @@ task distCommon(type: Copy) {
dist.dependsOn distCommon
classes.setDependsOn(classes.dependsOn.findAll { it != "compileJava" })
classes.setDependsOn(classes.dependsOn.findAll { it != "compileJava" })
@@ -0,0 +1,40 @@
/*
* 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 kotlin
import kotlin.annotation.AnnotationTarget.*
import kotlin.internal.RequireKotlin
import kotlin.internal.RequireKotlinVersionKind
@Experimental
@Target(
CLASS,
ANNOTATION_CLASS,
PROPERTY,
FIELD,
LOCAL_VARIABLE,
VALUE_PARAMETER,
CONSTRUCTOR,
FUNCTION,
PROPERTY_GETTER,
PROPERTY_SETTER,
TYPEALIAS
)
@Retention(AnnotationRetention.BINARY)
@RequireKotlin("1.2.50", versionKind = RequireKotlinVersionKind.COMPILER_VERSION)
public annotation class ExperimentalMultiplatform
/**
* This annotation is only applicable to `expect` annotation classes in multi-platform projects and marks that class as "optional".
* Optional expected class is allowed to have no corresponding actual class on the platform. Optional annotations can only be used
* to annotate something, not as types in signatures. If an optional annotation has no corresponding actual class on a platform,
* the annotation entries where it's used are simply erased when compiling code on that platform.
*/
@Target(ANNOTATION_CLASS)
@Retention(AnnotationRetention.BINARY)
@ExperimentalMultiplatform
@RequireKotlin("1.2.50", versionKind = RequireKotlinVersionKind.COMPILER_VERSION)
public annotation class OptionalExpectation
+4 -1
View File
@@ -137,7 +137,10 @@ compileKotlin2Js {
outputFile = "${buildDir}/classes/main/kotlin.js"
sourceMap = true
sourceMapPrefix = "./"
freeCompilerArgs += ["-source-map-base-dirs", [builtinsSrcDir, jsSrcDir, commonSrcDir, commonSrcDir2].collect { file(it).absoluteFile }.join(File.pathSeparator)]
freeCompilerArgs += [
"-source-map-base-dirs", [builtinsSrcDir, jsSrcDir, commonSrcDir, commonSrcDir2].collect { file(it).absoluteFile }.join(File.pathSeparator),
"-Xuse-experimental=kotlin.Experimental"
]
}
}
+2 -1
View File
@@ -174,7 +174,8 @@ compileKotlin {
"-Xallow-kotlin-package",
"-Xmultifile-parts-inherit",
"-Xnormalize-constructor-calls=enable",
"-module-name", "kotlin-stdlib"
"-module-name", "kotlin-stdlib",
"-Xuse-experimental=kotlin.Experimental"
]
}
}
@@ -31,6 +31,9 @@ public final class kotlin/Experimental$Level : java/lang/Enum {
public static fun values ()[Lkotlin/Experimental$Level;
}
public abstract interface annotation class kotlin/ExperimentalMultiplatform : java/lang/annotation/Annotation {
}
public abstract interface annotation class kotlin/ExtensionFunctionType : java/lang/annotation/Annotation {
}
@@ -96,6 +99,9 @@ public final class kotlin/NotImplementedError : java/lang/Error {
public synthetic fun <init> (Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public abstract interface annotation class kotlin/OptionalExpectation : java/lang/annotation/Annotation {
}
public final class kotlin/Pair : java/io/Serializable {
public fun <init> (Ljava/lang/Object;Ljava/lang/Object;)V
public final fun component1 ()Ljava/lang/Object;