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 deleted file mode 100644 index df0e36afd30..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/AdditionalBuiltInsMembersChecker.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.jvm.checkers - -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.diagnostics.DiagnosticSink -import org.jetbrains.kotlin.diagnostics.Errors -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 - -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( - declaration: KtDeclaration, - descriptor: DeclarationDescriptor, - diagnosticHolder: DiagnosticSink, - bindingContext: BindingContext, - languageVersionSettings: LanguageVersionSettings - ) { - if (languageVersionSettings.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) return - val resultingDescriptor = descriptor as? CallableMemberDescriptor ?: return - val overrideKeyword = declaration.modifierList?.getModifier(KtTokens.OVERRIDE_KEYWORD) ?: return - - val overriddenDescriptors = resultingDescriptor.original.overriddenDescriptors - if (overriddenDescriptors.isNotEmpty() && overriddenDescriptors.all { it.isAdditionalBuiltInMember() }) { - diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(overrideKeyword, 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 6ea2b677bee..49391cf8b9b 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 @@ -44,7 +44,6 @@ object JvmPlatformConfigurator : PlatformConfigurator( TypeParameterBoundIsNotArrayChecker(), JvmSyntheticApplicabilityChecker(), StrictfpApplicabilityChecker(), - AdditionalBuiltInsMemberOverrideDeclarationChecker, HeaderImplDeclarationChecker() ), @@ -57,8 +56,7 @@ object JvmPlatformConfigurator : PlatformConfigurator( SuperCallWithDefaultArgumentsChecker(), MissingDependencyClassChecker, ProtectedSyntheticExtensionCallChecker, - ReifiedTypeParameterSubstitutionChecker(), - AdditionalBuiltInsMembersCallChecker + ReifiedTypeParameterSubstitutionChecker() ), additionalTypeCheckers = listOf( diff --git a/compiler/testData/codegen/java8/box/streamBackwardCompatibility.kt b/compiler/testData/codegen/java8/box/streamBackwardCompatibility.kt new file mode 100644 index 00000000000..bf8695bdf32 --- /dev/null +++ b/compiler/testData/codegen/java8/box/streamBackwardCompatibility.kt @@ -0,0 +1,8 @@ +// LANGUAGE_VERSION: 1.0 +// WITH_RUNTIME +// FULL_JDK +class A(val x: List) : List by x + +fun box(): String { + return A(listOf("OK"))[0] +} diff --git a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt index 65e50f0f1bb..0d26c85c85c 100644 --- a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt +++ b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt @@ -3,24 +3,44 @@ // SKIP_TXT class A : java.util.ArrayList() { - override fun stream(): java.util.stream.Stream = super.stream() + // `stream` is defined in ArrayList, so it was impossible to override it in 1.0 + override fun stream(): java.util.stream.Stream = super.stream() + + // `sort` is defined in ArrayList, so it was possible to override it in 1.0 + override fun sort(c: Comparator?) { + super.sort(c) + } } class A1 : java.util.ArrayList() { - fun stream(): java.util.stream.Stream = super.stream() + // `stream` is defined in ArrayList, so it was possible to declare it in 1.0 without an 'override' keyword + fun stream(): java.util.stream.Stream = super.stream() + + // `sort` is defined in ArrayList, so it was impossible to declare it in 1.0 without an 'override' keyword + fun sort(c: Comparator?) { + super.sort(c) + } } interface A2 : List { - override fun stream(): java.util.stream.Stream = null!! + override fun stream(): java.util.stream.Stream = null!! } -class B : Throwable("", null, false, false) +class B : Throwable("", null, false, false) -fun Throwable.fillInStackTrace() = 1 +class B1 : RuntimeException() { + override fun fillInStackTrace(): Throwable { // 'override' keyword must be prohibited, as it was in 1.0.x + return this + } +} -fun foo(x: List, y: Throwable) { - x.stream() - java.util.ArrayList().stream() +class A3(val x: List) : List by x + +fun Throwable.fillInStackTrace() = 1 + +fun foo(x: List, y: Throwable, z: A3) { + x.stream() + java.util.ArrayList().stream() y.fillInStackTrace() checkType { _() } @@ -28,6 +48,8 @@ fun foo(x: List, y: Throwable) { // Falls back to extension in stdlib y.printStackTrace() + + z.stream() } interface X { diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java index 12312667208..ceffeb2cfa8 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/codegen/BlackBoxWithJava8CodegenTestGenerated.java @@ -120,6 +120,12 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg doTest(fileName); } + @TestMetadata("streamBackwardCompatibility.kt") + public void testStreamBackwardCompatibility() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/streamBackwardCompatibility.kt"); + doTest(fileName); + } + @TestMetadata("useStream.kt") public void testUseStream() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/useStream.kt"); 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 562237693ad..4af5a64d5da 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 @@ -21,8 +21,6 @@ import org.jetbrains.kotlin.builtins.CloneableClassScope 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 @@ -36,7 +34,6 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.platform.createMappedTypeParametersSubstitution import org.jetbrains.kotlin.resolve.OverridingUtil -import org.jetbrains.kotlin.resolve.descriptorUtil.LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType @@ -53,7 +50,6 @@ import org.jetbrains.kotlin.types.LazyWrappedType import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.addToStdlib.check -import org.jetbrains.kotlin.utils.addToStdlib.singletonList import java.io.Serializable import java.util.* @@ -82,22 +78,6 @@ open class JvmBuiltInsSettings( ).let { AnnotationsImpl(listOf(it)) } } - 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(), - Modality.FINAL, ClassKind.ANNOTATION_CLASS, moduleDescriptor.builtIns.anyType.singletonList(), - SourceElement.NO_SOURCE, /* isExternal = */ false - ).run { - initialize(MemberScope.Empty, emptySet(), null) - AnnotationDescriptorImpl(defaultType, emptyMap(), SourceElement.NO_SOURCE) - } - - AnnotationsImpl(listOf(lowPriorityAnnotation)) - } - private fun StorageManager.createMockJavaIoSerializableType(): KotlinType { val mockJavaIoPackageFragment = object : PackageFragmentDescriptorImpl(moduleDescriptor, FqName("java.io")) { override fun getMemberScope() = MemberScope.Empty @@ -131,6 +111,8 @@ open class JvmBuiltInsSettings( )) } + if (!isAdditionalBuiltInsFeatureSupported) return emptyList() + return getAdditionalFunctions(classDescriptor) { it.getContributedFunctions(name, NoLookupLocation.FROM_BUILTINS) }.mapNotNull { @@ -156,31 +138,24 @@ open class JvmBuiltInsSettings( } JDKMemberStatus.NOT_CONSIDERED -> { - if (!isAdditionalBuiltInsFeatureSupported) { - setAdditionalAnnotations(lowPriorityAnnotation) - } - else { - setAdditionalAnnotations(notConsideredDeprecation) - } + setAdditionalAnnotations(notConsideredDeprecation) } JDKMemberStatus.DROP -> return@mapNotNull null - JDKMemberStatus.WHITE_LIST -> { - if (!isAdditionalBuiltInsFeatureSupported) { - setAdditionalAnnotations(lowPriorityAnnotation) - } - } + JDKMemberStatus.WHITE_LIST -> Unit // Do nothing } }.build()!! } } - override fun getFunctionsNames(classDescriptor: DeserializedClassDescriptor): Set = - // NB: It's just an approximation that could be calculated relatively fast - // More precise computation would look like `getAdditionalFunctions` (and the measurements show that it would be rather slow) - classDescriptor.getJavaAnalogue()?.unsubstitutedMemberScope?.getFunctionNames() ?: emptySet() + override fun getFunctionsNames(classDescriptor: DeserializedClassDescriptor): Set { + if (!isAdditionalBuiltInsFeatureSupported) return emptySet() + // NB: It's just an approximation that could be calculated relatively fast + // More precise computation would look like `getAdditionalFunctions` (and the measurements show that it would be rather slow) + return classDescriptor.getJavaAnalogue()?.unsubstitutedMemberScope?.getFunctionNames() ?: emptySet() + } private fun getAdditionalFunctions( classDescriptor: DeserializedClassDescriptor, @@ -287,7 +262,7 @@ open class JvmBuiltInsSettings( } override fun getConstructors(classDescriptor: DeserializedClassDescriptor): Collection { - if (classDescriptor.kind != ClassKind.CLASS) return emptyList() + if (classDescriptor.kind != ClassKind.CLASS || !isAdditionalBuiltInsFeatureSupported) return emptyList() val javaAnalogueDescriptor = classDescriptor.getJavaAnalogue() ?: return emptyList() @@ -314,11 +289,7 @@ open class JvmBuiltInsSettings( setReturnType(classDescriptor.defaultType) setPreserveSourceElement() setSubstitution(substitutor.substitution) - - if (!isAdditionalBuiltInsFeatureSupported) { - setAdditionalAnnotations(lowPriorityAnnotation) - } - else if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) { + if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) { setAdditionalAnnotations(notConsideredDeprecation) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt index 933bf389167..08b9beffacc 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.types.KotlinType private val NO_INFER_ANNOTATION_FQ_NAME = FqName("kotlin.internal.NoInfer") private val EXACT_ANNOTATION_FQ_NAME = FqName("kotlin.internal.Exact") -val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution") +private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution") private val HIDES_MEMBERS_ANNOTATION_FQ_NAME = FqName("kotlin.internal.HidesMembers") private val ONLY_INPUT_TYPES_FQ_NAME = FqName("kotlin.internal.OnlyInputTypes") private val DYNAMIC_EXTENSION_FQ_NAME = FqName("kotlin.internal.DynamicExtension")