Micro optimization to avoid computing class FQ name when not necessary

KotlinBuiltIns.isConstructedFromGivenClass checks the simple name of the
class first, and only computes the full FQ name if it matches the last
segment of the expected FQ name
This commit is contained in:
Alexander Udalov
2017-06-20 19:33:22 +03:00
parent aed5b934f8
commit 5a25ba199a
8 changed files with 13 additions and 18 deletions
@@ -1082,6 +1082,10 @@ public abstract class KotlinBuiltIns {
return isConstructedFromGivenClass(type, FQ_NAMES.iterable); return isConstructedFromGivenClass(type, FQ_NAMES.iterable);
} }
public static boolean isThrowableOrNullableThrowable(@NotNull KotlinType type) {
return isConstructedFromGivenClass(type, FQ_NAMES.throwable);
}
public static boolean isKClass(@NotNull ClassDescriptor descriptor) { public static boolean isKClass(@NotNull ClassDescriptor descriptor) {
return classFqNameEquals(descriptor, FQ_NAMES.kClass); return classFqNameEquals(descriptor, FQ_NAMES.kClass);
} }
@@ -19,10 +19,8 @@ package org.jetbrains.kotlin.types.typeUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import java.util.* import java.util.*
@@ -58,10 +56,7 @@ fun KotlinType.isNullableAny(): Boolean = KotlinBuiltIns.isNullableAny(this)
fun KotlinType.isBoolean(): Boolean = KotlinBuiltIns.isBoolean(this) fun KotlinType.isBoolean(): Boolean = KotlinBuiltIns.isBoolean(this)
fun KotlinType.isPrimitiveNumberType(): Boolean = KotlinBuiltIns.isPrimitiveType(this) && !isBoolean() fun KotlinType.isPrimitiveNumberType(): Boolean = KotlinBuiltIns.isPrimitiveType(this) && !isBoolean()
fun KotlinType.isBooleanOrNullableBoolean(): Boolean = KotlinBuiltIns.isBooleanOrNullableBoolean(this) fun KotlinType.isBooleanOrNullableBoolean(): Boolean = KotlinBuiltIns.isBooleanOrNullableBoolean(this)
fun KotlinType.isThrowable(): Boolean = isConstructedFromClassWithGivenFqName(KotlinBuiltIns.FQ_NAMES.throwable) && !isMarkedNullable fun KotlinType.isNotNullThrowable(): Boolean = KotlinBuiltIns.isThrowableOrNullableThrowable(this) && !isMarkedNullable
fun KotlinType.isConstructedFromClassWithGivenFqName(fqName: FqName) =
(constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe == fqName.toUnsafe()
fun KotlinType.isTypeParameter(): Boolean = TypeUtils.isTypeParameter(this) fun KotlinType.isTypeParameter(): Boolean = TypeUtils.isTypeParameter(this)
@@ -30,8 +30,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
import org.jetbrains.kotlin.types.typeUtil.isConstructedFromClassWithGivenFqName
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
class ConvertTwoComparisonsToRangeCheckInspection : IntentionBasedInspection<KtBinaryExpression>( class ConvertTwoComparisonsToRangeCheckInspection : IntentionBasedInspection<KtBinaryExpression>(
@@ -189,4 +187,4 @@ class ConvertTwoComparisonsToRangeCheckIntention : SelfTargetingOffsetIndependen
this ?: return false this ?: return false
return this.isInteger()|| KotlinBuiltIns.isChar(this) return this.isInteger()|| KotlinBuiltIns.isChar(this)
} }
} }
@@ -270,7 +270,7 @@ public final class StaticContext {
else if (FunctionTypesKt.isBuiltinFunctionalType(type)) { else if (FunctionTypesKt.isBuiltinFunctionalType(type)) {
return pureFqn("Function", null); return pureFqn("Function", null);
} }
else if (TypeUtilsKt.isThrowable(classDescriptor.getDefaultType())) { else if (TypeUtilsKt.isNotNullThrowable(classDescriptor.getDefaultType())) {
return pureFqn("Error", null); return pureFqn("Error", null);
} }
} }
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -288,7 +287,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
if (KotlinBuiltIns.isStringOrNullableString(param.getType())) { if (KotlinBuiltIns.isStringOrNullableString(param.getType())) {
messageArgument = context.cacheExpressionIfNeeded(jsValue); messageArgument = context.cacheExpressionIfNeeded(jsValue);
} }
else if (TypeUtilsKt.isConstructedFromClassWithGivenFqName(param.getType(), KotlinBuiltIns.FQ_NAMES.throwable)) { else if (KotlinBuiltIns.isThrowableOrNullableThrowable(param.getType())) {
causeArgument = context.cacheExpressionIfNeeded(jsValue); causeArgument = context.cacheExpressionIfNeeded(jsValue);
} }
else { else {
@@ -28,13 +28,13 @@ import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntri
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.receivers.SuperCallReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.SuperCallReceiverValue
import org.jetbrains.kotlin.types.typeUtil.isThrowable import org.jetbrains.kotlin.types.typeUtil.isNotNullThrowable
object ExceptionPropertyIntrinsicFactory : FunctionIntrinsicFactory { object ExceptionPropertyIntrinsicFactory : FunctionIntrinsicFactory {
override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? {
if (descriptor !is PropertyGetterDescriptor) return null if (descriptor !is PropertyGetterDescriptor) return null
val classDescriptor = descriptor.correspondingProperty.containingDeclaration as? ClassDescriptor ?: return null val classDescriptor = descriptor.correspondingProperty.containingDeclaration as? ClassDescriptor ?: return null
if (!classDescriptor.defaultType.isThrowable()) return null if (!classDescriptor.defaultType.isNotNullThrowable()) return null
return Intrinsic return Intrinsic
} }
@@ -21,19 +21,18 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.JsExpression import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsInvocation import org.jetbrains.kotlin.js.backend.ast.JsInvocation
import org.jetbrains.kotlin.js.backend.ast.JsLiteral
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo
import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.typeUtil.isThrowable import org.jetbrains.kotlin.types.typeUtil.isNotNullThrowable
object ThrowableConstructorIntrinsicFactory : FunctionIntrinsicFactory { object ThrowableConstructorIntrinsicFactory : FunctionIntrinsicFactory {
override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? {
if (descriptor !is ConstructorDescriptor) return null if (descriptor !is ConstructorDescriptor) return null
if (!descriptor.constructedClass.defaultType.isThrowable()) return null if (!descriptor.constructedClass.defaultType.isNotNullThrowable()) return null
return Intrinsic return Intrinsic
} }
@@ -185,7 +185,7 @@ public final class JsDescriptorUtils {
public static boolean isImmediateSubtypeOfError(@NotNull ClassDescriptor descriptor) { public static boolean isImmediateSubtypeOfError(@NotNull ClassDescriptor descriptor) {
if (!isExceptionClass(descriptor)) return false; if (!isExceptionClass(descriptor)) return false;
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassOrAny(descriptor); ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassOrAny(descriptor);
return TypeUtilsKt.isThrowable(superClass.getDefaultType()) || AnnotationsUtils.isNativeObject(superClass); return TypeUtilsKt.isNotNullThrowable(superClass.getDefaultType()) || AnnotationsUtils.isNativeObject(superClass);
} }
public static boolean isExceptionClass(@NotNull ClassDescriptor descriptor) { public static boolean isExceptionClass(@NotNull ClassDescriptor descriptor) {