KT-2752: minor fixes after code review

This commit is contained in:
Alexey Andreev
2016-08-23 15:32:39 +03:00
parent 7956b038fd
commit aa5d15cff7
13 changed files with 36 additions and 86 deletions
@@ -25,11 +25,8 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
object CodegenUtil {
@@ -153,15 +150,6 @@ object CodegenUtil {
?: error("ClassDescriptor of superType should not be null: ${specifier.text}")
}
@JvmStatic
fun isEnumValueOfMethod(functionDescriptor: FunctionDescriptor): Boolean {
val methodTypeParameters = functionDescriptor.valueParameters
val nullableString = functionDescriptor.builtIns.stringType.makeNullable()
return DescriptorUtils.ENUM_VALUE_OF == functionDescriptor.name
&& methodTypeParameters.size == 1
&& KotlinTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters[0].type, nullableString)
}
@JvmStatic
fun getLineNumberForElement(statement: PsiElement, markEndOffset: Boolean): Int? {
val file = statement.containingFile
@@ -820,7 +820,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CollectionsKt.single(descriptor.getStaticScope().getContributedFunctions(ENUM_VALUE_OF, NoLookupLocation.FROM_BACKEND), new Function1<FunctionDescriptor, Boolean>() {
@Override
public Boolean invoke(FunctionDescriptor descriptor) {
return CodegenUtil.isEnumValueOfMethod(descriptor);
return DescriptorUtilsKt.isEnumValueOfMethod(descriptor);
}
});
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, valueOfFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUE_OF.asString(),
@@ -29,10 +29,8 @@ import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.SmartList
@@ -18,15 +18,12 @@ package org.jetbrains.kotlin.js.descriptorUtils
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.utils.addToStdlib.check
val KotlinType.nameIfStandardType: Name?
@@ -59,11 +56,3 @@ fun KotlinType.getJetTypeFqName(printTypeArguments: Boolean): String {
}
fun ClassDescriptor.hasPrimaryConstructor(): Boolean = unsubstitutedPrimaryConstructor != null
fun FunctionDescriptor.isEnumValueOfMethod(): Boolean {
val methodTypeParameters = valueParameters
val nullableString = TypeUtils.makeNullable(builtIns.stringType)
return DescriptorUtils.ENUM_VALUE_OF == name
&& methodTypeParameters.size == 1
&& KotlinTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters[0].type, nullableString)
}
@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.js.naming
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.js.descriptorUtils.isEnumValueOfMethod
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.*
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.descriptorUtil.isEnumValueOfMethod
import java.util.*
/**
@@ -32,7 +32,7 @@ import java.util.*
* to check whether names clash, by the code generator to place declarations to corresponding scopes and to produce
* fully-qualified names for static declarations.
*
* A new instance of this class can be created for each request, however, it's recommended to use shared instance, since
* A new instance of this class can be created for each request, however, it's recommended to use stable instance, since
* [NameSuggestion] supports caching.
*/
class NameSuggestion {
@@ -70,7 +70,7 @@ class NameSuggestion {
is ModuleDescriptor -> return null
is PackageFragmentDescriptor -> {
return if (!descriptor.name.isSpecial) {
return if (!descriptor.fqName.isRoot) {
SuggestedName(descriptor.fqName.pathSegments().map { it.asString() }, true, descriptor,
descriptor.containingDeclaration)
}
@@ -102,7 +102,7 @@ class NameSuggestion {
}
private fun generateDefault(descriptor: DeclarationDescriptor): SuggestedName {
// Dynamic declarations always require shared names as defined in Kotlin source code
// Dynamic declarations always require stable names as defined in Kotlin source code
if (descriptor.isDynamic()) {
return SuggestedName(listOf(descriptor.name.asString()), true, descriptor, descriptor.containingDeclaration!!)
}
@@ -167,7 +167,7 @@ class NameSuggestion {
}
companion object {
@JvmStatic private fun getMangledName(baseName: String, descriptor: DeclarationDescriptor): Pair<String, Boolean> {
private fun getMangledName(baseName: String, descriptor: DeclarationDescriptor): Pair<String, Boolean> {
// If we have a callable descriptor (property or method) it can override method in a parent class.
// Traverse to the topmost overridden method.
// It does not matter which path to choose during traversal, since front-end must ensure
@@ -193,7 +193,7 @@ class NameSuggestion {
return Pair(finalName, stable)
}
@JvmStatic fun getArgumentTypesAsString(descriptor: CallableDescriptor): String {
private fun getArgumentTypesAsString(descriptor: CallableDescriptor): String {
val argTypes = StringBuilder()
val receiverParameter = descriptor.extensionReceiverParameter
@@ -206,7 +206,7 @@ class NameSuggestion {
return argTypes.toString()
}
@JvmStatic fun getStableMangledName(suggestedName: String, forCalculateId: String): String {
fun getStableMangledName(suggestedName: String, forCalculateId: String): String {
val suffix = if (forCalculateId.isEmpty()) "" else "_${mangledId(forCalculateId)}\$"
return suggestedName + suffix
}
@@ -227,9 +227,7 @@ class NameSuggestion {
is PackageFragmentDescriptor -> descriptor.visibility.isPublicAPI
is ClassDescriptor -> {
// Open (abstract) public methods of classes or final public methods of open (abstract) classes should be stable
if (descriptor.modality == Modality.OPEN || descriptor.modality == Modality.ABSTRACT ||
containingDeclaration.modality == Modality.OPEN || containingDeclaration.modality == Modality.ABSTRACT
) {
if (containingDeclaration.modality == Modality.OPEN || containingDeclaration.modality == Modality.ABSTRACT) {
return descriptor.visibility.isPublicAPI
}
@@ -255,7 +253,7 @@ class NameSuggestion {
}
}
@JvmStatic fun mangledId(forCalculateId: String): String {
private fun mangledId(forCalculateId: String): String {
val absHashCode = Math.abs(forCalculateId.hashCode())
return if (absHashCode != 0) Integer.toString(absHashCode, Character.MAX_RADIX) else ""
}
@@ -46,8 +46,8 @@ public interface ErrorsJs {
ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory3<KtElement, String, DeclarationDescriptor, DeclarationDescriptor> JS_NAME_CLASH_SYNTHETIC =
DiagnosticFactory3.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtElement> JS_NAME_ON_PRIMARY_CONSTRUCTOR_PROHIBITED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtElement> JS_NAME_ON_ACCESSOR_AND_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> JS_NAME_ON_PRIMARY_CONSTRUCTOR_PROHIBITED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> JS_NAME_ON_ACCESSOR_AND_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> JS_NAME_IS_NOT_ON_ALL_ACCESSORS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<PsiElement> JS_NAME_PROHIBITED_FOR_OVERRIDE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> JS_NAME_PROHIBITED_FOR_EXTENSION_PROPERTY = DiagnosticFactory0.create(ERROR);
@@ -22,9 +22,9 @@ import org.jetbrains.kotlin.js.PredefinedAnnotation
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.SimpleDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.source.getPsi
object JsNameChecker : SimpleDeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink,
@@ -36,12 +36,10 @@ object JsNameChecker : SimpleDeclarationChecker {
}
}
if (AnnotationsUtils.getJsName(descriptor) == null) return
val jsNamePsi = AnnotationsUtils.getJsNameAnnotationPsi(bindingContext, declaration, descriptor) ?: return
val jsName = AnnotationsUtils.getJsNameAnnotation(descriptor) ?: return
val jsNamePsi = jsName.source.getPsi() ?: declaration
if (AnnotationsUtils.isNativeObject(descriptor) &&
AnnotationsUtils.getNameForAnnotatedObject(descriptor, PredefinedAnnotation.NATIVE) != null
) {
if (AnnotationsUtils.getNameForAnnotatedObject(descriptor, PredefinedAnnotation.NATIVE) != null) {
diagnosticHolder.report(ErrorsJs.JS_NAME_PROHIBITED_FOR_NAMED_NATIVE.on(jsNamePsi))
}
@@ -16,25 +16,20 @@
package org.jetbrains.kotlin.js.translate.utils;
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.*;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
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.psi.KtAnnotated;
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import java.util.List;
import java.util.Set;
public final class AnnotationsUtils {
private static final String JS_NAME = "kotlin.js.JsName";
@@ -128,7 +123,7 @@ public final class AnnotationsUtils {
}
@Nullable
private static AnnotationDescriptor getJsNameAnnotation(@NotNull DeclarationDescriptor descriptor) {
public static AnnotationDescriptor getJsNameAnnotation(@NotNull DeclarationDescriptor descriptor) {
AnnotationDescriptor annotation = getAnnotationByName(descriptor, new FqName(JS_NAME));
if (annotation == null) return null;
@@ -141,22 +136,6 @@ public final class AnnotationsUtils {
return annotation;
}
@Nullable
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);
if (annotationDescriptor == annotation) {
return entry;
}
}
return null;
}
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
@@ -4801,6 +4801,18 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("jsName.kt")
public void testJsName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsName/jsName.kt");
doTest(fileName);
}
@TestMetadata("jsNamePropertyAccessors.kt")
public void testJsNamePropertyAccessors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsName/jsNamePropertyAccessors.kt");
doTest(fileName);
}
@TestMetadata("overriddenMethod.kt")
public void testOverriddenMethod() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/jsName/overriddenMethod.kt");
@@ -5293,18 +5305,6 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("jsName.kt")
public void testJsName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/jsName.kt");
doTest(fileName);
}
@TestMetadata("jsNamePropertyAccessors.kt")
public void testJsNamePropertyAccessors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/jsNamePropertyAccessors.kt");
doTest(fileName);
}
@TestMetadata("kt1519.kt")
public void testKt1519() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/kt1519.kt");