Support external annotations in IDE when approximating flexible types
This commit is contained in:
+13
-13
@@ -16,20 +16,20 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.lazy.descriptors
|
package org.jetbrains.kotlin.resolve.lazy.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
|
||||||
import org.jetbrains.kotlin.psi.JetAnnotationEntry
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.JetAnnotationEntry
|
||||||
|
import org.jetbrains.kotlin.resolve.AnnotationResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
|
||||||
import org.jetbrains.kotlin.resolve.AnnotationResolver
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
abstract class LazyAnnotationsContext(
|
abstract class LazyAnnotationsContext(
|
||||||
val annotationResolver: AnnotationResolver,
|
val annotationResolver: AnnotationResolver,
|
||||||
@@ -75,9 +75,9 @@ public class LazyAnnotations(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun iterator(): Iterator<AnnotationDescriptor> {
|
override fun findExternalAnnotation(fqName: FqName) = null
|
||||||
return annotationEntries.stream().map(annotation).iterator()
|
|
||||||
}
|
override fun iterator(): Iterator<AnnotationDescriptor> = annotationEntries.sequence().map(annotation).iterator()
|
||||||
|
|
||||||
override fun forceResolveAllContents() {
|
override fun forceResolveAllContents() {
|
||||||
// To resolve all entries
|
// To resolve all entries
|
||||||
|
|||||||
+11
-2
@@ -32,9 +32,14 @@ class LazyJavaAnnotations(
|
|||||||
c.resolveAnnotation(annotation)
|
c.resolveAnnotation(annotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName) = annotationOwner.findAnnotation(fqName)?.let(annotationDescriptors)
|
override fun findAnnotation(fqName: FqName) =
|
||||||
|
annotationOwner.findAnnotation(fqName)?.let(annotationDescriptors)
|
||||||
|
|
||||||
override fun iterator() = annotationOwner.getAnnotations().sequence().map(annotationDescriptors).filterNotNull().iterator()
|
override fun findExternalAnnotation(fqName: FqName) =
|
||||||
|
c.externalAnnotationResolver.findExternalAnnotation(annotationOwner, fqName)?.let(annotationDescriptors)
|
||||||
|
|
||||||
|
override fun iterator() =
|
||||||
|
annotationOwner.getAnnotations().sequence().map(annotationDescriptors).filterNotNull().iterator()
|
||||||
|
|
||||||
override fun isEmpty() = !iterator().hasNext()
|
override fun isEmpty() = !iterator().hasNext()
|
||||||
}
|
}
|
||||||
@@ -47,6 +52,10 @@ class FilteredAnnotations(
|
|||||||
if (fqNameFilter(fqName)) delegate.findAnnotation(fqName)
|
if (fqNameFilter(fqName)) delegate.findAnnotation(fqName)
|
||||||
else null
|
else null
|
||||||
|
|
||||||
|
override fun findExternalAnnotation(fqName: FqName) =
|
||||||
|
if (fqNameFilter(fqName)) delegate.findExternalAnnotation(fqName)
|
||||||
|
else null
|
||||||
|
|
||||||
override fun iterator() = delegate.sequence()
|
override fun iterator() = delegate.sequence()
|
||||||
.filter { annotation ->
|
.filter { annotation ->
|
||||||
val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor()
|
val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor()
|
||||||
|
|||||||
@@ -24,12 +24,16 @@ public trait Annotations : Iterable<AnnotationDescriptor> {
|
|||||||
|
|
||||||
public fun findAnnotation(fqName: FqName): AnnotationDescriptor?
|
public fun findAnnotation(fqName: FqName): AnnotationDescriptor?
|
||||||
|
|
||||||
|
public fun findExternalAnnotation(fqName: FqName): AnnotationDescriptor?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
public val EMPTY: Annotations = object : Annotations {
|
public val EMPTY: Annotations = object : Annotations {
|
||||||
override fun isEmpty() = true
|
override fun isEmpty() = true
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName) = null
|
override fun findAnnotation(fqName: FqName) = null
|
||||||
|
|
||||||
|
override fun findExternalAnnotation(fqName: FqName) = null
|
||||||
|
|
||||||
override fun iterator() = emptyList<AnnotationDescriptor>().iterator()
|
override fun iterator() = emptyList<AnnotationDescriptor>().iterator()
|
||||||
|
|
||||||
override fun toString() = "EMPTY"
|
override fun toString() = "EMPTY"
|
||||||
|
|||||||
-68
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.descriptors.annotations;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AnnotationsImpl implements Annotations {
|
|
||||||
private final List<AnnotationDescriptor> annotations;
|
|
||||||
|
|
||||||
public AnnotationsImpl(@NotNull List<AnnotationDescriptor> annotations) {
|
|
||||||
this.annotations = annotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public List<AnnotationDescriptor> getAnnotationDescriptors() {
|
|
||||||
return annotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return getAnnotationDescriptors().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public AnnotationDescriptor findAnnotation(@NotNull FqName fqName) {
|
|
||||||
for (AnnotationDescriptor annotation : annotations) {
|
|
||||||
ClassifierDescriptor descriptor = annotation.getType().getConstructor().getDeclarationDescriptor();
|
|
||||||
if (descriptor instanceof ClassDescriptor && fqName.toUnsafe().equals(DescriptorUtils.getFqName(descriptor))) {
|
|
||||||
return annotation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Iterator<AnnotationDescriptor> iterator() {
|
|
||||||
return getAnnotationDescriptors().iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return annotations.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.descriptors.annotations
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
|
||||||
|
public class AnnotationsImpl(private val annotations: List<AnnotationDescriptor>) : Annotations {
|
||||||
|
override fun isEmpty() = annotations.isEmpty()
|
||||||
|
|
||||||
|
override fun findAnnotation(fqName: FqName) = annotations.firstOrNull {
|
||||||
|
val descriptor = it.getType().getConstructor().getDeclarationDescriptor()
|
||||||
|
descriptor is ClassDescriptor && fqName.toUnsafe() == DescriptorUtils.getFqName(descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findExternalAnnotation(fqName: FqName) = null
|
||||||
|
|
||||||
|
override fun iterator() = annotations.iterator()
|
||||||
|
|
||||||
|
override fun toString() = annotations.toString()
|
||||||
|
}
|
||||||
+6
-4
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.serialization.deserialization.descriptors
|
package org.jetbrains.kotlin.serialization.deserialization.descriptors
|
||||||
|
|
||||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||||
|
|
||||||
class DeserializedAnnotations(
|
class DeserializedAnnotations(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
@@ -32,11 +32,13 @@ class DeserializedAnnotations(
|
|||||||
|
|
||||||
override fun isEmpty(): Boolean = annotations().isEmpty()
|
override fun isEmpty(): Boolean = annotations().isEmpty()
|
||||||
|
|
||||||
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? = annotations().firstOrNull {
|
override fun findAnnotation(fqName: FqName) = annotations().firstOrNull {
|
||||||
annotation ->
|
annotation ->
|
||||||
val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor()
|
val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor()
|
||||||
descriptor is ClassDescriptor && fqName.equalsTo(DescriptorUtils.getFqName(descriptor))
|
descriptor is ClassDescriptor && fqName.equalsTo(DescriptorUtils.getFqName(descriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun findExternalAnnotation(fqName: FqName) = null
|
||||||
|
|
||||||
override fun iterator(): Iterator<AnnotationDescriptor> = annotations().iterator()
|
override fun iterator(): Iterator<AnnotationDescriptor> = annotations().iterator()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.substitute
|
import org.jetbrains.kotlin.types.typeUtil.substitute
|
||||||
import java.util.LinkedHashSet
|
|
||||||
|
|
||||||
fun JetType.makeNullable() = TypeUtils.makeNullable(this)
|
fun JetType.makeNullable() = TypeUtils.makeNullable(this)
|
||||||
fun JetType.makeNotNullable() = TypeUtils.makeNotNullable(this)
|
fun JetType.makeNotNullable() = TypeUtils.makeNotNullable(this)
|
||||||
@@ -63,20 +64,12 @@ public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true)
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JetType.isMarkedReadOnly() = getAnnotations().findAnnotation(JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null
|
private fun JetType.isMarkedReadOnly() = hasAnnotationMaybeExternal(JETBRAINS_READONLY_ANNOTATION)
|
||||||
private fun JetType.isMarkedNotNull() = getAnnotations().findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null
|
private fun JetType.isMarkedNotNull() = hasAnnotationMaybeExternal(JETBRAINS_NOT_NULL_ANNOTATION)
|
||||||
|
|
||||||
public fun JetType.getAllReferencedTypes(): Set<JetType> {
|
private fun JetType.hasAnnotationMaybeExternal(fqName: FqName) = with (getAnnotations()) {
|
||||||
val types = LinkedHashSet<JetType>()
|
findAnnotation(fqName) ?: findExternalAnnotation(fqName)
|
||||||
|
} != null
|
||||||
fun addType(type: JetType) {
|
|
||||||
types.add(type)
|
|
||||||
type.getArguments().forEach { addType(it.getType()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
addType(this)
|
|
||||||
return types
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum class TypeNullability {
|
public enum class TypeNullability {
|
||||||
NOT_NULL
|
NOT_NULL
|
||||||
|
|||||||
Reference in New Issue
Block a user