diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index 1f3632968e4..2a2e0a5a521 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -138,7 +138,7 @@ public class JvmCodegenUtil { return false; } - KotlinJvmBinaryClass binaryClass = ((LazyJavaPackageFragment) packageFragment).getMemberScope().getKotlinBinaryClass(); + KotlinJvmBinaryClass binaryClass = ((LazyJavaPackageFragment) packageFragment).getScope().getKotlinBinaryClass(); if (binaryClass instanceof VirtualFileKotlinClass) { VirtualFile file = ((VirtualFileKotlinClass) binaryClass).getFile(); if (file.getFileSystem().getProtocol() == StandardFileSystems.FILE_PROTOCOL) { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt index 2b5586bf725..518f492af67 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/incremental/IncrementalPackageFragmentProvider.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.kotlin.resolve.scopes.DecapitalizedAnnotationScope import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.serialization.PackageData import org.jetbrains.kotlin.serialization.ProtoBuf @@ -105,7 +106,7 @@ public class IncrementalPackageFragmentProvider( JetScope.Empty } else { - IncrementalPackageScope(JvmProtoBufUtil.readPackageDataFrom(packageDataBytes)) + DecapitalizedAnnotationScope.wrapIfNeeded(IncrementalPackageScope(JvmProtoBufUtil.readPackageDataFrom(packageDataBytes)), fqName) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyPackageDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyPackageDescriptor.java index 2b7de45d7b5..06650c4d020 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyPackageDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyPackageDescriptor.java @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil; import org.jetbrains.kotlin.resolve.lazy.LazyEntity; import org.jetbrains.kotlin.resolve.lazy.ResolveSession; import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider; +import org.jetbrains.kotlin.resolve.scopes.DecapitalizedAnnotationScope; import org.jetbrains.kotlin.resolve.scopes.JetScope; public class LazyPackageDescriptor extends PackageFragmentDescriptorImpl implements LazyEntity { @@ -41,7 +42,8 @@ public class LazyPackageDescriptor extends PackageFragmentDescriptorImpl impleme super(module, fqName); this.declarationProvider = declarationProvider; - this.memberScope = new LazyPackageMemberScope(resolveSession, declarationProvider, this); + // Wrapping is just a temporary hack to inject deprecated decapitalized annotation + this.memberScope = DecapitalizedAnnotationScope.Companion.wrapIfNeeded(new LazyPackageMemberScope(resolveSession, declarationProvider, this), fqName); for (JetFile file : declarationProvider.getPackageFiles()) { resolveSession.getTrace().record(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file, this); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt index c3c1fbcb4d7..e3b2cc7469d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaPackageFragmentProvider.kt @@ -51,7 +51,7 @@ public class LazyJavaPackageFragmentProvider( override fun getPackageFragments(fqName: FqName) = emptyOrSingletonList(getPackageFragment(fqName)) override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) = - getPackageFragment(fqName)?.getMemberScope()?.getSubPackages().orEmpty() + getPackageFragment(fqName)?.scope?.getSubPackages().orEmpty() fun getClass(javaClass: JavaClass): ClassDescriptor? = c.javaClassResolver.resolveClass(javaClass) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt index 68c538ea39e..06b53183265 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -22,12 +22,16 @@ import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement +import org.jetbrains.kotlin.resolve.scopes.DecapitalizedAnnotationScope +import org.jetbrains.kotlin.resolve.scopes.JetScope class LazyJavaPackageFragment( private val c: LazyJavaResolverContext, private val jPackage: JavaPackage ) : PackageFragmentDescriptorImpl(c.module, jPackage.getFqName()) { - private val scope by lazy { LazyJavaPackageScope(c, jPackage, this) } + val scope: LazyJavaPackageScope by lazy { LazyJavaPackageScope(c, jPackage, this) } + // Just a temporary hack to inject deprecated decapitalized annotation + private val wrappedScope by lazy { DecapitalizedAnnotationScope.wrapIfNeeded(scope, jPackage.getFqName()) } private val topLevelClasses = c.storageManager.createMemoizedFunctionWithNullableValues { javaClass: JavaClass -> @@ -36,7 +40,7 @@ class LazyJavaPackageFragment( internal fun resolveTopLevelClass(javaClass: JavaClass) = topLevelClasses(javaClass) - override fun getMemberScope() = scope + override fun getMemberScope(): JetScope = wrappedScope override fun toString() = "lazy java package fragment: $fqName" diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/DecapitalizedAnnotationScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/DecapitalizedAnnotationScope.kt new file mode 100644 index 00000000000..8bd69f81a89 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/DecapitalizedAnnotationScope.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2015 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.scopes + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe + +val DECAPITALIZED_DEPRECATED_ANNOTATIONS = arrayOf( + "Deprecated", "Extension", "Suppress", "Throws", + "jvm.Volatile", "jvm.Transient", "jvm.Strictfp", "jvm.Synchronized", + "jvm.JvmOverloads", "jvm.JvmName", "jvm.JvmStatic" +).map { FqName("kotlin.$it") }.toSet() + +val DECAPITALIZED_SHORT_NAMES = DECAPITALIZED_DEPRECATED_ANNOTATIONS.map { it.shortName().asString().decapitalize() }.toSet() + +public class DecapitalizedAnnotationScope(override val workerScope: JetScope) : AbstractScopeAdapter() { + override fun getClassifier(name: Name, location: LookupLocation) + = super.getClassifier(name, location) + ?: findDecapitalizedAnnotation(name, location) + + private fun findDecapitalizedAnnotation(name: Name, location: LookupLocation): ClassifierDescriptor? { + val nameAsString = name.asString() + + if (nameAsString[0].isUpperCase() || nameAsString !in DECAPITALIZED_SHORT_NAMES) return null + val capitalizedIdentifier = Name.identifier(nameAsString.capitalize()) + + val capitalizedClassifier = getClassifier(capitalizedIdentifier, location) ?: return null + + return if (capitalizedClassifier.fqNameSafe in DECAPITALIZED_DEPRECATED_ANNOTATIONS) + capitalizedClassifier + else + null + } + + companion object { + public fun wrapIfNeeded(scope: JetScope, fqName: FqName): JetScope { + if (fqName.firstSegmentIs(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) { + return DecapitalizedAnnotationScope(scope) + } + return scope + } + } +} diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt index 52f955cfcf6..d96e3158968 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt @@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.DecapitalizedAnnotationScope +import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.SerializedResourcePaths import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope @@ -56,10 +58,17 @@ public abstract class DeserializedPackageFragment( DeserializedPackageMemberScope(this, packageProto, nameResolver, components, classNames = { loadClassNames(packageProto) }) } - override fun getMemberScope() = deserializedMemberScope + // Just a temporary hack to inject deprecated decapitalized annotation + internal val deserializedMemberScopeWrapped by storageManager.createLazyValue { + DecapitalizedAnnotationScope.wrapIfNeeded(deserializedMemberScope, fqName) + } + + override fun getMemberScope(): JetScope { + return deserializedMemberScopeWrapped + } internal fun hasTopLevelClass(name: Name): Boolean { - return name in getMemberScope().classNames + return name in deserializedMemberScope.classNames } protected abstract fun loadClassNames(packageProto: ProtoBuf.Package): Collection