Introduce optimized BuiltInAnnotationDescriptor for built-in annotations
It's built on a FQ name and avoids resolution of the annotation class descriptor as much as possible
This commit is contained in:
+5
-3
@@ -19,12 +19,14 @@ package org.jetbrains.kotlin.load.kotlin
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
||||
import org.jetbrains.kotlin.descriptors.annotations.BuiltInAnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.createUnsafeVarianceAnnotation
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
internal class UnsafeVarianceTypeSubstitution(kotlinBuiltIns: KotlinBuiltIns) : TypeSubstitution() {
|
||||
private val unsafeVarianceAnnotations = AnnotationsImpl(listOf(kotlinBuiltIns.createUnsafeVarianceAnnotation()))
|
||||
internal class UnsafeVarianceTypeSubstitution(builtIns: KotlinBuiltIns) : TypeSubstitution() {
|
||||
private val unsafeVarianceAnnotations = AnnotationsImpl(listOf(
|
||||
BuiltInAnnotationDescriptor(builtIns, KotlinBuiltIns.FQ_NAMES.unsafeVariance, emptyMap())
|
||||
))
|
||||
|
||||
override fun get(key: KotlinType) = null
|
||||
|
||||
|
||||
@@ -563,11 +563,6 @@ public abstract class KotlinBuiltIns {
|
||||
return getBuiltInClassByName("Throwable");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getDeprecatedAnnotation() {
|
||||
return getBuiltInClassByName(FQ_NAMES.deprecated.shortName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ClassDescriptor getEnumEntry(@NotNull ClassDescriptor enumDescriptor, @NotNull String entryName) {
|
||||
ClassifierDescriptor result = enumDescriptor.getUnsubstitutedInnerClassesScope().getContributedClassifier(
|
||||
|
||||
@@ -20,10 +20,9 @@ import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFac
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
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.BuiltInAnnotationDescriptor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -164,12 +163,10 @@ fun getFunctionTypeArgumentProjections(
|
||||
parameterTypes.mapIndexedTo(arguments) { index, type ->
|
||||
val name = parameterNames?.get(index)?.takeUnless { it.isSpecial }
|
||||
val typeToUse = if (name != null) {
|
||||
val annotationClass = builtIns.getBuiltInClassByName(KotlinBuiltIns.FQ_NAMES.parameterName.shortName())
|
||||
val nameValue = ConstantValueFactory(builtIns).createStringValue(name.asString())
|
||||
val parameterNameAnnotation = AnnotationDescriptorImpl(
|
||||
annotationClass.defaultType,
|
||||
mapOf(Name.identifier("name") to nameValue),
|
||||
SourceElement.NO_SOURCE
|
||||
val parameterNameAnnotation = BuiltInAnnotationDescriptor(
|
||||
builtIns,
|
||||
KotlinBuiltIns.FQ_NAMES.parameterName,
|
||||
mapOf(Name.identifier("name") to ConstantValueFactory(builtIns).createStringValue(name.asString()))
|
||||
)
|
||||
type.replaceAnnotations(AnnotationsImpl(type.annotations + parameterNameAnnotation))
|
||||
}
|
||||
@@ -199,18 +196,14 @@ fun createFunctionType(
|
||||
val parameterCount = if (receiverType == null) size else size + 1
|
||||
val classDescriptor = if (suspendFunction) builtIns.getSuspendFunction(parameterCount) else builtIns.getFunction(parameterCount)
|
||||
|
||||
// TODO: preserve laziness of given annotations
|
||||
val typeAnnotations =
|
||||
if (receiverType == null || annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.extensionFunctionType) != null) {
|
||||
annotations
|
||||
}
|
||||
else {
|
||||
val extensionFunctionAnnotation = AnnotationDescriptorImpl(
|
||||
builtIns.getBuiltInClassByName(KotlinBuiltIns.FQ_NAMES.extensionFunctionType.shortName()).defaultType,
|
||||
emptyMap(), SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
// TODO: preserve laziness of given annotations
|
||||
AnnotationsImpl(annotations + extensionFunctionAnnotation)
|
||||
AnnotationsImpl(annotations +
|
||||
BuiltInAnnotationDescriptor(builtIns, KotlinBuiltIns.FQ_NAMES.extensionFunctionType, emptyMap()))
|
||||
}
|
||||
|
||||
return KotlinTypeFactory.simpleNotNullType(typeAnnotations, classDescriptor, arguments)
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.descriptors.annotations
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
|
||||
class BuiltInAnnotationDescriptor(
|
||||
private val builtIns: KotlinBuiltIns,
|
||||
override val fqName: FqName,
|
||||
override val allValueArguments: Map<Name, ConstantValue<*>>
|
||||
) : AnnotationDescriptor {
|
||||
override val type: KotlinType by lazy(PUBLICATION) {
|
||||
builtIns.getBuiltInClassByFqName(fqName).defaultType
|
||||
}
|
||||
|
||||
override val source: SourceElement
|
||||
get() = SourceElement.NO_SOURCE
|
||||
}
|
||||
+8
-14
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -36,23 +35,23 @@ fun KotlinBuiltIns.createDeprecatedAnnotation(
|
||||
replaceWith: String = "",
|
||||
level: String = "WARNING"
|
||||
): AnnotationDescriptor {
|
||||
val replaceWithAnnotation = AnnotationDescriptorImpl(
|
||||
getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.replaceWith).defaultType,
|
||||
val replaceWithAnnotation = BuiltInAnnotationDescriptor(
|
||||
this,
|
||||
KotlinBuiltIns.FQ_NAMES.replaceWith,
|
||||
mapOf(
|
||||
REPLACE_WITH_EXPRESSION_NAME to StringValue(replaceWith, this),
|
||||
REPLACE_WITH_IMPORTS_NAME to ArrayValue(emptyList(), getArrayType(Variance.INVARIANT, stringType), this)
|
||||
),
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
|
||||
return AnnotationDescriptorImpl(
|
||||
deprecatedAnnotation.defaultType,
|
||||
return BuiltInAnnotationDescriptor(
|
||||
this,
|
||||
KotlinBuiltIns.FQ_NAMES.deprecated,
|
||||
mapOf(
|
||||
DEPRECATED_MESSAGE_NAME to StringValue(message, this),
|
||||
DEPRECATED_REPLACE_WITH_NAME to AnnotationValue(replaceWithAnnotation),
|
||||
DEPRECATED_LEVEL_NAME to EnumValue(getDeprecationLevelEnumEntry(level) ?: error("Deprecation level $level not found"))
|
||||
),
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -62,11 +61,6 @@ private val DEPRECATED_LEVEL_NAME = Name.identifier("level")
|
||||
private val REPLACE_WITH_EXPRESSION_NAME = Name.identifier("expression")
|
||||
private val REPLACE_WITH_IMPORTS_NAME = Name.identifier("imports")
|
||||
|
||||
fun KotlinBuiltIns.createUnsafeVarianceAnnotation(): AnnotationDescriptor {
|
||||
val unsafeVarianceAnnotation = getBuiltInClassByFqName(KotlinBuiltIns.FQ_NAMES.unsafeVariance)
|
||||
return AnnotationDescriptorImpl(unsafeVarianceAnnotation.defaultType, emptyMap(), SourceElement.NO_SOURCE)
|
||||
}
|
||||
|
||||
private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.internal.InlineOnly")
|
||||
|
||||
fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean =
|
||||
|
||||
+2
-4
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.quickfix.replaceWith
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
@@ -37,12 +38,10 @@ import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
@@ -73,8 +72,7 @@ abstract class DeprecatedSymbolUsageFixBase(
|
||||
|
||||
companion object {
|
||||
fun fetchReplaceWithPattern(descriptor: DeclarationDescriptor, project: Project): ReplaceWith? {
|
||||
val annotationClass = descriptor.builtIns.deprecatedAnnotation
|
||||
val annotation = descriptor.annotations.findAnnotation(DescriptorUtils.getFqNameSafe(annotationClass)) ?: return null
|
||||
val annotation = descriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated) ?: return null
|
||||
val replaceWithValue = annotation.argumentValue(kotlin.Deprecated::replaceWith.name) as? AnnotationDescriptor ?: return null
|
||||
val pattern = replaceWithValue.argumentValue(kotlin.ReplaceWith::expression.name) as? String ?: return null
|
||||
if (pattern.isEmpty()) return null
|
||||
|
||||
Reference in New Issue
Block a user