| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """A tool to scan source files for unneeded grit includes. | 6 """A tool to scan source files for unneeded grit includes. |
| 7 | 7 |
| 8 Example: | 8 Example: |
| 9 cd /work/chrome/src | 9 cd /work/chrome/src |
| 10 tools/resources/list_unused_grit_header.py ui/strings/ui_strings.grd chrome ui | 10 tools/resources/list_unused_grit_header.py ui/strings/ui_strings.grd chrome ui |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 import os | 13 import os |
| 14 import sys | 14 import sys |
| 15 import xml.etree.ElementTree | 15 import xml.etree.ElementTree |
| 16 | 16 |
| 17 from find_unused_resources import GetBaseResourceId | 17 from find_unused_resources import GetBaseResourceId |
| 18 | 18 |
| 19 IF_ELSE_TAGS = ('if', 'else') | 19 IF_ELSE_THEN_TAGS = ('if', 'else', 'then') |
| 20 | 20 |
| 21 | 21 |
| 22 def Usage(prog_name): | 22 def Usage(prog_name): |
| 23 print prog_name, 'GRD_FILE PATHS_TO_SCAN' | 23 print prog_name, 'GRD_FILE PATHS_TO_SCAN' |
| 24 | 24 |
| 25 | 25 |
| 26 def FilterResourceIds(resource_id): | 26 def FilterResourceIds(resource_id): |
| 27 """If the resource starts with IDR_, find its base resource id.""" | 27 """If the resource starts with IDR_, find its base resource id.""" |
| 28 if resource_id.startswith('IDR_'): | 28 if resource_id.startswith('IDR_'): |
| 29 return GetBaseResourceId(resource_id) | 29 return GetBaseResourceId(resource_id) |
| 30 return resource_id | 30 return resource_id |
| 31 | 31 |
| 32 | 32 |
| 33 def GetResourcesForNode(node, parent_file, resource_tag): | 33 def GetResourcesForNode(node, parent_file, resource_tag): |
| 34 """Recursively iterate through a node and extract resource names. | 34 """Recursively iterate through a node and extract resource names. |
| 35 | 35 |
| 36 Args: | 36 Args: |
| 37 node: The node to iterate through. | 37 node: The node to iterate through. |
| 38 parent_file: The file that contains node. | 38 parent_file: The file that contains node. |
| 39 resource_tag: The resource tag to extract names from. | 39 resource_tag: The resource tag to extract names from. |
| 40 | 40 |
| 41 Returns: | 41 Returns: |
| 42 A list of resource names. | 42 A list of resource names. |
| 43 """ | 43 """ |
| 44 resources = [] | 44 resources = [] |
| 45 for child in node.getchildren(): | 45 for child in node.getchildren(): |
| 46 if child.tag == resource_tag: | 46 if child.tag == resource_tag: |
| 47 resources.append(child.attrib['name']) | 47 resources.append(child.attrib['name']) |
| 48 elif child.tag in IF_ELSE_TAGS: | 48 elif child.tag in IF_ELSE_THEN_TAGS: |
| 49 resources.extend(GetResourcesForNode(child, parent_file, resource_tag)) | 49 resources.extend(GetResourcesForNode(child, parent_file, resource_tag)) |
| 50 elif child.tag == 'part': | 50 elif child.tag == 'part': |
| 51 parent_dir = os.path.dirname(parent_file) | 51 parent_dir = os.path.dirname(parent_file) |
| 52 part_file = os.path.join(parent_dir, child.attrib['file']) | 52 part_file = os.path.join(parent_dir, child.attrib['file']) |
| 53 part_tree = xml.etree.ElementTree.parse(part_file) | 53 part_tree = xml.etree.ElementTree.parse(part_file) |
| 54 part_root = part_tree.getroot() | 54 part_root = part_tree.getroot() |
| 55 assert part_root.tag == 'grit-part' | 55 assert part_root.tag == 'grit-part' |
| 56 resources.extend(GetResourcesForNode(part_root, part_file, resource_tag)) | 56 resources.extend(GetResourcesForNode(part_root, part_file, resource_tag)) |
| 57 else: | 57 else: |
| 58 raise Exception('unknown tag:', child.tag) | 58 raise Exception('unknown tag:', child.tag) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 Returns: | 114 Returns: |
| 115 A grit header file name. | 115 A grit header file name. |
| 116 """ | 116 """ |
| 117 output_file = None | 117 output_file = None |
| 118 for child in node.getchildren(): | 118 for child in node.getchildren(): |
| 119 if child.tag == 'output': | 119 if child.tag == 'output': |
| 120 if child.attrib['type'] == 'rc_header': | 120 if child.attrib['type'] == 'rc_header': |
| 121 assert output_file is None | 121 assert output_file is None |
| 122 output_file = child.attrib['filename'] | 122 output_file = child.attrib['filename'] |
| 123 elif child.tag in IF_ELSE_TAGS: | 123 elif child.tag in IF_ELSE_THEN_TAGS: |
| 124 child_output_file = GetOutputFileForNode(child) | 124 child_output_file = GetOutputFileForNode(child) |
| 125 if not child_output_file: | 125 if not child_output_file: |
| 126 continue | 126 continue |
| 127 assert output_file is None | 127 assert output_file is None |
| 128 output_file = child_output_file | 128 output_file = child_output_file |
| 129 else: | 129 else: |
| 130 raise Exception('unknown tag:', child.tag) | 130 raise Exception('unknown tag:', child.tag) |
| 131 return output_file | 131 return output_file |
| 132 | 132 |
| 133 | 133 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 162 resources: The list of resource names in grit_header. | 162 resources: The list of resource names in grit_header. |
| 163 filename: The file to scan. | 163 filename: The file to scan. |
| 164 | 164 |
| 165 Returns: | 165 Returns: |
| 166 True if the file should include the grit header. | 166 True if the file should include the grit header. |
| 167 """ | 167 """ |
| 168 # A list of special keywords that implies the file needs grit headers. | 168 # A list of special keywords that implies the file needs grit headers. |
| 169 # To be more thorough, one would need to run a pre-processor. | 169 # To be more thorough, one would need to run a pre-processor. |
| 170 SPECIAL_KEYWORDS = ( | 170 SPECIAL_KEYWORDS = ( |
| 171 '#include "ui_localizer_table.h"', # ui_localizer.mm | 171 '#include "ui_localizer_table.h"', # ui_localizer.mm |
| 172 'DEFINE_RESOURCE_ID', # chrome/browser/android/resource_mapper.cc | 172 'DECLARE_RESOURCE_ID', # chrome/browser/android/resource_mapper.cc |
| 173 ) | 173 ) |
| 174 with open(filename, 'rb') as f: | 174 with open(filename, 'rb') as f: |
| 175 grit_header_line = grit_header + '"\n' | 175 grit_header_line = grit_header + '"\n' |
| 176 has_grit_header = False | 176 has_grit_header = False |
| 177 while True: | 177 while True: |
| 178 line = f.readline() | 178 line = f.readline() |
| 179 if not line: | 179 if not line: |
| 180 break | 180 break |
| 181 if line.endswith(grit_header_line): | 181 if line.endswith(grit_header_line): |
| 182 has_grit_header = True | 182 has_grit_header = True |
| (...skipping 13 matching lines...) Expand all Loading... |
| 196 grd_file = argv[1] | 196 grd_file = argv[1] |
| 197 paths_to_scan = argv[2:] | 197 paths_to_scan = argv[2:] |
| 198 for f in paths_to_scan: | 198 for f in paths_to_scan: |
| 199 if not os.path.exists(f): | 199 if not os.path.exists(f): |
| 200 print 'Error: %s does not exist' % f | 200 print 'Error: %s does not exist' % f |
| 201 return 1 | 201 return 1 |
| 202 | 202 |
| 203 tree = xml.etree.ElementTree.parse(grd_file) | 203 tree = xml.etree.ElementTree.parse(grd_file) |
| 204 grit_header = GetOutputHeaderFile(tree) | 204 grit_header = GetOutputHeaderFile(tree) |
| 205 if not grit_header: | 205 if not grit_header: |
| 206 print 'Error: %s does not generate any output headers.' % grit_header | 206 print 'Error: %s does not generate any output headers.' % grd_file |
| 207 return 1 | 207 return 1 |
| 208 |
| 208 resources = GetResourcesForGrdFile(tree, grd_file) | 209 resources = GetResourcesForGrdFile(tree, grd_file) |
| 209 | 210 |
| 210 files_with_unneeded_grit_includes = [] | 211 files_with_unneeded_grit_includes = [] |
| 211 for path_to_scan in paths_to_scan: | 212 for path_to_scan in paths_to_scan: |
| 212 if os.path.isdir(path_to_scan): | 213 if os.path.isdir(path_to_scan): |
| 213 for root, dirs, files in os.walk(path_to_scan): | 214 for root, dirs, files in os.walk(path_to_scan): |
| 214 if '.git' in dirs: | 215 if '.git' in dirs: |
| 215 dirs.remove('.git') | 216 dirs.remove('.git') |
| 216 full_paths = [os.path.join(root, f) for f in files if ShouldScanFile(f)] | 217 full_paths = [os.path.join(root, f) for f in files if ShouldScanFile(f)] |
| 217 files_with_unneeded_grit_includes.extend( | 218 files_with_unneeded_grit_includes.extend( |
| 218 [f for f in full_paths | 219 [f for f in full_paths |
| 219 if not NeedsGritInclude(grit_header, resources, f)]) | 220 if not NeedsGritInclude(grit_header, resources, f)]) |
| 220 elif os.path.isfile(path_to_scan): | 221 elif os.path.isfile(path_to_scan): |
| 221 if not NeedsGritInclude(grit_header, resources, path_to_scan): | 222 if not NeedsGritInclude(grit_header, resources, path_to_scan): |
| 222 files_with_unneeded_grit_includes.append(path_to_scan) | 223 files_with_unneeded_grit_includes.append(path_to_scan) |
| 223 else: | 224 else: |
| 224 print 'Warning: Skipping %s' % path_to_scan | 225 print 'Warning: Skipping %s' % path_to_scan |
| 225 | 226 |
| 226 if files_with_unneeded_grit_includes: | 227 if files_with_unneeded_grit_includes: |
| 227 print '\n'.join(files_with_unneeded_grit_includes) | 228 print '\n'.join(files_with_unneeded_grit_includes) |
| 228 return 2 | 229 return 2 |
| 229 return 0 | 230 return 0 |
| 230 | 231 |
| 231 | 232 |
| 232 if __name__ == '__main__': | 233 if __name__ == '__main__': |
| 233 sys.exit(main(sys.argv)) | 234 sys.exit(main(sys.argv)) |
| OLD | NEW |