KT-2752: fix JsName with explicit use target. Add some tests for JsName with use targets

This commit is contained in:
Alexey Andreev
2016-06-03 13:05:52 +03:00
parent be0013d9f2
commit 725d13b72e
20 changed files with 138 additions and 41 deletions
@@ -37,7 +37,7 @@ object JsNameChecker : SimpleDeclarationChecker {
}
if (AnnotationsUtils.getJsName(descriptor) == null) return
val jsNamePsi = AnnotationsUtils.getJsNameAnnotationPsi(bindingContext, declaration) ?: return
val jsNamePsi = AnnotationsUtils.getJsNameAnnotationPsi(bindingContext, declaration, descriptor) ?: return
when (descriptor) {
is ConstructorDescriptor -> {
@@ -22,15 +22,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.js.PredefinedAnnotation;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.psi.KtAnnotated;
import org.jetbrains.kotlin.psi.KtAnnotation;
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
@@ -124,7 +122,8 @@ public final class AnnotationsUtils {
@Nullable
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, @NotNull FqName fqName) {
return descriptor.getAnnotations().findAnnotation(fqName);
AnnotationWithTarget annotationWithTarget = Annotations.Companion.findAnyAnnotation(descriptor.getAnnotations(), (fqName));
return annotationWithTarget != null ? annotationWithTarget.getAnnotation() : null;
}
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
@@ -137,15 +136,9 @@ public final class AnnotationsUtils {
@Nullable
public static String getJsName(@NotNull DeclarationDescriptor descriptor) {
AnnotationDescriptor annotation = getAnnotationByName(descriptor, new FqName(JS_NAME));
AnnotationDescriptor annotation = getJsNameAnnotation(descriptor);
if (annotation == null) return null;
if (descriptor instanceof PropertyAccessorDescriptor) {
PropertyAccessorDescriptor accessor = (PropertyAccessorDescriptor) descriptor;
AnnotationDescriptor propertyAnnotation = getAnnotationByName(accessor.getCorrespondingProperty(), new FqName(JS_NAME));
if (propertyAnnotation == annotation) return null;
}
ConstantValue<?> value = annotation.getAllValueArguments().values().iterator().next();
assert value != null : "JsName annotation should always declare string parameter";
@@ -155,26 +148,28 @@ public final class AnnotationsUtils {
}
@Nullable
public static KtAnnotationEntry getJsNameAnnotationPsi(@NotNull BindingContext context, @NotNull KtAnnotated annotated) {
return findAnnotationPsi(context, annotated, new FqName(JS_NAME));
private static AnnotationDescriptor getJsNameAnnotation(@NotNull DeclarationDescriptor descriptor) {
AnnotationDescriptor annotation = getAnnotationByName(descriptor, new FqName(JS_NAME));
if (annotation == null) return null;
if (descriptor instanceof PropertyAccessorDescriptor) {
PropertyAccessorDescriptor accessor = (PropertyAccessorDescriptor) descriptor;
AnnotationDescriptor propertyAnnotation = getAnnotationByName(accessor.getCorrespondingProperty(), new FqName(JS_NAME));
if (propertyAnnotation == annotation) return null;
}
return annotation;
}
@Nullable
private static KtAnnotationEntry findAnnotationPsi(
@NotNull BindingContext context, @NotNull KtAnnotated annotated,
@NotNull FqName nameToFind
) {
FqNameUnsafe nameToFindUnsafe = nameToFind.toUnsafe();
public static KtAnnotationEntry getJsNameAnnotationPsi(@NotNull BindingContext context, @NotNull KtAnnotated annotated,
@NotNull DeclarationDescriptor descriptor) {
AnnotationDescriptor annotation = getJsNameAnnotation(descriptor);
if (annotation == null) return null;
for (KtAnnotationEntry entry : annotated.getAnnotationEntries()) {
AnnotationDescriptor annotationDescriptor = context.get(BindingContext.ANNOTATION, entry);
assert annotationDescriptor != null : "Annotation descriptor expected for annotation entry: " +
PsiUtilsKt.getTextWithLocation(entry);
ClassifierDescriptor typeDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
assert typeDescriptor instanceof ClassDescriptor : "Annotation type should be ClassDescriptor: " +
PsiUtilsKt.getTextWithLocation(entry);
FqNameUnsafe entryName = DescriptorUtils.getFqName(typeDescriptor);
if (entryName.equals(nameToFindUnsafe)) {
if (annotationDescriptor == annotation) {
return entry;
}
}