Skip to content

Commit 1d36c49

Browse files
committed
Copy: Copy elements and process usages under the same write action
In some cases doing these operations in separate write actions may lead to invalidation of copied elements #KT-18149 Fixed
1 parent 6b18ff1 commit 1d36c49

File tree

8 files changed

+570
-9
lines changed

8 files changed

+570
-9
lines changed

idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -245,23 +245,25 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() {
245245

246246
val targetFile: KtFile
247247
if (singleElementToCopy is KtFile) {
248-
targetFile = runWriteAction { targetDirectory.copyFileFrom(targetFileName, singleElementToCopy) as KtFile }
248+
targetFile = runWriteAction {
249+
val copiedFile = targetDirectory.copyFileFrom(targetFileName, singleElementToCopy) as KtFile
250+
performDelayedRefactoringRequests(project)
251+
copiedFile
252+
}
249253
}
250254
else {
251255
targetFile = getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand
252256
runWriteAction {
253257
val newElements = elementsToCopy.map { targetFile.add(it.copy()) as KtNamedDeclaration }
254258
elementsToCopy.zip(newElements).toMap(oldToNewElementsMapping)
255-
}
256-
}
257259

258-
runWriteAction {
259-
for (newElement in oldToNewElementsMapping.values) {
260-
restoredInternalUsages += restoreInternalUsages(newElement as KtElement, oldToNewElementsMapping, true)
261-
postProcessMoveUsages(restoredInternalUsages, oldToNewElementsMapping)
262-
}
260+
for (newElement in oldToNewElementsMapping.values) {
261+
restoredInternalUsages += restoreInternalUsages(newElement as KtElement, oldToNewElementsMapping, true)
262+
postProcessMoveUsages(restoredInternalUsages, oldToNewElementsMapping)
263+
}
263264

264-
performDelayedRefactoringRequests(project)
265+
performDelayedRefactoringRequests(project)
266+
}
265267
}
266268

267269
(oldToNewElementsMapping.values.singleOrNull() as? KtNamedDeclaration)?.let { newDeclaration ->
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package refactor;
2+
3+
public class ParentJava {
4+
public interface FaceJava {
5+
void inherit();
6+
}
7+
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package refactor.copy
2+
3+
import refactor.ParentJava
4+
import kotlin.properties.Delegates
5+
6+
enum class Possible {
7+
NO, YES
8+
}
9+
data class Potable(val p1: String)
10+
class Insider(val peace: String)
11+
12+
class Init {
13+
fun referred() = 0
14+
fun moved() = referred()
15+
}
16+
17+
interface FaceToFace {
18+
fun extract()
19+
}
20+
21+
abstract class AbsToAbs {
22+
abstract fun extract()
23+
}
24+
25+
class Simple {
26+
fun extract() {}
27+
}
28+
29+
annotation class MemAnn
30+
31+
class Variety<C> {
32+
// object
33+
object ExtractedObject {}
34+
// function
35+
tailrec fun tailrecFun(p: Int) { if (p > 0) tailrecFun(p - 1) }
36+
operator fun plus(other: Variety<C>) {}
37+
infix fun infixFun(other: Variety<C>) {}
38+
inline fun inlineFun(f: () -> Int) = f()
39+
external fun externalFun()
40+
internal fun internalFun() = 0
41+
protected fun protectedFun() = 0
42+
private fun privateFun() = 0
43+
fun <T> genFunB(p: T): T = p
44+
fun <T> genFunC(p: T): C where T : C = p
45+
@MemAnn fun annotatedFun() = 0
46+
final fun finalFun() = 0
47+
// property
48+
var publicProp = 0
49+
internal var internalProp = 0
50+
protected var protectedProp = 0
51+
private var privateProp = 0
52+
var <T> List<T>.genVarJ: T
53+
get() = last()
54+
set(p) {}
55+
var <T> List<T>.genVarL: T where T : C
56+
get() = last()
57+
set(p) {}
58+
@MemAnn val annotatedVal = 0
59+
var byVar by Delegates.notNull<Int>()
60+
lateinit var lateVal: String
61+
final val finalVal = 0
62+
// class
63+
class ExtractedClass {}
64+
// inner class
65+
inner class ExtractedInnerClass {}
66+
// anonymousInitializer
67+
init {}
68+
// secondaryConstructor
69+
constructor(p: Int)
70+
71+
fun refer(p1: List<String>) {
72+
val v1 = ExtractedObject
73+
val v2 = ExtractedClass()
74+
val v3 = ExtractedInnerClass()
75+
val v4 = tailrecFun(2)
76+
val v5 = this + this
77+
val v6 = this infixFun this
78+
val v7 = inlineFun { 7 }
79+
val vv = externalFun()
80+
val v8 = internalFun()
81+
val v9 = protectedFun()
82+
val vA = privateFun()
83+
val vB = genFunB(0)
84+
val vD = annotatedFun()
85+
val vw = finalFun()
86+
publicProp = publicProp + 1
87+
internalProp = internalProp + 1
88+
protectedProp = protectedProp + 1
89+
privateProp = privateProp + 1
90+
p1.genVarJ = p1.genVarJ + "+"
91+
val vK = annotatedVal
92+
byVar = byVar + 1
93+
lateVal = lateVal + "+"
94+
val vN = finalVal
95+
}
96+
}
97+
98+
fun <C> Variety<C>.extend() {}
99+
100+
object VarietyObject {
101+
const val constProp = 0
102+
103+
fun refer() {
104+
val vE = constProp
105+
}
106+
}
107+
108+
abstract class AbstractVariety {
109+
abstract fun abstractFun(): Int
110+
abstract var abstractVar: Int
111+
fun refer() = abstractFun() + abstractVar
112+
}
113+
114+
interface FaceVarietyObligation {
115+
fun abstractToAbstract()
116+
fun abstractToConcrete()
117+
fun concreteToConcrete()
118+
}
119+
120+
interface FaceVariety : FaceVarietyObligation {
121+
fun abstractFun()
122+
var abstractProperty: String
123+
fun concreteFun() {}
124+
override fun abstractToAbstract()
125+
override fun abstractToConcrete() {}
126+
override fun concreteToConcrete() {}
127+
}
128+
129+
@Suppress("LeakingThis")
130+
open class CtorParameter(pp: String, open val pv: String, open var pr: String) {
131+
var vb = pp + pv + pr
132+
init { vb += pp + pv + pr }
133+
constructor() : this("p", "v", "r")
134+
fun refer() {
135+
pr += pv
136+
vb += pr
137+
}
138+
companion object {
139+
val instance = CtorParameter()
140+
}
141+
}
142+
143+
class CtorParameterChild(val pvc: String, var prc: String) : CtorParameter(pvc, pvc, prc)
144+
class CtorParameterChild2: CtorParameter {
145+
constructor() : super("", "", "")
146+
}
147+
class CtorParameterChild3(override val pv: String, override var pr: String) : CtorParameter(pv, pv, pr)
148+
data class CtorData(val pv: String, var pr: String) {}
149+
150+
class Company {
151+
companion object {
152+
val companyVal = 0
153+
var companyVar = 0
154+
fun companyFun() = 0
155+
class CompanyClass {}
156+
object CompanyObject {}
157+
}
158+
159+
fun refer() {
160+
println(companyVal)
161+
companyVar = companyVar + 1
162+
println(companyFun())
163+
val v1 = CompanyClass()
164+
val v2 = CompanyObject
165+
}
166+
}
167+
168+
fun referCompany() {
169+
println(Company.companyVal)
170+
Company.companyVar = Company.companyVar + 1
171+
println(Company.companyFun())
172+
val v1 = Company.Companion.CompanyClass()
173+
val v2 = Company.Companion.CompanyObject
174+
}
175+
176+
class JavaChild : ParentJava.FaceJava {
177+
override fun inherit() {}
178+
}

0 commit comments

Comments
 (0)