J2K: move isEffectivelyExternal to kt-file, parameter -> receiver

This commit is contained in:
Mikhail Glukhikh
2017-04-28 12:41:27 +03:00
parent d5feb2d6f4
commit b8af0f5922
10 changed files with 38 additions and 33 deletions
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getDispatchReceiverWi
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.hasThisOrNoDispatchReceiver import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.hasThisOrNoDispatchReceiver
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils.* import org.jetbrains.kotlin.types.TypeUtils.*
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
@@ -642,7 +643,7 @@ class ControlFlowInformationProvider private constructor(
val containingClass = owner.getContainingClassOrObject() val containingClass = owner.getContainingClassOrObject()
val containingClassDescriptor = trace.get(DECLARATION_TO_DESCRIPTOR, containingClass) as? ClassDescriptor val containingClassDescriptor = trace.get(DECLARATION_TO_DESCRIPTOR, containingClass) as? ClassDescriptor
if (!DescriptorUtils.isAnnotationClass(containingClassDescriptor) && containingClassDescriptor?.isHeader == false && if (!DescriptorUtils.isAnnotationClass(containingClassDescriptor) && containingClassDescriptor?.isHeader == false &&
!DescriptorUtils.isEffectivelyExternal(containingClassDescriptor) !containingClassDescriptor.isEffectivelyExternal()
) { ) {
report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt) report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt)
} }
@@ -662,7 +663,7 @@ class ControlFlowInformationProvider private constructor(
|| functionDescriptor.isOverridableOrOverrides || functionDescriptor.isOverridableOrOverrides
|| owner.hasModifier(KtTokens.OVERRIDE_KEYWORD) || owner.hasModifier(KtTokens.OVERRIDE_KEYWORD)
|| functionDescriptor.isHeader || functionDescriptor.isImpl || functionDescriptor.isHeader || functionDescriptor.isImpl
|| DescriptorUtils.isEffectivelyExternal(functionDescriptor) || functionDescriptor.isEffectivelyExternal()
|| OperatorNameConventions.GET_VALUE == functionName || OperatorNameConventions.GET_VALUE == functionName
|| OperatorNameConventions.SET_VALUE == functionName || OperatorNameConventions.SET_VALUE == functionName
|| OperatorNameConventions.PROVIDE_DELEGATE == functionName) { || OperatorNameConventions.PROVIDE_DELEGATE == functionName) {
@@ -56,6 +56,7 @@ import java.util.*;
import static org.jetbrains.kotlin.config.LanguageFeature.TopLevelSealedInheritance; import static org.jetbrains.kotlin.config.LanguageFeature.TopLevelSealedInheritance;
import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.isEffectivelyExternal;
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
public class BodyResolver { public class BodyResolver {
@@ -165,7 +166,7 @@ public class BodyResolver {
@NotNull KtSecondaryConstructor constructor, @NotNull KtSecondaryConstructor constructor,
@NotNull ClassConstructorDescriptor descriptor @NotNull ClassConstructorDescriptor descriptor
) { ) {
if (descriptor.isHeader() || DescriptorUtils.isEffectivelyExternal(descriptor)) { if (descriptor.isHeader() || isEffectivelyExternal(descriptor)) {
// For header and external classes, we do not resolve constructor delegation calls because they are prohibited // For header and external classes, we do not resolve constructor delegation calls because they are prohibited
return DataFlowInfo.Companion.getEMPTY(); return DataFlowInfo.Companion.getEMPTY();
} }
@@ -366,7 +367,7 @@ public class BodyResolver {
descriptor.getUnsubstitutedPrimaryConstructor() != null && descriptor.getUnsubstitutedPrimaryConstructor() != null &&
superClass.getKind() != ClassKind.INTERFACE && superClass.getKind() != ClassKind.INTERFACE &&
!superClass.getConstructors().isEmpty() && !superClass.getConstructors().isEmpty() &&
!descriptor.isHeader() && !DescriptorUtils.isEffectivelyExternal(descriptor) && !descriptor.isHeader() && !isEffectivelyExternal(descriptor) &&
!ErrorUtils.isError(superClass) !ErrorUtils.isError(superClass)
) { ) {
trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier)); trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractMembers
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -697,7 +698,7 @@ class DeclarationsChecker(
} }
else { else {
val isUninitialized = trace.bindingContext.get(BindingContext.IS_UNINITIALIZED, propertyDescriptor) ?: false val isUninitialized = trace.bindingContext.get(BindingContext.IS_UNINITIALIZED, propertyDescriptor) ?: false
val isExternal = DescriptorUtils.isEffectivelyExternal(propertyDescriptor) val isExternal = propertyDescriptor.isEffectivelyExternal()
if (backingFieldRequired && !inTrait && !propertyDescriptor.isLateInit && !isHeader && isUninitialized && !isExternal) { if (backingFieldRequired && !inTrait && !propertyDescriptor.isLateInit && !isHeader && isUninitialized && !isExternal) {
if (containingDeclaration !is ClassDescriptor || hasAccessorImplementation) { if (containingDeclaration !is ClassDescriptor || hasAccessorImplementation) {
trace.report(MUST_BE_INITIALIZED.on(property)) trace.report(MUST_BE_INITIALIZED.on(property))
@@ -737,7 +738,7 @@ class DeclarationsChecker(
val containingDescriptor = functionDescriptor.containingDeclaration val containingDescriptor = functionDescriptor.containingDeclaration
val hasAbstractModifier = function.hasModifier(KtTokens.ABSTRACT_KEYWORD) val hasAbstractModifier = function.hasModifier(KtTokens.ABSTRACT_KEYWORD)
val hasExternalModifier = DescriptorUtils.isEffectivelyExternal(functionDescriptor) val hasExternalModifier = functionDescriptor.isEffectivelyExternal()
if (containingDescriptor is ClassDescriptor) { if (containingDescriptor is ClassDescriptor) {
val inInterface = containingDescriptor.kind == ClassKind.INTERFACE val inInterface = containingDescriptor.kind == ClassKind.INTERFACE
@@ -573,18 +573,6 @@ public class DescriptorUtils {
return scope.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.getALL_NAME_FILTER()); return scope.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.getALL_NAME_FILTER());
} }
public static boolean isEffectivelyExternal(@NotNull MemberDescriptor descriptor) {
if (descriptor.isExternal()) return true;
if (descriptor instanceof PropertyAccessorDescriptor) {
PropertyDescriptor variableDescriptor = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
if (isEffectivelyExternal(variableDescriptor)) return true;
}
ClassDescriptor containingClass = getContainingClass(descriptor);
return containingClass != null && isEffectivelyExternal(containingClass);
}
@NotNull @NotNull
public static FunctionDescriptor getFunctionByName(@NotNull MemberScope scope, @NotNull Name name) { public static FunctionDescriptor getFunctionByName(@NotNull MemberScope scope, @NotNull Name name) {
Collection<DeclarationDescriptor> functions = scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS, Collection<DeclarationDescriptor> functions = scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS,
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.getContainingClass
import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -411,4 +412,16 @@ fun DeclarationDescriptor.isCompanionObject(): Boolean = DescriptorUtils.isCompa
fun ClassDescriptor.isSubclassOf(superclass: ClassDescriptor): Boolean = DescriptorUtils.isSubclass(this, superclass) fun ClassDescriptor.isSubclassOf(superclass: ClassDescriptor): Boolean = DescriptorUtils.isSubclass(this, superclass)
val AnnotationDescriptor.annotationClass: ClassDescriptor? val AnnotationDescriptor.annotationClass: ClassDescriptor?
get() = type.constructor.declarationDescriptor as? ClassDescriptor get() = type.constructor.declarationDescriptor as? ClassDescriptor
fun MemberDescriptor.isEffectivelyExternal(): Boolean {
if (isExternal) return true
if (this is PropertyAccessorDescriptor) {
val variableDescriptor = correspondingProperty
if (variableDescriptor.isEffectivelyExternal()) return true
}
val containingClass = getContainingClass(this)
return containingClass != null && containingClass.isEffectivelyExternal()
}
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.inline.ReasonableInlineRule import org.jetbrains.kotlin.resolve.inline.ReasonableInlineRule
object ExtensionFunctionToExternalIsInlinable : ReasonableInlineRule { object ExtensionFunctionToExternalIsInlinable : ReasonableInlineRule {
@@ -31,6 +31,6 @@ object ExtensionFunctionToExternalIsInlinable : ReasonableInlineRule {
): Boolean { ): Boolean {
val receiverParameter = descriptor.extensionReceiverParameter ?: return false val receiverParameter = descriptor.extensionReceiverParameter ?: return false
val receiverClass = receiverParameter.value.type.constructor.declarationDescriptor as? ClassDescriptor ?: return false val receiverClass = receiverParameter.value.type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
return DescriptorUtils.isEffectivelyExternal(receiverClass) return receiverClass.isEffectivelyExternal()
} }
} }
@@ -145,7 +145,7 @@ object JsExternalChecker : SimpleDeclarationChecker {
} }
private fun checkDelegation(declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) { private fun checkDelegation(declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
if (descriptor !is MemberDescriptor || !DescriptorUtils.isEffectivelyExternal(descriptor)) return if (descriptor !is MemberDescriptor || !descriptor.isEffectivelyExternal()) return
if (declaration is KtClassOrObject) { if (declaration is KtClassOrObject) {
for (superTypeEntry in declaration.superTypeListEntries) { for (superTypeEntry in declaration.superTypeListEntries) {
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
@@ -38,12 +38,12 @@ object JsInheritanceChecker : SimpleDeclarationChecker {
diagnosticHolder: DiagnosticSink, diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext bindingContext: BindingContext
) { ) {
if (descriptor is FunctionDescriptor && !DescriptorUtils.isEffectivelyExternal(descriptor) && if (descriptor is FunctionDescriptor && !descriptor.isEffectivelyExternal() &&
isOverridingExternalWithOptionalParams(descriptor) isOverridingExternalWithOptionalParams(descriptor)
) { ) {
diagnosticHolder.report(ErrorsJs.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS.on(declaration)) diagnosticHolder.report(ErrorsJs.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS.on(declaration))
} }
else if (descriptor is ClassDescriptor && !DescriptorUtils.isEffectivelyExternal(descriptor)) { else if (descriptor is ClassDescriptor && !descriptor.isEffectivelyExternal()) {
val fakeOverriddenMethod = findFakeMethodOverridingExternalWithOptionalParams(descriptor) val fakeOverriddenMethod = findFakeMethodOverridingExternalWithOptionalParams(descriptor)
if (fakeOverriddenMethod != null) { if (fakeOverriddenMethod != null) {
diagnosticHolder.report(ErrorsJs.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE.on( diagnosticHolder.report(ErrorsJs.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE.on(
@@ -61,7 +61,7 @@ object JsInheritanceChecker : SimpleDeclarationChecker {
private fun isOverridingExternalWithOptionalParams(function: FunctionDescriptor): Boolean { private fun isOverridingExternalWithOptionalParams(function: FunctionDescriptor): Boolean {
if (!function.kind.isReal && function.modality == Modality.ABSTRACT) return false if (!function.kind.isReal && function.modality == Modality.ABSTRACT) return false
for (overriddenFunction in function.overriddenDescriptors.filter { DescriptorUtils.isEffectivelyExternal(it) }) { for (overriddenFunction in function.overriddenDescriptors.filter { it.isEffectivelyExternal() }) {
if (overriddenFunction.valueParameters.any { it.hasDefaultValue() }) return true if (overriddenFunction.valueParameters.any { it.hasDefaultValue() }) return true
} }
@@ -23,10 +23,10 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement
object JsRuntimeAnnotationChecker : SimpleDeclarationChecker { object JsRuntimeAnnotationChecker : SimpleDeclarationChecker {
@@ -42,7 +42,7 @@ object JsRuntimeAnnotationChecker : SimpleDeclarationChecker {
val annotationPsi = (annotationDescriptor.source as? PsiSourceElement)?.psi ?: declaration val annotationPsi = (annotationDescriptor.source as? PsiSourceElement)?.psi ?: declaration
if (descriptor is MemberDescriptor && DescriptorUtils.isEffectivelyExternal(descriptor)) { if (descriptor is MemberDescriptor && descriptor.isEffectivelyExternal()) {
diagnosticHolder.report(ErrorsJs.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION.on(annotationPsi)) diagnosticHolder.report(ErrorsJs.RUNTIME_ANNOTATION_ON_EXTERNAL_DECLARATION.on(annotationPsi))
} }
else { else {
@@ -39,6 +39,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass; import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getAnnotationClass;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.isEffectivelyExternal;
public final class AnnotationsUtils { public final class AnnotationsUtils {
private static final String JS_NAME = "kotlin.js.JsName"; private static final String JS_NAME = "kotlin.js.JsName";
@@ -99,7 +100,7 @@ public final class AnnotationsUtils {
return name != null ? name : descriptor.getName().asString(); return name != null ? name : descriptor.getName().asString();
} }
if (defaultJsName == null && isEffectivelyExternal(descriptor)) { if (defaultJsName == null && isEffectivelyExternalMember(descriptor)) {
return descriptor.getName().asString(); return descriptor.getName().asString();
} }
@@ -121,7 +122,7 @@ public final class AnnotationsUtils {
} }
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) { public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
if (hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE) || isEffectivelyExternal(descriptor)) return true; if (hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE) || isEffectivelyExternalMember(descriptor)) return true;
if (descriptor instanceof PropertyAccessorDescriptor) { if (descriptor instanceof PropertyAccessorDescriptor) {
PropertyAccessorDescriptor accessor = (PropertyAccessorDescriptor) descriptor; PropertyAccessorDescriptor accessor = (PropertyAccessorDescriptor) descriptor;
@@ -135,8 +136,8 @@ public final class AnnotationsUtils {
return isNativeObject(descriptor) && DescriptorUtils.isInterface(descriptor); return isNativeObject(descriptor) && DescriptorUtils.isInterface(descriptor);
} }
private static boolean isEffectivelyExternal(@NotNull DeclarationDescriptor descriptor) { private static boolean isEffectivelyExternalMember(@NotNull DeclarationDescriptor descriptor) {
return descriptor instanceof MemberDescriptor && DescriptorUtils.isEffectivelyExternal((MemberDescriptor) descriptor); return descriptor instanceof MemberDescriptor && isEffectivelyExternal((MemberDescriptor) descriptor);
} }
public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) { public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) {
@@ -164,7 +165,7 @@ public final class AnnotationsUtils {
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) { public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isHeader()) return true; if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isHeader()) return true;
if (isEffectivelyExternal(descriptor)) return true; if (isEffectivelyExternalMember(descriptor)) return true;
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) { for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) { if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {