KT-2752: declare properties as a pair of functions when accessors are marked with @JsName

This commit is contained in:
Alexey Andreev
2016-06-02 15:01:47 +03:00
parent 6e1a0901ac
commit be0013d9f2
17 changed files with 322 additions and 39 deletions
@@ -36,6 +36,7 @@ object JsNameChecker : SimpleDeclarationChecker {
}
}
if (AnnotationsUtils.getJsName(descriptor) == null) return
val jsNamePsi = AnnotationsUtils.getJsNameAnnotationPsi(bindingContext, declaration) ?: return
when (descriptor) {
@@ -45,7 +46,7 @@ object JsNameChecker : SimpleDeclarationChecker {
}
}
is PropertyAccessorDescriptor -> {
if (!descriptor.isDefault && AnnotationsUtils.getJsName(descriptor.correspondingProperty) != null) {
if (AnnotationsUtils.getJsName(descriptor.correspondingProperty) != null) {
diagnosticHolder.report(ErrorsJs.JS_NAME_ON_ACCESSOR_AND_PROPERTY.on(jsNamePsi))
}
}
@@ -97,15 +97,17 @@ class JsNameClashChecker : SimpleDeclarationChecker {
}
private fun collect(descriptor: DeclarationDescriptor, target: MutableMap<String, DeclarationDescriptor>) {
if (descriptor is PropertyDescriptor && descriptor.isExtension) {
descriptor.accessors.forEach { collect(it, target) }
}
else {
val fqn = fqnGenerator.generate(descriptor)
if (fqn.shared && isOpaque(fqn.descriptor)) {
target[fqn.names.last()] = fqn.descriptor
if (descriptor is PropertyDescriptor) {
if (descriptor.isExtension || AnnotationsUtils.hasJsNameInAccessors(descriptor)) {
descriptor.accessors.forEach { collect(it, target) }
return
}
}
val fqn = fqnGenerator.generate(descriptor)
if (fqn.shared && isOpaque(fqn.descriptor)) {
target[fqn.names.last()] = fqn.descriptor
}
}
private fun isOpaque(descriptor: DeclarationDescriptor) =
@@ -20,10 +20,7 @@ import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.js.PredefinedAnnotation;
import org.jetbrains.kotlin.name.FqName;
@@ -143,6 +140,12 @@ public final class AnnotationsUtils {
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;
}
ConstantValue<?> value = annotation.getAllValueArguments().values().iterator().next();
assert value != null : "JsName annotation should always declare string parameter";
@@ -202,4 +205,11 @@ public final class AnnotationsUtils {
ClassDescriptor containingClass = DescriptorUtils.getContainingClass(descriptor);
return containingClass != null && hasAnnotationOrInsideAnnotatedClass(containingClass, fqName);
}
public static boolean hasJsNameInAccessors(@NotNull PropertyDescriptor property) {
for (PropertyAccessorDescriptor accessor : property.getAccessors()) {
if (getJsName(accessor) != null) return true;
}
return false;
}
}