| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <set> | 5 #include <set> |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "tools/gn/commands.h" | 8 #include "tools/gn/commands.h" |
| 9 #include "tools/gn/filesystem_utils.h" | 9 #include "tools/gn/filesystem_utils.h" |
| 10 #include "tools/gn/input_file.h" | 10 #include "tools/gn/input_file.h" |
| 11 #include "tools/gn/item.h" | 11 #include "tools/gn/item.h" |
| 12 #include "tools/gn/item_node.h" | |
| 13 #include "tools/gn/pattern.h" | 12 #include "tools/gn/pattern.h" |
| 14 #include "tools/gn/setup.h" | 13 #include "tools/gn/setup.h" |
| 15 #include "tools/gn/standard_out.h" | 14 #include "tools/gn/standard_out.h" |
| 16 #include "tools/gn/target.h" | 15 #include "tools/gn/target.h" |
| 17 | 16 |
| 18 namespace commands { | 17 namespace commands { |
| 19 | 18 |
| 20 namespace { | 19 namespace { |
| 21 | 20 |
| 22 // Returns the file path generating this item node. | 21 // Returns the file path generating this record. |
| 23 base::FilePath FilePathForItemNode(const ItemNode& node) { | 22 base::FilePath FilePathForRecord(const BuilderRecord* record) { |
| 24 const InputFile* file = node.generated_from_here().begin().file(); | 23 if (!record->item()) |
| 25 if (!file) | |
| 26 return base::FilePath(FILE_PATH_LITERAL("=UNRESOLVED DEPENDENCY=")); | 24 return base::FilePath(FILE_PATH_LITERAL("=UNRESOLVED DEPENDENCY=")); |
| 27 return file->physical_name(); | 25 return record->item()->defined_from()->GetRange().begin().file() |
| 26 ->physical_name(); |
| 28 } | 27 } |
| 29 | 28 |
| 30 } // namespace | 29 } // namespace |
| 31 | 30 |
| 32 const char kRefs[] = "refs"; | 31 const char kRefs[] = "refs"; |
| 33 const char kRefs_HelpShort[] = | 32 const char kRefs_HelpShort[] = |
| 34 "refs: Find stuff referencing a target, directory, or config."; | 33 "refs: Find stuff referencing a target, directory, or config."; |
| 35 const char kRefs_Help[] = | 34 const char kRefs_Help[] = |
| 36 "gn refs <label_pattern> [--files]\n" | 35 "gn refs <label_pattern> [--files]\n" |
| 36 "\n" |
| 37 " Finds code referencing a given label. The label can be a\n" | 37 " Finds code referencing a given label. The label can be a\n" |
| 38 " target or config name. Unlike most other commands, unresolved\n" | 38 " target or config name. Unlike most other commands, unresolved\n" |
| 39 " dependencies will be tolerated. This allows you to use this command\n" | 39 " dependencies will be tolerated. This allows you to use this command\n" |
| 40 " to find references to targets you're in the process of moving.\n" | 40 " to find references to targets you're in the process of moving.\n" |
| 41 "\n" | 41 "\n" |
| 42 " By default, the mapping from source item to dest item (where the\n" | 42 " By default, the mapping from source item to dest item (where the\n" |
| 43 " pattern matches the dest item). See \"gn help pattern\" for\n" | 43 " pattern matches the dest item). See \"gn help pattern\" for\n" |
| 44 " information on pattern-matching rules.\n" | 44 " information on pattern-matching rules.\n" |
| 45 "\n" | 45 "\n" |
| 46 "Option:\n" | 46 "Option:\n" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 Pattern pattern(args[0]); | 84 Pattern pattern(args[0]); |
| 85 | 85 |
| 86 Setup* setup = new Setup; | 86 Setup* setup = new Setup; |
| 87 setup->set_check_for_bad_items(false); | 87 setup->set_check_for_bad_items(false); |
| 88 if (!setup->DoSetup() || !setup->Run()) | 88 if (!setup->DoSetup() || !setup->Run()) |
| 89 return 1; | 89 return 1; |
| 90 | 90 |
| 91 const ItemTree& item_tree = setup->build_settings().item_tree(); | 91 std::vector<const BuilderRecord*> records = setup->builder()->GetAllRecords(); |
| 92 base::AutoLock lock(item_tree.lock()); | |
| 93 | |
| 94 std::vector<const ItemNode*> nodes; | |
| 95 item_tree.GetAllItemNodesLocked(&nodes); | |
| 96 | 92 |
| 97 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 93 const CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
| 98 | 94 |
| 99 bool file_output = cmdline->HasSwitch("files"); | 95 bool file_output = cmdline->HasSwitch("files"); |
| 100 std::set<std::string> unique_output; | 96 std::set<std::string> unique_output; |
| 101 | 97 |
| 102 for (size_t node_index = 0; node_index < nodes.size(); node_index++) { | 98 for (size_t record_index = 0; record_index < records.size(); record_index++) { |
| 103 const ItemNode& node = *nodes[node_index]; | 99 const BuilderRecord* record = records[record_index]; |
| 104 const ItemNode::ItemNodeMap& deps = node.direct_dependencies(); | 100 const BuilderRecord::BuilderRecordSet& deps = record->all_deps(); |
| 105 for (ItemNode::ItemNodeMap::const_iterator d = deps.begin(); | 101 for (BuilderRecord::BuilderRecordSet::const_iterator d = deps.begin(); |
| 106 d != deps.end(); ++d) { | 102 d != deps.end(); ++d) { |
| 107 std::string label = d->first->item()->label().GetUserVisibleName(false); | 103 std::string label = (*d)->label().GetUserVisibleName(false); |
| 108 if (pattern.MatchesString(label)) { | 104 if (pattern.MatchesString(label)) { |
| 109 // Got a match. | 105 // Got a match. |
| 110 if (file_output) { | 106 if (file_output) { |
| 111 unique_output.insert(FilePathToUTF8(FilePathForItemNode(node))); | 107 unique_output.insert(FilePathToUTF8(FilePathForRecord(record))); |
| 112 break; // Found a match for this target's file, don't need more. | 108 break; // Found a match for this target's file, don't need more. |
| 113 } else { | 109 } else { |
| 114 // We can get dupes when there are differnet toolchains involved, | 110 // We can get dupes when there are differnet toolchains involved, |
| 115 // so we want to send all output through the de-duper. | 111 // so we want to send all output through the de-duper. |
| 116 unique_output.insert( | 112 unique_output.insert( |
| 117 node.item()->label().GetUserVisibleName(false) + " -> " + label); | 113 record->item()->label().GetUserVisibleName(false) + " -> " + |
| 114 label); |
| 118 } | 115 } |
| 119 } | 116 } |
| 120 } | 117 } |
| 121 } | 118 } |
| 122 | 119 |
| 123 for (std::set<std::string>::iterator i = unique_output.begin(); | 120 for (std::set<std::string>::iterator i = unique_output.begin(); |
| 124 i != unique_output.end(); ++i) | 121 i != unique_output.end(); ++i) |
| 125 OutputString(*i + "\n"); | 122 OutputString(*i + "\n"); |
| 126 | 123 |
| 127 return 0; | 124 return 0; |
| 128 } | 125 } |
| 129 | 126 |
| 130 } // namespace commands | 127 } // namespace commands |
| OLD | NEW |