diff --git a/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java b/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java index da9379c3dcc..0cf59abe21a 100644 --- a/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java +++ b/aswb/src/com/google/idea/blaze/android/qsync/BlazeAndroidQuerySyncPlugin.java @@ -24,11 +24,11 @@ import com.android.tools.idea.projectsystem.ScopeType; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.Futures; +import com.google.idea.blaze.android.qsync.projectstructure.AndroidFacetModuleCustomizer; import com.google.idea.blaze.android.resources.BlazeLightResourceClassService; import com.google.idea.blaze.android.sdk.BlazeSdkProvider; import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform; import com.google.idea.blaze.android.sync.model.idea.BlazeAndroidModel; -import com.google.idea.blaze.android.sync.projectstructure.AndroidFacetModuleCustomizer; import com.google.idea.blaze.android.sync.sdk.AndroidSdkFromProjectView; import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; import com.google.idea.blaze.base.model.primitives.WorkspaceType; @@ -40,6 +40,7 @@ import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings; import com.google.idea.blaze.common.Context; import com.google.idea.blaze.java.projectview.JavaLanguageLevelSection; +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; @@ -76,6 +77,7 @@ public void updateProjectSettingsForQuerySync( public void updateProjectStructureForQuerySync( Project project, Context context, + IdeModifiableModelsProvider models, WorkspaceRoot workspaceRoot, Module workspaceModule, Set androidResourceDirectories, @@ -86,8 +88,11 @@ public void updateProjectStructureForQuerySync( return; } + AndroidFacetModuleCustomizer androidFacetModuleCustomizer = + new AndroidFacetModuleCustomizer(models); + // Attach AndroidFacet to workspace modules - AndroidFacetModuleCustomizer.createAndroidFacet(workspaceModule, false); + androidFacetModuleCustomizer.createAndroidFacet(workspaceModule, false); // Add all source resource directories to this AndroidFacet AndroidFacet workspaceFacet = AndroidFacet.getInstance(workspaceModule); diff --git a/aswb/src/com/google/idea/blaze/android/qsync/projectstructure/AndroidFacetModuleCustomizer.java b/aswb/src/com/google/idea/blaze/android/qsync/projectstructure/AndroidFacetModuleCustomizer.java new file mode 100755 index 00000000000..a8db85e8119 --- /dev/null +++ b/aswb/src/com/google/idea/blaze/android/qsync/projectstructure/AndroidFacetModuleCustomizer.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.idea.blaze.android.qsync.projectstructure; + +import com.android.AndroidProjectTypes; +import com.android.builder.model.AndroidProject; +import com.intellij.facet.FacetManager; +import com.intellij.facet.ModifiableFacetModel; +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; +import com.intellij.openapi.module.Module; +import org.jetbrains.android.facet.AndroidFacet; +import org.jetbrains.android.facet.AndroidFacetProperties; +import org.jetbrains.android.facet.AndroidFacetPropertiesCompat; + +/** Adds the Android facet to modules imported from {@link AndroidProject}s. */ +public class AndroidFacetModuleCustomizer { + + private final IdeModifiableModelsProvider models; + + public AndroidFacetModuleCustomizer(IdeModifiableModelsProvider models) { + this.models = models; + } + + public void createAndroidFacet(Module module, boolean isApp) { + ModifiableFacetModel modifiableFacetModel = models.getModifiableFacetModel(module); + AndroidFacet facet = modifiableFacetModel.getFacetByType(AndroidFacet.ID); + FacetManager facetManager = FacetManager.getInstance(module); + if (facet != null) { + configureFacet(facet, isApp); + } else { + // Module does not have Android facet. Create one and add it. + facet = facetManager.createFacet(AndroidFacet.getFacetType(), AndroidFacet.NAME, null); + modifiableFacetModel.addFacet(facet); + configureFacet(facet, isApp); + } + } + + private static void configureFacet(AndroidFacet facet, boolean isApp) { + AndroidFacetProperties facetState = facet.getProperties(); + facetState.ALLOW_USER_CONFIGURATION = false; + facetState.PROJECT_TYPE = + isApp ? AndroidProjectTypes.PROJECT_TYPE_APP : AndroidProjectTypes.PROJECT_TYPE_LIBRARY; + facetState.MANIFEST_FILE_RELATIVE_PATH = ""; + facetState.RES_FOLDER_RELATIVE_PATH = ""; + facetState.ASSETS_FOLDER_RELATIVE_PATH = ""; + AndroidFacetPropertiesCompat.enableSourcesAutogeneration(facetState, false); + } +} diff --git a/base/src/com/google/idea/blaze/base/qsync/BlazeQuerySyncPlugin.java b/base/src/com/google/idea/blaze/base/qsync/BlazeQuerySyncPlugin.java index be444e5d5fa..70d64e69856 100644 --- a/base/src/com/google/idea/blaze/base/qsync/BlazeQuerySyncPlugin.java +++ b/base/src/com/google/idea/blaze/base/qsync/BlazeQuerySyncPlugin.java @@ -20,6 +20,7 @@ import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings; import com.google.idea.blaze.common.Context; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import java.util.Set; @@ -29,14 +30,15 @@ public interface BlazeQuerySyncPlugin { ExtensionPointName EP_NAME = ExtensionPointName.create("com.google.idea.blaze.QuerySyncPlugin"); - /** Updates the sdk for the project -- only used for the new query-sync */ + /** Updates the sdk and language settings for the project */ default void updateProjectSettingsForQuerySync( Project project, Context context, ProjectViewSet projectViewSet) {} - /** Modifies the IDE project structure -- only used for the new query-sync */ + /** Modifies the IDE project structure */ default void updateProjectStructureForQuerySync( Project project, Context context, + IdeModifiableModelsProvider models, WorkspaceRoot workspaceRoot, Module workspaceModule, Set androidResourceDirectories, diff --git a/base/src/com/google/idea/blaze/base/qsync/ProjectUpdater.java b/base/src/com/google/idea/blaze/base/qsync/ProjectUpdater.java index 44701bca13a..fde5e20bf7e 100644 --- a/base/src/com/google/idea/blaze/base/qsync/ProjectUpdater.java +++ b/base/src/com/google/idea/blaze/base/qsync/ProjectUpdater.java @@ -38,7 +38,6 @@ import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; import com.intellij.openapi.externalSystem.service.project.ProjectDataManager; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.ModuleTypeManager; import com.intellij.openapi.project.Project; @@ -46,7 +45,6 @@ import com.intellij.openapi.roots.DependencyScope; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.SourceFolder; import com.intellij.openapi.roots.libraries.Library; @@ -66,7 +64,7 @@ /** An object that monitors the build graph and applies the changes to the project structure. */ public class ProjectUpdater implements BlazeProjectListener { - private Project project; + private final Project project; private final BlazeImportSettings importSettings; private final ProjectViewSet projectViewSet; private final WorkspaceRoot workspaceRoot; @@ -101,16 +99,15 @@ public void graphCreated(Context context, BlazeProjectSnapshot graph) throws IOE } private void updateProjectModel(ProjectProto.Project spec, Context context) { - ModuleManager moduleManager = ModuleManager.getInstance(project); File imlDirectory = new File(BlazeDataStorage.getProjectDataDir(importSettings), "modules"); Transactions.submitWriteActionTransactionAndWait( () -> { + IdeModifiableModelsProvider models = + ProjectDataManager.getInstance().createModifiableModelsProvider(project); + for (BlazeQuerySyncPlugin syncPlugin : BlazeQuerySyncPlugin.EP_NAME.getExtensions()) { syncPlugin.updateProjectSettingsForQuerySync(project, context, projectViewSet); } - - IdeModifiableModelsProvider models = - ProjectDataManager.getInstance().createModifiableModelsProvider(project); int removedLibCount = removeUnusedLibraries(models, spec.getLibraryList()); if (removedLibCount > 0) { context.output(PrintOutput.output("Removed " + removedLibCount + " libs")); @@ -121,15 +118,14 @@ private void updateProjectModel(ProjectProto.Project spec, Context context) { libMapBuilder.put(libSpec.getName(), library); } ImmutableMap libMap = libMapBuilder.buildOrThrow(); - models.commit(); for (ProjectProto.Module moduleSpec : spec.getModulesList()) { Module module = - moduleManager.newModule( - imlDirectory.toPath().resolve(moduleSpec.getName() + ".iml"), + models.newModule( + imlDirectory.toPath().resolve(moduleSpec.getName() + ".iml").toString(), mapModuleType(moduleSpec.getType()).getId()); - ModifiableRootModel roots = ModuleRootManager.getInstance(module).getModifiableModel(); + ModifiableRootModel roots = models.getModifiableRootModel(module); // TODO: should this be encapsulated in ProjectProto.Module? roots.inheritSdk(); @@ -188,6 +184,7 @@ private void updateProjectModel(ProjectProto.Project spec, Context context) { syncPlugin.updateProjectStructureForQuerySync( project, context, + models, workspaceRoot, module, ImmutableSet.copyOf(moduleSpec.getAndroidResourceDirectoriesList()), @@ -197,7 +194,7 @@ private void updateProjectModel(ProjectProto.Project spec, Context context) { .build(), workspaceLanguageSettings); } - roots.commit(); + models.commit(); } }); } @@ -218,7 +215,7 @@ private Library getOrCreateLibrary( Function.identity())); // make sure the library contains only jar directory urls we want - ModifiableModel modifiableModel = library.getModifiableModel(); + ModifiableModel modifiableModel = models.getModifiableLibraryModel(library); Set foundJarDirectories = Sets.newHashSet(); for (String url : modifiableModel.getUrls(OrderRootType.CLASSES)) { @@ -256,7 +253,6 @@ private Library getOrCreateLibrary( modifiableModel.addRoot(missing, OrderRootType.SOURCES); } - modifiableModel.commit(); return library; }