From 8d3f6f1ce72981c021c8e1de1e162b53a06edd1d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 21 Nov 2016 11:29:02 +0300 Subject: [PATCH] Check platform<->impl declaration compatibility For each platform declaration, there must be at least one impl declaration in the module with the compatible signature; similarly, for each impl declaration, there must be at least one platform declaration with the compatible signature. Note that currently the presence of the 'impl' modifier is not checked yet. Also, the sad fact is that if you have platform and impl declarations which are not compatible, you get two errors: on the platform delcaration and on the impl declaration. This needs to be addressed as well --- .../jvm/platform/JvmPlatformConfigurator.kt | 4 +- .../jetbrains/kotlin/diagnostics/Errors.java | 7 + .../rendering/DefaultErrorMessages.java | 3 + ...atformIncompatibilityDiagnosticRenderer.kt | 45 +++ .../PlatformImplDeclarationChecker.kt | 315 ++++++++++++++++++ .../genericClassImplTypeAlias.kt | 1 + .../genericDeclarations/common.kt | 13 + .../multiplatform/genericDeclarations/jvm.kt | 15 + .../genericDeclarations/output.txt | 8 + .../implementClassWithTypeAlias/common.kt | 3 + .../implementClassWithTypeAlias/jvm.kt | 4 + .../implementClassWithTypeAlias/output.txt | 11 + .../incompatibleCallables/common.kt | 36 ++ .../incompatibleCallables/jvm.kt | 36 ++ .../incompatibleCallables/output.txt | 206 ++++++++++++ .../incompatibleClasses/common.kt | 25 ++ .../multiplatform/incompatibleClasses/jvm.kt | 25 ++ .../incompatibleClasses/output.txt | 143 ++++++++ .../incompatibleFunctions/common.kt | 14 + .../incompatibleFunctions/jvm.kt | 14 + .../incompatibleFunctions/output.txt | 101 ++++++ .../incompatibleProperties/common.kt | 2 + .../incompatibleProperties/jvm.kt | 2 + .../incompatibleProperties/output.txt | 26 ++ .../jetbrains/kotlin/tests/di/injection.kt | 2 - ...> AbstractMultiPlatformIntegrationTest.kt} | 48 +-- ...MultiPlatformIntegrationTestGenerated.java | 121 +++++++ .../kotlin/generators/tests/GenerateTests.kt | 10 +- .../js/resolve/JsPlatformConfigurator.kt | 16 +- 29 files changed, 1217 insertions(+), 39 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/PlatformIncompatibilityDiagnosticRenderer.kt create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformImplDeclarationChecker.kt create mode 100644 compiler/testData/multiplatform/genericDeclarations/common.kt create mode 100644 compiler/testData/multiplatform/genericDeclarations/jvm.kt create mode 100644 compiler/testData/multiplatform/genericDeclarations/output.txt create mode 100644 compiler/testData/multiplatform/implementClassWithTypeAlias/common.kt create mode 100644 compiler/testData/multiplatform/implementClassWithTypeAlias/jvm.kt create mode 100644 compiler/testData/multiplatform/implementClassWithTypeAlias/output.txt create mode 100644 compiler/testData/multiplatform/incompatibleCallables/common.kt create mode 100644 compiler/testData/multiplatform/incompatibleCallables/jvm.kt create mode 100644 compiler/testData/multiplatform/incompatibleCallables/output.txt create mode 100644 compiler/testData/multiplatform/incompatibleClasses/common.kt create mode 100644 compiler/testData/multiplatform/incompatibleClasses/jvm.kt create mode 100644 compiler/testData/multiplatform/incompatibleClasses/output.txt create mode 100644 compiler/testData/multiplatform/incompatibleFunctions/common.kt create mode 100644 compiler/testData/multiplatform/incompatibleFunctions/jvm.kt create mode 100644 compiler/testData/multiplatform/incompatibleFunctions/output.txt create mode 100644 compiler/testData/multiplatform/incompatibleProperties/common.kt create mode 100644 compiler/testData/multiplatform/incompatibleProperties/jvm.kt create mode 100644 compiler/testData/multiplatform/incompatibleProperties/output.txt rename compiler/tests/org/jetbrains/kotlin/multiplatform/{MultiPlatformIntegrationTest.kt => AbstractMultiPlatformIntegrationTest.kt} (61%) create mode 100644 compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index 98b7e7f21d7..3873b98b41a 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.container.useImpl import org.jetbrains.kotlin.container.useInstance import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.resolve.PlatformConfigurator +import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker import org.jetbrains.kotlin.resolve.jvm.JvmOverloadFilter import org.jetbrains.kotlin.resolve.jvm.JvmTypeSpecificityComparator import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionsTypeChecker @@ -43,7 +44,8 @@ object JvmPlatformConfigurator : PlatformConfigurator( TypeParameterBoundIsNotArrayChecker(), JvmSyntheticApplicabilityChecker(), StrictfpApplicabilityChecker(), - AdditionalBuiltInsMemberOverrideDeclarationChecker + AdditionalBuiltInsMemberOverrideDeclarationChecker, + PlatformImplDeclarationChecker() ), additionalCallCheckers = listOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 791b1c2c8ec..f54dfc71d2a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -33,12 +33,14 @@ import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData; import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier; +import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker; import org.jetbrains.kotlin.types.KotlinType; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.List; +import java.util.Map; import static org.jetbrains.kotlin.diagnostics.PositioningStrategies.*; import static org.jetbrains.kotlin.diagnostics.Severity.ERROR; @@ -502,6 +504,11 @@ public interface Errors { DiagnosticFactory0 IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory2>> PLATFORM_DECLARATION_WITHOUT_DEFINITION = + DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory0 PLATFORM_DEFINITION_WITHOUT_DECLARATION = DiagnosticFactory0.create(ERROR); + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Errors/warnings inside code blocks diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 0042210e2dc..a6457fe5869 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -268,6 +268,9 @@ public class DefaultErrorMessages { MAP.put(IMPL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of 'impl' type alias cannot contain use-site variance or star projections"); MAP.put(IMPL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of 'impl' type alias should be its type parameters in the same order, e.g. 'impl typealias Foo = Bar'"); + MAP.put(PLATFORM_DECLARATION_WITHOUT_DEFINITION, "No definition is found for platform declaration ''{0}''{1}", NAME, PlatformIncompatibilityDiagnosticRenderer.INSTANCE); + MAP.put(PLATFORM_DEFINITION_WITHOUT_DECLARATION, "Modifier 'impl' is only applicable to members that are initially declared in platform-independent code"); + 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); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/PlatformIncompatibilityDiagnosticRenderer.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/PlatformIncompatibilityDiagnosticRenderer.kt new file mode 100644 index 00000000000..faabc9c6798 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/PlatformIncompatibilityDiagnosticRenderer.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.diagnostics.rendering + +import org.jetbrains.kotlin.descriptors.MemberDescriptor +import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker + +object PlatformIncompatibilityDiagnosticRenderer : + DiagnosticParameterRenderer>> { + override fun render( + obj: Map>, + renderingContext: RenderingContext + ): String { + if (obj.isEmpty()) return "" + + return buildString { + appendln() + for ((incompatibility, descriptors) in obj) { + append("The following declaration") + if (descriptors.size == 1) append(" is") else append("s are") + append(" incompatible") + incompatibility.reason?.let { append(" because $it") } + appendln(":") + for (descriptor in descriptors) { + append(" ") + appendln(Renderers.COMPACT_WITH_MODIFIERS.render(descriptor, renderingContext)) + } + } + } + } +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformImplDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformImplDeclarationChecker.kt new file mode 100644 index 00000000000..95fb5755840 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformImplDeclarationChecker.kt @@ -0,0 +1,315 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.checkers + +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker.Compatibility.Compatible +import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker.Compatibility.Incompatible +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeConstructorSubstitution +import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.typeUtil.asTypeProjection +import org.jetbrains.kotlin.utils.keysToMap + +class PlatformImplDeclarationChecker : DeclarationChecker { + override fun check( + declaration: KtDeclaration, + descriptor: DeclarationDescriptor, + diagnosticHolder: DiagnosticSink, + bindingContext: BindingContext, + languageVersionSettings: LanguageVersionSettings + ) { + if (!languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return + + if (descriptor !is MemberDescriptor) return + + if (descriptor.isPlatform && declaration.hasModifier(KtTokens.PLATFORM_KEYWORD)) { + checkPlatformDeclarationHasDefinition(declaration, descriptor, diagnosticHolder) + } + else if (descriptor.isImpl && declaration.hasModifier(KtTokens.IMPL_KEYWORD)) { + checkImplementationHasPlatformDeclaration(declaration, descriptor, diagnosticHolder) + } + } + + private fun checkPlatformDeclarationHasDefinition( + reportOn: KtDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink + ) { + val compatibility = when (descriptor) { + is CallableMemberDescriptor -> { + descriptor.findNamesakesFromTheSameModule().filter { impl -> + descriptor != impl && + // TODO: support non-source definitions (e.g. from Java) + DescriptorToSourceUtils.getSourceFromDescriptor(impl) is KtElement + }.groupBy { impl -> + areCompatibleCallables(descriptor, impl) + } + } + is ClassDescriptor -> { + descriptor.findClassifiersFromTheSameModule().filter { impl -> + descriptor != impl && + DescriptorToSourceUtils.getSourceFromDescriptor(impl) is KtElement + }.groupBy { impl -> + areCompatibleClassifiers(descriptor, impl) + } + } + else -> null + } + + if (compatibility != null && !compatibility.containsKey(Compatible)) { + assert(compatibility.keys.all { it is Incompatible }) + @Suppress("UNCHECKED_CAST") + val incompatibility = compatibility as Map> + diagnosticHolder.report(Errors.PLATFORM_DECLARATION_WITHOUT_DEFINITION.on(reportOn, descriptor, incompatibility)) + } + } + + private fun checkImplementationHasPlatformDeclaration( + reportOn: KtDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink + ) { + val hasDeclaration = when (descriptor) { + is CallableMemberDescriptor -> descriptor.findNamesakesFromTheSameModule().any { declaration -> + descriptor != declaration && + declaration.isPlatform && + areCompatibleCallables(declaration, descriptor) == Compatible + } + is ClassifierDescriptor -> descriptor.findClassifiersFromTheSameModule().any { declaration -> + descriptor != declaration && + declaration is ClassDescriptor && declaration.isPlatform && + areCompatibleClassifiers(declaration, descriptor) == Compatible + } + else -> false + } + + if (!hasDeclaration) { + // TODO: do not report this error for members which are "almost compatible" with some platform declarations + diagnosticHolder.report(Errors.PLATFORM_DEFINITION_WITHOUT_DECLARATION.on(reportOn.modifierList!!.getModifier(KtTokens.IMPL_KEYWORD)!!)) + } + } + + private fun CallableMemberDescriptor.findNamesakesFromTheSameModule(): Collection { + val packageFqName = (containingDeclaration as? PackageFragmentDescriptor)?.fqName ?: return emptyList() + val myModule = this.module + val scope = myModule.getPackage(packageFqName).memberScope + + return when (this) { + is FunctionDescriptor -> scope.getContributedFunctions(name, NoLookupLocation.FOR_ALREADY_TRACKED) + is PropertyDescriptor -> scope.getContributedVariables(name, NoLookupLocation.FOR_ALREADY_TRACKED) + else -> throw AssertionError("Unsupported declaration: $this") + }.filter { + it.module == myModule // TODO: only obtain descriptors from our module to start with + } + } + + private fun ClassifierDescriptor.findClassifiersFromTheSameModule(): Collection { + // TODO: support nested classes + return module.getPackage(fqNameSafe.parent()).memberScope + .getDescriptorsFiltered(DescriptorKindFilter.CLASSIFIERS) { it == name } + .filterIsInstance() + } + + sealed class Compatibility { + // Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer + sealed class Incompatible(val reason: String?) : Compatibility() { + // Callables + + object ParameterShape : Incompatible("parameter shapes are different (extension vs non-extension)") + + object ParameterCount : Incompatible("number of value parameters is different") + object TypeParameterCount : Incompatible("number of type parameters is different") + + object ParameterTypes : Incompatible("parameter types are different") + object ReturnType : Incompatible("return type is different") + + object ParameterNames : Incompatible("parameter names are different") + object TypeParameterNames : Incompatible("names of type parameters are different") + + object ValueParameterHasDefault : Incompatible("some parameters have default values") + object ValueParameterModifiers : Incompatible("parameter modifiers are different (vararg, coroutine, crossinline, noinline)") + + // Functions + + object FunctionModifiers : Incompatible("modifiers are different (external, infix, inline, operator, suspend, tailrec)") + + // Properties + + object PropertyKind : Incompatible("property kinds are different (val vs var)") + object PropertyModifiers : Incompatible("modifiers are different (const, lateinit)") + + // Classifiers + + object ClassKind : Incompatible("class kinds are different (class, interface, object, enum, annotation)") + + object ClassModifiers : Incompatible("modifiers are different (data)") + + object Supertypes : Incompatible("some supertypes are missing in the implementation") + + // Common + + object Modality : Incompatible("modality is different") + object Visibility : Incompatible("visibility is different") + + object TypeParameterUpperBounds : Incompatible("upper bounds of type parameters are different") + object TypeParameterVariance : Incompatible("declaration-site variances of type parameters are different") + object TypeParameterReified : Incompatible("some type parameter is reified in one declaration and non-reified in the other") + + object Unknown : Incompatible(null) + } + + object Compatible : Compatibility() + } + + // a is the declaration in common code, b is the definition in the platform-specific code + private fun areCompatibleCallables(a: CallableMemberDescriptor, b: CallableMemberDescriptor): Compatibility { + assert(a.name == b.name) { "This function should be invoked only for declarations with the same name: $a, $b" } + assert(a.containingDeclaration is ClassDescriptor == b.containingDeclaration is ClassDescriptor) { + "This function should be invoked only for declarations in the same kind of container (both members or both top level): $a, $b" + } + + val aExtensionReceiver = a.extensionReceiverParameter + val bExtensionReceiver = b.extensionReceiverParameter + if ((aExtensionReceiver != null) != (bExtensionReceiver != null)) return Incompatible.ParameterShape + + val aParams = a.valueParameters + val bParams = b.valueParameters + if (aParams.size != bParams.size) return Incompatible.ParameterCount + + val aTypeParams = a.typeParameters + val bTypeParams = b.typeParameters + if (aTypeParams.size != bTypeParams.size) return Incompatible.TypeParameterCount + + val substitutor = Substitutor(aTypeParams, bTypeParams) + + if (aParams.map { substitutor(it.type) } != bParams.map { it.type } || + aExtensionReceiver?.type?.let(substitutor) != bExtensionReceiver?.type) return Incompatible.ParameterTypes + if (substitutor(a.returnType) != b.returnType) return Incompatible.ReturnType + + if (!equalsBy(aParams, bParams, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames + if (!equalsBy(aTypeParams, bTypeParams, TypeParameterDescriptor::getName)) return Incompatible.TypeParameterNames + + if (a.modality != b.modality) return Incompatible.Modality + if (a.visibility != b.visibility) return Incompatible.Visibility + + areCompatibleTypeParameters(aTypeParams, bTypeParams, substitutor).let { if (it != Compatible) return it } + + if (!equalsBy(aParams, bParams, ValueParameterDescriptor::declaresDefaultValue)) return Incompatible.ValueParameterHasDefault + if (!equalsBy(aParams, bParams, { p -> listOf(p.varargElementType != null, p.isCoroutine, p.isCrossinline, p.isNoinline) })) return Incompatible.ValueParameterModifiers + + when { + a is FunctionDescriptor && b is FunctionDescriptor -> areCompatibleFunctions(a, b).let { if (it != Compatible) return it } + a is PropertyDescriptor && b is PropertyDescriptor -> areCompatibleProperties(a, b).let { if (it != Compatible) return it } + else -> throw AssertionError("Unsupported declarations: $a, $b") + } + + // TODO: check 'impl' modifier + + return Compatible + } + + private fun areCompatibleTypeParameters(a: List, b: List, substitutor: Substitutor): Compatibility { + if (a.map { substitutor(it.defaultType) } != b.map { it.defaultType }) return Incompatible.TypeParameterUpperBounds + if (!equalsBy(a, b, TypeParameterDescriptor::getVariance)) return Incompatible.TypeParameterVariance + if (!equalsBy(a, b, TypeParameterDescriptor::isReified)) return Incompatible.TypeParameterReified + + return Compatible + } + + private fun areCompatibleFunctions(a: FunctionDescriptor, b: FunctionDescriptor): Compatibility { + if (!equalBy(a, b) { f -> + listOf(f.isExternal, f.isInfix, f.isInline, f.isOperator, f.isSuspend, f.isTailrec) + }) return Incompatible.FunctionModifiers + + return Compatible + } + + private fun areCompatibleProperties(a: PropertyDescriptor, b: PropertyDescriptor): Compatibility { + if (!equalBy(a, b) { p -> p.isVar }) return Incompatible.PropertyKind + if (!equalBy(a, b) { p -> listOf(p.isConst, p.isLateInit) }) return Incompatible.PropertyModifiers + + return Compatible + } + + private fun areCompatibleClassifiers(a: ClassDescriptor, other: ClassifierDescriptor): Compatibility { + assert(a.fqNameUnsafe == other.fqNameUnsafe) { "This function should be invoked only for declarations with the same name: $a, $other" } + + val b = when (other) { + is ClassDescriptor -> other + is TypeAliasDescriptor -> other.classDescriptor ?: return Incompatible.Unknown + else -> throw AssertionError("Incorrect impl classifier for $a: $other") + } + + if (a.kind != b.kind) return Incompatible.ClassKind + + val aTypeParams = a.declaredTypeParameters + val bTypeParams = b.declaredTypeParameters + if (aTypeParams.size != bTypeParams.size) return Incompatible.TypeParameterCount + + val substitutor = Substitutor(aTypeParams, bTypeParams) + + if (a.modality != b.modality) return Incompatible.Modality + if (a.visibility != b.visibility) return Incompatible.Visibility + + areCompatibleTypeParameters(aTypeParams, bTypeParams, substitutor).let { if (it != Compatible) return it } + + if (!equalBy(a, b) { it.isData }) return Incompatible.ClassModifiers + + if (!b.typeConstructor.supertypes.containsAll(a.typeConstructor.supertypes.map(substitutor))) return Incompatible.Supertypes + + // TODO: check scopes + // TODO: check 'impl' modifier + + return Compatible + } + + private inline fun equalBy(first: T, second: T, selector: (T) -> K): Boolean = + selector(first) == selector(second) + + private inline fun equalsBy(first: List, second: List, selector: (T) -> K): Boolean { + for (i in first.indices) { + if (selector(first[i]) != selector(second[i])) return false + } + + return true + } + + // This substitutor takes the type from A's signature and returns the type that should be in that place in B's signature + private class Substitutor( + aTypeParams: List, + bTypeParams: List + ) : (KotlinType?) -> KotlinType? { + val typeSubstitutor = TypeSubstitutor.create(TypeConstructorSubstitution.createByParametersMap( + aTypeParams.keysToMap { bTypeParams[it.index].defaultType.asTypeProjection() } + )) + + override fun invoke(type: KotlinType?): KotlinType? = + type?.asTypeProjection()?.let(typeSubstitutor::substitute)?.type + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/platformClass/genericClassImplTypeAlias.kt b/compiler/testData/diagnostics/tests/multiplatform/platformClass/genericClassImplTypeAlias.kt index 1c72d1d2773..6454c30f5b4 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/platformClass/genericClassImplTypeAlias.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/platformClass/genericClassImplTypeAlias.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -PLATFORM_DEFINITION_WITHOUT_DECLARATION // !LANGUAGE: +MultiPlatformProjects // MODULE: m1-common // FILE: common.kt diff --git a/compiler/testData/multiplatform/genericDeclarations/common.kt b/compiler/testData/multiplatform/genericDeclarations/common.kt new file mode 100644 index 00000000000..9cff5eb1326 --- /dev/null +++ b/compiler/testData/multiplatform/genericDeclarations/common.kt @@ -0,0 +1,13 @@ +platform fun f1(): T + +platform fun f2(t: T) + +platform fun , V : MutableList> f3(v: Map>, w: Comparable<*>) + +platform fun > Array.sort(): Unit + +platform class C1 +platform class C2> +platform class C3> + +platform abstract class AbstractList : MutableList diff --git a/compiler/testData/multiplatform/genericDeclarations/jvm.kt b/compiler/testData/multiplatform/genericDeclarations/jvm.kt new file mode 100644 index 00000000000..a0af9e5b67e --- /dev/null +++ b/compiler/testData/multiplatform/genericDeclarations/jvm.kt @@ -0,0 +1,15 @@ +impl fun f1(): T = throw AssertionError() + +impl fun f2(t: T) {} + +impl fun , V : MutableList> f3(v: Map>, w: Comparable<*>) {} + +impl fun > Array.sort(): Unit { + java.util.Arrays.sort(this) +} + +impl class C1 +impl class C2> +impl class C3> + +impl abstract class AbstractList : MutableList, java.io.Serializable diff --git a/compiler/testData/multiplatform/genericDeclarations/output.txt b/compiler/testData/multiplatform/genericDeclarations/output.txt new file mode 100644 index 00000000000..ce9e219309f --- /dev/null +++ b/compiler/testData/multiplatform/genericDeclarations/output.txt @@ -0,0 +1,8 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: OK +Output: + diff --git a/compiler/testData/multiplatform/implementClassWithTypeAlias/common.kt b/compiler/testData/multiplatform/implementClassWithTypeAlias/common.kt new file mode 100644 index 00000000000..fc53898517d --- /dev/null +++ b/compiler/testData/multiplatform/implementClassWithTypeAlias/common.kt @@ -0,0 +1,3 @@ +platform class C1 { + fun foo(a: A): List? +} diff --git a/compiler/testData/multiplatform/implementClassWithTypeAlias/jvm.kt b/compiler/testData/multiplatform/implementClassWithTypeAlias/jvm.kt new file mode 100644 index 00000000000..916937db06e --- /dev/null +++ b/compiler/testData/multiplatform/implementClassWithTypeAlias/jvm.kt @@ -0,0 +1,4 @@ +impl typealias C1 = C1Impl +class C1Impl { + fun foo(a: A): List? = null +} diff --git a/compiler/testData/multiplatform/implementClassWithTypeAlias/output.txt b/compiler/testData/multiplatform/implementClassWithTypeAlias/output.txt new file mode 100644 index 00000000000..f12f8c5d70d --- /dev/null +++ b/compiler/testData/multiplatform/implementClassWithTypeAlias/output.txt @@ -0,0 +1,11 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: OK +Output: +compiler/testData/multiplatform/implementClassWithTypeAlias/jvm.kt:3:13: warning: parameter 'a' is never used + fun foo(a: A): List? = null + ^ + diff --git a/compiler/testData/multiplatform/incompatibleCallables/common.kt b/compiler/testData/multiplatform/incompatibleCallables/common.kt new file mode 100644 index 00000000000..442585e840a --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleCallables/common.kt @@ -0,0 +1,36 @@ +platform fun f1() + +platform fun f2(name: String) + +platform fun f3(name: String) +platform fun String.f3ext() + +platform fun f4(name: String) + +platform fun String.f5() + +platform fun f6(p1: String, p2: Int) + +platform fun f7() + +internal platform fun f8() +private platform fun f9() +public platform fun f10() + +platform fun f11() +platform fun > f12() +platform fun > f13() + +platform inline fun f14() +platform inline fun f15() + +platform fun f16(s: String) + +platform fun f17(vararg s: String) +platform fun f18(s: Array) +platform inline fun f19(crossinline s: () -> Unit) +platform inline fun f20(s: () -> Unit) +platform inline fun f21(noinline s: () -> Unit) +platform inline fun f22(s: () -> Unit) +platform fun f23(coroutine c: Unit.() -> Continuation) +platform fun f24(c: Unit.() -> Continuation) diff --git a/compiler/testData/multiplatform/incompatibleCallables/jvm.kt b/compiler/testData/multiplatform/incompatibleCallables/jvm.kt new file mode 100644 index 00000000000..f435a456294 --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleCallables/jvm.kt @@ -0,0 +1,36 @@ +impl fun f1(): String = "" + +impl fun f2(otherName: String) {} + +impl fun f3(name: Double) {} +impl fun Double.f3ext() {} + +impl fun String.f4() {} + +impl fun f5(name: String) {} + +impl fun f6(p2: Int) {} + +impl fun f7() {} + +public impl fun f8() {} +internal impl fun f9() {} +private impl fun f10() {} + +impl fun f11() {} +impl fun > f12() {} +impl fun > f13() {} + +impl inline fun f14() {} +impl inline fun f15() {} + +impl fun f16(s: String = "") {} + +impl fun f17(s: Array) {} +impl fun f18(vararg s: String) {} +impl inline fun f19(s: () -> Unit) {} +impl inline fun f20(crossinline s: () -> Unit) {} +impl inline fun f21(s: () -> Unit) {} +impl inline fun f22(noinline s: () -> Unit) {} +impl fun f23(c: Unit.() -> Continuation) {} +impl fun f24(coroutine c: Unit.() -> Continuation) {} diff --git a/compiler/testData/multiplatform/incompatibleCallables/output.txt b/compiler/testData/multiplatform/incompatibleCallables/output.txt new file mode 100644 index 00000000000..d335a28cd2b --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleCallables/output.txt @@ -0,0 +1,206 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: COMPILATION_ERROR +Output: +compiler/testData/multiplatform/incompatibleCallables/common.kt:1:1: error: no definition is found for platform declaration 'f1' +The following declaration is incompatible because return type is different: + public impl fun f1(): String + +platform fun f1() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:3:1: error: no definition is found for platform declaration 'f2' +The following declaration is incompatible because parameter names are different: + public impl fun f2(otherName: String): Unit + +platform fun f2(name: String) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:5:1: error: no definition is found for platform declaration 'f3' +The following declaration is incompatible because parameter types are different: + public impl fun f3(name: Double): Unit + +platform fun f3(name: String) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:6:1: error: no definition is found for platform declaration 'f3ext' +The following declaration is incompatible because parameter types are different: + public impl fun Double.f3ext(): Unit + +platform fun String.f3ext() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:8:1: error: no definition is found for platform declaration 'f4' +The following declaration is incompatible because parameter shapes are different (extension vs non-extension): + public impl fun String.f4(): Unit + +platform fun f4(name: String) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:10:1: error: no definition is found for platform declaration 'f5' +The following declaration is incompatible because parameter shapes are different (extension vs non-extension): + public impl fun f5(name: String): Unit + +platform fun String.f5() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:12:1: error: no definition is found for platform declaration 'f6' +The following declaration is incompatible because number of value parameters is different: + public impl fun f6(p2: Int): Unit + +platform fun f6(p1: String, p2: Int) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:14:1: error: no definition is found for platform declaration 'f7' +The following declaration is incompatible because number of type parameters is different: + public impl fun f7(): Unit + +platform fun f7() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:16:1: error: no definition is found for platform declaration 'f8' +The following declaration is incompatible because visibility is different: + public impl fun f8(): Unit + +internal platform fun f8() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:17:1: error: no definition is found for platform declaration 'f9' +The following declaration is incompatible because visibility is different: + internal impl fun f9(): Unit + +private platform fun f9() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:18:1: error: no definition is found for platform declaration 'f10' +The following declaration is incompatible because visibility is different: + private impl fun f10(): Unit + +public platform fun f10() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:24:1: error: no definition is found for platform declaration 'f14' +The following declaration is incompatible because some type parameter is reified in one declaration and non-reified in the other: + public inline impl fun f14(): Unit + +platform inline fun f14() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:25:1: error: no definition is found for platform declaration 'f15' +The following declaration is incompatible because some type parameter is reified in one declaration and non-reified in the other: + public inline impl fun f15(): Unit + +platform inline fun f15() +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:27:1: error: no definition is found for platform declaration 'f16' +The following declaration is incompatible because some parameters have default values: + public impl fun f16(s: String = ...): Unit + +platform fun f16(s: String) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:29:1: error: no definition is found for platform declaration 'f17' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public impl fun f17(s: Array): Unit + +platform fun f17(vararg s: String) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:30:1: error: no definition is found for platform declaration 'f18' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public impl fun f18(vararg s: String): Unit + +platform fun f18(s: Array) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:31:1: error: no definition is found for platform declaration 'f19' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public inline impl fun f19(s: () -> Unit): Unit + +platform inline fun f19(crossinline s: () -> Unit) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:32:1: error: no definition is found for platform declaration 'f20' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public inline impl fun f20(crossinline s: () -> Unit): Unit + +platform inline fun f20(s: () -> Unit) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:33:1: error: no definition is found for platform declaration 'f21' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public inline impl fun f21(s: () -> Unit): Unit + +platform inline fun f21(noinline s: () -> Unit) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:34:1: error: no definition is found for platform declaration 'f22' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public inline impl fun f22(noinline s: () -> Unit): Unit + +platform inline fun f22(s: () -> Unit) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:35:1: error: no definition is found for platform declaration 'f23' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public impl fun f23(c: Unit.() -> Continuation): Unit + +platform fun f23(coroutine c: Unit.() -> Continuation) +^ +compiler/testData/multiplatform/incompatibleCallables/common.kt:36:1: error: no definition is found for platform declaration 'f24' +The following declaration is incompatible because parameter modifiers are different (vararg, coroutine, crossinline, noinline): + public impl fun f24(coroutine c: Unit.() -> Continuation): Unit + +platform fun f24(c: Unit.() -> Continuation) +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:1:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f1(): String = "" +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:3:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f2(otherName: String) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:5:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f3(name: Double) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:6:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun Double.f3ext() {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:8:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun String.f4() {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:10:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f5(name: String) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:12:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f6(p2: Int) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:14:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f7() {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:16:8: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +public impl fun f8() {} + ^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:17:10: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +internal impl fun f9() {} + ^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:18:9: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +private impl fun f10() {} + ^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:24:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun f14() {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:25:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun f15() {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:27:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f16(s: String = "") {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:29:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f17(s: Array) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:30:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f18(vararg s: String) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:31:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun f19(s: () -> Unit) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:32:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun f20(crossinline s: () -> Unit) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:33:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun f21(s: () -> Unit) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:34:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun f22(noinline s: () -> Unit) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:35:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f23(c: Unit.() -> Continuation) {} +^ +compiler/testData/multiplatform/incompatibleCallables/jvm.kt:36:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f24(coroutine c: Unit.() -> Continuation) {} +^ + diff --git a/compiler/testData/multiplatform/incompatibleClasses/common.kt b/compiler/testData/multiplatform/incompatibleClasses/common.kt new file mode 100644 index 00000000000..8bf528b935c --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleClasses/common.kt @@ -0,0 +1,25 @@ +platform class PClass +platform interface PInterface +platform object PObject +platform enum class PEnumClass +platform annotation class PAnnotationClass + +internal platform object InternalObject +public platform object PublicObject +private platform object PrivateObject + +open platform class OpenClass +abstract platform class AbstractClass +final platform class FinalClass + +// platform data class DataClass(val x: Int) +platform class NonDataClass(x: Int) + +platform class C1 +platform class C2 +platform class C3 + +platform class C4 + + +platform abstract class ExtendsNumber : Number diff --git a/compiler/testData/multiplatform/incompatibleClasses/jvm.kt b/compiler/testData/multiplatform/incompatibleClasses/jvm.kt new file mode 100644 index 00000000000..ca3f37c68ea --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleClasses/jvm.kt @@ -0,0 +1,25 @@ +impl interface PClass +impl object PInterface +impl enum class PObject +impl annotation class PEnumClass +impl class PAnnotationClass + +private impl object InternalObject +internal impl object PublicObject +public impl object PrivateObject + +final impl class OpenClass +open impl class AbstractClass +abstract impl class FinalClass + +// impl class DataClass(val x: Int) +impl data class NonDataClass(val x: Int) + +impl class C1 +impl class C2 +impl class C3 + +impl typealias C4 = C4Impl +class C4Impl + +impl abstract class ExtendsNumber : Any() diff --git a/compiler/testData/multiplatform/incompatibleClasses/output.txt b/compiler/testData/multiplatform/incompatibleClasses/output.txt new file mode 100644 index 00000000000..75ae5d7486c --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleClasses/output.txt @@ -0,0 +1,143 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: COMPILATION_ERROR +Output: +compiler/testData/multiplatform/incompatibleClasses/common.kt:1:16: error: no definition is found for platform declaration 'PClass' +The following declaration is incompatible because class kinds are different (class, interface, object, enum, annotation): + public impl interface PClass + +platform class PClass + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:2:20: error: no definition is found for platform declaration 'PInterface' +The following declaration is incompatible because class kinds are different (class, interface, object, enum, annotation): + public impl object PInterface + +platform interface PInterface + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:3:10: error: no definition is found for platform declaration 'PObject' +The following declaration is incompatible because class kinds are different (class, interface, object, enum, annotation): + public final impl enum class PObject : Enum + +platform object PObject + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:4:21: error: no definition is found for platform declaration 'PEnumClass' +The following declaration is incompatible because class kinds are different (class, interface, object, enum, annotation): + public final impl annotation class PEnumClass : Annotation + +platform enum class PEnumClass + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:5:27: error: no definition is found for platform declaration 'PAnnotationClass' +The following declaration is incompatible because class kinds are different (class, interface, object, enum, annotation): + public final impl class PAnnotationClass + +platform annotation class PAnnotationClass + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:7:19: error: no definition is found for platform declaration 'InternalObject' +The following declaration is incompatible because visibility is different: + private impl object InternalObject + +internal platform object InternalObject + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:8:17: error: no definition is found for platform declaration 'PublicObject' +The following declaration is incompatible because visibility is different: + internal impl object PublicObject + +public platform object PublicObject + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:9:18: error: no definition is found for platform declaration 'PrivateObject' +The following declaration is incompatible because visibility is different: + public impl object PrivateObject + +private platform object PrivateObject + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:11:21: error: no definition is found for platform declaration 'OpenClass' +The following declaration is incompatible because modality is different: + public final impl class OpenClass + +open platform class OpenClass + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:12:25: error: no definition is found for platform declaration 'AbstractClass' +The following declaration is incompatible because modality is different: + public open impl class AbstractClass + +abstract platform class AbstractClass + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:13:22: error: no definition is found for platform declaration 'FinalClass' +The following declaration is incompatible because modality is different: + public abstract impl class FinalClass + +final platform class FinalClass + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:16:16: error: no definition is found for platform declaration 'NonDataClass' +The following declaration is incompatible because modifiers are different (data): + public final impl data class NonDataClass + +platform class NonDataClass(x: Int) + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:18:16: error: no definition is found for platform declaration 'C1' +The following declaration is incompatible because number of type parameters is different: + public final impl class C1 + +platform class C1 + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:19:16: error: no definition is found for platform declaration 'C2' +The following declaration is incompatible because declaration-site variances of type parameters are different: + public final impl class C2 + +platform class C2 + ^ +compiler/testData/multiplatform/incompatibleClasses/common.kt:25:25: error: no definition is found for platform declaration 'ExtendsNumber' +The following declaration is incompatible because some supertypes are missing in the implementation: + public abstract impl class ExtendsNumber + +platform abstract class ExtendsNumber : Number + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:1:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl interface PClass +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:2:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl object PInterface +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:3:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl enum class PObject +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:4:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl annotation class PEnumClass +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:5:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl class PAnnotationClass +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:7:9: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +private impl object InternalObject + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:8:10: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +internal impl object PublicObject + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:9:8: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +public impl object PrivateObject + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:11:7: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +final impl class OpenClass + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:12:6: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +open impl class AbstractClass + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:13:10: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +abstract impl class FinalClass + ^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:16:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl data class NonDataClass(val x: Int) +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:18:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl class C1 +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:19:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl class C2 +^ +compiler/testData/multiplatform/incompatibleClasses/jvm.kt:25:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl abstract class ExtendsNumber : Any() +^ + diff --git a/compiler/testData/multiplatform/incompatibleFunctions/common.kt b/compiler/testData/multiplatform/incompatibleFunctions/common.kt new file mode 100644 index 00000000000..22f5fa1c0ae --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleFunctions/common.kt @@ -0,0 +1,14 @@ +platform infix fun Int.plus(s: CharSequence): Int +platform fun Int.minus(s: String): Int + +platform operator fun Double.times(x: CharArray) +platform fun Double.divide(x: ByteArray) + +platform external fun f1() +platform fun g1() + +platform inline fun f2() +platform fun g2() + +platform tailrec fun f3() +platform fun g3() diff --git a/compiler/testData/multiplatform/incompatibleFunctions/jvm.kt b/compiler/testData/multiplatform/incompatibleFunctions/jvm.kt new file mode 100644 index 00000000000..64d18ddacef --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleFunctions/jvm.kt @@ -0,0 +1,14 @@ +impl fun Int.plus(s: CharSequence): Int = 0 +impl infix fun Int.minus(s: String): Int = 1 + +impl fun Double.times(x: CharArray) {} +impl operator fun Double.divide(x: ByteArray) {} + +impl fun f1() {} +impl external fun g1() + +impl fun f2() {} +impl inline fun g2() {} + +impl fun f3() {} +impl tailrec fun g3() {} diff --git a/compiler/testData/multiplatform/incompatibleFunctions/output.txt b/compiler/testData/multiplatform/incompatibleFunctions/output.txt new file mode 100644 index 00000000000..c770dc78f0b --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleFunctions/output.txt @@ -0,0 +1,101 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: COMPILATION_ERROR +Output: +compiler/testData/multiplatform/incompatibleFunctions/common.kt:1:1: error: no definition is found for platform declaration 'plus' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public impl fun Int.plus(s: CharSequence): Int + +platform infix fun Int.plus(s: CharSequence): Int +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:2:1: error: no definition is found for platform declaration 'minus' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public infix impl fun Int.minus(s: String): Int + +platform fun Int.minus(s: String): Int +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:4:1: error: no definition is found for platform declaration 'times' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public impl fun Double.times(x: CharArray): Unit + +platform operator fun Double.times(x: CharArray) +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:5:1: error: no definition is found for platform declaration 'divide' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public operator impl fun Double.divide(x: ByteArray): Unit + +platform fun Double.divide(x: ByteArray) +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:7:1: error: no definition is found for platform declaration 'f1' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public impl fun f1(): Unit + +platform external fun f1() +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:8:1: error: no definition is found for platform declaration 'g1' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public external impl fun g1(): Unit + +platform fun g1() +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:10:1: error: no definition is found for platform declaration 'f2' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public impl fun f2(): Unit + +platform inline fun f2() +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:11:1: error: no definition is found for platform declaration 'g2' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public inline impl fun g2(): Unit + +platform fun g2() +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:13:1: error: no definition is found for platform declaration 'f3' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public impl fun f3(): Unit + +platform tailrec fun f3() +^ +compiler/testData/multiplatform/incompatibleFunctions/common.kt:14:1: error: no definition is found for platform declaration 'g3' +The following declaration is incompatible because modifiers are different (external, infix, inline, operator, suspend, tailrec): + public tailrec impl fun g3(): Unit + +platform fun g3() +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:1:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun Int.plus(s: CharSequence): Int = 0 +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:2:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl infix fun Int.minus(s: String): Int = 1 +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:4:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun Double.times(x: CharArray) {} +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:5:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl operator fun Double.divide(x: ByteArray) {} +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:5:6: error: 'operator' modifier is inapplicable on this function: illegal function name +impl operator fun Double.divide(x: ByteArray) {} + ^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:7:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f1() {} +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:8:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl external fun g1() +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:10:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f2() {} +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:11:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl inline fun g2() {} +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:13:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl fun f3() {} +^ +compiler/testData/multiplatform/incompatibleFunctions/jvm.kt:14:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl tailrec fun g3() {} +^ + diff --git a/compiler/testData/multiplatform/incompatibleProperties/common.kt b/compiler/testData/multiplatform/incompatibleProperties/common.kt new file mode 100644 index 00000000000..8f4eade6f63 --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleProperties/common.kt @@ -0,0 +1,2 @@ +platform val pval: String +platform var pvar: String diff --git a/compiler/testData/multiplatform/incompatibleProperties/jvm.kt b/compiler/testData/multiplatform/incompatibleProperties/jvm.kt new file mode 100644 index 00000000000..34770ea3eb5 --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleProperties/jvm.kt @@ -0,0 +1,2 @@ +impl var pval: String = "" +impl val pvar: String = "" diff --git a/compiler/testData/multiplatform/incompatibleProperties/output.txt b/compiler/testData/multiplatform/incompatibleProperties/output.txt new file mode 100644 index 00000000000..97a2ae8a542 --- /dev/null +++ b/compiler/testData/multiplatform/incompatibleProperties/output.txt @@ -0,0 +1,26 @@ +-- Common -- +Exit code: OK +Output: + +-- JVM -- +Exit code: COMPILATION_ERROR +Output: +compiler/testData/multiplatform/incompatibleProperties/common.kt:1:1: error: no definition is found for platform declaration 'pval' +The following declaration is incompatible because property kinds are different (val vs var): + public var pval: String + +platform val pval: String +^ +compiler/testData/multiplatform/incompatibleProperties/common.kt:2:1: error: no definition is found for platform declaration 'pvar' +The following declaration is incompatible because property kinds are different (val vs var): + public val pvar: String + +platform var pvar: String +^ +compiler/testData/multiplatform/incompatibleProperties/jvm.kt:1:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl var pval: String = "" +^ +compiler/testData/multiplatform/incompatibleProperties/jvm.kt:2:1: error: modifier 'impl' is only applicable to members that are initially declared in platform-independent code +impl val pvar: String = "" +^ + diff --git a/compiler/tests-common/org/jetbrains/kotlin/tests/di/injection.kt b/compiler/tests-common/org/jetbrains/kotlin/tests/di/injection.kt index 7f6f01e17cc..798be26e1d4 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/tests/di/injection.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/tests/di/injection.kt @@ -18,8 +18,6 @@ package org.jetbrains.kotlin.tests.di import com.intellij.openapi.project.Project import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl -import org.jetbrains.kotlin.container.* -import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.getValue import org.jetbrains.kotlin.container.useImpl diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt similarity index 61% rename from compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTest.kt rename to compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt index 3c8e7dcb5a7..461ce95370a 100644 --- a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt @@ -24,9 +24,9 @@ import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import java.io.File -class MultiPlatformIntegrationTest : KtUsefulTestCase() { +abstract class AbstractMultiPlatformIntegrationTest : KtUsefulTestCase() { fun doTest(directoryPath: String) { - val root = File(KotlinTestUtils.getTestDataPathBase() + directoryPath) + val root = File(directoryPath).apply { assert(exists()) } val commonSrc = File(root, "common.kt") val jsSrc = File(root, "js.kt") val jvmSrc = File(root, "jvm.kt") @@ -46,31 +46,31 @@ class MultiPlatformIntegrationTest : KtUsefulTestCase() { appendln("Output:") appendln(commonOutput) - val (jvmOutput, jvmExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JVMCompiler(), listOf( - jvmSrc.absolutePath, commonSrc.absolutePath, - "-d", jvmDest.absolutePath, - "-Xmulti-platform" - )) - appendln("-- JVM --") - appendln("Exit code: $jvmExitCode") - appendln("Output:") - appendln(jvmOutput) + if (jvmSrc.exists()) { + val (jvmOutput, jvmExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JVMCompiler(), listOf( + jvmSrc.absolutePath, commonSrc.absolutePath, + "-d", jvmDest.absolutePath, + "-Xmulti-platform" + )) + appendln("-- JVM --") + appendln("Exit code: $jvmExitCode") + appendln("Output:") + appendln(jvmOutput) + } - val (jsOutput, jsExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JSCompiler(), listOf( - jsSrc.absolutePath, commonSrc.absolutePath, - "-output", jsDest.absolutePath, - "-Xmulti-platform" - )) - appendln("-- JS --") - appendln("Exit code: $jsExitCode") - appendln("Output:") - append(jsOutput) + if (jsSrc.exists()) { + val (jsOutput, jsExitCode) = AbstractCliTest.executeCompilerGrabOutput(K2JSCompiler(), listOf( + jsSrc.absolutePath, commonSrc.absolutePath, + "-output", jsDest.absolutePath, + "-Xmulti-platform" + )) + appendln("-- JS --") + appendln("Exit code: $jsExitCode") + appendln("Output:") + append(jsOutput) + } } KotlinTestUtils.assertEqualsToFile(File(root, "output.txt"), result) } - - fun testSimple() { - doTest("/multiplatform/simple/") - } } diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java new file mode 100644 index 00000000000..f259e884f8e --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java @@ -0,0 +1,121 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.multiplatform; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/multiplatform") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatformIntegrationTest { + public void testAllFilesPresentInMultiplatform() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + + @TestMetadata("genericDeclarations") + public void testGenericDeclarations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/genericDeclarations/"); + doTest(fileName); + } + + @TestMetadata("implementClassWithTypeAlias") + public void testImplementClassWithTypeAlias() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/implementClassWithTypeAlias/"); + doTest(fileName); + } + + @TestMetadata("incompatibleCallables") + public void testIncompatibleCallables() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/incompatibleCallables/"); + doTest(fileName); + } + + @TestMetadata("incompatibleClasses") + public void testIncompatibleClasses() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/incompatibleClasses/"); + doTest(fileName); + } + + @TestMetadata("incompatibleFunctions") + public void testIncompatibleFunctions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/incompatibleFunctions/"); + doTest(fileName); + } + + @TestMetadata("incompatibleProperties") + public void testIncompatibleProperties() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/incompatibleProperties/"); + doTest(fileName); + } + + @TestMetadata("simple") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/simple/"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/multiplatform/classScopes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ClassScopes extends AbstractMultiPlatformIntegrationTest { + public void testAllFilesPresentInClassScopes() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/multiplatform/classScopes"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + + @TestMetadata("constructorIncorrectSignature") + public void testConstructorIncorrectSignature() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/constructorIncorrectSignature/"); + doTest(fileName); + } + + @TestMetadata("functionIncorrectSignature") + public void testFunctionIncorrectSignature() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/functionIncorrectSignature/"); + doTest(fileName); + } + + @TestMetadata("missingConstructor") + public void testMissingConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/missingConstructor/"); + doTest(fileName); + } + + @TestMetadata("missingFunction") + public void testMissingFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/missingFunction/"); + doTest(fileName); + } + + @TestMetadata("simple") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/classScopes/simple/"); + doTest(fileName); + } + + } + +} diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 404e225990d..244e5bf038c 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.android.* import org.jetbrains.kotlin.android.configure.AbstractConfigureProjectTest import org.jetbrains.kotlin.android.intentions.AbstractAndroidIntentionTest import org.jetbrains.kotlin.android.intentions.AbstractAndroidResourceIntentionTest +import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest import org.jetbrains.kotlin.android.quickfixes.AbstractAndroidQuickFixMultiFileTest import org.jetbrains.kotlin.annotation.AbstractAnnotationProcessorBoxTest import org.jetbrains.kotlin.annotation.processing.test.sourceRetention.AbstractBytecodeListingTestForSourceRetention @@ -131,6 +132,7 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest import org.jetbrains.kotlin.jps.build.* import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase import org.jetbrains.kotlin.jps.incremental.AbstractProtoComparisonTest +import org.jetbrains.kotlin.js.test.semantics.* import org.jetbrains.kotlin.jvm.compiler.* import org.jetbrains.kotlin.jvm.runtime.AbstractJvm8RuntimeDescriptorLoaderTest import org.jetbrains.kotlin.jvm.runtime.AbstractJvmRuntimeDescriptorLoaderTest @@ -139,6 +141,7 @@ import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBoxTest import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidBytecodeShapeTest import org.jetbrains.kotlin.lang.resolve.android.test.AbstractAndroidSyntheticPropertyDescriptorTest import org.jetbrains.kotlin.modules.xml.AbstractModuleXmlParserTest +import org.jetbrains.kotlin.multiplatform.AbstractMultiPlatformIntegrationTest import org.jetbrains.kotlin.parsing.AbstractParsingTest import org.jetbrains.kotlin.psi.patternMatching.AbstractPsiUnifierTest import org.jetbrains.kotlin.renderer.AbstractDescriptorRendererTest @@ -154,8 +157,6 @@ import org.jetbrains.kotlin.serialization.AbstractLocalClassProtoTest import org.jetbrains.kotlin.shortenRefs.AbstractShortenRefsTest import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.types.AbstractTypeBindingTest -import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest -import org.jetbrains.kotlin.js.test.semantics.* import java.io.File import java.lang.IllegalArgumentException import java.util.* @@ -187,11 +188,14 @@ fun main(args: Array) { model("diagnostics/testsWithJsStdLibAndBackendCompilation") } - testClass() { model("diagnostics/testWithModifiedMockJdk") } + testClass() { + model("multiplatform", extension = null, recursive = true, excludeParentDirs = true) + } + testClass() { model("foreignAnnotations/tests") } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt index 0ba612c3a7f..0a7a109ae82 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt @@ -19,25 +19,23 @@ package org.jetbrains.kotlin.js.resolve import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useImpl import org.jetbrains.kotlin.container.useInstance -import org.jetbrains.kotlin.js.resolve.diagnostics.JsCallChecker -import org.jetbrains.kotlin.js.resolve.diagnostics.JsNameChecker -import org.jetbrains.kotlin.js.resolve.diagnostics.JsNameClashChecker -import org.jetbrains.kotlin.js.resolve.diagnostics.JsNativeRttiChecker -import org.jetbrains.kotlin.js.resolve.diagnostics.JsReifiedNativeChecker -import org.jetbrains.kotlin.js.resolve.diagnostics.NativeInnerClassChecker +import org.jetbrains.kotlin.js.resolve.diagnostics.* import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap import org.jetbrains.kotlin.resolve.IdentifierChecker import org.jetbrains.kotlin.resolve.OverloadFilter import org.jetbrains.kotlin.resolve.PlatformConfigurator -import org.jetbrains.kotlin.js.resolve.diagnostics.JsReflectionAPICallChecker +import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker import org.jetbrains.kotlin.resolve.scopes.SyntheticConstructorsProvider import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.types.DynamicTypesAllowed object JsPlatformConfigurator : PlatformConfigurator( DynamicTypesAllowed(), - additionalDeclarationCheckers = listOf(NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(), - NativeInnerClassChecker(), JsNameChecker), + additionalDeclarationCheckers = listOf( + NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker(), NativeInnerClassChecker(), + JsNameChecker, + PlatformImplDeclarationChecker() + ), additionalCallCheckers = listOf(), additionalTypeCheckers = listOf(), additionalClassifierUsageCheckers = listOf(),