15
15
*/
16
16
package com .google .idea .blaze .base .qsync ;
17
17
18
- import static com .google .common .collect .ImmutableList .toImmutableList ;
19
- import static com .google .common .collect .ImmutableSet .toImmutableSet ;
20
- import static java .util .Arrays .stream ;
21
-
22
18
import com .google .common .collect .ImmutableList ;
23
19
import com .google .common .collect .ImmutableMap ;
24
20
import com .google .common .collect .ImmutableSet ;
37
33
import com .google .idea .blaze .qsync .project .ProjectPath ;
38
34
import com .google .idea .blaze .qsync .project .ProjectProto ;
39
35
import com .google .idea .blaze .qsync .project .ProjectProto .LibrarySource ;
40
- import com .google .idea .common .util .Transactions ;
41
36
import com .intellij .openapi .externalSystem .service .project .IdeModifiableModelsProvider ;
42
37
import com .intellij .openapi .externalSystem .service .project .ProjectDataManager ;
43
38
import com .intellij .openapi .module .Module ;
54
49
import com .intellij .openapi .roots .libraries .Library ;
55
50
import com .intellij .openapi .roots .libraries .Library .ModifiableModel ;
56
51
import com .intellij .openapi .vfs .VfsUtil ;
52
+ import org .jetbrains .jps .model .java .JavaSourceRootProperties ;
53
+ import org .jetbrains .jps .model .java .JavaSourceRootType ;
54
+ import org .jetbrains .jps .model .java .JpsJavaExtensionService ;
55
+
57
56
import java .io .File ;
58
57
import java .nio .file .Path ;
59
58
import java .nio .file .Paths ;
59
+ import java .util .AbstractMap ;
60
60
import java .util .List ;
61
61
import java .util .Set ;
62
62
import java .util .function .Function ;
63
- import org .jetbrains .jps .model .java .JavaSourceRootProperties ;
64
- import org .jetbrains .jps .model .java .JavaSourceRootType ;
65
- import org .jetbrains .jps .model .java .JpsJavaExtensionService ;
66
63
67
- /** An object that monitors the build graph and applies the changes to the project structure. */
64
+ import static com .google .common .collect .ImmutableList .toImmutableList ;
65
+ import static com .google .common .collect .ImmutableSet .toImmutableSet ;
66
+ import static java .util .Arrays .stream ;
67
+
68
+ /**
69
+ * An object that monitors the build graph and applies the changes to the project structure.
70
+ */
68
71
public class ProjectUpdater implements QuerySyncProjectListener {
69
72
70
- /** Entry point for instantiating {@link ProjectUpdater}. */
73
+ /**
74
+ * Entry point for instantiating {@link ProjectUpdater}.
75
+ */
71
76
public static class Provider implements QuerySyncProjectListenerProvider {
72
77
@ Override
73
78
public QuerySyncProjectListener createListener (QuerySyncProject querySyncProject ) {
@@ -116,14 +121,16 @@ public void onNewProjectSnapshot(Context<?> context, QuerySyncProjectSnapshot gr
116
121
117
122
private void updateProjectModel (ProjectProto .Project spec , Context <?> context ) {
118
123
File imlDirectory = new File (BlazeDataStorage .getProjectDataDir (importSettings ), "modules" );
119
- Transactions .submitWriteActionTransactionAndWait (
124
+ ProjectUpdaterThreadingUtils .Companion .performWriteAction (() -> {
125
+ for (BlazeQuerySyncPlugin syncPlugin : BlazeQuerySyncPlugin .EP_NAME .getExtensions ()) {
126
+ syncPlugin .updateProjectSettingsForQuerySync (project , context , projectViewSet );
127
+ }
128
+ });
129
+ ProjectUpdaterThreadingUtils .Companion .readWriteAction (
120
130
() -> {
121
131
IdeModifiableModelsProvider models =
122
132
ProjectDataManager .getInstance ().createModifiableModelsProvider (project );
123
133
124
- for (BlazeQuerySyncPlugin syncPlugin : BlazeQuerySyncPlugin .EP_NAME .getExtensions ()) {
125
- syncPlugin .updateProjectSettingsForQuerySync (project , context , projectViewSet );
126
- }
127
134
int removedLibCount = removeUnusedLibraries (models , spec .getLibraryList ());
128
135
if (removedLibCount > 0 ) {
129
136
context .output (PrintOutput .output ("Removed " + removedLibCount + " libs" ));
@@ -135,90 +142,98 @@ private void updateProjectModel(ProjectProto.Project spec, Context<?> context) {
135
142
}
136
143
ImmutableMap <String , Library > libMap = libMapBuilder .buildOrThrow ();
137
144
138
- for (ProjectProto .Module moduleSpec : spec .getModulesList ()) {
139
- Module module =
140
- models .newModule (
141
- imlDirectory .toPath ().resolve (moduleSpec .getName () + ".iml" ).toString (),
142
- mapModuleType (moduleSpec .getType ()).getId ());
145
+ List <AbstractMap .SimpleImmutableEntry <Module , ProjectProto .Module >> modules =
146
+ spec .getModulesList ().stream ().map (moduleSpec -> {
147
+ Module module =
148
+ models .newModule (
149
+ imlDirectory .toPath ().resolve (moduleSpec .getName () + ".iml" ).toString (),
150
+ mapModuleType (moduleSpec .getType ()).getId ());
143
151
144
- ModifiableRootModel roots = models .getModifiableRootModel (module );
145
- ImmutableList <OrderEntry > existingLibraryOrderEntries =
146
- stream (roots .getOrderEntries ())
147
- .filter (it -> it instanceof LibraryOrderEntry )
148
- .collect (toImmutableList ());
149
- for (OrderEntry entry : existingLibraryOrderEntries ) {
150
- roots .removeOrderEntry (entry );
151
- }
152
- // TODO: should this be encapsulated in ProjectProto.Module?
153
- roots .inheritSdk ();
154
-
155
- // TODO instead of removing all content entries and re-adding, we should calculate the
156
- // diff.
157
- for (ContentEntry entry : roots .getContentEntries ()) {
158
- roots .removeContentEntry (entry );
159
- }
160
- for (ProjectProto .ContentEntry ceSpec : moduleSpec .getContentEntriesList ()) {
161
- ProjectPath projectPath = ProjectPath .create (ceSpec .getRoot ());
152
+ ModifiableRootModel roots = models .getModifiableRootModel (module );
153
+ ImmutableList <OrderEntry > existingLibraryOrderEntries =
154
+ stream (roots .getOrderEntries ())
155
+ .filter (it -> it instanceof LibraryOrderEntry )
156
+ .collect (toImmutableList ());
157
+ for (OrderEntry entry : existingLibraryOrderEntries ) {
158
+ roots .removeOrderEntry (entry );
159
+ }
160
+ // TODO: should this be encapsulated in ProjectProto.Module?
161
+ roots .inheritSdk ();
162
162
163
- ContentEntry contentEntry =
164
- roots .addContentEntry (
165
- UrlUtil .pathToUrl (projectPathResolver .resolve (projectPath ).toString ()));
166
- for (ProjectProto .SourceFolder sfSpec : ceSpec .getSourcesList ()) {
167
- ProjectPath sourceFolderProjectPath = ProjectPath .create (sfSpec .getProjectPath ());
163
+ // TODO instead of removing all content entries and re-adding, we should calculate the
164
+ // diff.
165
+ for (ContentEntry entry : roots .getContentEntries ()) {
166
+ roots .removeContentEntry (entry );
167
+ }
168
+ for (ProjectProto .ContentEntry ceSpec : moduleSpec .getContentEntriesList ()) {
169
+ ProjectPath projectPath = ProjectPath .create (ceSpec .getRoot ());
168
170
169
- JavaSourceRootProperties properties =
170
- JpsJavaExtensionService .getInstance ()
171
- .createSourceRootProperties (
172
- sfSpec .getPackagePrefix (), sfSpec .getIsGenerated ());
173
- JavaSourceRootType rootType =
174
- sfSpec .getIsTest () ? JavaSourceRootType .TEST_SOURCE : JavaSourceRootType .SOURCE ;
175
- String url =
176
- UrlUtil .pathToUrl (
177
- projectPathResolver .resolve (sourceFolderProjectPath ).toString (),
178
- sourceFolderProjectPath .innerJarPath ());
179
- SourceFolder unused = contentEntry .addSourceFolder (url , rootType , properties );
180
- }
181
- for (String exclude : ceSpec .getExcludesList ()) {
182
- contentEntry .addExcludeFolder (
183
- UrlUtil .pathToIdeaDirectoryUrl (workspaceRoot .absolutePathFor (exclude )));
184
- }
185
- }
171
+ ContentEntry contentEntry =
172
+ roots .addContentEntry (
173
+ UrlUtil .pathToUrl (projectPathResolver .resolve (projectPath ).toString ()));
174
+ for (ProjectProto .SourceFolder sfSpec : ceSpec .getSourcesList ()) {
175
+ ProjectPath sourceFolderProjectPath = ProjectPath .create (sfSpec .getProjectPath ());
186
176
187
- for (String lib : moduleSpec .getLibraryNameList ()) {
188
- Library library = libMap .get (lib );
189
- if (library == null ) {
190
- throw new IllegalStateException (
191
- "Module refers to library " + lib + " not present in the project spec" );
192
- }
193
- LibraryOrderEntry entry = roots .addLibraryEntry (library );
194
- // TODO should this stuff be specified by the Module proto too?
195
- entry .setScope (DependencyScope .COMPILE );
196
- entry .setExported (false );
197
- }
177
+ JavaSourceRootProperties properties =
178
+ JpsJavaExtensionService .getInstance ()
179
+ .createSourceRootProperties (
180
+ sfSpec .getPackagePrefix (), sfSpec .getIsGenerated ());
181
+ JavaSourceRootType rootType =
182
+ sfSpec .getIsTest () ? JavaSourceRootType .TEST_SOURCE : JavaSourceRootType .SOURCE ;
183
+ String url =
184
+ UrlUtil .pathToUrl (
185
+ projectPathResolver .resolve (sourceFolderProjectPath ).toString (),
186
+ sourceFolderProjectPath .innerJarPath ());
187
+ SourceFolder unused = contentEntry .addSourceFolder (url , rootType , properties );
188
+ }
189
+ for (String exclude : ceSpec .getExcludesList ()) {
190
+ contentEntry .addExcludeFolder (
191
+ UrlUtil .pathToIdeaDirectoryUrl (workspaceRoot .absolutePathFor (exclude )));
192
+ }
193
+ }
198
194
199
- WorkspaceLanguageSettings workspaceLanguageSettings =
200
- LanguageSupport .createWorkspaceLanguageSettings (projectViewSet );
195
+ for (String lib : moduleSpec .getLibraryNameList ()) {
196
+ Library library = libMap .get (lib );
197
+ if (library == null ) {
198
+ throw new IllegalStateException (
199
+ "Module refers to library " + lib + " not present in the project spec" );
200
+ }
201
+ LibraryOrderEntry entry = roots .addLibraryEntry (library );
202
+ // TODO should this stuff be specified by the Module proto too?
203
+ entry .setScope (DependencyScope .COMPILE );
204
+ entry .setExported (false );
205
+ }
206
+ return new AbstractMap .SimpleImmutableEntry <>(module , moduleSpec );
207
+ }).toList ();
208
+ return new AbstractMap .SimpleImmutableEntry <>(models , modules );
209
+ },
210
+ readValue -> {
211
+ IdeModifiableModelsProvider models = readValue .getKey ();
212
+ WorkspaceLanguageSettings workspaceLanguageSettings =
213
+ LanguageSupport .createWorkspaceLanguageSettings (projectViewSet );
201
214
202
- for (BlazeQuerySyncPlugin syncPlugin : BlazeQuerySyncPlugin .EP_NAME .getExtensions ()) {
203
- // TODO update ProjectProto.Module and updateProjectStructure() to allow a more
204
- // suitable
205
- // data type to be passed in here instead of androidResourceDirectories and
206
- // androidSourcePackages
215
+ for (BlazeQuerySyncPlugin syncPlugin : BlazeQuerySyncPlugin .EP_NAME .getExtensions ()) {
216
+ // TODO update ProjectProto.Module and updateProjectStructure() to allow a more
217
+ // suitable
218
+ // data type to be passed in here instead of androidResourceDirectories and
219
+ // androidSourcePackages
220
+ for (AbstractMap .SimpleImmutableEntry <Module , ProjectProto .Module > moduleEntry : readValue .getValue ()) {
221
+ ProjectProto .Module moduleSpec = moduleEntry .getValue ();
207
222
syncPlugin .updateProjectStructureForQuerySync (
208
223
project ,
209
224
context ,
210
225
models ,
211
226
workspaceRoot ,
212
- module ,
227
+ moduleEntry . getKey () ,
213
228
ImmutableSet .copyOf (moduleSpec .getAndroidResourceDirectoriesList ()),
214
229
ImmutableSet .<String >builder ()
215
230
.addAll (moduleSpec .getAndroidSourcePackagesList ())
216
231
.addAll (moduleSpec .getAndroidCustomPackagesList ())
217
232
.build (),
218
233
workspaceLanguageSettings );
219
234
}
220
- models .commit ();
221
235
}
236
+ models .commit ();
222
237
});
223
238
}
224
239
0 commit comments