From 57040f6f9dabaf4a2d610e5d437737ca9d6e1965 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 5 Mar 2019 11:25:07 +0300 Subject: [PATCH] Minor: refactoring & fix warnings --- .../kotlin/descriptors/typeParameterUtils.kt | 36 ++++--- .../org/jetbrains/kotlin/types/KotlinType.kt | 15 ++- .../kotlin/types/KotlinTypeFactory.kt | 97 ++++++++++--------- .../org/jetbrains/kotlin/utils/SmartSet.kt | 23 +++-- .../jetbrains/kotlin/idea/util/TypeUtils.kt | 89 +++++++++-------- .../SpecifyTypeExplicitlyIntention.kt | 3 +- .../extractableAnalysisUtil.kt | 73 ++++++-------- 7 files changed, 168 insertions(+), 168 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt index bf31ad66de6..cc0f840c982 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/typeParameterUtils.kt @@ -29,40 +29,40 @@ fun ClassifierDescriptorWithTypeParameters.computeConstructorTypeParameters(): L if (!isInner && containingDeclaration !is CallableDescriptor) return declaredParameters val parametersFromContainingFunctions = - parents.takeWhile { it is CallableDescriptor } - .flatMap { (it as CallableDescriptor).typeParameters.asSequence() }.toList() + parents.takeWhile { it is CallableDescriptor } + .flatMap { (it as CallableDescriptor).typeParameters.asSequence() }.toList() val containingClassTypeConstructorParameters = parents.firstIsInstanceOrNull()?.typeConstructor?.parameters.orEmpty() if (parametersFromContainingFunctions.isEmpty() && containingClassTypeConstructorParameters.isEmpty()) return declaredTypeParameters val additional = - (parametersFromContainingFunctions + containingClassTypeConstructorParameters) - .map { it.capturedCopyForInnerDeclaration(this, declaredParameters.size) } + (parametersFromContainingFunctions + containingClassTypeConstructorParameters) + .map { it.capturedCopyForInnerDeclaration(this, declaredParameters.size) } return declaredParameters + additional } private fun TypeParameterDescriptor.capturedCopyForInnerDeclaration( - declarationDescriptor: DeclarationDescriptor, - declaredTypeParametersCount: Int + declarationDescriptor: DeclarationDescriptor, + declaredTypeParametersCount: Int ) = CapturedTypeParameterDescriptor(this, declarationDescriptor, declaredTypeParametersCount) private class CapturedTypeParameterDescriptor( - private val originalDescriptor: TypeParameterDescriptor, - private val declarationDescriptor: DeclarationDescriptor, - private val declaredTypeParametersCount: Int + private val originalDescriptor: TypeParameterDescriptor, + private val declarationDescriptor: DeclarationDescriptor, + private val declaredTypeParametersCount: Int ) : TypeParameterDescriptor by originalDescriptor { override fun isCapturedFromOuterDeclaration() = true override fun getOriginal() = originalDescriptor.original override fun getContainingDeclaration() = declarationDescriptor override fun getIndex() = declaredTypeParametersCount + originalDescriptor.index - override fun toString() = originalDescriptor.toString() + "[inner-copy]" + override fun toString() = "$originalDescriptor[inner-copy]" } class PossiblyInnerType( - val classifierDescriptor: ClassifierDescriptorWithTypeParameters, - val arguments: List, - val outerType: PossiblyInnerType? + val classifierDescriptor: ClassifierDescriptorWithTypeParameters, + val arguments: List, + val outerType: PossiblyInnerType? ) { val classDescriptor: ClassDescriptor get() = classifierDescriptor as ClassDescriptor @@ -74,7 +74,10 @@ fun KotlinType.buildPossiblyInnerType(): PossiblyInnerType? { return buildPossiblyInnerType(constructor.declarationDescriptor as? ClassifierDescriptorWithTypeParameters, 0) } -private fun KotlinType.buildPossiblyInnerType(classifierDescriptor: ClassifierDescriptorWithTypeParameters?, index: Int): PossiblyInnerType? { +private fun KotlinType.buildPossiblyInnerType( + classifierDescriptor: ClassifierDescriptorWithTypeParameters?, + index: Int +): PossiblyInnerType? { if (classifierDescriptor == null || ErrorUtils.isError(classifierDescriptor)) return null val toIndex = classifierDescriptor.declaredTypeParameters.size + index @@ -88,6 +91,7 @@ private fun KotlinType.buildPossiblyInnerType(classifierDescriptor: ClassifierDe val argumentsSubList = arguments.subList(index, toIndex) return PossiblyInnerType( - classifierDescriptor, argumentsSubList, - buildPossiblyInnerType(classifierDescriptor.containingDeclaration as? ClassifierDescriptorWithTypeParameters, toIndex)) + classifierDescriptor, argumentsSubList, + buildPossiblyInnerType(classifierDescriptor.containingDeclaration as? ClassifierDescriptorWithTypeParameters, toIndex) + ) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt index f960f886911..e85a28d6690 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinType.kt @@ -82,7 +82,7 @@ abstract class WrappedType : KotlinType() { override val isMarkedNullable: Boolean get() = delegate.isMarkedNullable override val memberScope: MemberScope get() = delegate.memberScope - override final fun unwrap(): UnwrappedType { + final override fun unwrap(): UnwrappedType { var result = delegate while (result is WrappedType) { result = result.delegate @@ -93,8 +93,7 @@ abstract class WrappedType : KotlinType() { override fun toString(): String { return if (isComputed()) { delegate.toString() - } - else { + } else { "" } } @@ -111,11 +110,11 @@ abstract class WrappedType : KotlinType() { * * todo: specify what happens with internal structure when we apply some [TypeSubstitutor] */ -sealed class UnwrappedType: KotlinType() { +sealed class UnwrappedType : KotlinType() { abstract fun replaceAnnotations(newAnnotations: Annotations): UnwrappedType abstract fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType - override final fun unwrap(): UnwrappedType = this + final override fun unwrap(): UnwrappedType = this } /** @@ -134,7 +133,7 @@ abstract class SimpleType : UnwrappedType(), SimpleTypeMarker, TypeArgumentListM } append(constructor) - if (!arguments.isEmpty()) arguments.joinTo(this, separator = ", ", prefix = "<", postfix = ">") + if (arguments.isNotEmpty()) arguments.joinTo(this, separator = ", ", prefix = "<", postfix = ">") if (isMarkedNullable) append("?") } } @@ -142,7 +141,7 @@ abstract class SimpleType : UnwrappedType(), SimpleTypeMarker, TypeArgumentListM // lowerBound is a subtype of upperBound abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleType) : - UnwrappedType(), SubtypingRepresentatives, FlexibleTypeMarker { + UnwrappedType(), SubtypingRepresentatives, FlexibleTypeMarker { abstract val delegate: SimpleType @@ -167,5 +166,5 @@ abstract class FlexibleType(val lowerBound: SimpleType, val upperBound: SimpleTy val KotlinType.isError: Boolean get() = unwrap().let { unwrapped -> unwrapped is ErrorType || - (unwrapped is FlexibleType && unwrapped.delegate is ErrorType) + (unwrapped is FlexibleType && unwrapped.delegate is ErrorType) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt index 94171d072f1..e1eed94718f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.scopes.MemberScope -import java.lang.IllegalStateException object KotlinTypeFactory { private fun computeMemberScope(constructor: TypeConstructor, arguments: List): MemberScope { @@ -41,48 +40,54 @@ object KotlinTypeFactory { @JvmStatic fun simpleType( - annotations: Annotations, - constructor: TypeConstructor, - arguments: List, - nullable: Boolean + annotations: Annotations, + constructor: TypeConstructor, + arguments: List, + nullable: Boolean ): SimpleType { if (annotations.isEmpty() && arguments.isEmpty() && !nullable && constructor.declarationDescriptor != null) { return constructor.declarationDescriptor!!.defaultType } - return simpleTypeWithNonTrivialMemberScope(annotations, constructor, arguments, nullable, computeMemberScope(constructor, arguments)) + return simpleTypeWithNonTrivialMemberScope( + annotations, + constructor, + arguments, + nullable, + computeMemberScope(constructor, arguments) + ) } @JvmStatic fun simpleTypeWithNonTrivialMemberScope( - annotations: Annotations, - constructor: TypeConstructor, - arguments: List, - nullable: Boolean, - memberScope: MemberScope + annotations: Annotations, + constructor: TypeConstructor, + arguments: List, + nullable: Boolean, + memberScope: MemberScope ): SimpleType = - SimpleTypeImpl(constructor, arguments, nullable, memberScope) - .let { - if (annotations.isEmpty()) - it - else - AnnotatedSimpleType(it, annotations) - } + SimpleTypeImpl(constructor, arguments, nullable, memberScope) + .let { + if (annotations.isEmpty()) + it + else + AnnotatedSimpleType(it, annotations) + } @JvmStatic fun simpleNotNullType( - annotations: Annotations, - descriptor: ClassDescriptor, - arguments: List + annotations: Annotations, + descriptor: ClassDescriptor, + arguments: List ): SimpleType = simpleType(annotations, descriptor.typeConstructor, arguments, nullable = false) @JvmStatic fun simpleType( - baseType: SimpleType, - annotations: Annotations = baseType.annotations, - constructor: TypeConstructor = baseType.constructor, - arguments: List = baseType.arguments, - nullable: Boolean = baseType.isMarkedNullable + baseType: SimpleType, + annotations: Annotations = baseType.annotations, + constructor: TypeConstructor = baseType.constructor, + arguments: List = baseType.arguments, + nullable: Boolean = baseType.isMarkedNullable ): SimpleType = simpleType(annotations, constructor, arguments, nullable) @JvmStatic @@ -93,26 +98,24 @@ object KotlinTypeFactory { } private class SimpleTypeImpl( - override val constructor: TypeConstructor, - override val arguments: List, - override val isMarkedNullable: Boolean, - override val memberScope: MemberScope + override val constructor: TypeConstructor, + override val arguments: List, + override val isMarkedNullable: Boolean, + override val memberScope: MemberScope ) : SimpleType() { override val annotations: Annotations get() = Annotations.EMPTY override fun replaceAnnotations(newAnnotations: Annotations) = - if (newAnnotations.isEmpty()) - this - else - AnnotatedSimpleType(this, newAnnotations) + if (newAnnotations.isEmpty()) + this + else + AnnotatedSimpleType(this, newAnnotations) - override fun makeNullableAsSpecified(newNullability: Boolean) = - if (newNullability == isMarkedNullable) - this - else if (newNullability) - NullableSimpleType(this) - else - NotNullSimpleType(this) + override fun makeNullableAsSpecified(newNullability: Boolean) = when { + newNullability == isMarkedNullable -> this + newNullability -> NullableSimpleType(this) + else -> NotNullSimpleType(this) + } init { if (memberScope is ErrorUtils.ErrorScope) { @@ -123,10 +126,10 @@ private class SimpleTypeImpl( abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() { override fun replaceAnnotations(newAnnotations: Annotations) = - if (newAnnotations !== annotations) - AnnotatedSimpleType(this, newAnnotations) - else - this + if (newAnnotations !== annotations) + AnnotatedSimpleType(this, newAnnotations) + else + this override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType { if (newNullability == isMarkedNullable) return this @@ -135,8 +138,8 @@ abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : Del } private class AnnotatedSimpleType( - delegate: SimpleType, - override val annotations: Annotations + delegate: SimpleType, + override val annotations: Annotations ) : DelegatingSimpleTypeImpl(delegate) private class NullableSimpleType(delegate: SimpleType) : DelegatingSimpleTypeImpl(delegate) { diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/SmartSet.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/SmartSet.kt index 7ea5f029ea1..64a71eca352 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/SmartSet.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/SmartSet.kt @@ -27,7 +27,7 @@ import java.util.* @Suppress("UNCHECKED_CAST") class SmartSet private constructor() : AbstractSet() { companion object { - private val ARRAY_THRESHOLD = 5 + private const val ARRAY_THRESHOLD = 5 @JvmStatic fun create() = SmartSet() @@ -42,11 +42,11 @@ class SmartSet private constructor() : AbstractSet() { override var size: Int = 0 override fun iterator(): MutableIterator = when { - size == 0 -> Collections.emptySet().iterator() - size == 1 -> SingletonIterator(data as T) - size < ARRAY_THRESHOLD -> ArrayIterator(data as Array) - else -> (data as MutableSet).iterator() - } + size == 0 -> Collections.emptySet().iterator() + size == 1 -> SingletonIterator(data as T) + size < ARRAY_THRESHOLD -> ArrayIterator(data as Array) + else -> (data as MutableSet).iterator() + } override fun add(element: T): Boolean { when { @@ -61,7 +61,7 @@ class SmartSet private constructor() : AbstractSet() { val arr = data as Array if (element in arr) return false data = if (size == ARRAY_THRESHOLD - 1) linkedSetOf(*arr).apply { add(element) } - else Arrays.copyOf(arr, size + 1).apply { set(size - 1, element) } + else arr.copyOf(size + 1).apply { set(size - 1, element) } } else -> { val set = data as MutableSet @@ -89,11 +89,10 @@ class SmartSet private constructor() : AbstractSet() { private var hasNext = true override fun next(): T = - if (hasNext) { - hasNext = false - element - } - else throw NoSuchElementException() + if (hasNext) { + hasNext = false + element + } else throw NoSuchElementException() override fun hasNext() = hasNext diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt index 2820e6b5db7..02cd24a3a3a 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt @@ -33,16 +33,16 @@ import org.jetbrains.kotlin.types.typeUtil.* import org.jetbrains.kotlin.utils.SmartSet fun KotlinType.approximateFlexibleTypes( - preferNotNull: Boolean = false, - preferStarForRaw: Boolean = false + preferNotNull: Boolean = false, + preferStarForRaw: Boolean = false ): KotlinType { if (isDynamic()) return this return unwrapEnhancement().approximateNonDynamicFlexibleTypes(preferNotNull, preferStarForRaw) } private fun KotlinType.approximateNonDynamicFlexibleTypes( - preferNotNull: Boolean = false, - preferStarForRaw: Boolean = false + preferNotNull: Boolean = false, + preferStarForRaw: Boolean = false ): SimpleType { if (this is ErrorType) return this @@ -55,10 +55,10 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes( // Foo! -> Foo? // Foo! -> Foo? var approximation = - if (isCollection) - flexible.lowerBound.makeNullableAsSpecified(!preferNotNull) - else - if (this is RawType && preferStarForRaw) flexible.upperBound.makeNullableAsSpecified(!preferNotNull) + if (isCollection) + flexible.lowerBound.makeNullableAsSpecified(!preferNotNull) + else + if (this is RawType && preferStarForRaw) flexible.upperBound.makeNullableAsSpecified(!preferNotNull) else if (preferNotNull) flexible.lowerBound else flexible.upperBound @@ -66,7 +66,10 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes( approximation = if (nullability() == TypeNullability.NOT_NULL) approximation.makeNullableAsSpecified(false) else approximation - if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType(approximation)) { + if (approximation.isMarkedNullable && !flexible.lowerBound.isMarkedNullable && TypeUtils.isTypeParameter(approximation) && TypeUtils.hasNullableSuperType( + approximation + ) + ) { approximation = approximation.makeNullableAsSpecified(false) } @@ -76,11 +79,12 @@ private fun KotlinType.approximateNonDynamicFlexibleTypes( (unwrap() as? AbbreviatedType)?.let { return AbbreviatedType(it.expandedType, it.abbreviation.approximateNonDynamicFlexibleTypes(preferNotNull)) } - return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(annotations, - constructor, - arguments.map { it.substitute { type -> type.approximateFlexibleTypes(preferNotNull = true) } }, - isMarkedNullable, - ErrorUtils.createErrorScope("This type is not supposed to be used in member resolution", true) + return KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( + annotations, + constructor, + arguments.map { it.substitute { type -> type.approximateFlexibleTypes(preferNotNull = true) } }, + isMarkedNullable, + ErrorUtils.createErrorScope("This type is not supposed to be used in member resolution", true) ) } @@ -102,7 +106,7 @@ fun KotlinType.isResolvableInScope(scope: LexicalScope?, checkTypeParameters: Bo fun KotlinType.approximateWithResolvableType(scope: LexicalScope?, checkTypeParameters: Boolean): KotlinType { if (isError || isResolvableInScope(scope, checkTypeParameters)) return this return supertypes().firstOrNull { it.isResolvableInScope(scope, checkTypeParameters) } - ?: builtIns.anyType + ?: builtIns.anyType } fun KotlinType.anonymousObjectSuperTypeOrNull(): KotlinType? { @@ -114,34 +118,39 @@ fun KotlinType.anonymousObjectSuperTypeOrNull(): KotlinType? { } fun KotlinType.getResolvableApproximations( - scope: LexicalScope?, - checkTypeParameters: Boolean, - allowIntersections: Boolean = false + scope: LexicalScope?, + checkTypeParameters: Boolean, + allowIntersections: Boolean = false ): Sequence { return (listOf(this) + TypeUtils.getAllSupertypes(this)) - .asSequence() - .filter { it.isResolvableInScope(scope, checkTypeParameters, allowIntersections) } - .mapNotNull mapArgs@ { - val resolvableArgs = it.arguments.filterTo(SmartSet.create()) { it.type.isResolvableInScope(scope, checkTypeParameters) } - if (resolvableArgs.containsAll(it.arguments)) return@mapArgs it - - val newArguments = (it.arguments zip it.constructor.parameters).map { - val (arg, param) = it - when { - arg in resolvableArgs -> arg - - arg.projectionKind == Variance.OUT_VARIANCE || - param.variance == Variance.OUT_VARIANCE -> TypeProjectionImpl( - arg.projectionKind, - arg.type.approximateWithResolvableType(scope, checkTypeParameters) - ) - - else -> return@mapArgs null - } - } - - it.replace(newArguments) + .asSequence() + .filter { it.isResolvableInScope(scope, checkTypeParameters, allowIntersections) } + .mapNotNull mapArgs@{ + val resolvableArgs = it.arguments.filterTo(SmartSet.create()) { typeProjection -> + typeProjection.type.isResolvableInScope( + scope, + checkTypeParameters + ) } + if (resolvableArgs.containsAll(it.arguments)) return@mapArgs it + + val newArguments = (it.arguments zip it.constructor.parameters).map { pair -> + val (arg, param) = pair + when { + arg in resolvableArgs -> arg + + arg.projectionKind == Variance.OUT_VARIANCE || + param.variance == Variance.OUT_VARIANCE -> TypeProjectionImpl( + arg.projectionKind, + arg.type.approximateWithResolvableType(scope, checkTypeParameters) + ) + + else -> return@mapArgs null + } + } + + it.replace(newArguments) + } } fun KotlinType.isAbstract(): Boolean { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt index 948a25b9fec..fa67e3cb4e6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt @@ -185,7 +185,8 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention, defaultItem: KotlinType ) : ChooseValueExpression(items, defaultItem) { - override fun getLookupString(element: KotlinType) = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(element) + override fun getLookupString(element: KotlinType) = + IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(element) override fun getResult(element: KotlinType): String { val renderType = IdeDescriptorRenderers.SOURCE_CODE.renderType(element) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt index 2437cbc9607..4ca106388a8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt @@ -107,11 +107,12 @@ private fun List.getVarDescriptorsAccessedAfterwards(bindingContext fun doTraversal(instruction: Instruction) { traverseFollowingInstructions(instruction, visitedInstructions) { when { - it is AccessValueInstruction && it !in this -> - PseudocodeUtil.extractVariableDescriptorIfAny(it, bindingContext)?.let { accessedAfterwards.add(it) } + it is AccessValueInstruction && it !in this -> PseudocodeUtil.extractVariableDescriptorIfAny( + it, + bindingContext + )?.let { descriptor -> accessedAfterwards.add(descriptor) } - it is LocalFunctionDeclarationInstruction -> - doTraversal(it.body.enterInstruction) + it is LocalFunctionDeclarationInstruction -> doTraversal(it.body.enterInstruction) } TraverseInstructionResult.CONTINUE @@ -238,26 +239,18 @@ private fun ExtractionData.analyzeControlFlow( val jumpExits = ArrayList() exitPoints.forEach { val e = (it as? UnconditionalJumpInstruction)?.element - val inst = - when { - it !is ReturnValueInstruction && it !is ReturnNoValueInstruction && it.owner != pseudocode -> - null - it is UnconditionalJumpInstruction && it.targetLabel.isJumpToError -> - it - e != null && e !is KtBreakExpression && e !is KtContinueExpression -> - it.previousInstructions.firstOrNull() - else -> - it - } - when (inst) { - is ReturnValueInstruction -> { - if (inst.owner == pseudocode) { - if (inst.returnExpressionIfAny == null) { - defaultExits.add(inst) - } else { - valuedReturnExits.add(inst) - } + when (val inst = when { + it !is ReturnValueInstruction && it !is ReturnNoValueInstruction && it.owner != pseudocode -> null + it is UnconditionalJumpInstruction && it.targetLabel.isJumpToError -> it + e != null && e !is KtBreakExpression && e !is KtContinueExpression -> it.previousInstructions.firstOrNull() + else -> it + }) { + is ReturnValueInstruction -> if (inst.owner == pseudocode) { + if (inst.returnExpressionIfAny == null) { + defaultExits.add(inst) + } else { + valuedReturnExits.add(inst) } } @@ -266,16 +259,10 @@ private fun ExtractionData.analyzeControlFlow( if ((element is KtReturnExpression && inst.owner == pseudocode) || element is KtBreakExpression || element is KtContinueExpression - ) { - jumpExits.add(inst) - } else if (element !is KtThrowExpression && !inst.targetLabel.isJumpToError) { - defaultExits.add(inst) - } + ) jumpExits.add(inst) else if (element !is KtThrowExpression && !inst.targetLabel.isJumpToError) defaultExits.add(inst) } - else -> if (inst != null && inst !is LocalFunctionDeclarationInstruction) { - defaultExits.add(inst) - } + else -> if (inst != null && inst !is LocalFunctionDeclarationInstruction) defaultExits.add(inst) } } @@ -306,9 +293,7 @@ private fun ExtractionData.analyzeControlFlow( val controlFlow = if (defaultReturnType.isMeaningful()) { emptyControlFlow.copy(outputValues = Collections.singletonList(ExpressionValue(false, defaultResultExpressions, defaultReturnType))) - } else { - emptyControlFlow - } + } else emptyControlFlow if (declarationsToReport.isNotEmpty()) { val localVarStr = declarationsToReport.map { it.renderForMessage(bindingContext)!! }.distinct().sorted() @@ -670,16 +655,16 @@ fun ExtractionData.performAnalysis(): AnalysisResult { val modifiedVarDescriptorsForControlFlow = HashMap(modifiedVarDescriptorsWithExpressions) modifiedVarDescriptorsForControlFlow.keys.retainAll(localInstructions.getVarDescriptorsAccessedAfterwards(bindingContext)) val (controlFlow, controlFlowMessage) = - analyzeControlFlow( - localInstructions, - pseudocode, - originalFile.findModuleDescriptor(), - bindingContext, - modifiedVarDescriptorsForControlFlow, - options, - targetScope, - paramsInfo.parameters - ) + analyzeControlFlow( + localInstructions, + pseudocode, + originalFile.findModuleDescriptor(), + bindingContext, + modifiedVarDescriptorsForControlFlow, + options, + targetScope, + paramsInfo.parameters + ) controlFlowMessage?.let { messages.add(it) } val returnType = controlFlow.outputValueBoxer.returnType