public static DependencyType merge(DependencyType left, DependencyType right) { if (left.equals(right)) { return left; } Preconditions.checkArgument( !left.equals(COMPILED_SHADOW) && !right.equals(COMPILED_SHADOW), "The COMPILED_SHADOW type cannot be merged with other types."); return DependencyType.PROD; }
/** * @param targetGraph input graph. * @return module graph corresponding to the supplied {@link TargetGraph}. Multiple targets from * the same base path are mapped to a single module, therefore an IjModuleGraph edge exists * between two modules (Ma, Mb) if a TargetGraph edge existed between a pair of nodes (Ta, Tb) * and Ma contains Ta and Mb contains Tb. */ public static IjModuleGraph from( final TargetGraph targetGraph, final IjLibraryFactory libraryFactory, final IjModuleFactory moduleFactory) { final ImmutableMap<BuildTarget, IjModule> rulesToModules = createModules(targetGraph, moduleFactory); final ExportedDepsClosureResolver exportedDepsClosureResolver = new ExportedDepsClosureResolver(targetGraph); ImmutableMap.Builder<IjProjectElement, ImmutableMap<IjProjectElement, DependencyType>> depsBuilder = ImmutableMap.builder(); final Set<IjLibrary> referencedLibraries = new HashSet<>(); for (final IjModule module : FluentIterable.from(rulesToModules.values()).toSet()) { Map<IjProjectElement, DependencyType> moduleDeps = new HashMap<>(); for (Map.Entry<BuildTarget, DependencyType> entry : module.getDependencies().entrySet()) { BuildTarget depBuildTarget = entry.getKey(); DependencyType depType = entry.getValue(); ImmutableSet<IjProjectElement> depElements; if (depType.equals(DependencyType.COMPILED_SHADOW)) { TargetNode<?> targetNode = Preconditions.checkNotNull(targetGraph.get(depBuildTarget)); Optional<IjLibrary> library = libraryFactory.getLibrary(targetNode); if (library.isPresent()) { depElements = ImmutableSet.<IjProjectElement>of(library.get()); } else { depElements = ImmutableSet.of(); } } else { depElements = FluentIterable.from( exportedDepsClosureResolver.getExportedDepsClosure(depBuildTarget)) .append(depBuildTarget) .filter( new Predicate<BuildTarget>() { @Override public boolean apply(BuildTarget input) { // The exported deps closure can contain references back to targets // contained // in the module, so filter those out. TargetNode<?> targetNode = targetGraph.get(input); return !module.getTargets().contains(targetNode); } }) .transform( new Function<BuildTarget, IjProjectElement>() { @Nullable @Override public IjProjectElement apply(BuildTarget depTarget) { IjModule depModule = rulesToModules.get(depTarget); if (depModule != null) { return depModule; } TargetNode<?> targetNode = Preconditions.checkNotNull(targetGraph.get(depTarget)); IjLibrary library = libraryFactory.getLibrary(targetNode).orNull(); return library; } }) .filter(Predicates.notNull()) .toSet(); } for (IjProjectElement depElement : depElements) { Preconditions.checkState(!depElement.equals(module)); DependencyType.putWithMerge(moduleDeps, depElement, depType); } } if (!module.getExtraClassPathDependencies().isEmpty()) { IjLibrary extraClassPathLibrary = IjLibrary.builder() .setClassPaths(module.getExtraClassPathDependencies()) .setTargets(ImmutableSet.<TargetNode<?>>of()) .setName("library_" + module.getName() + "_extra_classpath") .build(); moduleDeps.put(extraClassPathLibrary, DependencyType.PROD); } referencedLibraries.addAll( FluentIterable.from(moduleDeps.keySet()).filter(IjLibrary.class).toSet()); depsBuilder.put(module, ImmutableMap.copyOf(moduleDeps)); } for (IjLibrary library : referencedLibraries) { depsBuilder.put(library, ImmutableMap.<IjProjectElement, DependencyType>of()); } return new IjModuleGraph(depsBuilder.build()); }