Allow to trigger search for external annotations lazily
This commit is contained in:
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.jet.lang.resolve.java.lazy
|
||||
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaAnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationOwner
|
||||
|
||||
fun LazyJavaResolverContextWithTypes.resolveAnnotations(javaAnnotations: Collection<JavaAnnotation>): List<AnnotationDescriptor>
|
||||
= javaAnnotations.map {jAnnotation -> LazyJavaAnnotationDescriptor(this, jAnnotation)}
|
||||
|
||||
// TODO: These methods are a workaround for inability to refactor List<AnnotationDescriptor> -> Annotations at the moment
|
||||
fun JavaAnnotationOwner.hasMutableAnnotation(): Boolean = false
|
||||
fun JavaAnnotationOwner.hasReadOnlyAnnotation(): Boolean = false
|
||||
fun JavaAnnotationOwner.hasNotNullAnnotation(): Boolean = false
|
||||
@@ -24,11 +24,13 @@ import org.jetbrains.jet.lang.resolve.java.JavaClassFinder
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaAnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.ExternalAnnotationResolver
|
||||
|
||||
open class LazyJavaResolverContext(
|
||||
val storageManager: StorageManager,
|
||||
val finder: JavaClassFinder,
|
||||
val javaClassResolver: LazyJavaClassResolver
|
||||
val javaClassResolver: LazyJavaClassResolver,
|
||||
val externalAnnotationResolver: ExternalAnnotationResolver
|
||||
)
|
||||
|
||||
fun LazyJavaResolverContext.withTypes(
|
||||
@@ -37,6 +39,7 @@ fun LazyJavaResolverContext.withTypes(
|
||||
storageManager,
|
||||
finder,
|
||||
javaClassResolver,
|
||||
externalAnnotationResolver,
|
||||
LazyJavaTypeResolver(this, typeParameterResolver),
|
||||
typeParameterResolver)
|
||||
|
||||
@@ -44,14 +47,12 @@ class LazyJavaResolverContextWithTypes(
|
||||
storageManager: StorageManager,
|
||||
finder: JavaClassFinder,
|
||||
javaClassResolver: LazyJavaClassResolver,
|
||||
externalAnnotationResolver: ExternalAnnotationResolver,
|
||||
val typeResolver: LazyJavaTypeResolver,
|
||||
val typeParameterResolver: TypeParameterResolver
|
||||
) : LazyJavaResolverContext(storageManager, finder, javaClassResolver)
|
||||
) : LazyJavaResolverContext(storageManager, finder, javaClassResolver, externalAnnotationResolver)
|
||||
|
||||
fun LazyJavaResolverContextWithTypes.child(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
typeParameters: Set<JavaTypeParameter>
|
||||
): LazyJavaResolverContextWithTypes = this.withTypes(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameters))
|
||||
|
||||
fun LazyJavaResolverContextWithTypes.resolveAnnotations(javaAnnotations: Collection<JavaAnnotation>): List<AnnotationDescriptor>
|
||||
= javaAnnotations.map {jAnnotation -> LazyJavaAnnotationDescriptor(this, jAnnotation)}
|
||||
): LazyJavaResolverContextWithTypes = this.withTypes(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameters))
|
||||
+2
-1
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyType
|
||||
import org.jetbrains.jet.utils.valuesToMap
|
||||
import org.jetbrains.jet.utils.keysToMap
|
||||
import org.jetbrains.jet.utils.keysToMapExceptNulls
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||
|
||||
@@ -128,7 +129,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
}
|
||||
|
||||
private fun resolveFromJavaClassObjectType(javaType: JavaType): CompileTimeConstant<*>? {
|
||||
val `type` = c.typeResolver.transformJavaType(javaType, TypeUsage.MEMBER_SIGNATURE_INVARIANT)
|
||||
val `type` = c.typeResolver.transformJavaType(javaType, TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes())
|
||||
val jlClass = c.javaClassResolver.resolveClassByFqName(JavaAnnotationArgumentResolver.JL_CLASS_FQ_NAME)
|
||||
if (jlClass == null) return null
|
||||
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorFactory
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.child
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.resolveAnnotations
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
|
||||
|
||||
class LazyJavaClassDescriptor(
|
||||
private val c: LazyJavaResolverContextWithTypes,
|
||||
@@ -82,7 +83,7 @@ class LazyJavaClassDescriptor(
|
||||
private val _supertypes = c.storageManager.createLazyValue {
|
||||
jClass.getSupertypes().map {
|
||||
supertype ->
|
||||
innerC.typeResolver.transformJavaType(supertype, TypeUsage.SUPERTYPE)
|
||||
innerC.typeResolver.transformJavaType(supertype, TypeUsage.SUPERTYPE.toAttributes())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -22,9 +22,9 @@ import org.jetbrains.jet.lang.types.Variance
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
|
||||
|
||||
class LazyJavaTypeParameterDescriptor(
|
||||
private val c: LazyJavaResolverContextWithTypes,
|
||||
@@ -46,7 +46,7 @@ class LazyJavaTypeParameterDescriptor(
|
||||
}
|
||||
else {
|
||||
return bounds.map {
|
||||
javaType -> c.typeResolver.transformJavaType(javaType, TypeUsage.UPPER_BOUND)
|
||||
javaType -> c.typeResolver.transformJavaType(javaType, TypeUsage.UPPER_BOUND.toAttributes())
|
||||
}.toSet()
|
||||
}
|
||||
}
|
||||
|
||||
+62
-21
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.lazy.types
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaType
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||
@@ -26,8 +25,6 @@ import org.jetbrains.jet.lang.resolve.java.resolver.*
|
||||
import org.jetbrains.jet.lang.types.Variance.*
|
||||
import org.jetbrains.jet.lang.types.*
|
||||
import org.jetbrains.kotlin.util.iif
|
||||
import org.jetbrains.jet.utils.*
|
||||
import org.jetbrains.jet.storage.*
|
||||
import org.jetbrains.kotlin.util.eq
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaPrimitiveType
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType
|
||||
@@ -37,11 +34,11 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.util.sure
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolver
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolverImpl
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationOwner
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.*
|
||||
import org.jetbrains.jet.storage.*
|
||||
|
||||
class LazyJavaTypeResolver(
|
||||
private val c: LazyJavaResolverContext,
|
||||
@@ -49,7 +46,7 @@ class LazyJavaTypeResolver(
|
||||
) {
|
||||
private val NOT_NULL_POSITIONS = setOf(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT, SUPERTYPE)
|
||||
|
||||
public fun transformJavaType(javaType: JavaType, howThisTypeIsUsed: TypeUsage): JetType {
|
||||
public fun transformJavaType(javaType: JavaType, attr: JavaTypeAttributes): JetType {
|
||||
return when (javaType) {
|
||||
is JavaPrimitiveType -> {
|
||||
val canonicalText = javaType.getCanonicalText()
|
||||
@@ -57,33 +54,36 @@ class LazyJavaTypeResolver(
|
||||
assert(jetType != null, "Primitive type is not found: " + canonicalText)
|
||||
return jetType!!
|
||||
}
|
||||
is JavaClassifierType -> LazyJavaClassifierType(javaType, howThisTypeIsUsed).applyNullablility(howThisTypeIsUsed)
|
||||
is JavaArrayType -> transformArrayType(javaType, howThisTypeIsUsed).applyNullablility(howThisTypeIsUsed)
|
||||
is JavaClassifierType -> LazyJavaClassifierType(javaType, attr).applyNullablility(attr)
|
||||
is JavaArrayType -> transformArrayType(javaType, attr).applyNullablility(attr)
|
||||
else -> throw UnsupportedOperationException("Unsupported type: " + javaType)
|
||||
}
|
||||
}
|
||||
|
||||
public fun transformArrayType(arrayType: JavaArrayType, howThisTypeIsUsed: TypeUsage, isVararg: Boolean = false): JetType {
|
||||
public fun transformArrayType(arrayType: JavaArrayType, attr: JavaTypeAttributes, isVararg: Boolean = false): JetType {
|
||||
val javaComponentType = arrayType.getComponentType()
|
||||
if (javaComponentType is JavaPrimitiveType) {
|
||||
val jetType = JavaToKotlinClassMap.getInstance().mapPrimitiveKotlinClass("[" + javaComponentType.getCanonicalText())
|
||||
if (jetType != null) return jetType
|
||||
}
|
||||
|
||||
val projectionKind = if (howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT && !isVararg) OUT_VARIANCE else INVARIANT
|
||||
val projectionKind = if (attr.howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT && !isVararg) OUT_VARIANCE else INVARIANT
|
||||
|
||||
val howArgumentTypeIsUsed = isVararg.iif(MEMBER_SIGNATURE_CONTRAVARIANT, TYPE_ARGUMENT)
|
||||
val componentType = transformJavaType(javaComponentType, howArgumentTypeIsUsed)
|
||||
val componentType = transformJavaType(javaComponentType, howArgumentTypeIsUsed.toAttributes())
|
||||
return TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getArrayType(projectionKind, componentType))
|
||||
}
|
||||
|
||||
private fun JetType.applyNullablility(howThisTypeIsUsed: TypeUsage): JetType {
|
||||
return TypeUtils.makeNullableAsSpecified(this, howThisTypeIsUsed !in NOT_NULL_POSITIONS)
|
||||
private fun JetType.applyNullablility(attr: JavaTypeAttributes): JetType {
|
||||
if (attr.howThisTypeIsUsed in NOT_NULL_POSITIONS) {
|
||||
return TypeUtils.makeNotNullable(this)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun transformToTypeProjection(
|
||||
javaType: JavaType,
|
||||
howThisTypeIsUsed: TypeUsage,
|
||||
attr: JavaTypeAttributes,
|
||||
typeConstructorBeingApplied: () -> TypeConstructor,
|
||||
typeParameterIndex: Int
|
||||
): TypeProjection {
|
||||
@@ -93,10 +93,10 @@ class LazyJavaTypeResolver(
|
||||
if (bound == null)
|
||||
LazyStarProjection(c, typeConstructorBeingApplied, typeParameterIndex)
|
||||
else {
|
||||
TypeProjectionImpl(javaType.isExtends().iif(OUT_VARIANCE, IN_VARIANCE), transformJavaType(bound, UPPER_BOUND))
|
||||
TypeProjectionImpl(javaType.isExtends().iif(OUT_VARIANCE, IN_VARIANCE), transformJavaType(bound, UPPER_BOUND.toAttributes()))
|
||||
}
|
||||
}
|
||||
else -> TypeProjectionImpl(INVARIANT, transformJavaType(javaType, howThisTypeIsUsed))
|
||||
else -> TypeProjectionImpl(INVARIANT, transformJavaType(javaType, attr))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ class LazyJavaTypeResolver(
|
||||
|
||||
private inner class LazyJavaClassifierType(
|
||||
private val javaType: JavaClassifierType,
|
||||
private val howThisTypeIsUsed: TypeUsage
|
||||
private val attr: JavaTypeAttributes
|
||||
) : LazyType(c.storageManager) {
|
||||
|
||||
|
||||
@@ -126,7 +126,18 @@ class LazyJavaTypeResolver(
|
||||
is JavaClass -> {
|
||||
val fqName = classifier.getFqName()
|
||||
.sure("Class type should have a FQ name: " + classifier)
|
||||
val classData = JavaToKotlinClassMap.getInstance().mapKotlinClass(fqName, howThisTypeIsUsed)
|
||||
|
||||
val javaToKotlinClassMap = JavaToKotlinClassMap.getInstance()
|
||||
val howThisTypeIsUsedEffectively = when {
|
||||
// This case has to be checked before isMarkedReadOnly/isMarkedMutable, because those two are slow
|
||||
// not mapped, we don't care about being marked mutable/read-only
|
||||
javaToKotlinClassMap.mapPlatformClass(fqName).isEmpty() -> attr.howThisTypeIsUsed
|
||||
|
||||
// Read (possibly external) annotations
|
||||
else -> attr.howThisTypeIsUsedAccordingToAnnotations
|
||||
}
|
||||
|
||||
val classData = javaToKotlinClassMap.mapKotlinClass(fqName, howThisTypeIsUsedEffectively)
|
||||
?: c.javaClassResolver.resolveClass(classifier)
|
||||
|
||||
classData?.getTypeConstructor()
|
||||
@@ -141,11 +152,11 @@ class LazyJavaTypeResolver(
|
||||
}
|
||||
|
||||
override fun computeArguments(): List<TypeProjection> {
|
||||
var howTheProjectionIsUsed = howThisTypeIsUsed.eq(SUPERTYPE).iif(SUPERTYPE_ARGUMENT, TYPE_ARGUMENT)
|
||||
var howTheProjectionIsUsed = attr.howThisTypeIsUsed.eq(SUPERTYPE).iif(SUPERTYPE_ARGUMENT, TYPE_ARGUMENT)
|
||||
return javaType.getTypeArguments().withIndices().map {
|
||||
p ->
|
||||
val (i, t) = p
|
||||
transformToTypeProjection(t, howTheProjectionIsUsed, {getConstructor()}, i)
|
||||
transformToTypeProjection(t, howTheProjectionIsUsed.toAttributes(), {getConstructor()}, i)
|
||||
}.toList()
|
||||
}
|
||||
|
||||
@@ -156,5 +167,35 @@ class LazyJavaTypeResolver(
|
||||
|
||||
return (descriptor as ClassDescriptor).getMemberScope(getArguments())
|
||||
}
|
||||
|
||||
private val _nullable = c.storageManager.createLazyValue { !attr.isMarkedNotNull }
|
||||
override fun isNullable(): Boolean = _nullable()
|
||||
}
|
||||
}
|
||||
|
||||
trait JavaTypeAttributes {
|
||||
val howThisTypeIsUsed: TypeUsage
|
||||
val howThisTypeIsUsedAccordingToAnnotations: TypeUsage
|
||||
val isMarkedNotNull: Boolean
|
||||
}
|
||||
|
||||
class LazyJavaTypeAttributes(
|
||||
c: LazyJavaResolverContext,
|
||||
val annotationOwner: JavaAnnotationOwner,
|
||||
override val howThisTypeIsUsed: TypeUsage,
|
||||
computeHowThisTypeIsUsedAccrodingToAnnotations: () -> TypeUsage
|
||||
): JavaTypeAttributes {
|
||||
|
||||
override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage by c.storageManager.createLazyValue(
|
||||
computeHowThisTypeIsUsedAccrodingToAnnotations
|
||||
)
|
||||
|
||||
override val isMarkedNotNull: Boolean by c.storageManager.createLazyValue { annotationOwner.hasNotNullAnnotation() }
|
||||
}
|
||||
|
||||
fun TypeUsage.toAttributes() = object : JavaTypeAttributes {
|
||||
override val howThisTypeIsUsed: TypeUsage = this@toAttributes
|
||||
override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage
|
||||
get() = howThisTypeIsUsed
|
||||
override val isMarkedNotNull: Boolean = false
|
||||
}
|
||||
Reference in New Issue
Block a user