| Index: tools/gn/command_ls.cc
 | 
| diff --git a/tools/gn/command_ls.cc b/tools/gn/command_ls.cc
 | 
| index a2dc38ce75cd151630efea2498c60a43efcdfc56..ed4aaca2496a593a7d187ee56e8722d84ecee514 100644
 | 
| --- a/tools/gn/command_ls.cc
 | 
| +++ b/tools/gn/command_ls.cc
 | 
| @@ -18,9 +18,10 @@ const char kLs[] = "ls";
 | 
|  const char kLs_HelpShort[] =
 | 
|      "ls: List matching targets.";
 | 
|  const char kLs_Help[] =
 | 
| -    "gn ls <out_dir> [<label_pattern>] [--out] [--all-toolchains]\n"
 | 
| +    "gn ls <out_dir> [<label_pattern>] [--all-toolchains] [--as=...]\n"
 | 
| +    "      [--type=...] [--testonly=...]\n"
 | 
|      "\n"
 | 
| -    "  Lists all targets matching the given pattern for the given builn\n"
 | 
| +    "  Lists all targets matching the given pattern for the given build\n"
 | 
|      "  directory. By default, only targets in the default toolchain will\n"
 | 
|      "  be matched unless a toolchain is explicitly supplied.\n"
 | 
|      "\n"
 | 
| @@ -29,14 +30,19 @@ const char kLs_Help[] =
 | 
|      "  \"gn help label_pattern\"). If you need more complex expressions,\n"
 | 
|      "  pipe the result through grep.\n"
 | 
|      "\n"
 | 
| -    "  --out\n"
 | 
| -    "      Lists the results as the files generated by the matching targets.\n"
 | 
| -    "      These files will be relative to the build directory such that\n"
 | 
| -    "      they can be specified on Ninja's command line as a file to build.\n"
 | 
| +    "Options\n"
 | 
| +    "\n"
 | 
| +    TARGET_PRINTING_MODE_COMMAND_LINE_HELP
 | 
|      "\n"
 | 
|      "  --all-toolchains\n"
 | 
| -    "      Matches all toolchains. If the label pattern does not specify an\n"
 | 
| -    "      explicit toolchain, labels from all toolchains will be matched.\n"
 | 
| +    "      Matches all toolchains. When set, if the label pattern does not\n"
 | 
| +    "      specify an explicit toolchain, labels from all toolchains will be\n"
 | 
| +    "      matched. When unset, only targets in the default toolchain will\n"
 | 
| +    "      be matched unless an explicit toolchain in the label is set.\n"
 | 
| +    "\n"
 | 
| +    TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP
 | 
| +    "\n"
 | 
| +    TARGET_TYPE_FILTER_COMMAND_LINE_HELP
 | 
|      "\n"
 | 
|      "Examples\n"
 | 
|      "\n"
 | 
| @@ -49,10 +55,13 @@ const char kLs_Help[] =
 | 
|      "  gn ls out/Debug \"//base:*\"\n"
 | 
|      "      Lists all targets defined in //base/BUILD.gn.\n"
 | 
|      "\n"
 | 
| -    "  gn ls out/Debug //base --out\n"
 | 
| +    "  gn ls out/Debug //base --as=output\n"
 | 
|      "      Lists the build output file for //base:base\n"
 | 
|      "\n"
 | 
| -    "  gn ls out/Debug \"//base/*\" --out | xargs ninja -C out/Debug\n"
 | 
| +    "  gn ls out/Debug --type=executable\n"
 | 
| +    "      Lists all executables produced by the build.\n"
 | 
| +    "\n"
 | 
| +    "  gn ls out/Debug \"//base/*\" --as=output | xargs ninja -C out/Debug\n"
 | 
|      "      Builds all targets in //base and all subdirectories.\n"
 | 
|      "\n"
 | 
|      "  gn ls out/Debug //base --all-toolchains\n"
 | 
| @@ -60,9 +69,9 @@ const char kLs_Help[] =
 | 
|      "      in multiple toolchains).\n";
 | 
|  
 | 
|  int RunLs(const std::vector<std::string>& args) {
 | 
| -  if (args.size() != 1 && args.size() != 2) {
 | 
| +  if (args.size() == 0) {
 | 
|      Err(Location(), "You're holding it wrong.",
 | 
| -        "Usage: \"gn ls <build dir> [<label_pattern>]\"").PrintToStdout();
 | 
| +        "Usage: \"gn ls <build dir> [<label_pattern>]*\"").PrintToStdout();
 | 
|      return 1;
 | 
|    }
 | 
|  
 | 
| @@ -73,13 +82,21 @@ int RunLs(const std::vector<std::string>& args) {
 | 
|    const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
 | 
|    bool all_toolchains = cmdline->HasSwitch("all-toolchains");
 | 
|  
 | 
| -  // Find matching targets.
 | 
|    std::vector<const Target*> matches;
 | 
| -  if (args.size() == 2) {
 | 
| -    // Given a pattern, match it.
 | 
| -    if (!ResolveTargetsFromCommandLinePattern(setup, args[1], all_toolchains,
 | 
| -                                              &matches))
 | 
| +  if (args.size() > 1) {
 | 
| +    // Some patterns or explicit labels were specified.
 | 
| +    std::vector<std::string> inputs(args.begin() + 1, args.end());
 | 
| +
 | 
| +    UniqueVector<const Target*> target_matches;
 | 
| +    UniqueVector<const Config*> config_matches;
 | 
| +    UniqueVector<const Toolchain*> toolchain_matches;
 | 
| +    UniqueVector<SourceFile> file_matches;
 | 
| +    if (!ResolveFromCommandLineInput(setup, inputs, all_toolchains,
 | 
| +                                     &target_matches, &config_matches,
 | 
| +                                     &toolchain_matches, &file_matches))
 | 
|        return 1;
 | 
| +    matches.insert(matches.begin(),
 | 
| +                   target_matches.begin(), target_matches.end());
 | 
|    } else if (all_toolchains) {
 | 
|      // List all resolved targets.
 | 
|      matches = setup->builder()->GetAllResolvedTargets();
 | 
| @@ -90,29 +107,7 @@ int RunLs(const std::vector<std::string>& args) {
 | 
|          matches.push_back(target);
 | 
|      }
 | 
|    }
 | 
| -
 | 
| -  if (cmdline->HasSwitch("out")) {
 | 
| -    // List results as build files.
 | 
| -    for (const auto& match : matches) {
 | 
| -      OutputString(match->dependency_output_file().value());
 | 
| -      OutputString("\n");
 | 
| -    }
 | 
| -  } else {
 | 
| -    // List results as sorted labels.
 | 
| -    std::vector<Label> sorted_matches;
 | 
| -    for (const auto& match : matches)
 | 
| -      sorted_matches.push_back(match->label());
 | 
| -    std::sort(sorted_matches.begin(), sorted_matches.end());
 | 
| -
 | 
| -    Label default_tc_label = setup->loader()->default_toolchain_label();
 | 
| -    for (const auto& match : sorted_matches) {
 | 
| -      // Print toolchain only for ones not in the default toolchain.
 | 
| -      OutputString(match.GetUserVisibleName(
 | 
| -          match.GetToolchainLabel() != default_tc_label));
 | 
| -      OutputString("\n");
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| +  FilterAndPrintTargets(false, &matches);
 | 
|    return 0;
 | 
|  }
 | 
|  
 | 
| 
 |