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