private void walkRuleAndAdd()

in src/com/facebook/buck/command/Project.java [727:834]


  private void walkRuleAndAdd(
      final BuildRule rule,
      final boolean isForTests,
      final LinkedHashSet<DependentModule> dependencies,
      @Nullable final BuildRule srcTarget) {

    final String basePathForRule = rule.getBuildTarget().getBasePath();
    new AbstractDependencyVisitor(rule, true /* excludeRoot */) {

      private final LinkedHashSet<DependentModule> librariesToAdd = Sets.newLinkedHashSet();
      private final LinkedHashSet<DependentModule> modulesToAdd = Sets.newLinkedHashSet();

      @Override
      public ImmutableSet<BuildRule> visit(BuildRule dep) {
        ImmutableSet<BuildRule> depsToVisit;
        if (rule.getProperties().is(PACKAGING) ||
            dep instanceof AndroidResourceRule ||
            dep == rule) {
          depsToVisit = dep.getDeps();
        } else if (dep.getProperties().is(LIBRARY) && dep instanceof ExportDependencies) {
          depsToVisit = ((ExportDependencies)dep).getExportedDeps();
        } else {
          depsToVisit = ImmutableSet.of();
        }

        // Special Case: If we are traversing the test_target and we encounter a library rule in the
        // same package that is not the src_target, then we should traverse the deps. Consider the
        // following build file:
        //
        // android_library(
        //   name = 'lib',
        //   srcs = glob(['*.java'], excludes = ['*Test.java']),
        //   deps = [
        //     # LOTS OF DEPS
        //   ],
        // )
        //
        // java_test(
        //   name = 'test',
        //   srcs = glob(['*Test.java']),
        //   deps = [
        //     ':lib',
        //     # MOAR DEPS
        //   ],
        // )
        //
        // project_config(
        //   test_target = ':test',
        // )
        //
        // Note that the only source folder for this IntelliJ module is the current directory. Thus,
        // the current directory should be treated as a source folder with test sources, but it
        // should contain the union of :lib and :test's deps as dependent modules.
        if (isForTests
            && depsToVisit.isEmpty()
            && dep.getBuildTarget().getBasePath().equals(basePathForRule)
            && !dep.equals(srcTarget)) {
          depsToVisit = dep.getDeps();
        }

        DependentModule dependentModule;
        if (dep instanceof PrebuiltJarRule) {
          libraryJars.add((PrebuiltJarRule) dep);
          String libraryName = getIntellijNameForRule(dep);
          dependentModule = DependentModule.newLibrary(dep.getBuildTarget(), libraryName);
        } else if (dep instanceof NdkLibrary) {
          String moduleName = getIntellijNameForRule(dep);
          dependentModule = DependentModule.newModule(dep.getBuildTarget(), moduleName);
        } else if (dep.getFullyQualifiedName().startsWith(ANDROID_GEN_BUILD_TARGET_PREFIX)) {
          return depsToVisit;
        } else if (dep instanceof JavaLibraryRule || dep instanceof AndroidResourceRule) {
          String moduleName = getIntellijNameForRule(dep);
          dependentModule = DependentModule.newModule(dep.getBuildTarget(), moduleName);
        } else {
          return depsToVisit;
        }

        if (isForTests) {
          dependentModule.scope = "TEST";
        } else {
          // If the dependentModule has already been added in the "TEST" scope, then it should be
          // removed and then re-added using the current (compile) scope.
          String currentScope = dependentModule.scope;
          dependentModule.scope = "TEST";
          if (dependencies.contains(dependentModule)) {
            dependencies.remove(dependentModule);
          }
          dependentModule.scope = currentScope;
        }

        // Slate the module for addition to the dependencies collection. Modules are added to
        // dependencies collection once the traversal is complete in the onComplete() method.
        if (dependentModule.isLibrary()) {
          librariesToAdd.add(dependentModule);
        } else {
          modulesToAdd.add(dependentModule);
        }

        return depsToVisit;
      }

      @Override
      protected void onComplete() {
        dependencies.addAll(librariesToAdd);
        dependencies.addAll(modulesToAdd);
      }
    }.start();
  }