Skip to content

Commit c7e4f8e

Browse files
authored
[IJ plugin] v3 -> v4 migration: deprecations/renames, part 2 (#5109)
1 parent 64dd0d9 commit c7e4f8e

File tree

8 files changed

+218
-17
lines changed

8 files changed

+218
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.apollographql.ijplugin.refactoring.migration.item
2+
3+
import com.apollographql.ijplugin.refactoring.findMethodReferences
4+
import com.intellij.openapi.project.Project
5+
import com.intellij.psi.PsiMigration
6+
import com.intellij.psi.search.GlobalSearchScope
7+
import com.intellij.psi.util.parentOfType
8+
import org.jetbrains.kotlin.psi.KtCallExpression
9+
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
10+
11+
class ConstructorInsteadOfBuilder(
12+
private val containingDeclarationName: String,
13+
private val methodName: String,
14+
) : MigrationItem() {
15+
override fun findUsages(project: Project, migration: PsiMigration, searchScope: GlobalSearchScope): List<MigrationItemUsageInfo> {
16+
return findMethodReferences(
17+
project = project,
18+
className = containingDeclarationName,
19+
methodName = methodName,
20+
).toMigrationItemUsageInfo()
21+
}
22+
23+
override fun performRefactoring(project: Project, migration: PsiMigration, usage: MigrationItemUsageInfo) {
24+
val element = usage.element
25+
val dotQualifiedExpression = element.parentOfType<KtDotQualifiedExpression>()?: return
26+
// myObj.method(x, y) -> myObj.myObj(x, y)
27+
(dotQualifiedExpression.selectorExpression as? KtCallExpression)?.calleeExpression?.replace(dotQualifiedExpression.receiverExpression)
28+
// myObj.myObj(x, y) -> myObj(x, y)
29+
dotQualifiedExpression.selectorExpression?.let { dotQualifiedExpression.replace(it) }
30+
}
31+
}

intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/refactoring/migration/item/MigrationItemUsageInfo.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fun Array<UsageInfo>.toMigrationItemUsageInfo(): List<MigrationItemUsageInfo> {
5050
}
5151

5252
context(MigrationItem)
53-
fun PsiReference.toMigrationItemUsageInfo() = MigrationItemUsageInfo(migrationItem = this@MigrationItem, reference = this)
53+
fun PsiReference.toMigrationItemUsageInfo(attachedData: Any? = null) = MigrationItemUsageInfo(migrationItem = this@MigrationItem, reference = this, attachedData = attachedData)
5454

5555
context(MigrationItem)
5656
fun Collection<PsiReference>.toMigrationItemUsageInfo(): List<MigrationItemUsageInfo> {
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
package com.apollographql.ijplugin.refactoring.migration.v3tov4.item
1+
package com.apollographql.ijplugin.refactoring.migration.item
22

33
import com.apollographql.ijplugin.refactoring.findMethodReferences
4-
import com.apollographql.ijplugin.refactoring.migration.apollo3
5-
import com.apollographql.ijplugin.refactoring.migration.item.MigrationItem
6-
import com.apollographql.ijplugin.refactoring.migration.item.MigrationItemUsageInfo
7-
import com.apollographql.ijplugin.refactoring.migration.item.toMigrationItemUsageInfo
84
import com.intellij.openapi.project.Project
95
import com.intellij.psi.PsiMigration
106
import com.intellij.psi.search.GlobalSearchScope
@@ -13,25 +9,31 @@ import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
139
import org.jetbrains.kotlin.psi.KtImportDirective
1410
import org.jetbrains.kotlin.psi.KtPsiFactory
1511

16-
object ReplaceExecuteCacheAndNetwork : MigrationItem() {
12+
class UpdateMethodCall(
13+
private val containingDeclarationName: String,
14+
private val methodName: String,
15+
private val replacementExpression: String,
16+
private val extensionTargetClassName: String? = null,
17+
private vararg val importsToAdd: String,
18+
) : MigrationItem() {
1719
override fun findUsages(project: Project, migration: PsiMigration, searchScope: GlobalSearchScope): List<MigrationItemUsageInfo> {
1820
return findMethodReferences(
1921
project = project,
20-
className = "$apollo3.cache.normalized.NormalizedCache",
21-
methodName = "executeCacheAndNetwork",
22-
extensionTargetClassName = "$apollo3.ApolloCall"
22+
className = containingDeclarationName,
23+
methodName = methodName,
24+
extensionTargetClassName = extensionTargetClassName
2325
).toMigrationItemUsageInfo()
2426
}
2527

2628
override fun performRefactoring(project: Project, migration: PsiMigration, usage: MigrationItemUsageInfo) {
27-
val element = usage.element
29+
val element = usage.element
2830
val importDirective = element.parentOfType<KtImportDirective>()
2931
if (importDirective != null) {
3032
// Reference is an import
3133
return
3234
}
33-
element.parentOfType<KtDotQualifiedExpression>()?.selectorExpression?.replace(KtPsiFactory(project).createExpression("fetchPolicy(FetchPolicy.CacheAndNetwork).toFlow()"))
35+
element.parentOfType<KtDotQualifiedExpression>()?.selectorExpression?.replace(KtPsiFactory(project).createExpression(replacementExpression))
3436
}
3537

36-
override fun importsToAdd() = setOf("$apollo3.cache.normalized.fetchPolicy", "$apollo3.cache.normalized.FetchPolicy")
38+
override fun importsToAdd() = importsToAdd.toSet()
3739
}

intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/refactoring/migration/v3tov4/ApolloV3ToV4MigrationProcessor.kt

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ package com.apollographql.ijplugin.refactoring.migration.v3tov4
33
import com.apollographql.ijplugin.ApolloBundle
44
import com.apollographql.ijplugin.refactoring.migration.ApolloMigrationRefactoringProcessor
55
import com.apollographql.ijplugin.refactoring.migration.apollo3
6+
import com.apollographql.ijplugin.refactoring.migration.item.ConstructorInsteadOfBuilder
67
import com.apollographql.ijplugin.refactoring.migration.item.RemoveMethodCall
78
import com.apollographql.ijplugin.refactoring.migration.item.UpdateClassName
89
import com.apollographql.ijplugin.refactoring.migration.item.UpdateFieldName
910
import com.apollographql.ijplugin.refactoring.migration.item.UpdateGradleDependenciesBuildKts
1011
import com.apollographql.ijplugin.refactoring.migration.item.UpdateGradleDependenciesInToml
1112
import com.apollographql.ijplugin.refactoring.migration.item.UpdateGradlePluginInBuildKts
13+
import com.apollographql.ijplugin.refactoring.migration.item.UpdateMethodCall
1214
import com.apollographql.ijplugin.refactoring.migration.item.UpdateMethodName
1315
import com.apollographql.ijplugin.refactoring.migration.v3tov4.item.RemoveWatchMethodArguments
14-
import com.apollographql.ijplugin.refactoring.migration.v3tov4.item.ReplaceExecuteCacheAndNetwork
16+
import com.apollographql.ijplugin.refactoring.migration.v3tov4.item.UpdateWebSocketReconnectWhen
1517
import com.intellij.openapi.project.Project
1618

1719
private const val apollo4LatestVersion = "4.0.0-alpha.2"
@@ -30,10 +32,42 @@ class ApolloV3ToV4MigrationProcessor(project: Project) : ApolloMigrationRefactor
3032
UpdateFieldName("$apollo3.exception.ApolloCompositeException", "first", "suppressedExceptions.first()"),
3133
UpdateFieldName("$apollo3.exception.ApolloCompositeException", "second", "suppressedExceptions.getOrNull(1)"),
3234
UpdateClassName("$apollo3.exception.ApolloCompositeException", "$apollo3.exception.ApolloException"),
35+
UpdateClassName("$apollo3.exception.ApolloCanceledException", "$apollo3.exception.ApolloException"),
36+
UpdateClassName("$apollo3.exception.ApolloGenericException", "$apollo3.exception.ApolloException"),
3337
UpdateMethodName("$apollo3.ast.GQLResult", "valueAssertNoErrors", "getOrThrow"),
38+
UpdateMethodName("$apollo3.cache.normalized.api.CacheHeaders", "toBuilder", "newBuilder"),
39+
UpdateMethodName("$apollo3.ApolloClient", "dispose", "close"),
40+
UpdateMethodName("$apollo3.ApolloClient", "mutate", "mutation"),
41+
UpdateMethodName("$apollo3.ApolloClient", "subscribe", "subscription"),
42+
UpdateMethodName("$apollo3.ApolloClient.Companion", "builder", "Builder"),
43+
UpdateMethodName("$apollo3.ApolloClient.Builder", "requestedDispatcher", "dispatcher"),
44+
UpdateMethodName("$apollo3.cache.http.DiskLruHttpCache", "delete", "clearAll"),
3445
RemoveMethodCall("$apollo3.cache.normalized.NormalizedCache", "emitCacheMisses", extensionTargetClassName = "$apollo3.api.MutableExecutionOptions"),
46+
UpdateMethodCall(
47+
"$apollo3.cache.normalized.NormalizedCache",
48+
"executeCacheAndNetwork",
49+
"fetchPolicy(FetchPolicy.CacheAndNetwork).toFlow()",
50+
extensionTargetClassName = "$apollo3.ApolloCall",
51+
"$apollo3.cache.normalized.fetchPolicy",
52+
"$apollo3.cache.normalized.FetchPolicy",
53+
),
54+
UpdateMethodCall(
55+
"$apollo3.cache.normalized.NormalizedCache",
56+
"clearNormalizedCache",
57+
replacementExpression = "apolloStore.clearAll()",
58+
extensionTargetClassName = "$apollo3.ApolloClient",
59+
"$apollo3.cache.normalized.apolloStore",
60+
),
61+
UpdateMethodCall(
62+
"$apollo3.cache.normalized.NormalizedCache",
63+
"apolloStore",
64+
replacementExpression = "apolloStore",
65+
extensionTargetClassName = "$apollo3.ApolloClient",
66+
"$apollo3.cache.normalized.apolloStore",
67+
),
3568
RemoveWatchMethodArguments,
36-
ReplaceExecuteCacheAndNetwork,
69+
ConstructorInsteadOfBuilder("$apollo3.cache.normalized.api.CacheKey.Companion", "from"),
70+
UpdateWebSocketReconnectWhen,
3771

3872
// Gradle
3973
UpdateGradlePluginInBuildKts(apollo3, apollo3, apollo4LatestVersion),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.apollographql.ijplugin.refactoring.migration.v3tov4.item
2+
3+
import com.apollographql.ijplugin.refactoring.findMethodReferences
4+
import com.apollographql.ijplugin.refactoring.migration.apollo3
5+
import com.apollographql.ijplugin.refactoring.migration.item.MigrationItem
6+
import com.apollographql.ijplugin.refactoring.migration.item.MigrationItemUsageInfo
7+
import com.apollographql.ijplugin.refactoring.migration.item.toMigrationItemUsageInfo
8+
import com.intellij.openapi.project.Project
9+
import com.intellij.psi.PsiMigration
10+
import com.intellij.psi.search.GlobalSearchScope
11+
import com.intellij.psi.util.parentOfType
12+
import org.jetbrains.kotlin.psi.KtCallExpression
13+
import org.jetbrains.kotlin.psi.KtLambdaArgument
14+
import org.jetbrains.kotlin.psi.KtPsiFactory
15+
16+
object UpdateWebSocketReconnectWhen : MigrationItem() {
17+
override fun findUsages(project: Project, migration: PsiMigration, searchScope: GlobalSearchScope): List<MigrationItemUsageInfo> {
18+
return findMethodReferences(
19+
project = project,
20+
className = "$apollo3.ApolloClient.Builder",
21+
methodName = "webSocketReconnectWhen",
22+
)
23+
.map { it.toMigrationItemUsageInfo("webSocketReopenWhen") } +
24+
findMethodReferences(
25+
project = project,
26+
className = "$apollo3.network.ws.WebSocketNetworkTransport.Builder",
27+
methodName = "reconnectWhen",
28+
)
29+
.map { it.toMigrationItemUsageInfo("reopenWhen") }
30+
}
31+
32+
override fun performRefactoring(project: Project, migration: PsiMigration, usage: MigrationItemUsageInfo) {
33+
val element = usage.element
34+
val methodCall = element.parentOfType<KtCallExpression>() ?: return
35+
val lambdaArgument = methodCall.valueArguments.firstOrNull() as? KtLambdaArgument ?: return
36+
val lambdaExpression = lambdaArgument.getLambdaExpression() ?: return
37+
val lambdaParameters = lambdaExpression.functionLiteral.valueParameterList
38+
val psiFactory = KtPsiFactory(project)
39+
element.replace(psiFactory.createExpression(usage.attachedData()))
40+
if (lambdaParameters == null) {
41+
// { ... } -> { it, _ -> ...}
42+
val newLambdaExpression = psiFactory.createLambdaExpression("it, _", lambdaExpression.bodyExpression!!.text)
43+
lambdaExpression.replace(newLambdaExpression)
44+
} else {
45+
// { a -> ...} -> { a, _ -> ...}
46+
lambdaParameters.addParameter(psiFactory.createParameter("_"))
47+
}
48+
}
49+
}

intellij-plugin/src/test/kotlin/com/apollographql/ijplugin/ApolloV3ToV4MigrationTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class ApolloV3ToV4MigrationTest : ApolloTestCase() {
1616
"com.apollographql.apollo3:apollo-mpp-utils-jvm:3.8.2",
1717
"com.apollographql.apollo3:apollo-runtime-jvm:3.8.2",
1818
"com.apollographql.apollo3:apollo-normalized-cache-jvm:3.8.2",
19+
"com.apollographql.apollo3:apollo-http-cache:3.8.2",
1920
)
2021

2122
override fun getTestDataPath() = "src/test/testData/migration/v3-to-v4"

intellij-plugin/src/test/testData/migration/v3-to-v4/deprecations.kt

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,30 @@ package com.example.myapplication
22

33
import com.apollographql.apollo3.ApolloClient
44
import com.apollographql.apollo3.api.ApolloResponse
5+
import com.apollographql.apollo3.api.Mutation
56
import com.apollographql.apollo3.api.Query
7+
import com.apollographql.apollo3.api.Subscription
8+
import com.apollographql.apollo3.cache.http.DiskLruHttpCache
9+
import com.apollographql.apollo3.cache.normalized.api.CacheHeaders
10+
import com.apollographql.apollo3.cache.normalized.api.CacheKey
11+
import com.apollographql.apollo3.cache.normalized.apolloStore
612
import com.apollographql.apollo3.cache.normalized.emitCacheMisses
713
import com.apollographql.apollo3.cache.normalized.executeCacheAndNetwork
814
import com.apollographql.apollo3.cache.normalized.watch
15+
import com.apollographql.apollo3.exception.ApolloCanceledException
916
import com.apollographql.apollo3.exception.ApolloCompositeException
17+
import com.apollographql.apollo3.exception.ApolloGenericException
18+
import com.apollographql.apollo3.network.ws.WebSocketNetworkTransport
1019

1120
suspend fun test() {
1221
val response: ApolloResponse<*>? = null
1322
println(response?.dataAssertNoErrors)
1423

15-
val apolloClient: ApolloClient? = null
24+
val apolloClient: ApolloClient? = ApolloClient.builder()
25+
.requestedDispatcher(null)
26+
.webSocketReconnectWhen { true }
27+
.webSocketReconnectWhen { a -> true }
28+
.build()
1629
val query: Query<*>? = null
1730

1831
apolloClient!!.query(query!!).emitCacheMisses(true).toFlow()
@@ -28,4 +41,34 @@ suspend fun test() {
2841
println(compositeException!!.second)
2942

3043
apolloClient!!.query(query!!).executeCacheAndNetwork()
44+
45+
apolloClient!!.apolloStore.clearAll()
46+
47+
apolloClient!!.apolloStore().clearAll()
48+
49+
val cacheHeaders: CacheHeaders = CacheHeaders.NONE.toBuilder().build()
50+
51+
val cacheKey1 = CacheKey.from("typeName", listOf("a"))
52+
val cacheKey2 = CacheKey.from("typeName", "a", "b")
53+
54+
apolloClient.dispose()
55+
56+
val mutation: Mutation<*>? = null
57+
apolloClient.mutate(mutation!!)
58+
59+
val subscription: Subscription<*>? = null
60+
apolloClient.subscribe(subscription!!)
61+
62+
val webSocketNetworkTransport = WebSocketNetworkTransport.Builder()
63+
.reconnectWhen { true }
64+
.reconnectWhen { a -> true }
65+
.build()
66+
67+
try {
68+
} catch (e1: ApolloGenericException) {
69+
} catch (e2: ApolloCanceledException) {
70+
}
71+
72+
val diskLruHttpCache: DiskLruHttpCache? = null
73+
diskLruHttpCache!!.delete()
3174
}

intellij-plugin/src/test/testData/migration/v3-to-v4/deprecations_after.kt

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,28 @@ package com.example.myapplication
22

33
import com.apollographql.apollo3.ApolloClient
44
import com.apollographql.apollo3.api.ApolloResponse
5+
import com.apollographql.apollo3.api.Mutation
56
import com.apollographql.apollo3.api.Query
7+
import com.apollographql.apollo3.api.Subscription
8+
import com.apollographql.apollo3.cache.http.DiskLruHttpCache
9+
import com.apollographql.apollo3.cache.normalized.api.CacheHeaders
10+
import com.apollographql.apollo3.cache.normalized.api.CacheKey
11+
import com.apollographql.apollo3.cache.normalized.apolloStore
612
import com.apollographql.apollo3.cache.normalized.watch
713
import com.apollographql.apollo3.exception.ApolloException
14+
import com.apollographql.apollo3.network.ws.WebSocketNetworkTransport
815
import com.apollographql.apollo3.cache.normalized.fetchPolicy
916
import com.apollographql.apollo3.cache.normalized.FetchPolicy
1017

1118
suspend fun test() {
1219
val response: ApolloResponse<*>? = null
1320
println(response?.dataOrThrow())
1421

15-
val apolloClient: ApolloClient? = null
22+
val apolloClient: ApolloClient? = ApolloClient.Builder()
23+
.dispatcher(null)
24+
.webSocketReopenWhen { it, _ -> true }
25+
.webSocketReopenWhen { a, _ -> true }
26+
.build()
1627
val query: Query<*>? = null
1728

1829
apolloClient!!.query(query!!).toFlow()
@@ -28,4 +39,34 @@ suspend fun test() {
2839
println(compositeException!!.suppressedExceptions.getOrNull(1))
2940

3041
apolloClient!!.query(query!!).fetchPolicy(FetchPolicy.CacheAndNetwork).toFlow()
42+
43+
apolloClient!!.apolloStore.clearAll()
44+
45+
apolloClient!!.apolloStore.clearAll()
46+
47+
val cacheHeaders: CacheHeaders = CacheHeaders.NONE.newBuilder().build()
48+
49+
val cacheKey1 = CacheKey("typeName", listOf("a"))
50+
val cacheKey2 = CacheKey("typeName", "a", "b")
51+
52+
apolloClient.close()
53+
54+
val mutation: Mutation<*>? = null
55+
apolloClient.mutation(mutation!!)
56+
57+
val subscription: Subscription<*>? = null
58+
apolloClient.subscription(subscription!!)
59+
60+
val webSocketNetworkTransport = WebSocketNetworkTransport.Builder()
61+
.reopenWhen { it, _ -> true }
62+
.reopenWhen { a, _ -> true }
63+
.build()
64+
65+
try {
66+
} catch (e1: ApolloException) {
67+
} catch (e2: ApolloException) {
68+
}
69+
70+
val diskLruHttpCache: DiskLruHttpCache? = null
71+
diskLruHttpCache!!.clearAll()
3172
}

0 commit comments

Comments
 (0)