diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/bin/scopify.py')
-rwxr-xr-x | contexts/data/lib/closure-library/closure/bin/scopify.py | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/contexts/data/lib/closure-library/closure/bin/scopify.py b/contexts/data/lib/closure-library/closure/bin/scopify.py deleted file mode 100755 index e30220b..0000000 --- a/contexts/data/lib/closure-library/closure/bin/scopify.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/python2.4 -# -# Copyright 2010 The Closure Library Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS-IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -"""Automatically converts codebases over to goog.scope. - -Usage: -cd path/to/my/dir; -../../../../javascript/closure/bin/scopify.py - -Scans every file in this directory, recursively. Looks for existing -goog.scope calls, and goog.require'd symbols. If it makes sense to -generate a goog.scope call for the file, then we will do so, and -try to auto-generate some aliases based on the goog.require'd symbols. - -Known Issues: - - When a file is goog.scope'd, the file contents will be indented +2. - This may put some lines over 80 chars. These will need to be fixed manually. - - We will only try to create aliases for capitalized names. We do not check - to see if those names will conflict with any existing locals. - - This creates merge conflicts for every line of every outstanding change. - If you intend to run this on your codebase, make sure your team members - know. Better yet, send them this script so that they can scopify their - outstanding changes and "accept theirs". - - When an alias is "captured", it can no longer be stubbed out for testing. - Run your tests. - -""" - -__author__ = 'nicksantos@google.com (Nick Santos)' - -import os.path -import re -import sys - -REQUIRES_RE = re.compile(r"goog.require\('([^']*)'\)") - -# Edit this manually if you want something to "always" be aliased. -# TODO(nicksantos): Add a flag for this. -DEFAULT_ALIASES = {} - -def Transform(lines): - """Converts the contents of a file into javascript that uses goog.scope. - - Arguments: - lines: A list of strings, corresponding to each line of the file. - Returns: - A new list of strings, or None if the file was not modified. - """ - requires = [] - - # Do an initial scan to be sure that this file can be processed. - for line in lines: - # Skip this file if it has already been scopified. - if line.find('goog.scope') != -1: - return None - - # If there are any global vars or functions, then we also have - # to skip the whole file. We might be able to deal with this - # more elegantly. - if line.find('var ') == 0 or line.find('function ') == 0: - return None - - for match in REQUIRES_RE.finditer(line): - requires.append(match.group(1)) - - if len(requires) == 0: - return None - - # Backwards-sort the requires, so that when one is a substring of another, - # we match the longer one first. - for val in DEFAULT_ALIASES.values(): - if requires.count(val) == 0: - requires.append(val) - - requires.sort() - requires.reverse() - - # Generate a map of requires to their aliases - aliases_to_globals = DEFAULT_ALIASES.copy() - for req in requires: - index = req.rfind('.') - if index == -1: - alias = req - else: - alias = req[(index + 1):] - - # Don't scopify lowercase namespaces, because they may conflict with - # local variables. - if alias[0].isupper(): - aliases_to_globals[alias] = req - - aliases_to_matchers = {} - globals_to_aliases = {} - for alias, symbol in aliases_to_globals.items(): - globals_to_aliases[symbol] = alias - aliases_to_matchers[alias] = re.compile('\\b%s\\b' % symbol) - - # Insert a goog.scope that aliases all required symbols. - result = [] - - START = 0 - SEEN_REQUIRES = 1 - IN_SCOPE = 2 - - mode = START - aliases_used = set() - insertion_index = None - for line in lines: - if mode == START: - result.append(line) - - if re.search(REQUIRES_RE, line): - mode = SEEN_REQUIRES - - elif mode == SEEN_REQUIRES: - if (line and - not re.search(REQUIRES_RE, line) and - not line.isspace()): - result.append('goog.scope(function() {\n') - insertion_index = len(result) - result.append('\n') - mode = IN_SCOPE - else: - result.append(line) - - if mode == IN_SCOPE: - for symbol in requires: - if not symbol in globals_to_aliases: - continue - - alias = globals_to_aliases[symbol] - matcher = aliases_to_matchers[alias] - for match in matcher.finditer(line): - # Check to make sure we're not in a string. - # We do this by being as conservative as possible: - # if there are any quote or double quote characters - # before the symbol on this line, then bail out. - before_symbol = line[:match.start(0)] - if before_symbol.count('"') > 0 or before_symbol.count("'") > 0: - continue - - line = line.replace(match.group(0), alias) - aliases_used.add(alias) - - if line.isspace(): - # Truncate all-whitespace lines - result.append('\n') - else: - result.append(' ' + line) - - if len(aliases_used): - aliases_used = [alias for alias in aliases_used] - aliases_used.sort() - aliases_used.reverse() - for alias in aliases_used: - symbol = aliases_to_globals[alias] - result.insert(insertion_index, - ' var %s = %s;\n' % (alias, symbol)) - result.append('});\n') - return result - else: - return None - -def TransformFileAt(path): - """Converts a file into javascript that uses goog.scope. - - Arguments: - path: A path to a file. - """ - f = open(path) - lines = Transform(f.readlines()) - if lines: - f = open(path, 'w') - for l in lines: - f.write(l) - f.close() - -if __name__ == '__main__': - args = sys.argv[1:] - if not len(args): - args = '.' - - for file_name in args: - if os.path.isdir(file_name): - for root, dirs, files in os.walk(file_name): - for name in files: - if name.endswith('.js') and \ - not os.path.islink(os.path.join(root, name)): - TransformFileAt(os.path.join(root, name)) - else: - if file_name.endswith('.js') and \ - not os.path.islink(file_name): - TransformFileAt(file_name) |