diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index 8ddf89cf473..e32794ef4bd 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.frontend.java.di import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.container.* import org.jetbrains.kotlin.context.LazyResolveToken @@ -140,7 +141,8 @@ fun StorageComponentContainer.javaAnalysisInit() { // 'initBuiltIns' body cannot be merged with 'javaAnalysisInit' because the latter is used in IDE, // where built-ins instances are shared between modules and manual initialization is necessary (to avoid multiple initialization) fun StorageComponentContainer.initJvmBuiltInsForTopDownAnalysis() { - get().initialize(get()) + get().initialize(get(), + get().supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) } class ContainerForTopDownAnalyzerForJvm(container: StorageComponentContainer) { 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 02e1069f70a..cfc338f7b06 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 @@ -29,20 +29,8 @@ import org.jetbrains.kotlin.load.java.isFromBuiltins import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DeclarationChecker -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.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 - - reportErrorIfAdditionalBuiltinDescriptor(resultingDescriptor, context.trace, reportOn) - } -} - object AdditionalBuiltInsMemberOverrideDeclarationChecker : DeclarationChecker { override fun check( declaration: KtDeclaration, 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 7f92f196deb..67a64a93ec4 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 @@ -54,8 +54,7 @@ object JvmPlatformConfigurator : PlatformConfigurator( UnsupportedSyntheticCallableReferenceChecker(), SuperCallWithDefaultArgumentsChecker(), MissingDependencyClassChecker(), - ProtectedSyntheticExtensionCallChecker, - AdditionalBuiltInsMembersCallChecker + ProtectedSyntheticExtensionCallChecker ), additionalTypeCheckers = listOf( diff --git a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt index b192bde94c5..ecd63c52388 100644 --- a/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt +++ b/compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/unsupportedFeature.kt @@ -1,18 +1,27 @@ +// !CHECK_TYPE // !LANGUAGE: -AdditionalBuiltInsMembers // 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() { // TODO: should be allowed - fun stream(): java.util.stream.Stream = super.stream() + fun stream(): java.util.stream.Stream = super.stream() } -class B : Throwable("", null, false, false) +class B : Throwable("", null, false, false) -fun foo(x: List) { - x.stream() - java.util.ArrayList().stream() +fun Throwable.fillInStackTrace() = 1 + +fun foo(x: List, y: Throwable) { + x.stream() + java.util.ArrayList().stream() + + y.fillInStackTrace() checkType { _() } + + // TODO: Relevant extensions has been removed from stdlib + // We should consider reverting their removal + y.printStackTrace() } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt index 44764c6325e..ed5674f4586 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/MultiModuleJavaAnalysisCustomTest.kt @@ -26,6 +26,9 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -77,7 +80,11 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() { packagePartProviderFactory = { a, b -> JvmPackagePartProvider(environment) } ) - builtIns.initialize(resolverForProject.descriptorForModule(resolverForProject.allModules.first())) + builtIns.initialize( + resolverForProject.descriptorForModule(resolverForProject.allModules.first()), + resolverForProject.resolverForModule(resolverForProject.allModules.first()) + .componentProvider.get() + .supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) performChecks(resolverForProject, modules) } 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 aafed499506..0437e9c3fa4 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 @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.builtins.BuiltInsInitializer import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.annotations.createDeprecatedAnnotation import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl @@ -31,6 +32,7 @@ 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 @@ -47,17 +49,20 @@ 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.* open class JvmBuiltInsSettings( private val moduleDescriptor: ModuleDescriptor, storageManager: StorageManager, - deferredOwnerModuleDescriptor: () -> ModuleDescriptor + deferredOwnerModuleDescriptor: () -> ModuleDescriptor, + isAdditionalBuiltInsFeatureSupported: () -> Boolean ) : AdditionalClassPartsProvider, PlatformDependentDeclarationFilter { private val j2kClassMap = JavaToKotlinClassMap.INSTANCE private val ownerModuleDescriptor: ModuleDescriptor by lazy(deferredOwnerModuleDescriptor) + private val isAdditionalBuiltInsFeatureSupported: Boolean by lazy(isAdditionalBuiltInsFeatureSupported) private val mockSerializableType = storageManager.createMockJavaIoSerializableType() @@ -70,6 +75,28 @@ 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 + 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 + ).run { + initialize(MemberScope.Empty, emptySet(), null) + 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)) + } + private fun StorageManager.createMockJavaIoSerializableType(): KotlinType { val mockJavaIoPackageFragment = object : PackageFragmentDescriptorImpl(moduleDescriptor, FqName("java.io")) { override fun getMemberScope() = MemberScope.Empty @@ -120,12 +147,21 @@ open class JvmBuiltInsSettings( } JDKMemberStatus.NOT_CONSIDERED -> { - setAdditionalAnnotations(notConsideredDeprecation) + if (!isAdditionalBuiltInsFeatureSupported) { + setAdditionalAnnotations(notSupportedDeprecation) + } + else { + setAdditionalAnnotations(notConsideredDeprecation) + } } JDKMemberStatus.DROP -> return@mapNotNull null - JDKMemberStatus.WHITE_LIST -> {} // Do nothing + JDKMemberStatus.WHITE_LIST -> { + if (!isAdditionalBuiltInsFeatureSupported) { + setAdditionalAnnotations(notSupportedDeprecation) + } + } } }.build()!! @@ -260,7 +296,10 @@ open class JvmBuiltInsSettings( setPreserveSourceElement() setSubstitution(substitutor.substitution) - if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) { + if (!isAdditionalBuiltInsFeatureSupported) { + setAdditionalAnnotations(notSupportedDeprecation) + } + else if (SignatureBuildingComponents.signature(javaAnalogueDescriptor, javaConstructor.computeJvmDescriptor()) !in WHITE_LIST_CONSTRUCTOR_SIGNATURES) { setAdditionalAnnotations(notConsideredDeprecation) } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JvmBuiltIns.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JvmBuiltIns.kt index cb9ec579dd4..b164eaf4987 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JvmBuiltIns.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JvmBuiltIns.kt @@ -26,10 +26,12 @@ import org.jetbrains.kotlin.utils.sure class JvmBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManager) { // Module containing JDK classes or having them among dependencies private var ownerModuleDescriptor: ModuleDescriptor? = null + private var isAdditionalBuiltInsFeatureSupported: Boolean = true - fun initialize(moduleDescriptor: ModuleDescriptor) { + fun initialize(moduleDescriptor: ModuleDescriptor, isAdditionalBuiltInsFeatureSupported: Boolean) { assert(ownerModuleDescriptor == null) { "JvmBuiltins repeated initialization" } this.ownerModuleDescriptor = moduleDescriptor + this.isAdditionalBuiltInsFeatureSupported = isAdditionalBuiltInsFeatureSupported } lateinit var settings: JvmBuiltInsSettings @@ -39,7 +41,8 @@ class JvmBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageManage override fun getPlatformDependentDeclarationFilter(): PlatformDependentDeclarationFilter { settings = JvmBuiltInsSettings( builtInsModule, storageManager, - { ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" } } + { ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" } }, + { isAdditionalBuiltInsFeatureSupported } ) return settings diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt index ef2664b350f..3bf82f56b32 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/RuntimeModuleData.kt @@ -63,7 +63,7 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext) - builtIns.initialize(module) + builtIns.initialize(module, isAdditionalBuiltInsFeatureSupported = true) val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, javaResolverCache) val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt index f80f13295dd..9e3a6c09605 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/annotationsForResolve.kt @@ -27,7 +27,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") -private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_FQ_NAME = FqName("kotlin.internal.LowPriorityInOverloadResolution") +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") @@ -65,4 +65,4 @@ private class AnnotationsWithOnly(val presentAnnotation: FqName): Annotations { override fun getUseSiteTargetedAnnotations(): List = emptyList() override fun getAllAnnotations(): List = emptyList() -} \ No newline at end of file +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt index b2eb4b6fb2a..9367dc6339c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt @@ -32,6 +32,9 @@ import org.jetbrains.kotlin.analyzer.EmptyResolverForProject import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.container.getService import org.jetbrains.kotlin.context.GlobalContext import org.jetbrains.kotlin.context.GlobalContextImpl @@ -381,9 +384,12 @@ private fun globalResolveSessionProvider( if (newBuiltIns is JvmBuiltIns) { val sdkInfo = SdkInfo(project, sdk!!) - newBuiltIns.initialize(moduleResolverProvider.resolverForProject.descriptorForModule(sdkInfo)) + newBuiltIns.initialize( + moduleResolverProvider.resolverForProject.descriptorForModule(sdkInfo), + moduleResolverProvider.resolverForProject.resolverForModule(sdkInfo) + .componentProvider.get() + .supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) } moduleResolverProvider } -