Search in sources :

Example 1 with AndroidResourceModule

use of com.google.idea.blaze.android.sync.model.AndroidResourceModule in project intellij by bazelbuild.

the class BlazeAndroidWorkspaceImporter method buildAndroidResourceModules.

private ImmutableList<AndroidResourceModule> buildAndroidResourceModules(WorkspaceBuilder workspaceBuilder) {
    // Filter empty resource modules
    Stream<AndroidResourceModule> androidResourceModuleStream = workspaceBuilder.androidResourceModules.stream().map(AndroidResourceModule.Builder::build).filter(androidResourceModule -> !androidResourceModule.isEmpty()).filter(androidResourceModule -> !androidResourceModule.resources.isEmpty());
    List<AndroidResourceModule> androidResourceModules = androidResourceModuleStream.collect(Collectors.toList());
    // Detect, filter, and warn about multiple R classes
    Multimap<String, AndroidResourceModule> javaPackageToResourceModule = ArrayListMultimap.create();
    for (AndroidResourceModule androidResourceModule : androidResourceModules) {
        TargetIdeInfo target = targetMap.get(androidResourceModule.targetKey);
        AndroidIdeInfo androidIdeInfo = target.androidIdeInfo;
        assert androidIdeInfo != null;
        javaPackageToResourceModule.put(androidIdeInfo.resourceJavaPackage, androidResourceModule);
    }
    List<AndroidResourceModule> result = Lists.newArrayList();
    for (String resourceJavaPackage : javaPackageToResourceModule.keySet()) {
        Collection<AndroidResourceModule> androidResourceModulesWithJavaPackage = javaPackageToResourceModule.get(resourceJavaPackage);
        if (androidResourceModulesWithJavaPackage.size() == 1) {
            result.addAll(androidResourceModulesWithJavaPackage);
        } else {
            StringBuilder messageBuilder = new StringBuilder();
            messageBuilder.append("Multiple R classes generated with the same java package ").append(resourceJavaPackage).append(".R: ");
            messageBuilder.append('\n');
            for (AndroidResourceModule androidResourceModule : androidResourceModulesWithJavaPackage) {
                messageBuilder.append("  ").append(androidResourceModule.targetKey).append('\n');
            }
            String message = messageBuilder.toString();
            context.output(new PerformanceWarning(message));
            IssueOutput.warn(message).submit(context);
            result.add(selectBestAndroidResourceModule(androidResourceModulesWithJavaPackage));
        }
    }
    Collections.sort(result, (lhs, rhs) -> lhs.targetKey.compareTo(rhs.targetKey));
    return ImmutableList.copyOf(result);
}
Also used : ArrayListMultimap(com.google.common.collect.ArrayListMultimap) BlazeContext(com.google.idea.blaze.base.scope.BlazeContext) GeneratedAndroidResourcesSection(com.google.idea.blaze.android.projectview.GeneratedAndroidResourcesSection) LibraryArtifact(com.google.idea.blaze.base.ideinfo.LibraryArtifact) Multimap(com.google.common.collect.Multimap) BlazeResourceLibrary(com.google.idea.blaze.android.sync.model.BlazeResourceLibrary) AndroidIdeInfo(com.google.idea.blaze.base.ideinfo.AndroidIdeInfo) Kind(com.google.idea.blaze.base.model.primitives.Kind) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) AarLibrary(com.google.idea.blaze.android.sync.model.AarLibrary) IssueOutput(com.google.idea.blaze.base.scope.output.IssueOutput) TargetIdeInfo(com.google.idea.blaze.base.ideinfo.TargetIdeInfo) Project(com.intellij.openapi.project.Project) TransitiveResourceMap(com.google.idea.blaze.android.sync.importer.aggregators.TransitiveResourceMap) ProjectViewTargetImportFilter(com.google.idea.blaze.base.sync.projectview.ProjectViewTargetImportFilter) LanguageClass(com.google.idea.blaze.base.model.primitives.LanguageClass) PerformanceWarning(com.google.idea.blaze.base.scope.output.PerformanceWarning) JavaSourceFilter(com.google.idea.blaze.java.sync.importer.JavaSourceFilter) ImmutableSet(com.google.common.collect.ImmutableSet) AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) ArtifactLocation(com.google.idea.blaze.base.ideinfo.ArtifactLocation) Collection(java.util.Collection) Set(java.util.Set) ComparisonChain(com.google.common.collect.ComparisonChain) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) BlazeAndroidImportResult(com.google.idea.blaze.android.sync.model.BlazeAndroidImportResult) Objects(java.util.Objects) Nullable(org.jetbrains.annotations.Nullable) GeneratedResourceWarnings(com.google.idea.blaze.android.sync.importer.problems.GeneratedResourceWarnings) List(java.util.List) Stream(java.util.stream.Stream) ProjectViewSet(com.google.idea.blaze.base.projectview.ProjectViewSet) WorkspaceRoot(com.google.idea.blaze.base.model.primitives.WorkspaceRoot) TargetKey(com.google.idea.blaze.base.ideinfo.TargetKey) ArtifactLocationDecoder(com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder) Collections(java.util.Collections) TargetMap(com.google.idea.blaze.base.ideinfo.TargetMap) TargetIdeInfo(com.google.idea.blaze.base.ideinfo.TargetIdeInfo) AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) PerformanceWarning(com.google.idea.blaze.base.scope.output.PerformanceWarning) AndroidIdeInfo(com.google.idea.blaze.base.ideinfo.AndroidIdeInfo)

Example 2 with AndroidResourceModule

use of com.google.idea.blaze.android.sync.model.AndroidResourceModule in project intellij by bazelbuild.

the class BlazeCreateResourceUtils method setupResDirectoryChoices.

static void setupResDirectoryChoices(Project project, @Nullable VirtualFile contextFile, JBLabel resDirLabel, ComboboxWithBrowseButton resDirComboAndBrowser) {
    // Reset the item list before filling it back up.
    resDirComboAndBrowser.getComboBox().removeAllItems();
    BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
    if (blazeProjectData != null) {
        BlazeAndroidSyncData syncData = blazeProjectData.syncState.get(BlazeAndroidSyncData.class);
        if (syncData != null) {
            ImmutableCollection<TargetKey> rulesRelatedToContext = null;
            File fileFromContext = null;
            if (contextFile != null) {
                fileFromContext = VfsUtilCore.virtualToIoFile(contextFile);
                rulesRelatedToContext = SourceToTargetMap.getInstance(project).getRulesForSourceFile(fileFromContext);
                if (rulesRelatedToContext.isEmpty()) {
                    rulesRelatedToContext = null;
                }
            }
            ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
            // Sort:
            // - contextFile/res if contextFile is a directory,
            // to optimize the right click on directory case, or the "closest" string
            // match to the contextFile from the res directories known to blaze
            // - the rest of the direct dirs, then transitive dirs of the context rules,
            // then any known res dir in the project
            // as a backup, in alphabetical order.
            Set<File> resourceDirs = Sets.newTreeSet();
            Set<File> transitiveDirs = Sets.newTreeSet();
            Set<File> allResDirs = Sets.newTreeSet();
            for (AndroidResourceModule androidResourceModule : syncData.importResult.androidResourceModules) {
                Collection<File> resources = artifactLocationDecoder.decodeAll(androidResourceModule.resources);
                Collection<File> transitiveResources = artifactLocationDecoder.decodeAll(androidResourceModule.transitiveResources);
                // labelsRelatedToContext should include deps,
                // but as a first pass we only check the rules themselves
                // for resources. If we come up empty, then have anyResDir as a backup.
                allResDirs.addAll(transitiveResources);
                if (rulesRelatedToContext != null && !rulesRelatedToContext.contains(androidResourceModule.targetKey)) {
                    continue;
                }
                resourceDirs.addAll(resources);
                transitiveDirs.addAll(transitiveResources);
            }
            // No need to show some directories twice.
            transitiveDirs.removeAll(resourceDirs);
            JComboBox resDirCombo = resDirComboAndBrowser.getComboBox();
            // Allow the user to browse and overwrite some of the entries,
            // in case our inference is wrong.
            resDirCombo.setEditable(true);
            // After the use confirms the choice, a directory will be created if it is missing.
            if (fileFromContext != null && fileFromContext.isDirectory()) {
                File closestDirToContext = new File(fileFromContext.getPath(), "res");
                resDirCombo.setSelectedItem(closestDirToContext);
            } else {
                // If we're not completely sure, let people know there are options
                // via the placeholder text, and put the most likely on top.
                String placeHolder = PLACEHOLDER_TEXT;
                resDirCombo.addItem(placeHolder);
                resDirCombo.setSelectedItem(placeHolder);
                if (fileFromContext != null) {
                    File closestDirToContext = findClosestDirToContext(fileFromContext.getPath(), resourceDirs);
                    closestDirToContext = closestDirToContext != null ? closestDirToContext : findClosestDirToContext(fileFromContext.getPath(), transitiveDirs);
                    if (closestDirToContext != null) {
                        resDirCombo.addItem(closestDirToContext);
                        resourceDirs.remove(closestDirToContext);
                        transitiveDirs.remove(closestDirToContext);
                    }
                }
            }
            if (!resourceDirs.isEmpty() || !transitiveDirs.isEmpty()) {
                for (File resourceDir : resourceDirs) {
                    resDirCombo.addItem(resourceDir);
                }
                for (File resourceDir : transitiveDirs) {
                    resDirCombo.addItem(resourceDir);
                }
            } else {
                for (File resourceDir : allResDirs) {
                    resDirCombo.addItem(resourceDir);
                }
            }
            resDirComboAndBrowser.setVisible(true);
            resDirLabel.setVisible(true);
        }
    }
}
Also used : AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) JComboBox(javax.swing.JComboBox) BlazeProjectData(com.google.idea.blaze.base.model.BlazeProjectData) ArtifactLocationDecoder(com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder) TargetKey(com.google.idea.blaze.base.ideinfo.TargetKey) BlazeAndroidSyncData(com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData) VirtualFile(com.intellij.openapi.vfs.VirtualFile) File(java.io.File)

Example 3 with AndroidResourceModule

use of com.google.idea.blaze.android.sync.model.AndroidResourceModule in project intellij by bazelbuild.

the class BlazeRenderErrorContributor method reportIssues.

@Override
public Collection<RenderErrorModel.Issue> reportIssues() {
    BlazeProjectData blazeProjectData = BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
    if (blazeProjectData == null || !logger.hasErrors()) {
        return getIssues();
    }
    TargetMap targetMap = blazeProjectData.targetMap;
    ArtifactLocationDecoder decoder = blazeProjectData.artifactLocationDecoder;
    AndroidResourceModule resourceModule = AndroidResourceModuleRegistry.getInstance(project).get(module);
    if (resourceModule == null) {
        return getIssues();
    }
    TargetIdeInfo target = targetMap.get(resourceModule.targetKey);
    if (target == null) {
        return getIssues();
    }
    reportGeneratedResources(resourceModule, targetMap, decoder);
    reportNonStandardAndroidManifestName(target, decoder);
    reportResourceTargetShouldDependOnClassTarget(target, targetMap, decoder);
    return getIssues();
}
Also used : TargetIdeInfo(com.google.idea.blaze.base.ideinfo.TargetIdeInfo) AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) BlazeProjectData(com.google.idea.blaze.base.model.BlazeProjectData) ArtifactLocationDecoder(com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder) SourceToTargetMap(com.google.idea.blaze.base.targetmaps.SourceToTargetMap) TargetMap(com.google.idea.blaze.base.ideinfo.TargetMap)

Example 4 with AndroidResourceModule

use of com.google.idea.blaze.android.sync.model.AndroidResourceModule in project intellij by bazelbuild.

the class AndroidResourceModuleRegistryTest method testPutDifferentKeysSameValue.

@Test
public void testPutDifferentKeysSameValue() {
    Module moduleOne = mock(Module.class);
    Module moduleTwo = mock(Module.class);
    AndroidResourceModule resourceModule = AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:one"))).build();
    registry.put(moduleOne, resourceModule);
    try {
        registry.put(moduleTwo, resourceModule);
        THROW_ASSERTION_ERROR.fail("Expected IllegalArgumentException");
    } catch (IllegalArgumentException ignored) {
    // ignored
    }
    assertThat(registry.get(moduleOne)).isEqualTo(resourceModule);
    assertThat(registry.get(moduleTwo)).isNull();
}
Also used : AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) Module(com.intellij.openapi.module.Module) Test(org.junit.Test)

Example 5 with AndroidResourceModule

use of com.google.idea.blaze.android.sync.model.AndroidResourceModule in project intellij by bazelbuild.

the class AndroidResourceModuleRegistryTest method testPutSameKeyDifferentValues.

@Test
public void testPutSameKeyDifferentValues() {
    Module module = mock(Module.class);
    AndroidResourceModule resourceModuleOne = AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:one"))).build();
    AndroidResourceModule resourceModuleTwo = AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:two"))).build();
    registry.put(module, resourceModuleOne);
    registry.put(module, resourceModuleTwo);
    assertThat(registry.get(module)).isEqualTo(resourceModuleTwo);
}
Also used : AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) AndroidResourceModule(com.google.idea.blaze.android.sync.model.AndroidResourceModule) Module(com.intellij.openapi.module.Module) Test(org.junit.Test)

Aggregations

AndroidResourceModule (com.google.idea.blaze.android.sync.model.AndroidResourceModule)9 TargetIdeInfo (com.google.idea.blaze.base.ideinfo.TargetIdeInfo)5 TargetKey (com.google.idea.blaze.base.ideinfo.TargetKey)5 ArtifactLocationDecoder (com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder)5 Module (com.intellij.openapi.module.Module)5 AndroidIdeInfo (com.google.idea.blaze.base.ideinfo.AndroidIdeInfo)4 ImmutableList (com.google.common.collect.ImmutableList)3 Lists (com.google.common.collect.Lists)3 Sets (com.google.common.collect.Sets)3 GeneratedAndroidResourcesSection (com.google.idea.blaze.android.projectview.GeneratedAndroidResourcesSection)3 BlazeAndroidSyncData (com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData)3 ArtifactLocation (com.google.idea.blaze.base.ideinfo.ArtifactLocation)3 Kind (com.google.idea.blaze.base.model.primitives.Kind)3 WorkspaceRoot (com.google.idea.blaze.base.model.primitives.WorkspaceRoot)3 ProjectViewSet (com.google.idea.blaze.base.projectview.ProjectViewSet)3 BlazeContext (com.google.idea.blaze.base.scope.BlazeContext)3 Project (com.intellij.openapi.project.Project)3 File (java.io.File)3 Collection (java.util.Collection)3 List (java.util.List)3