123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #!/usr/bin/env python
- #
- # Copyright (C) 2011 Google Inc. All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are
- # met:
- #
- # * Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # * Redistributions in binary form must reproduce the above
- # copyright notice, this list of conditions and the following disclaimer
- # in the documentation and/or other materials provided with the
- # distribution.
- # * Neither the name of Google Inc. nor the names of its
- # contributors may be used to endorse or promote products derived from
- # this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- import codecs
- import logging
- import os
- import os.path
- import re
- import sys
- from webkitpy.common.checkout.scm import SCMDetector
- from webkitpy.common.system.filesystem import FileSystem
- from webkitpy.common.system.executive import Executive
- from webkitpy.common.system.logutils import configure_logging
- from webkitpy.style.checker import ProcessorBase
- from webkitpy.style.filereader import TextFileReader
- from webkitpy.style.main import change_directory
- _inspector_directory = "Source/WebCore/inspector/front-end"
- _localized_strings = "Source/WebCore/English.lproj/localizedStrings.js"
- _log = logging.getLogger("check-inspector-strings")
- class StringsExtractor(ProcessorBase):
- def __init__(self, patterns):
- self._patterns = patterns
- self.strings = []
- for p in self._patterns:
- self.strings.append([])
- def should_process(self, file_path):
- return file_path.endswith(".js") and (not file_path.endswith("InjectedScript.js"))
- def process(self, lines, file_path, line_numbers=None):
- for line in lines:
- comment_start = line.find("//")
- if comment_start != -1:
- line = line[:comment_start]
- index = 0
- for pattern in self._patterns:
- line_strings = re.findall(pattern, line)
- for string in line_strings:
- self.strings[index].append(string)
- index += 1
- class LocalizedStringsExtractor:
- def __init__(self):
- self.localized_strings = []
- def process_file(self, file_path):
- localized_strings_file = codecs.open(file_path, encoding="utf-8", mode="r")
- try:
- contents = localized_strings_file.read()
- lines = contents.split("\n")
- for line in lines:
- match = re.match(r"localizedStrings\[\"((?:[^\"\\]|\\.)*?)\"", line)
- if match:
- self.localized_strings.append(match.group(1))
- finally:
- localized_strings_file.close()
- def extract_ui_strings(str, out):
- line_unrecognized = False
- idx = 0
- while idx < len(str):
- idx = str.find("WebInspector.UIString(", idx)
- if idx == -1:
- break
- idx = idx + len("WebInspector.UIString(")
- balance = 1
- item_recognized = False
- while idx < len(str):
- if str[idx] == ')':
- balance = balance - 1
- if balance == 0:
- break
- elif str[idx] == '(':
- balance = balance + 1
- elif balance == 1:
- if str[idx] == ',':
- break
- elif str[idx] == '"':
- str_idx = idx + 1
- while str_idx < len(str):
- if str[str_idx] == '\\':
- str_idx = str_idx + 1
- elif str[str_idx] == '"':
- out.add(str[idx + 1 : str_idx])
- idx = str_idx
- item_recognized = True
- break
- str_idx = str_idx + 1
- idx = idx + 1
- if not item_recognized:
- line_unrecognized = True
- if line_unrecognized:
- _log.info("Unrecognized: %s" % str)
- if __name__ == "__main__":
- configure_logging()
- cwd = os.path.abspath(os.curdir)
- filesystem = FileSystem()
- scm = SCMDetector(filesystem, Executive()).detect_scm_system(cwd)
- if scm is None:
- _log.error("WebKit checkout not found: You must run this script "
- "from within a WebKit checkout.")
- sys.exit(1)
- checkout_root = scm.checkout_root
- _log.debug("WebKit checkout found with root: %s" % checkout_root)
- change_directory(filesystem, checkout_root=checkout_root, paths=None)
- strings_extractor = StringsExtractor([r"(WebInspector\.UIString\(.*)", r"\"((?:[^\"\\]|\\.)*?)\""])
- file_reader = TextFileReader(filesystem, strings_extractor)
- file_reader.process_paths([_inspector_directory])
- localized_strings_extractor = LocalizedStringsExtractor()
- localized_strings_extractor.process_file(_localized_strings)
- raw_ui_strings = frozenset(strings_extractor.strings[0])
- ui_strings = set()
- for s in raw_ui_strings:
- extract_ui_strings(s, ui_strings)
- strings = frozenset(strings_extractor.strings[1])
- localized_strings = frozenset(localized_strings_extractor.localized_strings)
- new_strings = ui_strings - localized_strings
- for s in new_strings:
- _log.info("New: \"%s\"" % (s))
- old_strings = localized_strings - ui_strings
- suspicious_strings = strings & old_strings
- for s in suspicious_strings:
- _log.info("Suspicious: \"%s\"" % (s))
- unused_strings = old_strings - strings
- for s in unused_strings:
- _log.info("Unused: \"%s\"" % (s))
- localized_strings_duplicates = {}
- for s in localized_strings_extractor.localized_strings:
- if s in localized_strings_duplicates:
- _log.info("Duplicate: \"%s\"" % (s))
- else:
- localized_strings_duplicates.setdefault(s)
|