diff --git a/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java b/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java new file mode 100644 index 00000000000..162fd8f1793 --- /dev/null +++ b/aswb/sdkcompat/as222/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.projectsystem; + +import com.android.tools.idea.projectsystem.AndroidModuleSystem; +import com.intellij.openapi.module.Module; + +/** Blaze implementation of {@link AndroidModuleSystem}. */ +public class BlazeModuleSystem extends BlazeModuleSystemBase { + + BlazeModuleSystem(Module module) { + super(module); + } +} diff --git a/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java b/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java new file mode 100644 index 00000000000..162fd8f1793 --- /dev/null +++ b/aswb/sdkcompat/as223/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.projectsystem; + +import com.android.tools.idea.projectsystem.AndroidModuleSystem; +import com.intellij.openapi.module.Module; + +/** Blaze implementation of {@link AndroidModuleSystem}. */ +public class BlazeModuleSystem extends BlazeModuleSystemBase { + + BlazeModuleSystem(Module module) { + super(module); + } +} diff --git a/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java b/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java new file mode 100644 index 00000000000..162fd8f1793 --- /dev/null +++ b/aswb/sdkcompat/as231/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.projectsystem; + +import com.android.tools.idea.projectsystem.AndroidModuleSystem; +import com.intellij.openapi.module.Module; + +/** Blaze implementation of {@link AndroidModuleSystem}. */ +public class BlazeModuleSystem extends BlazeModuleSystemBase { + + BlazeModuleSystem(Module module) { + super(module); + } +} diff --git a/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java new file mode 100644 index 00000000000..162fd8f1793 --- /dev/null +++ b/aswb/sdkcompat/asdev/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.projectsystem; + +import com.android.tools.idea.projectsystem.AndroidModuleSystem; +import com.intellij.openapi.module.Module; + +/** Blaze implementation of {@link AndroidModuleSystem}. */ +public class BlazeModuleSystem extends BlazeModuleSystemBase { + + BlazeModuleSystem(Module module) { + super(module); + } +} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java deleted file mode 100644 index 7dac9c56882..00000000000 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystem.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2020 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.projectsystem; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -import com.android.ide.common.util.PathString; -import com.android.projectmodel.ExternalAndroidLibrary; -import com.android.projectmodel.ExternalLibraryImpl; -import com.android.projectmodel.SelectiveResourceFolder; -import com.android.tools.idea.projectsystem.AndroidModuleSystem; -import com.android.tools.idea.projectsystem.DependencyScopeType; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.idea.blaze.android.libraries.UnpackedAars; -import com.google.idea.blaze.android.sync.model.AarLibrary; -import com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry; -import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData; -import com.google.idea.blaze.android.sync.qsync.AndroidExternalLibraryManager; -import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; -import com.google.idea.blaze.base.model.BlazeLibrary; -import com.google.idea.blaze.base.model.BlazeProjectData; -import com.google.idea.blaze.base.projectview.ProjectViewManager; -import com.google.idea.blaze.base.qsync.ArtifactTracker; -import com.google.idea.blaze.base.qsync.QuerySync; -import com.google.idea.blaze.base.qsync.QuerySyncManager; -import com.google.idea.blaze.base.sync.SyncCache; -import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; -import com.google.idea.blaze.base.sync.libraries.BlazeLibraryCollector; -import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import java.io.File; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; - -/** Blaze implementation of {@link AndroidModuleSystem}. */ -public class BlazeModuleSystem extends BlazeModuleSystemBase { - - private static final Logger logger = Logger.getInstance(BlazeModuleSystem.class); - private AndroidExternalLibraryManager androidExternalLibraryManager = null; - - BlazeModuleSystem(Module module) { - super(module); - if (QuerySync.isEnabled()) { - androidExternalLibraryManager = - new AndroidExternalLibraryManager( - () -> { - if (!QuerySyncManager.getInstance(project).isProjectLoaded()) { - return ImmutableList.of(); - } - ArtifactTracker artifactTracker = - QuerySyncManager.getInstance(project).getArtifactTracker(); - Path aarDirectory = artifactTracker.getExternalAarDirectory(); - // This can be called by the IDE as the user navigates the project and so might be - // called before a sync has been completed and the project structure has been set - // up. - if (!aarDirectory.toFile().exists()) { - logger.warn("Aar library directory not created yet"); - return ImmutableList.of(); - } - try (Stream stream = Files.list(aarDirectory)) { - return stream.collect(toImmutableList()); - } catch (IOException ioe) { - throw new UncheckedIOException("Could not list aars", ioe); - } - }); - } - } - - public Collection getDependentLibraries() { - if (QuerySync.isEnabled()) { - return androidExternalLibraryManager.getExternalLibraries(); - } - BlazeProjectData blazeProjectData = - BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); - - if (blazeProjectData == null) { - return ImmutableList.of(); - } - - if (isWorkspaceModule) { - return SyncCache.getInstance(project) - .get(BlazeModuleSystem.class, BlazeModuleSystem::getLibrariesForWorkspaceModule); - } - - AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project); - TargetIdeInfo target = blazeProjectData.getTargetMap().get(registry.getTargetKey(module)); - if (target == null) { - // this can happen if the module points to the , - // does not contain any resource - // contains all external resources as module's local resources, so there's - // no dependent libraries - return ImmutableList.of(); - } - - BlazeAndroidSyncData androidSyncData = - blazeProjectData.getSyncState().get(BlazeAndroidSyncData.class); - if (androidSyncData == null) { - return ImmutableList.of(); - } - - ImmutableList.Builder libraries = ImmutableList.builder(); - ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); - ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); - for (String libraryKey : registry.get(module).resourceLibraryKeys) { - ImmutableMap aarLibraries = androidSyncData.importResult.aarLibraries; - ExternalAndroidLibrary externalLibrary = - toExternalLibrary(project, aarLibraries.get(libraryKey), decoder); - if (externalLibrary != null) { - libraries.add(externalLibraryInterner.intern(externalLibrary)); - } - } - return libraries.build(); - } - - private static ImmutableList getLibrariesForWorkspaceModule( - Project project, BlazeProjectData blazeProjectData) { - ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); - ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); - ImmutableList.Builder libraries = ImmutableList.builder(); - for (BlazeLibrary library : - BlazeLibraryCollector.getLibraries( - ProjectViewManager.getInstance(project).getProjectViewSet(), blazeProjectData)) { - if (library instanceof AarLibrary) { - ExternalAndroidLibrary externalLibrary = - toExternalLibrary(project, (AarLibrary) library, decoder); - if (externalLibrary != null) { - libraries.add(externalLibraryInterner.intern(externalLibrary)); - } - } - } - return libraries.build(); - } - - @Nullable - static ExternalAndroidLibrary toExternalLibrary( - Project project, @Nullable AarLibrary library, ArtifactLocationDecoder decoder) { - if (library == null) { - return null; - } - UnpackedAars unpackedAars = UnpackedAars.getInstance(project); - File aarFile = unpackedAars.getAarDir(decoder, library); - if (aarFile == null) { - logger.warn( - String.format( - "Fail to locate AAR file %s. Re-sync the project may solve the problem", - library.aarArtifact)); - return null; - } - File resFolder = unpackedAars.getResourceDirectory(decoder, library); - PathString resFolderPathString = resFolder == null ? null : new PathString(resFolder); - return new ExternalLibraryImpl(library.key.toString()) - .withLocation(new PathString(aarFile)) - .withManifestFile( - resFolderPathString == null - ? null - : resFolderPathString.getParentOrRoot().resolve("AndroidManifest.xml")) - .withResFolder( - resFolderPathString == null - ? null - : new SelectiveResourceFolder(resFolderPathString, null)) - .withSymbolFile( - resFolderPathString == null - ? null - : resFolderPathString.getParentOrRoot().resolve("R.txt")) - .withPackageName(library.resourcePackage); - } - - @Override - public Collection getAndroidLibraryDependencies( - DependencyScopeType dependencyScopeType) { - if (dependencyScopeType == DependencyScopeType.MAIN) { - return getDependentLibraries(); - } else { - return Collections.emptyList(); - } - } -} diff --git a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java index c57cb39f4a3..b81aaaf1b2a 100644 --- a/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java +++ b/aswb/src/com/google/idea/blaze/android/projectsystem/BlazeModuleSystemBase.java @@ -23,6 +23,9 @@ import com.android.ide.common.repository.GradleCoordinate; import com.android.ide.common.util.PathString; import com.android.manifmerger.ManifestSystemProperty; +import com.android.projectmodel.ExternalAndroidLibrary; +import com.android.projectmodel.ExternalLibraryImpl; +import com.android.projectmodel.SelectiveResourceFolder; import com.android.tools.idea.projectsystem.AndroidModuleSystem; import com.android.tools.idea.projectsystem.CapabilityNotSupported; import com.android.tools.idea.projectsystem.CapabilityStatus; @@ -43,8 +46,11 @@ import com.google.idea.blaze.android.compose.ComposeStatusProvider; import com.google.idea.blaze.android.libraries.UnpackedAars; import com.google.idea.blaze.android.npw.project.BlazeAndroidModuleTemplate; +import com.google.idea.blaze.android.sync.model.AarLibrary; import com.google.idea.blaze.android.sync.model.AndroidResourceModule; import com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry; +import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData; +import com.google.idea.blaze.android.sync.qsync.AndroidExternalLibraryManager; import com.google.idea.blaze.base.command.buildresult.OutputArtifactResolver; import com.google.idea.blaze.base.ideinfo.AndroidAarIdeInfo; import com.google.idea.blaze.base.ideinfo.ArtifactLocation; @@ -53,15 +59,21 @@ import com.google.idea.blaze.base.ideinfo.TargetKey; import com.google.idea.blaze.base.io.VfsUtils; import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager; +import com.google.idea.blaze.base.model.BlazeLibrary; import com.google.idea.blaze.base.model.BlazeProjectData; import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; +import com.google.idea.blaze.base.projectview.ProjectViewManager; +import com.google.idea.blaze.base.qsync.ArtifactTracker; import com.google.idea.blaze.base.qsync.DependencyTracker; import com.google.idea.blaze.base.qsync.QuerySync; import com.google.idea.blaze.base.qsync.QuerySyncManager; import com.google.idea.blaze.base.scope.BlazeContext; import com.google.idea.blaze.base.settings.Blaze; +import com.google.idea.blaze.base.sync.SyncCache; import com.google.idea.blaze.base.sync.data.BlazeDataStorage; import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager; +import com.google.idea.blaze.base.sync.libraries.BlazeLibraryCollector; +import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder; import com.google.idea.blaze.base.targetmaps.ReverseDependencyMap; import com.google.idea.blaze.base.targetmaps.TransitiveDependencyMap; import com.google.idea.blaze.common.Label; @@ -79,7 +91,11 @@ import com.intellij.psi.search.ProjectScope; import java.io.File; import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -107,6 +123,7 @@ abstract class BlazeModuleSystemBase implements AndroidModuleSystem { SampleDataDirectoryProvider sampleDataDirectoryProvider; RenderJarClassFileFinder classFileFinder; final boolean isWorkspaceModule; + private AndroidExternalLibraryManager androidExternalLibraryManager = null; BlazeModuleSystemBase(Module module) { this.module = module; @@ -114,6 +131,30 @@ abstract class BlazeModuleSystemBase implements AndroidModuleSystem { classFileFinder = new RenderJarClassFileFinder(module); sampleDataDirectoryProvider = new BlazeSampleDataDirectoryProvider(module); isWorkspaceModule = module.getName().equals(BlazeDataStorage.WORKSPACE_MODULE_NAME); + if (QuerySync.isEnabled()) { + androidExternalLibraryManager = + new AndroidExternalLibraryManager( + () -> { + if (!QuerySyncManager.getInstance(project).isProjectLoaded()) { + return ImmutableList.of(); + } + ArtifactTracker artifactTracker = + QuerySyncManager.getInstance(project).getArtifactTracker(); + Path aarDirectory = artifactTracker.getExternalAarDirectory(); + // This can be called by the IDE as the user navigates the project and so might be + // called before a sync has been completed and the project structure has been set + // up. + if (!aarDirectory.toFile().exists()) { + logger.warn("Aar library directory not created yet"); + return ImmutableList.of(); + } + try (Stream stream = Files.list(aarDirectory)) { + return stream.collect(toImmutableList()); + } catch (IOException ioe) { + throw new UncheckedIOException("Could not list aars", ioe); + } + }); + } } @Override @@ -519,6 +560,115 @@ public boolean getUsesCompose() { return ComposeStatusProvider.isComposeEnabled(project); } + public Collection getDependentLibraries() { + if (QuerySync.isEnabled()) { + return androidExternalLibraryManager.getExternalLibraries(); + } + BlazeProjectData blazeProjectData = + BlazeProjectDataManager.getInstance(project).getBlazeProjectData(); + + if (blazeProjectData == null) { + return ImmutableList.of(); + } + + if (isWorkspaceModule) { + return SyncCache.getInstance(project) + .get(BlazeModuleSystem.class, BlazeModuleSystemBase::getLibrariesForWorkspaceModule); + } + + AndroidResourceModuleRegistry registry = AndroidResourceModuleRegistry.getInstance(project); + TargetIdeInfo target = blazeProjectData.getTargetMap().get(registry.getTargetKey(module)); + if (target == null) { + // this can happen if the module points to the , + // does not contain any resource + // contains all external resources as module's local resources, so there's + // no dependent libraries + return ImmutableList.of(); + } + + BlazeAndroidSyncData androidSyncData = + blazeProjectData.getSyncState().get(BlazeAndroidSyncData.class); + if (androidSyncData == null) { + return ImmutableList.of(); + } + + ImmutableList.Builder libraries = ImmutableList.builder(); + ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); + ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); + for (String libraryKey : registry.get(module).resourceLibraryKeys) { + ImmutableMap aarLibraries = androidSyncData.importResult.aarLibraries; + ExternalAndroidLibrary externalLibrary = + toExternalLibrary(project, aarLibraries.get(libraryKey), decoder); + if (externalLibrary != null) { + libraries.add(externalLibraryInterner.intern(externalLibrary)); + } + } + return libraries.build(); + } + + private static ImmutableList getLibrariesForWorkspaceModule( + Project project, BlazeProjectData blazeProjectData) { + ArtifactLocationDecoder decoder = blazeProjectData.getArtifactLocationDecoder(); + ExternalLibraryInterner externalLibraryInterner = ExternalLibraryInterner.getInstance(project); + ImmutableList.Builder libraries = ImmutableList.builder(); + for (BlazeLibrary library : + BlazeLibraryCollector.getLibraries( + ProjectViewManager.getInstance(project).getProjectViewSet(), blazeProjectData)) { + if (library instanceof AarLibrary) { + ExternalAndroidLibrary externalLibrary = + toExternalLibrary(project, (AarLibrary) library, decoder); + if (externalLibrary != null) { + libraries.add(externalLibraryInterner.intern(externalLibrary)); + } + } + } + return libraries.build(); + } + + @Nullable + static ExternalAndroidLibrary toExternalLibrary( + Project project, @Nullable AarLibrary library, ArtifactLocationDecoder decoder) { + if (library == null) { + return null; + } + UnpackedAars unpackedAars = UnpackedAars.getInstance(project); + File aarFile = unpackedAars.getAarDir(decoder, library); + if (aarFile == null) { + logger.warn( + String.format( + "Fail to locate AAR file %s. Re-sync the project may solve the problem", + library.aarArtifact)); + return null; + } + File resFolder = unpackedAars.getResourceDirectory(decoder, library); + PathString resFolderPathString = resFolder == null ? null : new PathString(resFolder); + return new ExternalLibraryImpl(library.key.toString()) + .withLocation(new PathString(aarFile)) + .withManifestFile( + resFolderPathString == null + ? null + : resFolderPathString.getParentOrRoot().resolve("AndroidManifest.xml")) + .withResFolder( + resFolderPathString == null + ? null + : new SelectiveResourceFolder(resFolderPathString, null)) + .withSymbolFile( + resFolderPathString == null + ? null + : resFolderPathString.getParentOrRoot().resolve("R.txt")) + .withPackageName(library.resourcePackage); + } + + @Override + public Collection getAndroidLibraryDependencies( + DependencyScopeType dependencyScopeType) { + if (dependencyScopeType == DependencyScopeType.MAIN) { + return getDependentLibraries(); + } else { + return Collections.emptyList(); + } + } + @TestOnly public static BlazeModuleSystem create(Module module) { Preconditions.checkState(ApplicationManager.getApplication().isUnitTestMode());