[K/JS] Add ability to exclude declarations from export by a new annotation @JsExport.Ignore.
This commit is contained in:
@@ -89,13 +89,8 @@ public class PackageCodegenImpl implements PackageCodegen {
|
|||||||
|
|
||||||
for (KtDeclaration declaration : file.getDeclarations()) {
|
for (KtDeclaration declaration : file.getDeclarations()) {
|
||||||
if (declaration instanceof KtClassOrObject) {
|
if (declaration instanceof KtClassOrObject) {
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, declaration);
|
|
||||||
if (PsiUtilsKt.hasExpectModifier(declaration)) {
|
if (PsiUtilsKt.hasExpectModifier(declaration)) {
|
||||||
if (descriptor != null && OptionalAnnotationUtil.shouldGenerateExpectClass(descriptor)) {
|
addDescriptorToOptionalAnnotationsIfNeeded((KtClassOrObject) declaration, state);
|
||||||
assert OptionalAnnotationUtil.isOptionalAnnotationClass(descriptor) :
|
|
||||||
"Expect class should be generated only if it's an optional annotation: " + descriptor;
|
|
||||||
state.getFactory().getPackagePartRegistry().getOptionalAnnotations().add(descriptor);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +115,27 @@ public class PackageCodegenImpl implements PackageCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void addDescriptorToOptionalAnnotationsIfNeeded(@NotNull KtClassOrObject declaration, @NotNull GenerationState state) {
|
||||||
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, declaration);
|
||||||
|
if (descriptor == null || !OptionalAnnotationUtil.shouldGenerateExpectClass(descriptor)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert OptionalAnnotationUtil.isOptionalAnnotationClass(descriptor) :
|
||||||
|
"Expect class should be generated only if it's an optional annotation: " + descriptor;
|
||||||
|
|
||||||
|
state.getFactory().getPackagePartRegistry().getOptionalAnnotations().add(descriptor);
|
||||||
|
|
||||||
|
KtClassBody body = declaration.getBody();
|
||||||
|
|
||||||
|
if (body != null) {
|
||||||
|
for (KtDeclaration childDeclaration : body.getDeclarations()) {
|
||||||
|
if (!(childDeclaration instanceof KtClassOrObject)) continue;
|
||||||
|
addDescriptorToOptionalAnnotationsIfNeeded((KtClassOrObject) childDeclaration, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void generateFile(@NotNull KtFile file) {
|
private void generateFile(@NotNull KtFile file) {
|
||||||
JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file);
|
JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file);
|
||||||
if (fileClassInfo.getWithJvmMultifileClass()) return;
|
if (fileClassInfo.getWithJvmMultifileClass()) return;
|
||||||
|
|||||||
@@ -789,7 +789,6 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<KtNamedDeclaration> ACTUAL_MISSING = DiagnosticFactory0.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_EXPECTATION_NOT_ON_EXPECTED = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> NESTED_OPTIONAL_EXPECTATION = DiagnosticFactory0.create(ERROR);
|
|
||||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
|
|||||||
-1
@@ -333,7 +333,6 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'");
|
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_EXPECTATION_NOT_ON_EXPECTED, "'@OptionalExpectation' can only be used on an expected annotation class");
|
||||||
MAP.put(NESTED_OPTIONAL_EXPECTATION, "'@OptionalExpectation' cannot be used on a nested class");
|
|
||||||
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
|
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
|
||||||
MAP.put(OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE, "Declaration annotated with '@OptionalExpectation' can only be used in common module sources");
|
MAP.put(OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE, "Declaration annotated with '@OptionalExpectation' can only be used in common module sources");
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -7,25 +7,16 @@ package org.jetbrains.kotlin.resolve.checkers
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||||
|
|
||||||
object OptionalExpectationChecker {
|
object OptionalExpectationChecker {
|
||||||
fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, trace: BindingTrace) {
|
fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, trace: BindingTrace) {
|
||||||
val isExpect = descriptor is MemberDescriptor && descriptor.isExpect
|
if (descriptor !is MemberDescriptor || !descriptor.isExpect) {
|
||||||
if (isExpect) {
|
|
||||||
if (DescriptorUtils.isAnnotationClass(descriptor) && descriptor.containingDeclaration !is PackageFragmentDescriptor) {
|
|
||||||
getOptionalExpectationEntry(declaration, trace)?.let {
|
|
||||||
trace.report(Errors.NESTED_OPTIONAL_EXPECTATION.on(it))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getOptionalExpectationEntry(declaration, trace)?.let {
|
getOptionalExpectationEntry(declaration, trace)?.let {
|
||||||
trace.report(Errors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED.on(it))
|
trace.report(Errors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED.on(it))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,11 @@ internal fun PsiElement.isUsageAsAnnotationOrImport(): Boolean {
|
|||||||
val parent = parent
|
val parent = parent
|
||||||
|
|
||||||
if (parent is KtUserType) {
|
if (parent is KtUserType) {
|
||||||
return parent.parent is KtTypeReference &&
|
return (parent.parent is KtUserType && parent.isUsageAsAnnotationOrImport()) || (
|
||||||
parent.parent.parent is KtConstructorCalleeExpression &&
|
parent.parent is KtTypeReference &&
|
||||||
parent.parent.parent.parent is KtAnnotationEntry
|
parent.parent.parent is KtConstructorCalleeExpression &&
|
||||||
|
parent.parent.parent.parent is KtAnnotationEntry
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent is KtDotQualifiedExpression && parent.parent is KtImportDirective
|
return parent is KtDotQualifiedExpression && parent.parent is KtImportDirective
|
||||||
|
|||||||
+3
-2
@@ -22,8 +22,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
@@ -740,6 +738,9 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
|||||||
if (context.additionalExportedDeclarations.contains(declaration))
|
if (context.additionalExportedDeclarations.contains(declaration))
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
if (declaration.isJsExportIgnore())
|
||||||
|
return false
|
||||||
|
|
||||||
if (declaration is IrOverridableDeclaration<*>) {
|
if (declaration is IrOverridableDeclaration<*>) {
|
||||||
val overriddenNonEmpty = declaration
|
val overriddenNonEmpty = declaration
|
||||||
.overriddenSymbols
|
.overriddenSymbols
|
||||||
|
|||||||
+2
-1
@@ -113,7 +113,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
if (property.getter?.extensionReceiverParameter != null || property.setter?.extensionReceiverParameter != null)
|
if (property.getter?.extensionReceiverParameter != null || property.setter?.extensionReceiverParameter != null)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (!property.visibility.isPublicAPI || property.isSimpleProperty)
|
if (!property.visibility.isPublicAPI || property.isSimpleProperty || property.isJsExportIgnore())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -223,6 +223,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSimpleFunction.isDefinedInsideExportedInterface(): Boolean {
|
private fun IrSimpleFunction.isDefinedInsideExportedInterface(): Boolean {
|
||||||
|
if (isJsExportIgnore() || correspondingPropertySymbol?.owner?.isJsExportIgnore() == true) return false
|
||||||
return (!isFakeOverride && parentClassOrNull.isExportedInterface(context.staticContext.backendContext)) ||
|
return (!isFakeOverride && parentClassOrNull.isExportedInterface(context.staticContext.backendContext)) ||
|
||||||
overriddenSymbols.any { it.owner.isDefinedInsideExportedInterface() }
|
overriddenSymbols.any { it.owner.isDefinedInsideExportedInterface() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ object JsAnnotations {
|
|||||||
val jsQualifierFqn = FqName("kotlin.js.JsQualifier")
|
val jsQualifierFqn = FqName("kotlin.js.JsQualifier")
|
||||||
val jsExportFqn = FqName("kotlin.js.JsExport")
|
val jsExportFqn = FqName("kotlin.js.JsExport")
|
||||||
val jsImplicitExportFqn = FqName("kotlin.js.JsImplicitExport")
|
val jsImplicitExportFqn = FqName("kotlin.js.JsImplicitExport")
|
||||||
|
val jsExportIgnoreFqn = FqName("kotlin.js.JsExport.Ignore")
|
||||||
val jsNativeGetter = FqName("kotlin.js.nativeGetter")
|
val jsNativeGetter = FqName("kotlin.js.nativeGetter")
|
||||||
val jsNativeSetter = FqName("kotlin.js.nativeSetter")
|
val jsNativeSetter = FqName("kotlin.js.nativeSetter")
|
||||||
val jsNativeInvoke = FqName("kotlin.js.nativeInvoke")
|
val jsNativeInvoke = FqName("kotlin.js.nativeInvoke")
|
||||||
@@ -61,6 +62,9 @@ fun IrAnnotationContainer.isJsExport(): Boolean =
|
|||||||
fun IrAnnotationContainer.isJsImplicitExport(): Boolean =
|
fun IrAnnotationContainer.isJsImplicitExport(): Boolean =
|
||||||
hasAnnotation(JsAnnotations.jsImplicitExportFqn)
|
hasAnnotation(JsAnnotations.jsImplicitExportFqn)
|
||||||
|
|
||||||
|
fun IrAnnotationContainer.isJsExportIgnore(): Boolean =
|
||||||
|
hasAnnotation(JsAnnotations.jsExportIgnoreFqn)
|
||||||
|
|
||||||
fun IrAnnotationContainer.isJsNativeGetter(): Boolean = hasAnnotation(JsAnnotations.jsNativeGetter)
|
fun IrAnnotationContainer.isJsNativeGetter(): Boolean = hasAnnotation(JsAnnotations.jsNativeGetter)
|
||||||
|
|
||||||
fun IrAnnotationContainer.isJsNativeSetter(): Boolean = hasAnnotation(JsAnnotations.jsNativeSetter)
|
fun IrAnnotationContainer.isJsNativeSetter(): Boolean = hasAnnotation(JsAnnotations.jsNativeSetter)
|
||||||
|
|||||||
+11
-3
@@ -23,9 +23,17 @@ class ProcessOptionalAnnotations(private val context: JvmBackendContext) : FileL
|
|||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
for (declaration in irFile.declarations) {
|
for (declaration in irFile.declarations) {
|
||||||
if (declaration !is IrClass || !declaration.isOptionalAnnotationClass) continue
|
if (declaration !is IrClass || !declaration.isOptionalAnnotationClass) continue
|
||||||
// TODO FirMetadataSource.Class
|
declaration.registerOptionalAnnotations()
|
||||||
val metadataSource = (declaration.metadata as? DescriptorMetadataSource.Class)?.descriptor ?: continue
|
}
|
||||||
context.state.factory.packagePartRegistry.optionalAnnotations += metadataSource
|
}
|
||||||
|
|
||||||
|
private fun IrClass.registerOptionalAnnotations() {
|
||||||
|
// TODO FirMetadataSource.Class
|
||||||
|
val metadataSource = (metadata as? DescriptorMetadataSource.Class)?.descriptor ?: return
|
||||||
|
context.state.factory.packagePartRegistry.optionalAnnotations += metadataSource
|
||||||
|
|
||||||
|
declarations.forEach {
|
||||||
|
if (it is IrClass && it.isOptionalAnnotationClass) it.registerOptionalAnnotations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.impl.IrClassPublicSymbolImpl
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -89,12 +90,18 @@ val IrClass.packageFqName: FqName?
|
|||||||
get() = symbol.signature?.packageFqName() ?: parent.getPackageFragment()?.fqName
|
get() = symbol.signature?.packageFqName() ?: parent.getPackageFragment()?.fqName
|
||||||
|
|
||||||
fun IrDeclarationWithName.hasEqualFqName(fqName: FqName): Boolean =
|
fun IrDeclarationWithName.hasEqualFqName(fqName: FqName): Boolean =
|
||||||
name == fqName.shortName() && when (val parent = parent) {
|
symbol.hasEqualFqName(fqName) || name == fqName.shortName() && when (val parent = parent) {
|
||||||
is IrPackageFragment -> parent.fqName == fqName.parent()
|
is IrPackageFragment -> parent.fqName == fqName.parent()
|
||||||
is IrDeclarationWithName -> parent.hasEqualFqName(fqName.parent())
|
is IrDeclarationWithName -> parent.hasEqualFqName(fqName.parent())
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrSymbol.hasEqualFqName(fqName: FqName): Boolean {
|
||||||
|
return this is IrClassPublicSymbolImpl && with(signature as? IdSignature.CommonSignature ?: return false) {
|
||||||
|
FqName("$packageFqName.$declarationFqName") == fqName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun List<IrConstructorCall>.hasAnnotation(fqName: FqName): Boolean =
|
fun List<IrConstructorCall>.hasAnnotation(fqName: FqName): Boolean =
|
||||||
any { it.annotationClass.hasEqualFqName(fqName) }
|
any { it.annotationClass.hasEqualFqName(fqName) }
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ package a
|
|||||||
expect annotation class A(val x: Int)
|
expect annotation class A(val x: Int)
|
||||||
|
|
||||||
@OptionalExpectation
|
@OptionalExpectation
|
||||||
expect annotation class B(val s: String)
|
expect annotation class B(val s: String) {
|
||||||
|
@OptionalExpectation
|
||||||
|
annotation class C(val a: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
// FILE: actual.kt
|
// FILE: actual.kt
|
||||||
|
|
||||||
@@ -33,6 +36,7 @@ import a.B
|
|||||||
|
|
||||||
@A(42)
|
@A(42)
|
||||||
@B("OK")
|
@B("OK")
|
||||||
|
@B.C(true)
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ annotation class InOtherAnnotation(val a: A)
|
|||||||
fun useInOtherAnnotation() {}
|
fun useInOtherAnnotation() {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
expect class C {
|
expect class C {
|
||||||
@OptionalExpectation
|
@OptionalExpectation
|
||||||
annotation class Nested
|
annotation class Nested
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ 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
|
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
|
||||||
@InOtherAnnotation(A())
|
@InOtherAnnotation(A())
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:25:5: error: '@OptionalExpectation' cannot be used on a nested class
|
|
||||||
@OptionalExpectation
|
|
||||||
^
|
|
||||||
|
|
||||||
-- JVM --
|
-- JVM --
|
||||||
Exit code: COMPILATION_ERROR
|
Exit code: COMPILATION_ERROR
|
||||||
@@ -41,9 +38,6 @@ 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
|
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:19:20: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
|
||||||
@InOtherAnnotation(A())
|
@InOtherAnnotation(A())
|
||||||
^
|
^
|
||||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:25:5: error: '@OptionalExpectation' cannot be used on a nested class
|
|
||||||
@OptionalExpectation
|
|
||||||
^
|
|
||||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/jvm.kt:1:24: error: declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry
|
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
|
fun useInReturnType(): A? = null
|
||||||
^
|
^
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.resolve
|
package org.jetbrains.kotlin.js.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.container.StorageComponentContainer
|
import org.jetbrains.kotlin.container.StorageComponentContainer
|
||||||
import org.jetbrains.kotlin.container.useImpl
|
import org.jetbrains.kotlin.container.useImpl
|
||||||
import org.jetbrains.kotlin.container.useInstance
|
import org.jetbrains.kotlin.container.useInstance
|
||||||
@@ -25,7 +24,7 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
JsRuntimeAnnotationChecker,
|
JsRuntimeAnnotationChecker,
|
||||||
JsDynamicDeclarationChecker,
|
JsDynamicDeclarationChecker,
|
||||||
JsExportAnnotationChecker,
|
JsExportAnnotationChecker,
|
||||||
JsExportDeclarationChecker,
|
JsExportDeclarationChecker
|
||||||
),
|
),
|
||||||
additionalCallCheckers = listOf(
|
additionalCallCheckers = listOf(
|
||||||
JsModuleCallChecker,
|
JsModuleCallChecker,
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ public interface ErrorsJs {
|
|||||||
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
DiagnosticFactory0<PsiElement> NESTED_JS_EXPORT = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> NESTED_JS_EXPORT = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory1<KtExpression, String> WRONG_EXPORTED_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory1<KtExpression, String> WRONG_EXPORTED_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
DiagnosticFactory2<PsiElement, String, KotlinType> NON_EXPORTABLE_TYPE = DiagnosticFactory2.create(WARNING, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory2<PsiElement, String, KotlinType> NON_EXPORTABLE_TYPE = DiagnosticFactory2.create(WARNING, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.js.PredefinedAnnotation;
|
import org.jetbrains.kotlin.js.PredefinedAnnotation;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||||
@@ -41,6 +42,7 @@ import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.isEf
|
|||||||
public final class AnnotationsUtils {
|
public final class AnnotationsUtils {
|
||||||
public static final FqName JS_NAME = new FqName("kotlin.js.JsName");
|
public static final FqName JS_NAME = new FqName("kotlin.js.JsName");
|
||||||
private static final FqName JS_EXPORT = new FqName("kotlin.js.JsExport");
|
private static final FqName JS_EXPORT = new FqName("kotlin.js.JsExport");
|
||||||
|
private static final FqName JS_EXPORT_IGNORE = new FqName("kotlin.js.JsExport.Ignore");
|
||||||
public static final FqName JS_MODULE_ANNOTATION = new FqName("kotlin.js.JsModule");
|
public static final FqName JS_MODULE_ANNOTATION = new FqName("kotlin.js.JsModule");
|
||||||
private static final FqName JS_NON_MODULE_ANNOTATION = new FqName("kotlin.js.JsNonModule");
|
private static final FqName JS_NON_MODULE_ANNOTATION = new FqName("kotlin.js.JsNonModule");
|
||||||
public static final FqName JS_QUALIFIER_ANNOTATION = new FqName("kotlin.js.JsQualifier");
|
public static final FqName JS_QUALIFIER_ANNOTATION = new FqName("kotlin.js.JsQualifier");
|
||||||
@@ -122,6 +124,7 @@ public final class AnnotationsUtils {
|
|||||||
if (memberDescriptor.getVisibility() != DescriptorVisibilities.PUBLIC) return false;
|
if (memberDescriptor.getVisibility() != DescriptorVisibilities.PUBLIC) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasAnnotationOrInsideAnnotatedClass(descriptor, JS_EXPORT_IGNORE)) return false;
|
||||||
if (hasAnnotationOrInsideAnnotatedClass(descriptor, JS_EXPORT)) return true;
|
if (hasAnnotationOrInsideAnnotatedClass(descriptor, JS_EXPORT)) return true;
|
||||||
|
|
||||||
if (CollectionsKt.any(getContainingFileAnnotations(bindingContext, descriptor), annotation ->
|
if (CollectionsKt.any(getContainingFileAnnotations(bindingContext, descriptor), annotation ->
|
||||||
|
|||||||
@@ -156,7 +156,6 @@ val unzipJsShell by task<Copy> {
|
|||||||
val testDataDir = project(":js:js.translator").projectDir.resolve("testData")
|
val testDataDir = project(":js:js.translator").projectDir.resolve("testData")
|
||||||
val typescriptTestsDir = testDataDir.resolve("typescript-export")
|
val typescriptTestsDir = testDataDir.resolve("typescript-export")
|
||||||
|
|
||||||
|
|
||||||
val installTsDependencies = task<NpmTask>("installTsDependencies") {
|
val installTsDependencies = task<NpmTask>("installTsDependencies") {
|
||||||
workingDir.set(testDataDir)
|
workingDir.set(testDataDir)
|
||||||
args.set(listOf("install"))
|
args.set(listOf("install"))
|
||||||
|
|||||||
@@ -2118,6 +2118,24 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/export/defaultInlineClassConstructorParamInExportedFile.kt");
|
runTest("js/js.translator/testData/box/export/defaultInlineClassConstructorParamInExportedFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeMembersFromExport.kt")
|
||||||
|
public void testExcludeMembersFromExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeMembersFromExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeTopLevelFromExport.kt")
|
||||||
|
public void testExcludeTopLevelFromExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeTopLevelFromExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeTopLevelFromExportWithoutFileJsExport.kt")
|
||||||
|
public void testExcludeTopLevelFromExportWithoutFileJsExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeTopLevelFromExportWithoutFileJsExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("exportAllFile.kt")
|
@TestMetadata("exportAllFile.kt")
|
||||||
public void testExportAllFile() throws Exception {
|
public void testExportAllFile() throws Exception {
|
||||||
|
|||||||
+18
@@ -2590,6 +2590,24 @@ public class FirJsTestGenerated extends AbstractFirJsTest {
|
|||||||
runTest("js/js.translator/testData/box/export/defaultInlineClassConstructorParamInExportedFile.kt");
|
runTest("js/js.translator/testData/box/export/defaultInlineClassConstructorParamInExportedFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeMembersFromExport.kt")
|
||||||
|
public void testExcludeMembersFromExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeMembersFromExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeTopLevelFromExport.kt")
|
||||||
|
public void testExcludeTopLevelFromExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeTopLevelFromExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeTopLevelFromExportWithoutFileJsExport.kt")
|
||||||
|
public void testExcludeTopLevelFromExportWithoutFileJsExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeTopLevelFromExportWithoutFileJsExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("exportAllFile.kt")
|
@TestMetadata("exportAllFile.kt")
|
||||||
public void testExportAllFile() throws Exception {
|
public void testExportAllFile() throws Exception {
|
||||||
|
|||||||
+18
@@ -2590,6 +2590,24 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/export/defaultInlineClassConstructorParamInExportedFile.kt");
|
runTest("js/js.translator/testData/box/export/defaultInlineClassConstructorParamInExportedFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeMembersFromExport.kt")
|
||||||
|
public void testExcludeMembersFromExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeMembersFromExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeTopLevelFromExport.kt")
|
||||||
|
public void testExcludeTopLevelFromExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeTopLevelFromExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excludeTopLevelFromExportWithoutFileJsExport.kt")
|
||||||
|
public void testExcludeTopLevelFromExportWithoutFileJsExport() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/export/excludeTopLevelFromExportWithoutFileJsExport.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("exportAllFile.kt")
|
@TestMetadata("exportAllFile.kt")
|
||||||
public void testExportAllFile() throws Exception {
|
public void testExportAllFile() throws Exception {
|
||||||
|
|||||||
Generated
+64
@@ -185,6 +185,38 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/excluded-exported-declarations")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Excluded_exported_declarations {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExcluded_exported_declarations() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/excluded-exported-declarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excluded-exported-declarations.kt")
|
||||||
|
public void testExcluded_exported_declarations() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/excluded-exported-declarations/excluded-exported-declarations.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/excluded-exported-declarations-in-exported-file")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Excluded_exported_declarations_in_exported_file {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInExcluded_exported_declarations_in_exported_file() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/excluded-exported-declarations-in-exported-file"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("excluded-exported-declarations.kt")
|
||||||
|
public void testExcluded_exported_declarations() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/excluded-exported-declarations-in-exported-file/excluded-exported-declarations.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/functions")
|
@TestMetadata("js/js.translator/testData/typescript-export/functions")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@@ -497,6 +529,38 @@ public class IrJsTypeScriptExportTestGenerated extends AbstractIrJsTypeScriptExp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/not-exported-declarations")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Not_exported_declarations {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInNot_exported_declarations() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/not-exported-declarations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("not-exported-declarations.kt")
|
||||||
|
public void testNot_exported_declarations() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/not-exported-declarations/not-exported-declarations.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("js/js.translator/testData/typescript-export/not-exported-declarations-in-exported-file")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class Not_exported_declarations_in_exported_file {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInNot_exported_declarations_in_exported_file() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/typescript-export/not-exported-declarations-in-exported-file"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("not-exported-declarations.kt")
|
||||||
|
public void testNot_exported_declarations() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/typescript-export/not-exported-declarations-in-exported-file/not-exported-declarations.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("js/js.translator/testData/typescript-export/objects")
|
@TestMetadata("js/js.translator/testData/typescript-export/objects")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
@JsExport
|
||||||
|
class Bar(val value: String) {
|
||||||
|
@JsExport.Ignore
|
||||||
|
constructor(): this("SECONDARY")
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val excludedValue: Int = 42
|
||||||
|
|
||||||
|
fun foo(): String = "FOO"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun excludedFun(): String = "EXCLUDED_FUN"
|
||||||
|
|
||||||
|
class Nested
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
class ExcludedNested {
|
||||||
|
fun doSomething(): String = "SOMETHING"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun baz(): String = "BAZ"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun excludedFun(): String = "STATIC EXCLUDED_FUN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.js
|
||||||
|
function box() {
|
||||||
|
var Bar = this.lib.Bar;
|
||||||
|
var bar = new Bar("TEST");
|
||||||
|
|
||||||
|
if (bar.value !== "TEST") return "Error: exported property was not exported"
|
||||||
|
if (bar.excludedValue === 42) return "Error: not exported property was exported"
|
||||||
|
|
||||||
|
if (bar.foo() !== "FOO") return "Error: exported function was not exported"
|
||||||
|
if (typeof bar.excludedFun === "function") return "Error: not exported function was exported"
|
||||||
|
|
||||||
|
if (typeof Bar.Nested !== "function") return "Error: exported nested class was not exported"
|
||||||
|
if (typeof Bar.ExcludedNested === "function") return "Error: not exported nested class was exported"
|
||||||
|
|
||||||
|
if (Bar.Companion.baz() !== "BAZ") return "Error: exported companion function was not exported"
|
||||||
|
if (typeof Bar.Companion.excludedFun === "function") return "Error: not exported companion function was exported"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
@file:JsExport
|
||||||
|
|
||||||
|
val value: String = "TEST"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val excludedValue: Int = 42
|
||||||
|
|
||||||
|
fun foo(): String = "FOO"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun excludedFun(): String = "EXCLUDED_FUN"
|
||||||
|
|
||||||
|
class SomeClass
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
class ExcludedSomeClass {
|
||||||
|
fun doSomething(): String = "SOMETHING"
|
||||||
|
}
|
||||||
|
|
||||||
|
object Companion {
|
||||||
|
fun baz(): String = "BAZ"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun excludedFun(): String = "STATIC EXCLUDED_FUN"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.js
|
||||||
|
function box() {
|
||||||
|
var lib = this.lib;
|
||||||
|
|
||||||
|
if (lib.value !== "TEST") return "Error: exported property was not exported"
|
||||||
|
if (lib.excludedValue === 42) return "Error: not exported property was exported"
|
||||||
|
|
||||||
|
if (lib.foo() !== "FOO") return "Error: exported function was not exported"
|
||||||
|
if (typeof lib.excludedFun === "function") return "Error: not exported function was exported"
|
||||||
|
|
||||||
|
if (typeof lib.SomeClass !== "function") return "Error: exported nested class was not exported"
|
||||||
|
if (typeof lib.ExcludedSomeClass === "function") return "Error: not exported nested class was exported"
|
||||||
|
|
||||||
|
if (lib.Companion.baz() !== "BAZ") return "Error: exported companion function was not exported"
|
||||||
|
if (typeof lib.Companion.excludedFun === "function") return "Error: not exported companion function was exported"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
val value: String = "TEST"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
val excludedValue: Int = 42
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
fun foo(): String = "FOO"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun excludedFun(): String = "EXCLUDED_FUN"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
class SomeClass
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
@JsExport
|
||||||
|
class ExcludedSomeClass {
|
||||||
|
fun doSomething(): String = "SOMETHING"
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
object Companion {
|
||||||
|
fun baz(): String = "BAZ"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun excludedFun(): String = "STATIC EXCLUDED_FUN"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.js
|
||||||
|
function box() {
|
||||||
|
var lib = this.lib;
|
||||||
|
|
||||||
|
if (lib.value !== "TEST") return "Error: exported property was not exported"
|
||||||
|
if (lib.excludedValue === 42) return "Error: not exported property was exported"
|
||||||
|
|
||||||
|
if (lib.foo() !== "FOO") return "Error: exported function was not exported"
|
||||||
|
if (typeof lib.excludedFun === "function") return "Error: not exported function was exported"
|
||||||
|
|
||||||
|
if (typeof lib.SomeClass !== "function") return "Error: exported nested class was not exported"
|
||||||
|
if (typeof lib.ExcludedSomeClass === "function") return "Error: not exported nested class was exported"
|
||||||
|
|
||||||
|
if (lib.Companion.baz() !== "BAZ") return "Error: exported companion function was not exported"
|
||||||
|
if (typeof lib.Companion.excludedFun === "function") return "Error: not exported companion function was exported"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
declare namespace JS_TESTS {
|
||||||
|
type Nullable<T> = T | null | undefined
|
||||||
|
namespace foo {
|
||||||
|
const foo: string;
|
||||||
|
function bar(): string;
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/** This file is generated by {@link :js:js.test:generateJsExportOnFileTestFilesForTS} task. DO NOT MODIFY MANUALLY */
|
||||||
|
|
||||||
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// MODULE: JS_TESTS
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: declarations.kt
|
||||||
|
|
||||||
|
@file:JsExport
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val baz: String = "Baz"
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun inter(): String = "inter"
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
class NotExportableNestedInsideInterface
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
|
||||||
|
object Comanion {
|
||||||
|
val foo: String ="FOO"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val foo: String = "Foo"
|
||||||
|
|
||||||
|
|
||||||
|
fun bar() = "Bar"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
|
||||||
|
inline fun <A, reified B> A.notExportableReified(): Boolean = this is B
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
|
||||||
|
suspend fun notExportableSuspend(): String = "SuspendResult"
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun notExportableReturn(): List<String> = listOf("1", "2")
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val String.notExportableExentsionProperty: String
|
||||||
|
get() = "notExportableExentsionProperty"
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
annotation class NotExportableAnnotation
|
||||||
|
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
value class NotExportableInlineClass(val value: Int)
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
"use strict";
|
||||||
|
var foo = JS_TESTS.foo;
|
||||||
|
function assert(condition, message) {
|
||||||
|
if (message === void 0) { message = "Assertion failed"; }
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function box() {
|
||||||
|
assert(foo.foo === "Foo", "Error in property 'foo'");
|
||||||
|
assert(foo.bar() === "Bar", "Error in property 'bar'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.baz === undefined, "Error in property 'baz'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.inter === undefined, "Error in method 'inter'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableNestedInsideInterface === undefined, "Error in class 'NotExportableNestedInsideInterface'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.Companion === undefined, "Error in object 'Companion'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReified === undefined, "Error in method 'notExportableReified'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReturn === undefined, "Error in method 'notExportableReturn'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'");
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
import foo = JS_TESTS.foo;
|
||||||
|
|
||||||
|
|
||||||
|
function assert(condition: boolean, message: string = "Assertion failed") {
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function box(): string {
|
||||||
|
assert(foo.foo === "Foo", "Error in property 'foo'")
|
||||||
|
assert(foo.bar() === "Bar", "Error in property 'bar'")
|
||||||
|
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.baz === undefined, "Error in property 'baz'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.inter === undefined, "Error in method 'inter'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableNestedInsideInterface === undefined, "Error in class 'NotExportableNestedInsideInterface'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.Companion === undefined, "Error in object 'Companion'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReified === undefined, "Error in method 'notExportableReified'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReturn === undefined, "Error in method 'notExportableReturn'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'")
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"include": [ "./*" ],
|
||||||
|
"extends": "../common.tsconfig.json"
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
declare namespace JS_TESTS {
|
||||||
|
type Nullable<T> = T | null | undefined
|
||||||
|
namespace foo {
|
||||||
|
const foo: string;
|
||||||
|
function bar(): string;
|
||||||
|
}
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// MODULE: JS_TESTS
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: declarations.kt
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
val baz: String = "Baz"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun inter(): String = "inter"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
class NotExportableNestedInsideInterface
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
@JsExport
|
||||||
|
object Comanion {
|
||||||
|
val foo: String ="FOO"
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
val foo: String = "Foo"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
fun bar() = "Bar"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
@JsExport
|
||||||
|
inline fun <A, reified B> A.notExportableReified(): Boolean = this is B
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
@JsExport
|
||||||
|
suspend fun notExportableSuspend(): String = "SuspendResult"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun notExportableReturn(): List<String> = listOf("1", "2")
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
val String.notExportableExentsionProperty: String
|
||||||
|
get() = "notExportableExentsionProperty"
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
annotation class NotExportableAnnotation
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
@JsExport.Ignore
|
||||||
|
value class NotExportableInlineClass(val value: Int)
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
"use strict";
|
||||||
|
var foo = JS_TESTS.foo;
|
||||||
|
function assert(condition, message) {
|
||||||
|
if (message === void 0) { message = "Assertion failed"; }
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function box() {
|
||||||
|
assert(foo.foo === "Foo", "Error in property 'foo'");
|
||||||
|
assert(foo.bar() === "Bar", "Error in property 'bar'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.baz === undefined, "Error in property 'baz'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.inter === undefined, "Error in method 'inter'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableNestedInsideInterface === undefined, "Error in class 'NotExportableNestedInsideInterface'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.Companion === undefined, "Error in object 'Companion'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReified === undefined, "Error in method 'notExportableReified'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReturn === undefined, "Error in method 'notExportableReturn'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'");
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
import foo = JS_TESTS.foo;
|
||||||
|
|
||||||
|
|
||||||
|
function assert(condition: boolean, message: string = "Assertion failed") {
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function box(): string {
|
||||||
|
assert(foo.foo === "Foo", "Error in property 'foo'")
|
||||||
|
assert(foo.bar() === "Bar", "Error in property 'bar'")
|
||||||
|
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.baz === undefined, "Error in property 'baz'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.inter === undefined, "Error in method 'inter'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableNestedInsideInterface === undefined, "Error in class 'NotExportableNestedInsideInterface'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.Companion === undefined, "Error in object 'Companion'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReified === undefined, "Error in method 'notExportableReified'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableReturn === undefined, "Error in method 'notExportableReturn'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(foo.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'")
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"include": [ "./*" ],
|
||||||
|
"extends": "../common.tsconfig.json"
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
declare namespace JS_TESTS {
|
||||||
|
type Nullable<T> = T | null | undefined
|
||||||
|
namespace foo {
|
||||||
|
interface ExportedInterface {
|
||||||
|
readonly __doNotUseOrImplementIt: {
|
||||||
|
readonly "foo.ExportedInterface": unique symbol;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
class OnlyFooParamExported implements foo.ExportedInterface {
|
||||||
|
constructor(foo: string);
|
||||||
|
get foo(): string;
|
||||||
|
readonly __doNotUseOrImplementIt: foo.ExportedInterface["__doNotUseOrImplementIt"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/** This file is generated by {@link :js:js.test:generateJsExportOnFileTestFilesForTS} task. DO NOT MODIFY MANUALLY */
|
||||||
|
|
||||||
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// MODULE: JS_TESTS
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: declarations.kt
|
||||||
|
|
||||||
|
@file:JsExport
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
|
||||||
|
interface ExportedInterface {
|
||||||
|
@JsExport.Ignore
|
||||||
|
val baz: String
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun inter(): String
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
class NotExportableNestedInsideInterface
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
companion object {
|
||||||
|
val foo: String ="FOO"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class OnlyFooParamExported(val foo: String) : ExportedInterface {
|
||||||
|
@JsExport.Ignore
|
||||||
|
constructor() : this("TEST")
|
||||||
|
|
||||||
|
override val baz = "Baz"
|
||||||
|
|
||||||
|
override fun inter(): String = "Inter"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val bar = "Bar"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
inline fun <A, reified B> A.notExportableReified(): Boolean = this is B
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
suspend fun notExportableSuspend(): String = "SuspendResult"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun notExportableReturn(): List<String> = listOf("1", "2")
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val String.notExportableExentsionProperty: String
|
||||||
|
get() = "notExportableExentsionProperty"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
annotation class NotExportableAnnotation
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
value class NotExportableInlineClass(val value: Int)
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
var OnlyFooParamExported = JS_TESTS.foo.OnlyFooParamExported;
|
||||||
|
function assert(condition, message) {
|
||||||
|
if (message === void 0) { message = "Assertion failed"; }
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function box() {
|
||||||
|
var onlyFooParamExported = new OnlyFooParamExported("TEST");
|
||||||
|
assert(OnlyFooParamExported.length === 1, "Error in constructor'");
|
||||||
|
assert(onlyFooParamExported.foo === "TEST", "Error in property 'foo'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.bar === undefined, "Error in property 'bar'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.baz === undefined, "Error in property 'baz'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.inter === undefined, "Error in method 'inter'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReified === undefined, "Error in method 'notExportableReified'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReturn === undefined, "Error in method 'notExportableReturn'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'");
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
import OnlyFooParamExported = JS_TESTS.foo.OnlyFooParamExported;
|
||||||
|
|
||||||
|
|
||||||
|
function assert(condition: boolean, message: string = "Assertion failed") {
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function box(): string {
|
||||||
|
const onlyFooParamExported = new OnlyFooParamExported("TEST")
|
||||||
|
assert(OnlyFooParamExported.length === 1, "Error in constructor'")
|
||||||
|
assert(onlyFooParamExported.foo === "TEST", "Error in property 'foo'")
|
||||||
|
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.bar === undefined, "Error in property 'bar'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.baz === undefined, "Error in property 'baz'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.inter === undefined, "Error in method 'inter'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReified === undefined, "Error in method 'notExportableReified'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReturn === undefined, "Error in method 'notExportableReturn'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'")
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
js/js.translator/testData/typescript-export/not-exported-declarations-in-exported-file/tsconfig.json
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"include": [ "./*" ],
|
||||||
|
"extends": "../common.tsconfig.json"
|
||||||
|
}
|
||||||
js/js.translator/testData/typescript-export/not-exported-declarations/not-exported-declarations.d.ts
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
declare namespace JS_TESTS {
|
||||||
|
type Nullable<T> = T | null | undefined
|
||||||
|
namespace foo {
|
||||||
|
interface ExportedInterface {
|
||||||
|
readonly __doNotUseOrImplementIt: {
|
||||||
|
readonly "foo.ExportedInterface": unique symbol;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
class OnlyFooParamExported implements foo.ExportedInterface {
|
||||||
|
constructor(foo: string);
|
||||||
|
get foo(): string;
|
||||||
|
readonly __doNotUseOrImplementIt: foo.ExportedInterface["__doNotUseOrImplementIt"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// CHECK_TYPESCRIPT_DECLARATIONS
|
||||||
|
// RUN_PLAIN_BOX_FUNCTION
|
||||||
|
// SKIP_MINIFICATION
|
||||||
|
// SKIP_NODE_JS
|
||||||
|
// INFER_MAIN_MODULE
|
||||||
|
// MODULE: JS_TESTS
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FILE: declarations.kt
|
||||||
|
|
||||||
|
package foo
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
interface ExportedInterface {
|
||||||
|
@JsExport.Ignore
|
||||||
|
val baz: String
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun inter(): String
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
class NotExportableNestedInsideInterface
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
companion object {
|
||||||
|
val foo: String ="FOO"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsExport
|
||||||
|
class OnlyFooParamExported(val foo: String) : ExportedInterface {
|
||||||
|
@JsExport.Ignore
|
||||||
|
constructor() : this("TEST")
|
||||||
|
|
||||||
|
override val baz = "Baz"
|
||||||
|
|
||||||
|
override fun inter(): String = "Inter"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val bar = "Bar"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
inline fun <A, reified B> A.notExportableReified(): Boolean = this is B
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
suspend fun notExportableSuspend(): String = "SuspendResult"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
fun notExportableReturn(): List<String> = listOf("1", "2")
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
val String.notExportableExentsionProperty: String
|
||||||
|
get() = "notExportableExentsionProperty"
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
annotation class NotExportableAnnotation
|
||||||
|
|
||||||
|
@JsExport.Ignore
|
||||||
|
value class NotExportableInlineClass(val value: Int)
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
var OnlyFooParamExported = JS_TESTS.foo.OnlyFooParamExported;
|
||||||
|
function assert(condition, message) {
|
||||||
|
if (message === void 0) { message = "Assertion failed"; }
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function box() {
|
||||||
|
var onlyFooParamExported = new OnlyFooParamExported("TEST");
|
||||||
|
assert(OnlyFooParamExported.length === 1, "Error in constructor'");
|
||||||
|
assert(onlyFooParamExported.foo === "TEST", "Error in property 'foo'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.bar === undefined, "Error in property 'bar'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.baz === undefined, "Error in property 'baz'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.inter === undefined, "Error in method 'inter'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReified === undefined, "Error in method 'notExportableReified'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReturn === undefined, "Error in method 'notExportableReturn'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'");
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'");
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
import OnlyFooParamExported = JS_TESTS.foo.OnlyFooParamExported;
|
||||||
|
|
||||||
|
|
||||||
|
function assert(condition: boolean, message: string = "Assertion failed") {
|
||||||
|
if (!condition) {
|
||||||
|
throw message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function box(): string {
|
||||||
|
const onlyFooParamExported = new OnlyFooParamExported("TEST")
|
||||||
|
assert(OnlyFooParamExported.length === 1, "Error in constructor'")
|
||||||
|
assert(onlyFooParamExported.foo === "TEST", "Error in property 'foo'")
|
||||||
|
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.bar === undefined, "Error in property 'bar'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.baz === undefined, "Error in property 'baz'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.inter === undefined, "Error in method 'inter'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReified === undefined, "Error in method 'notExportableReified'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableSuspend === undefined, "Error in method 'notExportableSuspend'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableReturn === undefined, "Error in method 'notExportableReturn'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(onlyFooParamExported.notExportableExentsionProperty === undefined, "Error in method 'notExportableExentsionProperty'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableAnnotation === undefined, "Error in nested class 'NotExportableAnnotation'")
|
||||||
|
// @ts-expect-error "the param should not be exported either in TS, or in JS"
|
||||||
|
assert(OnlyFooParamExported.NotExportableInlineClass === undefined, "Error in nested class 'NotExportableInlineClass'")
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"include": [ "./*" ],
|
||||||
|
"extends": "../common.tsconfig.json"
|
||||||
|
}
|
||||||
@@ -240,6 +240,14 @@ public external interface JsClass<T : kotlin.Any> {
|
|||||||
@kotlin.SinceKotlin(version = "1.3")
|
@kotlin.SinceKotlin(version = "1.3")
|
||||||
public final annotation class JsExport : kotlin.Annotation {
|
public final annotation class JsExport : kotlin.Annotation {
|
||||||
public constructor JsExport()
|
public constructor JsExport()
|
||||||
|
|
||||||
|
@kotlin.js.ExperimentalJsExport
|
||||||
|
@kotlin.annotation.Retention(value = AnnotationRetention.BINARY)
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR})
|
||||||
|
@kotlin.SinceKotlin(version = "1.8")
|
||||||
|
public final annotation class Ignore : kotlin.Annotation {
|
||||||
|
public constructor Ignore()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.annotation.Retention(value = AnnotationRetention.BINARY)
|
@kotlin.annotation.Retention(value = AnnotationRetention.BINARY)
|
||||||
|
|||||||
@@ -239,6 +239,14 @@ public external interface JsClass<T : kotlin.Any> {
|
|||||||
@kotlin.SinceKotlin(version = "1.3")
|
@kotlin.SinceKotlin(version = "1.3")
|
||||||
public final annotation class JsExport : kotlin.Annotation {
|
public final annotation class JsExport : kotlin.Annotation {
|
||||||
public constructor JsExport()
|
public constructor JsExport()
|
||||||
|
|
||||||
|
@kotlin.js.ExperimentalJsExport
|
||||||
|
@kotlin.annotation.Retention(value = AnnotationRetention.BINARY)
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR})
|
||||||
|
@kotlin.SinceKotlin(version = "1.8")
|
||||||
|
public final annotation class Ignore : kotlin.Annotation {
|
||||||
|
public constructor Ignore()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.annotation.Retention(value = AnnotationRetention.BINARY)
|
@kotlin.annotation.Retention(value = AnnotationRetention.BINARY)
|
||||||
|
|||||||
@@ -63,4 +63,18 @@ public annotation class ExperimentalJsExport
|
|||||||
@Target(CLASS, PROPERTY, FUNCTION, FILE)
|
@Target(CLASS, PROPERTY, FUNCTION, FILE)
|
||||||
@SinceKotlin("1.4")
|
@SinceKotlin("1.4")
|
||||||
@OptionalExpectation
|
@OptionalExpectation
|
||||||
public expect annotation class JsExport()
|
public expect annotation class JsExport() {
|
||||||
|
/*
|
||||||
|
* The annotation prevents exporting the annotated member of an exported class.
|
||||||
|
* This annotation is experimental, meaning that the restrictions mentioned above are subject to change.
|
||||||
|
*/
|
||||||
|
@ExperimentalJsExport
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@Target(CLASS, PROPERTY, FUNCTION)
|
||||||
|
@SinceKotlin("1.8")
|
||||||
|
// Suppress until bootstrapping
|
||||||
|
@Suppress("NESTED_OPTIONAL_EXPECTATION")
|
||||||
|
@OptionalExpectation
|
||||||
|
public annotation class Ignore()
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,18 @@ public annotation class JsQualifier(val value: String)
|
|||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
@Target(CLASS, PROPERTY, FUNCTION, FILE)
|
@Target(CLASS, PROPERTY, FUNCTION, FILE)
|
||||||
@SinceKotlin("1.3")
|
@SinceKotlin("1.3")
|
||||||
public actual annotation class JsExport
|
public actual annotation class JsExport {
|
||||||
|
/*
|
||||||
|
* The annotation prevents exporting the annotated member of an exported class.
|
||||||
|
* This annotation is experimental, meaning that the restrictions mentioned above are subject to change.
|
||||||
|
*/
|
||||||
|
@ExperimentalJsExport
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@Target(CLASS, PROPERTY, FUNCTION, CONSTRUCTOR)
|
||||||
|
@SinceKotlin("1.8")
|
||||||
|
public actual annotation class Ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces a top-level property to be initialized eagerly, opposed to lazily on the first access to file and/or property.
|
* Forces a top-level property to be initialized eagerly, opposed to lazily on the first access to file and/or property.
|
||||||
|
|||||||
@@ -13,7 +13,17 @@ package kotlin.js
|
|||||||
@ExperimentalJsExport
|
@ExperimentalJsExport
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
@Target(AnnotationTarget.FUNCTION)
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
public actual annotation class JsExport
|
public actual annotation class JsExport {
|
||||||
|
@ExperimentalJsExport
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
@Target(
|
||||||
|
AnnotationTarget.CLASS,
|
||||||
|
AnnotationTarget.FUNCTION,
|
||||||
|
AnnotationTarget.PROPERTY,
|
||||||
|
AnnotationTarget.CONSTRUCTOR,
|
||||||
|
)
|
||||||
|
public actual annotation class Ignore
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies JavaScript name for external and imported declarations
|
* Specifies JavaScript name for external and imported declarations
|
||||||
|
|||||||
Reference in New Issue
Block a user