@@ -3,6 +3,7 @@ package com.apollographql.ijplugin.codegen
3
3
import com.apollographql.ijplugin.gradle.CODEGEN_GRADLE_TASK_NAME
4
4
import com.apollographql.ijplugin.gradle.GradleHasSyncedListener
5
5
import com.apollographql.ijplugin.gradle.SimpleProgressListener
6
+ import com.apollographql.ijplugin.gradle.apolloKotlinProjectModelService
6
7
import com.apollographql.ijplugin.gradle.getGradleRootPath
7
8
import com.apollographql.ijplugin.gradle.runGradleBuild
8
9
import com.apollographql.ijplugin.project.ApolloProjectListener
@@ -12,13 +13,15 @@ import com.apollographql.ijplugin.settings.ProjectSettingsListener
12
13
import com.apollographql.ijplugin.settings.ProjectSettingsState
13
14
import com.apollographql.ijplugin.settings.projectSettingsState
14
15
import com.apollographql.ijplugin.util.apolloGeneratedSourcesRoots
16
+ import com.apollographql.ijplugin.util.apolloKotlinService
15
17
import com.apollographql.ijplugin.util.dispose
16
18
import com.apollographql.ijplugin.util.isNotDisposed
17
19
import com.apollographql.ijplugin.util.logd
18
20
import com.apollographql.ijplugin.util.logw
19
21
import com.apollographql.ijplugin.util.newDisposable
20
22
import com.apollographql.ijplugin.util.runWriteActionInEdt
21
23
import com.intellij.lang.jsgraphql.GraphQLFileType
24
+ import com.intellij.lang.jsgraphql.psi.GraphQLFile
22
25
import com.intellij.openapi.Disposable
23
26
import com.intellij.openapi.components.Service
24
27
import com.intellij.openapi.editor.Document
@@ -33,6 +36,7 @@ import com.intellij.openapi.project.Project
33
36
import com.intellij.openapi.roots.ProjectRootManager
34
37
import com.intellij.openapi.util.CheckedDisposable
35
38
import com.intellij.openapi.vfs.VfsUtil
39
+ import com.intellij.psi.PsiDocumentManager
36
40
import kotlinx.coroutines.CoroutineScope
37
41
import kotlinx.coroutines.launch
38
42
import org.gradle.tooling.CancellationTokenSource
@@ -83,20 +87,19 @@ class ApolloCodegenService(
83
87
84
88
private fun startOrStopCodegenObservers () {
85
89
if (shouldTriggerCodegenAutomatically()) {
86
- // To make the codegen more reactive, any touched GraphQL document will automatically be saved (thus triggering Gradle )
90
+ // To make the codegen more reactive, any touched GraphQL document will automatically be saved (thus triggering the codegen )
87
91
// as soon as the current editor is changed.
88
92
startObserveDocumentChanges()
89
93
startObserveFileEditorChanges()
90
94
91
- startContinuousGradleCodegen ()
95
+ startCodegen ()
92
96
93
- // Since we rely on Gradle's continuous build, which is not re-triggered when Gradle build files change, observe that
94
- // ourselves and restart the build when it happens.
97
+ // A Gradle sync is a good indicator that Gradle files have changed - trigger a codegen build when that happens.
95
98
startObserveGradleHasSynced()
96
99
} else {
97
100
stopObserveDocumentChanges()
98
101
stopObserveFileEditorChanges()
99
- stopContinuousGradleCodegen ()
102
+ stopCodegen ()
100
103
stopObserveGradleHasSynced()
101
104
}
102
105
}
@@ -144,8 +147,11 @@ class ApolloCodegenService(
144
147
fileEditorChangesDisposable = disposable
145
148
project.messageBus.connect(disposable).subscribe(FileEditorManagerListener .FILE_EDITOR_MANAGER , object : FileEditorManagerListener {
146
149
override fun selectionChanged (event : FileEditorManagerEvent ) {
147
- logd(event.newFile)
150
+ logd(event.newFile?.path )
148
151
dirtyGqlDocument?.let {
152
+ val operationGraphQLFile = PsiDocumentManager .getInstance(project).getPsiFile(dirtyGqlDocument!! ) as ? GraphQLFile
153
+ val apolloKotlinService = operationGraphQLFile?.apolloKotlinService()
154
+ logd(" apolloKotlinService=${apolloKotlinService?.id} " )
149
155
dirtyGqlDocument = null
150
156
runWriteActionInEdt {
151
157
try {
@@ -156,6 +162,14 @@ class ApolloCodegenService(
156
162
logw(e, " Failed to save document" )
157
163
}
158
164
}
165
+
166
+ if (apolloKotlinService?.hasCompilerOptions == true ) {
167
+ // We can use the built-in Apollo compiler
168
+ ApolloCompilerHelper (project).generateSources(apolloKotlinService)
169
+ } else {
170
+ // Fall back to the Gradle codegen task
171
+ startGradleCodegen()
172
+ }
159
173
}
160
174
}
161
175
})
@@ -167,7 +181,7 @@ class ApolloCodegenService(
167
181
fileEditorChangesDisposable = null
168
182
}
169
183
170
- private fun startContinuousGradleCodegen () {
184
+ private fun startGradleCodegen () {
171
185
logd()
172
186
173
187
if (gradleCodegenCancellation != null ) {
@@ -178,18 +192,17 @@ class ApolloCodegenService(
178
192
val modules = ModuleManager .getInstance(project).modules
179
193
coroutineScope.launch {
180
194
gradleCodegenCancellation = GradleConnector .newCancellationTokenSource()
181
- logd(" Start Gradle" )
195
+ logd(" Start Gradle codegen build " )
182
196
try {
183
197
val cancellationToken = gradleCodegenCancellation!! .token()
184
198
val gradleProjectPath = project.getGradleRootPath()
185
199
if (gradleProjectPath == null ) {
186
200
logw(" Could not get Gradle root project path" )
187
201
return @launch
188
202
}
189
- runGradleBuild(project, gradleProjectPath) {
190
- it .forTasks(CODEGEN_GRADLE_TASK_NAME )
203
+ runGradleBuild(project, gradleProjectPath) { buildLauncher ->
204
+ buildLauncher .forTasks(CODEGEN_GRADLE_TASK_NAME )
191
205
.withCancellationToken(cancellationToken)
192
- .addArguments(" --continuous" )
193
206
.let {
194
207
if (project.projectSettingsState.automaticCodegenAdditionalGradleJvmArguments.isNotEmpty()) {
195
208
it.addJvmArguments(project.projectSettingsState.automaticCodegenAdditionalGradleJvmArguments.split(' ' ))
@@ -199,24 +212,24 @@ class ApolloCodegenService(
199
212
}
200
213
.addProgressListener(object : SimpleProgressListener () {
201
214
override fun onSuccess () {
202
- logd(" Gradle build success, marking generated source roots as dirty" )
215
+ logd(" Gradle codegen build success, marking generated source roots as dirty" )
203
216
// Mark the generated sources dirty so the files are visible to the IDE
204
217
val generatedSourceRoots = modules.flatMap { it.apolloGeneratedSourcesRoots() }
205
218
logd(" Mark dirty $generatedSourceRoots " )
206
219
VfsUtil .markDirtyAndRefresh(true , true , true , * generatedSourceRoots.toTypedArray())
207
220
}
208
221
})
209
222
}
210
- logd(" Gradle execution finished" )
223
+ logd(" Gradle codegen build finished" )
211
224
} catch (t: Throwable ) {
212
- logd(t, " Gradle execution failed" )
225
+ logd(t, " Gradle codegen build failed" )
213
226
} finally {
214
227
gradleCodegenCancellation = null
215
228
}
216
229
}
217
230
}
218
231
219
- private fun stopContinuousGradleCodegen () {
232
+ private fun stopCodegen () {
220
233
logd()
221
234
gradleCodegenCancellation?.cancel()
222
235
gradleCodegenCancellation = null
@@ -235,12 +248,22 @@ class ApolloCodegenService(
235
248
project.messageBus.connect(disposable).subscribe(GradleHasSyncedListener .TOPIC , object : GradleHasSyncedListener {
236
249
override fun gradleHasSynced () {
237
250
logd()
238
- stopContinuousGradleCodegen ()
239
- if (shouldTriggerCodegenAutomatically()) startContinuousGradleCodegen ()
251
+ stopCodegen ()
252
+ if (shouldTriggerCodegenAutomatically()) startCodegen ()
240
253
}
241
254
})
242
255
}
243
256
257
+ private fun startCodegen () {
258
+ if (project.apolloKotlinProjectModelService.getApolloKotlinServices().any { it.hasCompilerOptions }) {
259
+ logd(" Using Apollo compiler for codegen" )
260
+ ApolloCompilerHelper (project).generateAllSources()
261
+ } else {
262
+ logd(" Using Gradle codegen task" )
263
+ startGradleCodegen()
264
+ }
265
+ }
266
+
244
267
private fun stopObserveGradleHasSynced () {
245
268
logd()
246
269
dispose(gradleHasSyncedDisposable)
@@ -249,6 +272,6 @@ class ApolloCodegenService(
249
272
250
273
override fun dispose () {
251
274
logd(" project=${project.name} " )
252
- stopContinuousGradleCodegen ()
275
+ stopCodegen ()
253
276
}
254
277
}
0 commit comments