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.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.name.isSubpackageOf
|
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.Call
|
||||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
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.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
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.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
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
|
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 {
|
fun shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings: LanguageVersionSettings): Boolean {
|
||||||
return languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem) && languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_1
|
return languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem) && languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkModConvention(descriptor: FunctionDescriptor, languageVersionSettings: LanguageVersionSettings,
|
private fun checkModConvention(
|
||||||
diagnosticHolder: DiagnosticSink, modifier: PsiElement) {
|
descriptor: FunctionDescriptor, languageVersionSettings: LanguageVersionSettings,
|
||||||
|
diagnosticHolder: DiagnosticSink, modifier: PsiElement
|
||||||
|
) {
|
||||||
if (!descriptor.isOperatorMod()) return
|
if (!descriptor.isOperatorMod()) return
|
||||||
|
|
||||||
if (descriptor.hasSubpackageOfKotlin()) {
|
if (KotlinBuiltIns.isUnderKotlinPackage(descriptor)) {
|
||||||
if (shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
|
if (shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
|
||||||
addWarningAboutDeprecatedMod(descriptor, diagnosticHolder, modifier)
|
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]
|
val newNameConvention = OperatorConventions.REM_TO_MOD_OPERATION_NAMES.inverse()[descriptor.name]
|
||||||
diagnosticHolder.report(Errors.DEPRECATED_BINARY_MOD_AS_REM.on(reportOn, descriptor, newNameConvention!!.asString()))
|
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<*>? {
|
private fun evaluateCall(callExpression: KtExpression, receiverExpression: KtExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
|
||||||
val resolvedCall = callExpression.getResolvedCall(trace.bindingContext) ?: return null
|
val resolvedCall = callExpression.getResolvedCall(trace.bindingContext) ?: return null
|
||||||
|
if (!KotlinBuiltIns.isUnderKotlinPackage(resolvedCall.resultingDescriptor)) return null
|
||||||
val descriptorFqName = resolvedCall.resultingDescriptor.fqNameOrNull() ?: return null
|
|
||||||
if (!descriptorFqName.isSubpackageOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)) return null
|
|
||||||
|
|
||||||
val resultingDescriptorName = resolvedCall.resultingDescriptor.name
|
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.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.DeprecationLevelValue.*
|
import org.jetbrains.kotlin.resolve.DeprecationLevelValue.*
|
||||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
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.isOperatorMod
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.shouldWarnAboutDeprecatedModFromBuiltIns
|
import org.jetbrains.kotlin.resolve.calls.checkers.shouldWarnAboutDeprecatedModFromBuiltIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
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> {
|
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
|
// 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)) {
|
if (!shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -210,8 +210,8 @@ class LazyJavaClassDescriptor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getPurelyImplementedSupertype(): KotlinType? {
|
private fun getPurelyImplementedSupertype(): KotlinType? {
|
||||||
val annotatedPurelyImplementedFqName = getPurelyImplementsFqNameFromAnnotation()?.takeIf {
|
val annotatedPurelyImplementedFqName = getPurelyImplementsFqNameFromAnnotation()?.takeIf { fqName ->
|
||||||
!it.isRoot && it.toUnsafe().startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)
|
!fqName.isRoot && fqName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
val purelyImplementedFqName =
|
val purelyImplementedFqName =
|
||||||
|
|||||||
@@ -381,6 +381,20 @@ public abstract class KotlinBuiltIns {
|
|||||||
return DescriptorUtils.getParentOfType(descriptor, BuiltInsPackageFragment.class, false) != null;
|
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
|
@NotNull
|
||||||
public MemberScope getBuiltInsPackageScope() {
|
public MemberScope getBuiltInsPackageScope() {
|
||||||
return packageFragments.invoke().builtInsPackageFragment.getMemberScope();
|
return packageFragments.invoke().builtInsPackageFragment.getMemberScope();
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ public final class FqName {
|
|||||||
return fqName.pathSegments();
|
return fqName.pathSegments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean startsWith(@NotNull Name segment) {
|
||||||
|
return fqName.startsWith(segment);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static FqName topLevel(@NotNull Name shortName) {
|
public static FqName topLevel(@NotNull Name shortName) {
|
||||||
return new FqName(FqNameUnsafe.topLevel(shortName));
|
return new FqName(FqNameUnsafe.topLevel(shortName));
|
||||||
|
|||||||
Reference in New Issue
Block a user