Introduce KotlinBuiltIns.isUnderKotlinPackage
Semantics is the same as in the former FunctionDescriptor.hasSubpackageOfKotlin, but it doesn't compute the FQ name of the descriptor
This commit is contained in:
+5
-13
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.isSubpackageOf
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||
@@ -34,7 +33,6 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
@@ -105,22 +103,17 @@ fun FunctionDescriptor.isOperatorMod(): Boolean {
|
||||
return this.isOperator && name in OperatorConventions.REM_TO_MOD_OPERATION_NAMES.values
|
||||
}
|
||||
|
||||
// This is an alternate function to KotlinBuiltIns.isBuiltIn
|
||||
// It is safer as it produces stable results independent of target platform (Java/JS/Native)
|
||||
fun FunctionDescriptor.hasSubpackageOfKotlin(): Boolean {
|
||||
val descriptorFqName = fqNameOrNull() ?: return false
|
||||
return descriptorFqName.isSubpackageOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)
|
||||
}
|
||||
|
||||
fun shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings: LanguageVersionSettings): Boolean {
|
||||
return languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem) && languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_1
|
||||
}
|
||||
|
||||
private fun checkModConvention(descriptor: FunctionDescriptor, languageVersionSettings: LanguageVersionSettings,
|
||||
diagnosticHolder: DiagnosticSink, modifier: PsiElement) {
|
||||
private fun checkModConvention(
|
||||
descriptor: FunctionDescriptor, languageVersionSettings: LanguageVersionSettings,
|
||||
diagnosticHolder: DiagnosticSink, modifier: PsiElement
|
||||
) {
|
||||
if (!descriptor.isOperatorMod()) return
|
||||
|
||||
if (descriptor.hasSubpackageOfKotlin()) {
|
||||
if (KotlinBuiltIns.isUnderKotlinPackage(descriptor)) {
|
||||
if (shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
|
||||
addWarningAboutDeprecatedMod(descriptor, diagnosticHolder, modifier)
|
||||
}
|
||||
@@ -136,4 +129,3 @@ private fun addWarningAboutDeprecatedMod(descriptor: FunctionDescriptor, diagnos
|
||||
val newNameConvention = OperatorConventions.REM_TO_MOD_OPERATION_NAMES.inverse()[descriptor.name]
|
||||
diagnosticHolder.report(Errors.DEPRECATED_BINARY_MOD_AS_REM.on(reportOn, descriptor, newNameConvention!!.asString()))
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -473,9 +473,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
|
||||
private fun evaluateCall(callExpression: KtExpression, receiverExpression: KtExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
|
||||
val resolvedCall = callExpression.getResolvedCall(trace.bindingContext) ?: return null
|
||||
|
||||
val descriptorFqName = resolvedCall.resultingDescriptor.fqNameOrNull() ?: return null
|
||||
if (!descriptorFqName.isSubpackageOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)) return null
|
||||
if (!KotlinBuiltIns.isUnderKotlinPackage(resolvedCall.resultingDescriptor)) return null
|
||||
|
||||
val resultingDescriptorName = resolvedCall.resultingDescriptor.name
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.DeprecationLevelValue.*
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.hasSubpackageOfKotlin
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.isOperatorMod
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.shouldWarnAboutDeprecatedModFromBuiltIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
@@ -190,7 +189,7 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor, languageVers
|
||||
|
||||
private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: LanguageVersionSettings): List<Deprecation> {
|
||||
// The problem is that declaration `mod` in built-ins has @Deprecated annotation but actually it was deprecated only in version 1.1
|
||||
if (this is FunctionDescriptor && this.isOperatorMod() && this.hasSubpackageOfKotlin()) {
|
||||
if (this is FunctionDescriptor && this.isOperatorMod() && KotlinBuiltIns.isUnderKotlinPackage(this)) {
|
||||
if (!shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
+2
-2
@@ -210,8 +210,8 @@ class LazyJavaClassDescriptor(
|
||||
}
|
||||
|
||||
private fun getPurelyImplementedSupertype(): KotlinType? {
|
||||
val annotatedPurelyImplementedFqName = getPurelyImplementsFqNameFromAnnotation()?.takeIf {
|
||||
!it.isRoot && it.toUnsafe().startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)
|
||||
val annotatedPurelyImplementedFqName = getPurelyImplementsFqNameFromAnnotation()?.takeIf { fqName ->
|
||||
!fqName.isRoot && fqName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)
|
||||
}
|
||||
|
||||
val purelyImplementedFqName =
|
||||
|
||||
@@ -381,6 +381,20 @@ public abstract class KotlinBuiltIns {
|
||||
return DescriptorUtils.getParentOfType(descriptor, BuiltInsPackageFragment.class, false) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the containing package of the descriptor is "kotlin" or any subpackage of "kotlin"
|
||||
*/
|
||||
public static boolean isUnderKotlinPackage(@NotNull DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor current = descriptor;
|
||||
while (current != null) {
|
||||
if (current instanceof PackageFragmentDescriptor) {
|
||||
return ((PackageFragmentDescriptor) current).getFqName().startsWith(BUILT_INS_PACKAGE_NAME);
|
||||
}
|
||||
current = current.getContainingDeclaration();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MemberScope getBuiltInsPackageScope() {
|
||||
return packageFragments.invoke().builtInsPackageFragment.getMemberScope();
|
||||
|
||||
@@ -98,6 +98,10 @@ public final class FqName {
|
||||
return fqName.pathSegments();
|
||||
}
|
||||
|
||||
public boolean startsWith(@NotNull Name segment) {
|
||||
return fqName.startsWith(segment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FqName topLevel(@NotNull Name shortName) {
|
||||
return new FqName(FqNameUnsafe.topLevel(shortName));
|
||||
|
||||
Reference in New Issue
Block a user