Replace FqName by ClassId where possible in Java resolver

This commit is contained in:
Alexander Udalov
2014-08-29 12:06:33 +04:00
parent 9648c50ac9
commit e3b01f073f
6 changed files with 59 additions and 33 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java.structure.impl;
import com.intellij.psi.*; import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation; import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation;
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationArgument; import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationArgument;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
@@ -49,20 +50,36 @@ public class JavaAnnotationImpl extends JavaElementImpl<PsiAnnotation> implement
@Override @Override
@Nullable @Nullable
public FqName getFqName() { public ClassId getClassId() {
String qualifiedName = getPsi().getQualifiedName(); PsiClass resolved = resolvePsi();
return qualifiedName == null ? null : new FqName(qualifiedName); return resolved == null ? null : computeClassId(resolved);
} }
@Nullable @Nullable
@Override @Override
public JavaClass resolve() { public JavaClass resolve() {
PsiClass resolved = resolvePsi();
return resolved == null ? null : new JavaClassImpl(resolved);
}
@Nullable
private static ClassId computeClassId(@NotNull PsiClass psiClass) {
PsiClass container = psiClass.getContainingClass();
if (container != null) {
ClassId parentClassId = computeClassId(container);
return parentClassId == null ? null : parentClassId.createNestedClassId(Name.identifier(psiClass.getName()));
}
String fqName = psiClass.getQualifiedName();
return fqName == null ? null : ClassId.topLevel(new FqName(fqName));
}
@Nullable
private PsiClass resolvePsi() {
PsiJavaCodeReferenceElement referenceElement = getPsi().getNameReferenceElement(); PsiJavaCodeReferenceElement referenceElement = getPsi().getNameReferenceElement();
if (referenceElement == null) return null; if (referenceElement == null) return null;
PsiElement resolved = referenceElement.resolve(); PsiElement resolved = referenceElement.resolve();
if (!(resolved instanceof PsiClass)) return null; return resolved instanceof PsiClass ? (PsiClass) resolved : null;
return new JavaClassImpl((PsiClass) resolved);
} }
} }
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -102,8 +103,8 @@ public final class JvmAnnotationNames {
SPECIAL_ANNOTATIONS.add(KotlinSyntheticClass.CLASS_NAME); SPECIAL_ANNOTATIONS.add(KotlinSyntheticClass.CLASS_NAME);
} }
public static boolean isSpecialAnnotation(@NotNull FqName fqName) { public static boolean isSpecialAnnotation(@NotNull ClassId classId) {
return isSpecialAnnotation(JvmClassName.byFqNameWithoutInnerClasses(fqName)); return isSpecialAnnotation(JvmClassName.byClassId(classId));
} }
public static boolean isSpecialAnnotation(@NotNull JvmClassName name) { public static boolean isSpecialAnnotation(@NotNull JvmClassName name) {
@@ -17,12 +17,10 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
public class JvmClassName { public class JvmClassName {
@NotNull @NotNull
@@ -30,6 +28,15 @@ public class JvmClassName {
return new JvmClassName(internalName); return new JvmClassName(internalName);
} }
@NotNull
public static JvmClassName byClassId(@NotNull ClassId classId) {
FqName packageFqName = classId.getPackageFqName();
String relativeClassName = classId.getRelativeClassName().asString().replace('.', '$');
return packageFqName.isRoot()
? new JvmClassName(relativeClassName)
: new JvmClassName(packageFqName.asString().replace('.', '/') + "/" + relativeClassName);
}
/** /**
* WARNING: fq name cannot be uniquely mapped to JVM class name. * WARNING: fq name cannot be uniquely mapped to JVM class name.
*/ */
@@ -21,17 +21,13 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationOwner
import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.descriptors.annotations.Annotations import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor 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.JvmAnnotationNames import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.resolveAnnotation
class LazyJavaAnnotations(c: LazyJavaResolverContextWithTypes, val annotationOwner: JavaAnnotationOwner) : Annotations { class LazyJavaAnnotations(c: LazyJavaResolverContextWithTypes, val annotationOwner: JavaAnnotationOwner) : Annotations {
private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues { private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues {
(jAnnotation: JavaAnnotation) -> (annotation: JavaAnnotation) ->
val fqName = jAnnotation.getFqName() c.resolveAnnotation(annotation)
if (fqName == null || JvmAnnotationNames.isSpecialAnnotation(fqName)) {
null
}
else LazyJavaAnnotationDescriptor(c, jAnnotation)
} }
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? { override fun findAnnotation(fqName: FqName): AnnotationDescriptor? {
@@ -17,11 +17,10 @@
package org.jetbrains.jet.lang.resolve.java.lazy.descriptors package org.jetbrains.jet.lang.resolve.java.lazy.descriptors
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.jet.lang.types.JetType import org.jetbrains.jet.lang.types.*
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContextWithTypes
import org.jetbrains.jet.lang.resolve.java.structure.* import org.jetbrains.jet.lang.resolve.java.structure.*
import org.jetbrains.jet.lang.types.ErrorUtils
import org.jetbrains.jet.lang.resolve.constants.* import org.jetbrains.jet.lang.resolve.constants.*
import org.jetbrains.jet.lang.resolve.name.Name import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.name.FqName
@@ -30,27 +29,37 @@ import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.*
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage import org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage
import org.jetbrains.jet.lang.types.TypeProjectionImpl
import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaType import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaType
import org.jetbrains.jet.utils.valuesToMap import org.jetbrains.jet.utils.valuesToMap
import org.jetbrains.jet.utils.keysToMapExceptNulls import org.jetbrains.jet.utils.keysToMapExceptNulls
import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes import org.jetbrains.jet.lang.resolve.java.lazy.types.toAttributes
import org.jetbrains.jet.renderer.DescriptorRenderer import org.jetbrains.jet.renderer.DescriptorRenderer
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap
import org.jetbrains.jet.lang.types.TypeUtils
import org.jetbrains.jet.lang.resolve.resolveTopLevelClass import org.jetbrains.jet.lang.resolve.resolveTopLevelClass
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName
private object DEPRECATED_IN_JAVA : JavaLiteralAnnotationArgument { private object DEPRECATED_IN_JAVA : JavaLiteralAnnotationArgument {
override val name: Name? = null override val name: Name? = null
override val value: Any? = "Deprecated in Java" override val value: Any? = "Deprecated in Java"
} }
fun LazyJavaResolverContextWithTypes.resolveAnnotation(annotation: JavaAnnotation): LazyJavaAnnotationDescriptor? {
val classId = annotation.getClassId()
if (classId == null || JvmAnnotationNames.isSpecialAnnotation(classId)) return null
return LazyJavaAnnotationDescriptor(this, annotation)
}
class LazyJavaAnnotationDescriptor( class LazyJavaAnnotationDescriptor(
private val c: LazyJavaResolverContextWithTypes, private val c: LazyJavaResolverContextWithTypes,
val javaAnnotation : JavaAnnotation val javaAnnotation : JavaAnnotation
) : AnnotationDescriptor { ) : AnnotationDescriptor {
private val fqName = c.storageManager.createNullableLazyValue { javaAnnotation.getFqName() } private val fqName = c.storageManager.createNullableLazyValue {
val classId = javaAnnotation.getClassId()
if (classId == null) null
else kotlinFqNameToJavaFqName(classId.asSingleFqName())
}
private val _type = c.storageManager.createLazyValue {() : JetType -> private val _type = c.storageManager.createLazyValue {() : JetType ->
val fqName = fqName() val fqName = fqName()
if (fqName == null) return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation") if (fqName == null) return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
@@ -69,7 +78,7 @@ class LazyJavaAnnotationDescriptor(
arguments.valuesToMap { it.name } arguments.valuesToMap { it.name }
} }
private val valueArguments = c.storageManager.createMemoizedFunctionWithNullableValues<ValueParameterDescriptor, CompileTimeConstant<out Any?>> { private val valueArguments = c.storageManager.createMemoizedFunctionWithNullableValues<ValueParameterDescriptor, CompileTimeConstant<*>> {
valueParameter -> valueParameter ->
val nameToArg = nameToArgument() val nameToArg = nameToArgument()
@@ -109,14 +118,10 @@ class LazyJavaAnnotationDescriptor(
} }
private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): CompileTimeConstant<*>? { private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): CompileTimeConstant<*>? {
val fqName = javaAnnotation.getFqName() val descriptor = c.resolveAnnotation(javaAnnotation)
if (fqName == null) return null if (descriptor == null) return null
if (JvmAnnotationNames.isSpecialAnnotation(fqName)) { return AnnotationValue(descriptor)
return null
}
return AnnotationValue(LazyJavaAnnotationDescriptor(c, javaAnnotation))
} }
private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): CompileTimeConstant<*>? { private fun resolveFromArray(argumentName: Name, elements: List<JavaAnnotationArgument>): CompileTimeConstant<*>? {
@@ -18,7 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.structure;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.descriptors.serialization.ClassId;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collection; import java.util.Collection;
@@ -31,7 +31,7 @@ public interface JavaAnnotation extends JavaElement {
Collection<JavaAnnotationArgument> getArguments(); Collection<JavaAnnotationArgument> getArguments();
@Nullable @Nullable
FqName getFqName(); ClassId getClassId();
@Nullable @Nullable
JavaClass resolve(); JavaClass resolve();