From 9e69b74a1571e2eb95c70db1fb5e15aa6d83f9d4 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 21 May 2015 19:06:25 +0300 Subject: [PATCH] Extract Function: Extract smart-cast value as parameter #KT-7576 Fixed --- .../kotlin/cfg/pseudocode/pseudocodeUtil.kt | 10 +-- .../kotlin/psi/psiUtil/jetPsiUtil.kt | 9 +++ .../ExtractableCodeDescriptor.kt | 2 +- .../extractionEngine/ExtractionData.kt | 73 +++++++++++++------ .../extractableAnalysisUtil.kt | 34 ++++----- .../basic/extensionValUnderSmartCast.kt | 14 ++++ .../basic/extensionValUnderSmartCast.kt.after | 16 ++++ .../basic/memberValUnderSmartCast.kt | 12 +++ .../basic/memberValUnderSmartCast.kt.after | 14 ++++ ...berValUnderSmartCastAndImplicitReceiver.kt | 15 ++++ ...UnderSmartCastAndImplicitReceiver.kt.after | 17 +++++ .../basic/topLevelValUnderSmartCast.kt | 9 +++ .../basic/topLevelValUnderSmartCast.kt.after | 11 +++ .../introduce/JetExtractionTestGenerated.java | 24 ++++++ 14 files changed, 214 insertions(+), 46 deletions(-) create mode 100644 idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt.after create mode 100644 idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt.after create mode 100644 idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt.after create mode 100644 idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt create mode 100644 idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt.after diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtil.kt index 0ee28e44341..cbeb5875b82 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtil.kt @@ -191,13 +191,9 @@ public fun JetElement.getContainingPseudocode(context: BindingContext): Pseudoco ?: getNonStrictParentOfType() ?: return null - val enclosingPseudocodeDeclaration = if (pseudocodeDeclaration is JetFunctionLiteral) { - parents(withItself = false).firstOrNull { it is JetDeclaration && it !is JetFunctionLiteral } as? JetDeclaration - ?: pseudocodeDeclaration - } - else { - pseudocodeDeclaration - } + val enclosingPseudocodeDeclaration = (pseudocodeDeclaration as? JetFunctionLiteral)?.let { + it.parents(withItself = false).firstOrNull { it is JetDeclaration && it !is JetFunctionLiteral } as? JetDeclaration + } ?: pseudocodeDeclaration val enclosingPseudocode = PseudocodeUtil.generatePseudocode(enclosingPseudocodeDeclaration, context) return enclosingPseudocode.getPseudocodeByElement(pseudocodeDeclaration) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt index 806cb6692a7..abad4dcfa37 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/psiUtil/jetPsiUtil.kt @@ -667,3 +667,12 @@ public fun JetExpression.getAnnotationEntries(): List { else -> emptyList() } } + +public fun JetElement.getQualifiedExpressionForSelector(): JetQualifiedExpression? { + val parent = getParent() + return if (parent is JetQualifiedExpression && parent.getSelectorExpression() == this) parent else null +} + +public fun JetElement.getQualifiedExpressionForSelectorOrThis(): JetElement { + return getQualifiedExpressionForSelector() ?: this +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt index a1b91102dfd..aac75510083 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt @@ -77,7 +77,7 @@ class RenameReplacement(override val parameter: Parameter): ParameterReplacement [suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")] override fun invoke(e: JetElement): JetElement { - val expressionToReplace = e.getParent() as? JetThisExpression ?: e + var expressionToReplace = (e.getParent() as? JetThisExpression ?: e).getQualifiedExpressionForSelectorOrThis() val psiFactory = JetPsiFactory(e) val replacement = if (expressionToReplace is JetOperationReferenceExpression) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt index cc0e9106014..fab6f6e7ac3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractionData.kt @@ -30,18 +30,22 @@ import java.util.Collections import org.jetbrains.kotlin.psi.psiUtil.isInsideOf import java.util.ArrayList import com.intellij.psi.PsiNamedElement +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.core.compareDescriptors +import org.jetbrains.kotlin.idea.core.refactoring.getContextForContainingDeclarationBody import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector +import org.jetbrains.kotlin.types.JetType data class ExtractionOptions( val inferUnitTypeForUnusedValues: Boolean = true, @@ -65,7 +69,8 @@ data class ResolveResult( data class ResolvedReferenceInfo( val refExpr: JetSimpleNameExpression, val offsetInBody: Int, - val resolveResult: ResolveResult + val resolveResult: ResolveResult, + val smartCast: JetType? ) data class ExtractionData( @@ -105,6 +110,10 @@ data class ExtractionData( val originalStartOffset: Int? get() = originalElements.firstOrNull()?.let { e -> e.getTextRange()!!.getStartOffset() } + val commonParent = PsiTreeUtil.findCommonParent(originalElements) as JetElement + + val bindingContext: BindingContext? by Delegates.lazy { commonParent.getContextForContainingDeclarationBody() } + private val itFakeDeclaration by Delegates.lazy { JetPsiFactory(originalFile).createParameter("it: Any?") } val refOffsetToDeclaration by Delegates.lazy { @@ -115,33 +124,44 @@ data class ExtractionData( } val originalStartOffset = originalStartOffset + val context = bindingContext - if (originalStartOffset != null) { + if (originalStartOffset != null && context != null) { val resultMap = HashMap() - for ((ref, context) in JetFileReferencesResolver.resolve(originalFile, getExpressions())) { - if (ref !is JetSimpleNameExpression) continue - if (ref.getParent() is JetValueArgumentName) continue + val visitor = object: JetTreeVisitorVoid() { + override fun visitQualifiedExpression(expression: JetQualifiedExpression) { + if (context[BindingContext.SMARTCAST, expression] != null) { + expression.getSelectorExpression()?.accept(this) + return + } - val resolvedCall = ref.getResolvedCall(context)?.let { - (it as? VariableAsFunctionResolvedCall)?.functionCall ?: it + super.visitQualifiedExpression(expression) } - val descriptor = context[BindingContext.REFERENCE_TARGET, ref] - if (descriptor == null) continue + override fun visitSimpleNameExpression(ref: JetSimpleNameExpression) { + if (ref !is JetSimpleNameExpression) return + if (ref.getParent() is JetValueArgumentName) return - val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) as? PsiNamedElement - ?: if (isExtractableIt(descriptor, context)) itFakeDeclaration else continue + val resolvedCall = ref.getResolvedCall(context) + val descriptor = context[BindingContext.REFERENCE_TARGET, ref] ?: return + val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) as? PsiNamedElement + ?: if (isExtractableIt(descriptor, context)) itFakeDeclaration else return - val offset = ref.getTextRange()!!.getStartOffset() - originalStartOffset - resultMap[offset] = ResolveResult(ref, declaration, descriptor, resolvedCall) + val offset = ref.getTextRange()!!.getStartOffset() - originalStartOffset + resultMap[offset] = ResolveResult(ref, declaration, descriptor, resolvedCall) + } } + getExpressions().forEach { it.accept(visitor) } + resultMap } else Collections.emptyMap() } fun getBrokenReferencesInfo(body: JetBlockExpression): List { + val originalContext = bindingContext ?: return listOf() + val startOffset = body.getBlockContentOffset() val referencesInfo = ArrayList() @@ -150,22 +170,33 @@ data class ExtractionData( if (ref !is JetSimpleNameExpression) continue val offset = ref.getTextRange()!!.getStartOffset() - startOffset - val originalResolveResult = refOffsetToDeclaration[offset] - if (originalResolveResult == null) continue + val originalResolveResult = refOffsetToDeclaration[offset] ?: continue - val parent = ref.getParent() - if (parent is JetQualifiedExpression && parent.getSelectorExpression() == ref) { + val smartCast: JetType? + + // Qualified property reference: a.b + val qualifiedExpression = ref.getQualifiedExpressionForSelector() + if (qualifiedExpression != null) { + smartCast = originalContext[BindingContext.SMARTCAST, originalResolveResult.originalRefExpr.getParent() as JetExpression] val receiverDescriptor = (originalResolveResult.resolvedCall?.getDispatchReceiver() as? ThisReceiver)?.getDeclarationDescriptor() - if (!DescriptorUtils.isCompanionObject(receiverDescriptor) && parent.getReceiverExpression() !is JetSuperExpression) continue + if (smartCast == null + && !DescriptorUtils.isCompanionObject(receiverDescriptor) + && qualifiedExpression.getReceiverExpression() !is JetSuperExpression) continue } + else { + smartCast = originalContext[BindingContext.SMARTCAST, originalResolveResult.originalRefExpr] + } + + val parent = ref.getParent() + // Skip P in type references like 'P.Q' if (parent is JetUserType && (parent.getParent() as? JetUserType)?.getQualifier() == parent) continue val descriptor = context[BindingContext.REFERENCE_TARGET, ref] - if (!compareDescriptors(project, originalResolveResult.descriptor, descriptor) - && !originalResolveResult.declaration.isInsideOf(originalElements)) { - referencesInfo.add(ResolvedReferenceInfo(ref, offset, originalResolveResult)) + val isBadRef = !compareDescriptors(project, originalResolveResult.descriptor, descriptor) || smartCast != null + if (isBadRef && !originalResolveResult.declaration.isInsideOf(originalElements)) { + referencesInfo.add(ResolvedReferenceInfo(ref, offset, originalResolveResult, smartCast)) } } 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 aaa925e083f..1dc88e35eb6 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 @@ -633,10 +633,10 @@ private fun ExtractionData.inferParametersInfo( info.replacementMap[refInfo.offsetInBody] = FqNameReplacement(originalDescriptor.importableFqNameSafe) } else { - val extractThis = hasThisReceiver || thisExpr != null - val extractLocalVar = + val extractThis = (hasThisReceiver && refInfo.smartCast == null) || thisExpr != null + val extractOrdinaryParameter = originalDeclaration is JetMultiDeclarationEntry || - (originalDeclaration is JetProperty && originalDeclaration.isLocal()) || + originalDeclaration is JetProperty || originalDeclaration is JetParameter val extractFunctionRef = @@ -647,11 +647,15 @@ private fun ExtractionData.inferParametersInfo( val descriptorToExtract = (if (extractThis) thisDescriptor else null) ?: originalDescriptor - val extractParameter = extractThis || extractLocalVar || extractFunctionRef + val extractParameter = extractThis || extractOrdinaryParameter || extractFunctionRef if (extractParameter) { val parameterExpression = when { - receiverToExtract is ExpressionReceiver -> receiverToExtract.getExpression() - receiverToExtract.exists() -> null + receiverToExtract is ExpressionReceiver -> { + val receiverExpression = receiverToExtract.getExpression() + // If p.q has a smart-cast, then extract entire qualified expression + if (refInfo.smartCast != null) receiverExpression.getParent() as JetExpression else receiverExpression + } + receiverToExtract.exists() && refInfo.smartCast == null -> null else -> (originalRef.getParent() as? JetThisExpression) ?: originalRef } @@ -683,8 +687,10 @@ private fun ExtractionData.inferParametersInfo( val label = if (descriptorToExtract is ClassDescriptor) "@${descriptorToExtract.getName().asString()}" else "" "this$label" } - else - (thisExpr ?: ref).getText() ?: throw AssertionError("'this' reference shouldn't be empty: code fragment = $codeFragmentText") + else { + val argumentExpr = (thisExpr ?: ref).getQualifiedExpressionForSelectorOrThis() + argumentExpr.getText() ?: throw AssertionError("'this' reference shouldn't be empty: code fragment = $codeFragmentText") + } if (extractFunctionRef) { val receiverTypeText = (originalDeclaration as JetCallableDeclaration).getReceiverTypeReference()?.getText() ?: "" argumentText = "$receiverTypeText::$argumentText" @@ -807,24 +813,18 @@ fun ExtractionData.getDefaultVisibility(): String { } fun ExtractionData.performAnalysis(): AnalysisResult { - if (originalElements.isEmpty()) { - return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(ErrorMessage.NO_EXPRESSION)) - } + if (originalElements.isEmpty()) return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(ErrorMessage.NO_EXPRESSION)) val noContainerError = AnalysisResult(null, Status.CRITICAL_ERROR, listOf(ErrorMessage.NO_CONTAINER)) - val commonParent = PsiTreeUtil.findCommonParent(originalElements) as JetElement - - val bindingContext = commonParent.getContextForContainingDeclarationBody() - if (bindingContext == null) return noContainerError - - val targetScope = JetScopeUtils.getResolutionScope(targetSibling, bindingContext) + val bindingContext = bindingContext ?: return noContainerError val pseudocode = commonParent.getContainingPseudocode(bindingContext) ?: return noContainerError val localInstructions = getLocalInstructions(pseudocode) val modifiedVarDescriptorsWithExpressions = localInstructions.getModifiedVarDescriptors(bindingContext) + val targetScope = JetScopeUtils.getResolutionScope(targetSibling, bindingContext) val paramsInfo = inferParametersInfo(commonParent, pseudocode, bindingContext, targetScope, modifiedVarDescriptorsWithExpressions.keySet()) if (paramsInfo.errorMessage != null) { return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(paramsInfo.errorMessage!!)) diff --git a/idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt b/idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt new file mode 100644 index 00000000000..0d7edaeb854 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt @@ -0,0 +1,14 @@ +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: A +// PARAM_DESCRIPTOR: val a: A defined in test +class A { + +} + +val A.meters: Int? get() = 1 + +fun test() { + val a = A() + if (a.meters == null) return + val km = a.meters / 10 +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt.after b/idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt.after new file mode 100644 index 00000000000..4bc306c2b6d --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt.after @@ -0,0 +1,16 @@ +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: A +// PARAM_DESCRIPTOR: val a: A defined in test +class A { + +} + +val A.meters: Int? get() = 1 + +fun test() { + val a = A() + if (a.meters == null) return + val km = i(a) +} + +private fun i(a: A) = a.meters / 10 \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt new file mode 100644 index 00000000000..bccd8158e34 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt @@ -0,0 +1,12 @@ +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: internal final val meters: kotlin.Int? defined in A +class A { + val meters: Int? = 1 +} + +fun test() { + val a = A() + if (a.meters == null) return + val km = a.meters / 10 +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt.after b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt.after new file mode 100644 index 00000000000..f3a760b8300 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt.after @@ -0,0 +1,14 @@ +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: internal final val meters: kotlin.Int? defined in A +class A { + val meters: Int? = 1 +} + +fun test() { + val a = A() + if (a.meters == null) return + val km = i(a.meters) +} + +private fun i(meters: Int) = meters / 10 \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt new file mode 100644 index 00000000000..df99c7d3ff7 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: internal final val meters: kotlin.Int? defined in A +class A { + val meters: Int? = 1 +} + +fun test() { + val a = A() + with (a) { + if (meters == null) return + val km = meters / 10 + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt.after b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt.after new file mode 100644 index 00000000000..2963259b1ee --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt.after @@ -0,0 +1,17 @@ +// WITH_RUNTIME +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: internal final val meters: kotlin.Int? defined in A +class A { + val meters: Int? = 1 +} + +fun test() { + val a = A() + with (a) { + if (meters == null) return + val km = i(meters) + } +} + +private fun i(meters: Int) = meters / 10 \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt b/idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt new file mode 100644 index 00000000000..338e1844d79 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt @@ -0,0 +1,9 @@ +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: internal val meters: kotlin.Int? defined in root package +val meters: Int? = 1 + +fun test() { + if (meters == null) return + val km = meters / 10 +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt.after b/idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt.after new file mode 100644 index 00000000000..6c7bc9f24e4 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt.after @@ -0,0 +1,11 @@ +// SUGGESTED_NAMES: i, getKm +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: internal val meters: kotlin.Int? defined in root package +val meters: Int? = 1 + +fun test() { + if (meters == null) return + val km = i(meters) +} + +private fun i(meters: Int) = meters / 10 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index 36cf9fa72b0..d2d5527da30 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -348,6 +348,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("extensionValUnderSmartCast.kt") + public void testExtensionValUnderSmartCast() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/extensionValUnderSmartCast.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("fakeOverride.kt") public void testFakeOverride() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/fakeOverride.kt"); @@ -456,6 +462,18 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("memberValUnderSmartCast.kt") + public void testMemberValUnderSmartCast() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCast.kt"); + doExtractFunctionTest(fileName); + } + + @TestMetadata("memberValUnderSmartCastAndImplicitReceiver.kt") + public void testMemberValUnderSmartCastAndImplicitReceiver() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/memberValUnderSmartCastAndImplicitReceiver.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("misdirectedRef.kt") public void testMisdirectedRef() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/misdirectedRef.kt"); @@ -498,6 +516,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("topLevelValUnderSmartCast.kt") + public void testTopLevelValUnderSmartCast() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/topLevelValUnderSmartCast.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("traitFunction.kt") public void testTraitFunction() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/traitFunction.kt");