Inline Variable: Remove invalid imports and perform reference lengthening/shortening when inlining non-local declaration
#KT-8884 Fixed
This commit is contained in:
@@ -499,7 +499,7 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractInlineTest>() {
|
testClass<AbstractInlineTest>() {
|
||||||
model("refactoring/inline")
|
model("refactoring/inline", pattern = "^(\\w+)\\.kt$")
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractUnwrapRemoveTest>() {
|
testClass<AbstractUnwrapRemoveTest>() {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.openapi.editor.colors.EditorColors
|
import com.intellij.openapi.editor.colors.EditorColors
|
||||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.wm.WindowManager
|
import com.intellij.openapi.wm.WindowManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
@@ -33,17 +34,24 @@ import com.intellij.refactoring.HelpID
|
|||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
import com.intellij.refactoring.util.RefactoringMessageDialog
|
import com.intellij.refactoring.util.RefactoringMessageDialog
|
||||||
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.checkConflictsInteractively
|
import org.jetbrains.kotlin.idea.core.refactoring.checkConflictsInteractively
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.move.lazilyProcessInternalReferencesToUpdateOnPackageNameChange
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages
|
||||||
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -58,6 +66,11 @@ import org.jetbrains.kotlin.utils.sure
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KotlinInlineValHandler : InlineActionHandler() {
|
class KotlinInlineValHandler : InlineActionHandler() {
|
||||||
|
companion object {
|
||||||
|
private var KtSimpleNameExpression.internalUsageInfos: MutableMap<FqName, (KtSimpleNameExpression) -> UsageInfo?>?
|
||||||
|
by CopyableUserDataProperty(Key.create("INTERNAL_USAGE_INFOS"))
|
||||||
|
}
|
||||||
|
|
||||||
override fun isEnabledForLanguage(l: Language) = l == KotlinLanguage.INSTANCE
|
override fun isEnabledForLanguage(l: Language) = l == KotlinLanguage.INSTANCE
|
||||||
|
|
||||||
override fun canInlineElement(element: PsiElement): Boolean {
|
override fun canInlineElement(element: PsiElement): Boolean {
|
||||||
@@ -146,14 +159,28 @@ class KotlinInlineValHandler : InlineActionHandler() {
|
|||||||
val typeArgumentsForCall = getTypeArgumentsStringForCall(initializer)
|
val typeArgumentsForCall = getTypeArgumentsStringForCall(initializer)
|
||||||
val parametersForFunctionLiteral = getParametersForFunctionLiteral(initializer)
|
val parametersForFunctionLiteral = getParametersForFunctionLiteral(initializer)
|
||||||
|
|
||||||
val canHighlight = referenceExpressions.all { it.containingFile === file }
|
val isSingleFile = referenceExpressions.all { it.containingFile === file }
|
||||||
if (canHighlight) {
|
if (isSingleFile) {
|
||||||
highlightExpressions(project, editor, referenceExpressions)
|
highlightExpressions(project, editor, referenceExpressions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isSingleFile) {
|
||||||
|
val targetPackages = referenceExpressions.mapNotNullTo(LinkedHashSet()) { (it.containingFile as? KtFile)?.packageFqName }
|
||||||
|
for (targetPackage in targetPackages) {
|
||||||
|
if (targetPackage == file.packageFqName) continue
|
||||||
|
val packageNameInfo = PackageNameInfo(file.packageFqName, targetPackage.toUnsafe())
|
||||||
|
initializer.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) { expr, factory ->
|
||||||
|
val infos = expr.internalUsageInfos
|
||||||
|
?: LinkedHashMap<FqName, (KtSimpleNameExpression) -> UsageInfo?>()
|
||||||
|
.apply { expr.internalUsageInfos = this }
|
||||||
|
infos[targetPackage] = factory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun performRefactoring() {
|
fun performRefactoring() {
|
||||||
if (!showDialog(project, name, declaration, referenceExpressions)) {
|
if (!showDialog(project, name, declaration, referenceExpressions)) {
|
||||||
if (canHighlight) {
|
if (isSingleFile) {
|
||||||
val statusBar = WindowManager.getInstance().getStatusBar(project)
|
val statusBar = WindowManager.getInstance().getStatusBar(project)
|
||||||
statusBar?.info = RefactoringBundle.message("press.escape.to.remove.the.highlighting")
|
statusBar?.info = RefactoringBundle.message("press.escape.to.remove.the.highlighting")
|
||||||
}
|
}
|
||||||
@@ -161,23 +188,45 @@ class KotlinInlineValHandler : InlineActionHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) {
|
project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) {
|
||||||
val inlinedExpressions = referenceExpressions.flatMap { referenceExpression ->
|
val inlinedExpressions = referenceExpressions
|
||||||
if (assignments.contains(referenceExpression.parent)) return@flatMap emptyList<KtExpression>()
|
.flatMap { referenceExpression ->
|
||||||
doReplace(referenceExpression, initializer)
|
if (assignments.contains(referenceExpression.parent)) return@flatMap emptyList<KtExpression>()
|
||||||
}
|
|
||||||
|
val importDirective = referenceExpression.getStrictParentOfType<KtImportDirective>()
|
||||||
|
if (importDirective != null) {
|
||||||
|
val reference = referenceExpression.getQualifiedElementSelector()?.mainReference
|
||||||
|
if (reference != null && reference.multiResolve(false).size <= 1) {
|
||||||
|
importDirective.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
return@flatMap emptyList<KtExpression>()
|
||||||
|
}
|
||||||
|
|
||||||
|
doReplace(referenceExpression, initializer)
|
||||||
|
}
|
||||||
|
.mapNotNull { inlinedExpression ->
|
||||||
|
val pointer = inlinedExpression.createSmartPointer()
|
||||||
|
val targetPackage = inlinedExpression.getContainingKtFile().packageFqName
|
||||||
|
val expressionsToProcess = inlinedExpression.collectDescendantsOfType<KtSimpleNameExpression> { it.internalUsageInfos != null }
|
||||||
|
val internalUsages = expressionsToProcess.mapNotNull { it.internalUsageInfos!![targetPackage]?.invoke(it) }
|
||||||
|
expressionsToProcess.forEach { it.internalUsageInfos = null }
|
||||||
|
postProcessMoveUsages(internalUsages)
|
||||||
|
pointer.element
|
||||||
|
}
|
||||||
|
|
||||||
assignments.forEach { it.delete() }
|
assignments.forEach { it.delete() }
|
||||||
declaration.delete()
|
declaration.delete()
|
||||||
|
|
||||||
if (inlinedExpressions.isEmpty()) return@executeWriteCommand
|
if (inlinedExpressions.isNotEmpty()) {
|
||||||
|
typeArgumentsForCall?.let { addTypeArguments(it, inlinedExpressions) }
|
||||||
|
|
||||||
typeArgumentsForCall?.let { addTypeArguments(it, inlinedExpressions) }
|
parametersForFunctionLiteral?.let { addFunctionLiteralParameterTypes(it, inlinedExpressions) }
|
||||||
|
|
||||||
parametersForFunctionLiteral?.let { addFunctionLiteralParameterTypes(it, inlinedExpressions) }
|
if (isSingleFile) {
|
||||||
|
highlightExpressions(project, editor, inlinedExpressions)
|
||||||
if (canHighlight) {
|
}
|
||||||
highlightExpressions(project, editor, inlinedExpressions)
|
|
||||||
}
|
}
|
||||||
|
performDelayedShortening(project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import com.intellij.refactoring.util.MoveRenameUsageInfo
|
|||||||
import com.intellij.refactoring.util.NonCodeUsageInfo
|
import com.intellij.refactoring.util.NonCodeUsageInfo
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.IncorrectOperationException
|
import com.intellij.util.IncorrectOperationException
|
||||||
import com.intellij.util.containers.ContainerUtil
|
|
||||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -63,14 +62,24 @@ import org.jetbrains.kotlin.psi.psiUtil.*
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val UNKNOWN_PACKAGE_FQ_NAME = FqNameUnsafe("org.jetbrains.kotlin.idea.refactoring.move.<unknown-package>")
|
val UNKNOWN_PACKAGE_FQ_NAME = FqNameUnsafe("org.jetbrains.kotlin.idea.refactoring.move.<unknown-package>")
|
||||||
|
|
||||||
public class PackageNameInfo(val oldPackageName: FqName, val newPackageName: FqNameUnsafe)
|
public class PackageNameInfo(val oldPackageName: FqName, val newPackageName: FqNameUnsafe)
|
||||||
|
|
||||||
public fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo: PackageNameInfo): List<UsageInfo> {
|
fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo: PackageNameInfo): List<UsageInfo> {
|
||||||
val file = getContainingFile() as? KtFile ?: return listOf()
|
val usages = ArrayList<UsageInfo>()
|
||||||
|
lazilyProcessInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) { expr, factory -> usages.addIfNotNull(factory(expr)) }
|
||||||
|
return usages
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(
|
||||||
|
packageNameInfo: PackageNameInfo,
|
||||||
|
body: (originalRefExpr: KtSimpleNameExpression, usageFactory: (KtSimpleNameExpression) -> UsageInfo?) -> Unit
|
||||||
|
) {
|
||||||
|
val file = getContainingFile() as? KtFile ?: return
|
||||||
|
|
||||||
val importPaths = file.getImportDirectives().mapNotNull { it.getImportPath() }
|
val importPaths = file.getImportDirectives().mapNotNull { it.getImportPath() }
|
||||||
|
|
||||||
@@ -85,7 +94,7 @@ public fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(packageNam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processReference(refExpr: KtSimpleNameExpression, bindingContext: BindingContext): UsageInfo? {
|
fun processReference(refExpr: KtSimpleNameExpression, bindingContext: BindingContext): ((KtSimpleNameExpression) -> UsageInfo?)? {
|
||||||
val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.getImportableDescriptor() ?: return null
|
val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.getImportableDescriptor() ?: return null
|
||||||
|
|
||||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(getProject(), descriptor) ?: return null
|
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(getProject(), descriptor) ?: return null
|
||||||
@@ -95,11 +104,13 @@ public fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(packageNam
|
|||||||
|
|
||||||
if (isCallable && !isExtension) {
|
if (isCallable && !isExtension) {
|
||||||
val containingDescriptor = descriptor.getContainingDeclaration()
|
val containingDescriptor = descriptor.getContainingDeclaration()
|
||||||
val receiver = refExpr.getReceiverExpression()
|
if (refExpr.getReceiverExpression() != null) {
|
||||||
if (receiver != null) {
|
return fun(refExpr: KtSimpleNameExpression): UsageInfo? {
|
||||||
val receiverRef = receiver.getQualifiedElementSelector() as? KtSimpleNameExpression ?: return null
|
val receiver = refExpr.getReceiverExpression() ?: return null
|
||||||
if (bindingContext[BindingContext.QUALIFIER, receiverRef] == null) return null
|
val receiverRef = receiver.getQualifiedElementSelector() as? KtSimpleNameExpression ?: return null
|
||||||
return processReference(receiverRef, bindingContext)
|
if (bindingContext[BindingContext.QUALIFIER, receiverRef] == null) return null
|
||||||
|
return processReference(receiverRef, bindingContext)?.invoke(receiverRef)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (containingDescriptor !is PackageFragmentDescriptor) return null
|
if (containingDescriptor !is PackageFragmentDescriptor) return null
|
||||||
}
|
}
|
||||||
@@ -113,41 +124,38 @@ public fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(packageNam
|
|||||||
|
|
||||||
val oldPackageName = packageNameInfo.oldPackageName
|
val oldPackageName = packageNameInfo.oldPackageName
|
||||||
val newPackageName = packageNameInfo.newPackageName
|
val newPackageName = packageNameInfo.newPackageName
|
||||||
return when {
|
|
||||||
isExtension ||
|
|
||||||
packageName == oldPackageName ||
|
|
||||||
packageName?.asString() == newPackageName.asString() ||
|
|
||||||
isImported(descriptor) -> {
|
|
||||||
if (isAncestor(declaration, false)) {
|
|
||||||
if (descriptor.importableFqName == null) return null
|
|
||||||
if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null
|
|
||||||
if (packageName == null || !newPackageName.isSafe) return null
|
|
||||||
fqName.asString().let {
|
|
||||||
val prefix = packageName.asString()
|
|
||||||
val prefixOffset = it.indexOf(prefix)
|
|
||||||
val newFqName = FqName(it.replaceRange(prefixOffset..prefixOffset + prefix.length() - 1, newPackageName.asString()))
|
|
||||||
return MoveRenameSelfUsageInfo(refExpr.mainReference, declaration, newFqName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false)
|
fun doCreateUsageInfo(refExpr: KtSimpleNameExpression): UsageInfo? {
|
||||||
|
if (isAncestor(declaration, false)) {
|
||||||
|
if (descriptor.importableFqName == null) return null
|
||||||
|
if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null
|
||||||
|
if (packageName == null || !newPackageName.isSafe) return null
|
||||||
|
return fqName.asString().let {
|
||||||
|
val prefix = packageName.asString()
|
||||||
|
val prefixOffset = it.indexOf(prefix)
|
||||||
|
val newFqName = FqName(it.replaceRange(prefixOffset..prefixOffset + prefix.length() - 1, newPackageName.asString()))
|
||||||
|
MoveRenameSelfUsageInfo(refExpr.mainReference, declaration, newFqName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
return createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isExtension &&
|
||||||
|
packageName != oldPackageName &&
|
||||||
|
packageName?.asString() != newPackageName.asString() &&
|
||||||
|
!isImported(descriptor)) return null
|
||||||
|
return ::doCreateUsageInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
val referenceToContext = KotlinFileReferencesResolver.resolve(file = file, elements = listOf(this))
|
val referenceToContext = KotlinFileReferencesResolver.resolve(file = file, elements = listOf(this))
|
||||||
|
|
||||||
val usages = ArrayList<UsageInfo>()
|
|
||||||
for ((refExpr, bindingContext) in referenceToContext) {
|
for ((refExpr, bindingContext) in referenceToContext) {
|
||||||
if (refExpr !is KtSimpleNameExpression || refExpr.getParent() is KtThisExpression) continue
|
if (refExpr !is KtSimpleNameExpression || refExpr.getParent() is KtThisExpression) continue
|
||||||
if (bindingContext[BindingContext.QUALIFIER, refExpr] != null) continue
|
if (bindingContext[BindingContext.QUALIFIER, refExpr] != null) continue
|
||||||
|
|
||||||
processReference(refExpr, bindingContext)?.let { usages.add(it) }
|
processReference(refExpr, bindingContext)?.let { body(refExpr, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
return usages
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MoveRenameUsageInfoForExtension(
|
class MoveRenameUsageInfoForExtension(
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package boo
|
||||||
|
|
||||||
|
import foo.bar.a
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(a + a())
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package boo
|
||||||
|
|
||||||
|
import foo.bar.a
|
||||||
|
import foo.bar.b
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(b + a())
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package foo.bar
|
||||||
|
|
||||||
|
val b = 1
|
||||||
|
val <caret>a = b
|
||||||
|
fun a() = b
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package foo.bar
|
||||||
|
|
||||||
|
val b = 1
|
||||||
|
fun a() = b
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
val x = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
val x = 1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package baz
|
||||||
|
|
||||||
|
val y = 2
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package baz
|
||||||
|
|
||||||
|
val y = 2
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
import foo.z
|
||||||
|
|
||||||
|
fun test() = z + 1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package bar
|
||||||
|
|
||||||
|
import baz.y
|
||||||
|
|
||||||
|
fun test() = x + y + 1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package baz
|
||||||
|
|
||||||
|
import foo.z
|
||||||
|
|
||||||
|
fun test() = z + 1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package baz
|
||||||
|
|
||||||
|
import bar.x
|
||||||
|
|
||||||
|
fun test() = x + y + 1
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package other
|
||||||
|
|
||||||
|
import foo.z
|
||||||
|
|
||||||
|
fun test() = z + 1
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package other
|
||||||
|
|
||||||
|
import bar.x
|
||||||
|
import baz.y
|
||||||
|
|
||||||
|
fun test() = x + y + 1
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import bar.x
|
||||||
|
import baz.y
|
||||||
|
|
||||||
|
val <caret>z = x + y
|
||||||
|
|
||||||
|
fun test() = z + 1
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
import bar.x
|
||||||
|
import baz.y
|
||||||
|
|
||||||
|
fun test() = x + y + 1
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package boo
|
||||||
|
|
||||||
|
import foo.bar.a
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(a)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package boo
|
||||||
|
|
||||||
|
import foo.bar.b
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(b)
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package foo.bar
|
||||||
|
|
||||||
|
val b = 1
|
||||||
|
val <caret>a = b
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package foo.bar
|
||||||
|
|
||||||
|
val b = 1
|
||||||
@@ -22,18 +22,30 @@ import com.intellij.codeInsight.TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED
|
|||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||||
import com.intellij.testFramework.UsefulTestCase
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
|
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractInlineTest : KotlinLightCodeInsightFixtureTestCase() {
|
abstract class AbstractInlineTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
|
val fixture: JavaCodeInsightTestFixture
|
||||||
|
get() = myFixture
|
||||||
|
|
||||||
protected fun doTest(path: String) {
|
protected fun doTest(path: String) {
|
||||||
|
val mainFile = File(path)
|
||||||
val afterFile = File(path + ".after")
|
val afterFile = File(path + ".after")
|
||||||
|
|
||||||
myFixture.configureByFile(path)
|
val mainFileName = mainFile.name
|
||||||
|
val mainFileBaseName = FileUtil.getNameWithoutExtension(mainFileName)
|
||||||
|
val extraFiles = mainFile.parentFile.listFiles { file, name ->
|
||||||
|
name != mainFileName && name.startsWith("$mainFileBaseName.") && (name.endsWith(".kt") || name.endsWith(".java"))
|
||||||
|
}
|
||||||
|
val extraFilesToPsi = extraFiles.toMapBy { fixture.configureByFile(path.replace(mainFileName, it.name)) }
|
||||||
|
val file = myFixture.configureByFile(path)
|
||||||
|
|
||||||
val afterFileExists = afterFile.exists()
|
val afterFileExists = afterFile.exists()
|
||||||
|
|
||||||
@@ -47,7 +59,10 @@ abstract class AbstractInlineTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
|
|
||||||
TestCase.assertTrue(afterFileExists)
|
TestCase.assertTrue(afterFileExists)
|
||||||
UsefulTestCase.assertEmpty(expectedErrors)
|
UsefulTestCase.assertEmpty(expectedErrors)
|
||||||
myFixture.checkResult(FileUtil.loadFile(afterFile, true))
|
KotlinTestUtils.assertEqualsToFile(afterFile, file.text)
|
||||||
|
for ((extraPsiFile, extraFile) in extraFilesToPsi) {
|
||||||
|
KotlinTestUtils.assertEqualsToFile(File("${extraFile.path}.after"), extraPsiFile.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (e: CommonRefactoringUtil.RefactoringErrorHintException) {
|
catch (e: CommonRefactoringUtil.RefactoringErrorHintException) {
|
||||||
TestCase.assertFalse(afterFileExists)
|
TestCase.assertFalse(afterFileExists)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import java.util.regex.Pattern;
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class InlineTestGenerated extends AbstractInlineTest {
|
public class InlineTestGenerated extends AbstractInlineTest {
|
||||||
public void testAllFilesPresentInInline() throws Exception {
|
public void testAllFilesPresentInInline() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("Basic.kt")
|
@TestMetadata("Basic.kt")
|
||||||
@@ -154,7 +154,7 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class AddParenthesis extends AbstractInlineTest {
|
public static class AddParenthesis extends AbstractInlineTest {
|
||||||
public void testAllFilesPresentInAddParenthesis() throws Exception {
|
public void testAllFilesPresentInAddParenthesis() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/addParenthesis"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/addParenthesis"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("ArrayAccess.kt")
|
@TestMetadata("ArrayAccess.kt")
|
||||||
@@ -343,7 +343,7 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class ExplicateParameterTypes extends AbstractInlineTest {
|
public static class ExplicateParameterTypes extends AbstractInlineTest {
|
||||||
public void testAllFilesPresentInExplicateParameterTypes() throws Exception {
|
public void testAllFilesPresentInExplicateParameterTypes() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/explicateParameterTypes"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/explicateParameterTypes"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("EnoughDontExplicate.kt")
|
@TestMetadata("EnoughDontExplicate.kt")
|
||||||
@@ -394,7 +394,7 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class ExplicateTypeArgument extends AbstractInlineTest {
|
public static class ExplicateTypeArgument extends AbstractInlineTest {
|
||||||
public void testAllFilesPresentInExplicateTypeArgument() throws Exception {
|
public void testAllFilesPresentInExplicateTypeArgument() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/explicateTypeArgument"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/explicateTypeArgument"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("DeeperNestedCall.kt")
|
@TestMetadata("DeeperNestedCall.kt")
|
||||||
@@ -457,7 +457,7 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Property extends AbstractInlineTest {
|
public static class Property extends AbstractInlineTest {
|
||||||
public void testAllFilesPresentInProperty() throws Exception {
|
public void testAllFilesPresentInProperty() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/property"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/property"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("Basic.kt")
|
@TestMetadata("Basic.kt")
|
||||||
@@ -484,6 +484,18 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("keepImport.kt")
|
||||||
|
public void testKeepImport() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/keepImport.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multiplePackages.kt")
|
||||||
|
public void testMultiplePackages() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/multiplePackages.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("ObjectProperty.kt")
|
@TestMetadata("ObjectProperty.kt")
|
||||||
public void testObjectProperty() throws Exception {
|
public void testObjectProperty() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/ObjectProperty.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/ObjectProperty.kt");
|
||||||
@@ -496,6 +508,12 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("removeImport.kt")
|
||||||
|
public void testRemoveImport() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/removeImport.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("WithGetter.kt")
|
@TestMetadata("WithGetter.kt")
|
||||||
public void testWithGetter() throws Exception {
|
public void testWithGetter() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/WithGetter.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/property/WithGetter.kt");
|
||||||
@@ -520,7 +538,7 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInStringTemplates() throws Exception {
|
public void testAllFilesPresentInStringTemplates() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/stringTemplates"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/inline/stringTemplates"), Pattern.compile("^(\\w+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("blockEntry.kt")
|
@TestMetadata("blockEntry.kt")
|
||||||
|
|||||||
Reference in New Issue
Block a user