diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/AdditionalBuiltInsMembersChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/AdditionalBuiltInsMembersChecker.kt index 67ff173b884..b704d3f45b9 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/AdditionalBuiltInsMembersChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/AdditionalBuiltInsMembersChecker.kt @@ -28,8 +28,21 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker +import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker -import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence + +object AdditionalBuiltInsMembersCallChecker : CallChecker { + override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { + if (context.languageVersionSettings.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) return + val resultingDescriptor = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return + + if (resultingDescriptor.isAdditionalBuiltInMember()) { + context.trace.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.AdditionalBuiltInsMembers)) + } + } +} object AdditionalBuiltInsMemberOverrideDeclarationChecker : DeclarationChecker { override fun check( @@ -43,19 +56,11 @@ object AdditionalBuiltInsMemberOverrideDeclarationChecker : DeclarationChecker { val resultingDescriptor = descriptor as? CallableMemberDescriptor ?: return val overrideKeyword = declaration.modifierList?.getModifier(KtTokens.OVERRIDE_KEYWORD) ?: return - // TODO: allow to omit 'override' on additional built-ins members - reportErrorIfAdditionalBuiltinDescriptor(resultingDescriptor, diagnosticHolder, overrideKeyword) + if (resultingDescriptor.original.overriddenDescriptors.all { it.isAdditionalBuiltInMember() }) { + diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(overrideKeyword, LanguageFeature.AdditionalBuiltInsMembers)) + } } } -private fun reportErrorIfAdditionalBuiltinDescriptor( - descriptor: CallableMemberDescriptor, - diagnosticHolder: DiagnosticSink, - reportOn: PsiElement -) { - val overriddenTree = descriptor.overriddenTreeUniqueAsSequence(useOriginal = true) - - if (overriddenTree.any { KotlinBuiltIns.isBuiltIn(it) && it is JavaCallableMemberDescriptor }) { - diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.AdditionalBuiltInsMembers)) - } -} +private fun CallableMemberDescriptor.isAdditionalBuiltInMember() = + KotlinBuiltIns.isBuiltIn(this) && this is JavaCallableMemberDescriptor 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 26489f0f322..6ea2b677bee 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 @@ -22,11 +22,10 @@ import org.jetbrains.kotlin.container.useInstance import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.resolve.PlatformConfigurator import org.jetbrains.kotlin.resolve.calls.checkers.ReifiedTypeParameterSubstitutionChecker -import org.jetbrains.kotlin.resolve.checkers.MissingDependencyClassChecker import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker +import org.jetbrains.kotlin.resolve.checkers.MissingDependencyClassChecker import org.jetbrains.kotlin.resolve.jvm.* import org.jetbrains.kotlin.resolve.jvm.checkers.* -import org.jetbrains.kotlin.resolve.lazy.DelegationFilter import org.jetbrains.kotlin.synthetic.JavaSyntheticConstructorsProvider import org.jetbrains.kotlin.synthetic.JavaSyntheticScopes import org.jetbrains.kotlin.types.DynamicTypesSettings @@ -58,7 +57,8 @@ object JvmPlatformConfigurator : PlatformConfigurator( SuperCallWithDefaultArgumentsChecker(), MissingDependencyClassChecker, ProtectedSyntheticExtensionCallChecker, - ReifiedTypeParameterSubstitutionChecker() + ReifiedTypeParameterSubstitutionChecker(), + AdditionalBuiltInsMembersCallChecker ), additionalTypeCheckers = listOf( diff --git a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt index 34566c1aa42..a12cebf01af 100644 --- a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt +++ b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt @@ -3,20 +3,24 @@ // SKIP_TXT class A : java.util.ArrayList() { - override fun stream(): java.util.stream.Stream = super.stream() + override fun stream(): java.util.stream.Stream = super.stream() } class A1 : java.util.ArrayList() { - fun stream(): java.util.stream.Stream = super.stream() + fun stream(): java.util.stream.Stream = super.stream() } -class B : Throwable("", null, false, false) +interface A2 : List { + override fun stream(): java.util.stream.Stream = null!! +} + +class B : Throwable("", null, false, false) fun Throwable.fillInStackTrace() = 1 fun foo(x: List, y: Throwable) { - x.stream() - java.util.ArrayList().stream() + x.stream() + java.util.ArrayList().stream() y.fillInStackTrace() checkType { _() } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JvmBuiltInsSettings.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JvmBuiltInsSettings.kt index dea92df9fa0..562237693ad 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JvmBuiltInsSettings.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JvmBuiltInsSettings.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.builtins.JvmBuiltInClassDescriptorFactory import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl +import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl @@ -81,10 +82,9 @@ open class JvmBuiltInsSettings( ).let { AnnotationsImpl(listOf(it)) } } - private val notSupportedDeprecation by storageManager.createLazyValue { - // We use both LowPriorityInOverloadResolution to achieve the following goals: - // - If there is something to resolve to beside an additional built-in member, it's *almost* always will win - // - Otherwise error will be reported because of Deprecated annotation with Error level + private val lowPriorityAnnotation: Annotations by storageManager.createLazyValue { + // We use both LowPriorityInOverloadResolution to achieve the following goal: + // If there is something to resolve to beside an additional built-in member, it's *almost* always will win val lowPriorityAnnotation = ClassDescriptorImpl( moduleDescriptor.getPackage(LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME.parent()), LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME.shortName(), @@ -95,12 +95,7 @@ open class JvmBuiltInsSettings( AnnotationDescriptorImpl(defaultType, emptyMap(), SourceElement.NO_SOURCE) } - val errorDeprecation = moduleDescriptor.builtIns.createDeprecatedAnnotation( - "This member is not supported by Kotlin compiler on this language level", - level = DeprecationLevel.ERROR.name - ) - - AnnotationsImpl(listOf(lowPriorityAnnotation, errorDeprecation)) + AnnotationsImpl(listOf(lowPriorityAnnotation)) } private fun StorageManager.createMockJavaIoSerializableType(): KotlinType { @@ -162,7 +157,7 @@ open class JvmBuiltInsSettings( JDKMemberStatus.NOT_CONSIDERED -> { if (!isAdditionalBuiltInsFeatureSupported) { - setAdditionalAnnotations(notSupportedDeprecation) + setAdditionalAnnotations(lowPriorityAnnotation) } else { setAdditionalAnnotations(notConsideredDeprecation) @@ -173,7 +168,7 @@ open class JvmBuiltInsSettings( JDKMemberStatus.WHITE_LIST -> { if (!isAdditionalBuiltInsFeatureSupported) { - setAdditionalAnnotations(notSupportedDeprecation) + setAdditionalAnnotations(lowPriorityAnnotation) } } } @@ -321,7 +316,7 @@ open class JvmBuiltInsSettings( setSubstitution(substitutor.substitution) if (!isAdditionalBuiltInsFeatureSupported) { - setAdditionalAnnotations(notSupportedDeprecation) + setAdditionalAnnotations(lowPriorityAnnotation) } else if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) { setAdditionalAnnotations(notConsideredDeprecation)