summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xdom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py287
-rwxr-xr-xdom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py189
-rwxr-xr-xdom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py204
-rw-r--r--dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/jscompiler.py135
-rw-r--r--dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/source.py127
-rw-r--r--dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/treescan.py78
6 files changed, 1020 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py
new file mode 100755
index 0000000000..9e4e2eb339
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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.
+
+"""Utility for Closure Library dependency calculation.
+
+ClosureBuilder scans source files to build dependency info. From the
+dependencies, the script can produce a manifest in dependency order,
+a concatenated script, or compiled output from the Closure Compiler.
+
+Paths to files can be expressed as individual arguments to the tool (intended
+for use with find and xargs). As a convenience, --root can be used to specify
+all JS files below a directory.
+
+usage: %prog [options] [file1.js file2.js ...]
+"""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+import logging
+import optparse
+import os
+import sys
+
+import depstree
+import jscompiler
+import source
+import treescan
+
+
+def _GetOptionsParser():
+ """Get the options parser."""
+
+ parser = optparse.OptionParser(__doc__)
+ parser.add_option('-i',
+ '--input',
+ dest='inputs',
+ action='append',
+ default=[],
+ help='One or more input files to calculate dependencies '
+ 'for. The namespaces in this file will be combined with '
+ 'those given with the -n flag to form the set of '
+ 'namespaces to find dependencies for.')
+ parser.add_option('-n',
+ '--namespace',
+ dest='namespaces',
+ action='append',
+ default=[],
+ help='One or more namespaces to calculate dependencies '
+ 'for. These namespaces will be combined with those given '
+ 'with the -i flag to form the set of namespaces to find '
+ 'dependencies for. A Closure namespace is a '
+ 'dot-delimited path expression declared with a call to '
+ 'goog.provide() (e.g. "goog.array" or "foo.bar").')
+ parser.add_option('--root',
+ dest='roots',
+ action='append',
+ default=[],
+ help='The paths that should be traversed to build the '
+ 'dependencies.')
+ parser.add_option('-o',
+ '--output_mode',
+ dest='output_mode',
+ type='choice',
+ action='store',
+ choices=['list', 'script', 'compiled'],
+ default='list',
+ help='The type of output to generate from this script. '
+ 'Options are "list" for a list of filenames, "script" '
+ 'for a single script containing the contents of all the '
+ 'files, or "compiled" to produce compiled output with '
+ 'the Closure Compiler. Default is "list".')
+ parser.add_option('-c',
+ '--compiler_jar',
+ dest='compiler_jar',
+ action='store',
+ help='The location of the Closure compiler .jar file.')
+ parser.add_option('-f',
+ '--compiler_flags',
+ dest='compiler_flags',
+ default=[],
+ action='append',
+ help='Additional flags to pass to the Closure compiler. '
+ 'To pass multiple flags, --compiler_flags has to be '
+ 'specified multiple times.')
+ parser.add_option('-j',
+ '--jvm_flags',
+ dest='jvm_flags',
+ default=[],
+ action='append',
+ help='Additional flags to pass to the JVM compiler. '
+ 'To pass multiple flags, --jvm_flags has to be '
+ 'specified multiple times.')
+ parser.add_option('--output_file',
+ dest='output_file',
+ action='store',
+ help=('If specified, write output to this path instead of '
+ 'writing to standard output.'))
+
+ return parser
+
+
+def _GetInputByPath(path, sources):
+ """Get the source identified by a path.
+
+ Args:
+ path: str, A path to a file that identifies a source.
+ sources: An iterable collection of source objects.
+
+ Returns:
+ The source from sources identified by path, if found. Converts to
+ real paths for comparison.
+ """
+ for js_source in sources:
+ # Convert both to real paths for comparison.
+ if os.path.realpath(path) == os.path.realpath(js_source.GetPath()):
+ return js_source
+
+
+def _GetClosureBaseFile(sources):
+ """Given a set of sources, returns the one base.js file.
+
+ Note that if zero or two or more base.js files are found, an error message
+ will be written and the program will be exited.
+
+ Args:
+ sources: An iterable of _PathSource objects.
+
+ Returns:
+ The _PathSource representing the base Closure file.
+ """
+ base_files = [
+ js_source for js_source in sources if _IsClosureBaseFile(js_source)]
+
+ if not base_files:
+ logging.error('No Closure base.js file found.')
+ sys.exit(1)
+ if len(base_files) > 1:
+ logging.error('More than one Closure base.js files found at these paths:')
+ for base_file in base_files:
+ logging.error(base_file.GetPath())
+ sys.exit(1)
+ return base_files[0]
+
+
+def _IsClosureBaseFile(js_source):
+ """Returns true if the given _PathSource is the Closure base.js source."""
+ return (os.path.basename(js_source.GetPath()) == 'base.js' and
+ js_source.provides == set(['goog']))
+
+
+class _PathSource(source.Source):
+ """Source file subclass that remembers its file path."""
+
+ def __init__(self, path):
+ """Initialize a source.
+
+ Args:
+ path: str, Path to a JavaScript file. The source string will be read
+ from this file.
+ """
+ super(_PathSource, self).__init__(source.GetFileContents(path))
+
+ self._path = path
+
+ def __str__(self):
+ return 'PathSource %s' % self._path
+
+ def GetPath(self):
+ """Returns the path."""
+ return self._path
+
+
+def _WrapGoogModuleSource(src):
+ return ('goog.loadModule(function(exports) {{'
+ '"use strict";'
+ '{0}'
+ '\n' # terminate any trailing single line comment.
+ ';return exports'
+ '}});\n').format(src)
+
+
+def main():
+ logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
+ level=logging.INFO)
+ options, args = _GetOptionsParser().parse_args()
+
+ # Make our output pipe.
+ if options.output_file:
+ out = open(options.output_file, 'w')
+ else:
+ out = sys.stdout
+
+ sources = set()
+
+ logging.info('Scanning paths...')
+ for path in options.roots:
+ for js_path in treescan.ScanTreeForJsFiles(path):
+ sources.add(_PathSource(js_path))
+
+ # Add scripts specified on the command line.
+ for js_path in args:
+ sources.add(_PathSource(js_path))
+
+ logging.info('%s sources scanned.', len(sources))
+
+ # Though deps output doesn't need to query the tree, we still build it
+ # to validate dependencies.
+ logging.info('Building dependency tree..')
+ tree = depstree.DepsTree(sources)
+
+ input_namespaces = set()
+ inputs = options.inputs or []
+ for input_path in inputs:
+ js_input = _GetInputByPath(input_path, sources)
+ if not js_input:
+ logging.error('No source matched input %s', input_path)
+ sys.exit(1)
+ input_namespaces.update(js_input.provides)
+
+ input_namespaces.update(options.namespaces)
+
+ if not input_namespaces:
+ logging.error('No namespaces found. At least one namespace must be '
+ 'specified with the --namespace or --input flags.')
+ sys.exit(2)
+
+ # The Closure Library base file must go first.
+ base = _GetClosureBaseFile(sources)
+ deps = [base] + tree.GetDependencies(input_namespaces)
+
+ output_mode = options.output_mode
+ if output_mode == 'list':
+ out.writelines([js_source.GetPath() + '\n' for js_source in deps])
+ elif output_mode == 'script':
+ for js_source in deps:
+ src = js_source.GetSource()
+ if js_source.is_goog_module:
+ src = _WrapGoogModuleSource(src)
+ out.write(src + '\n')
+ elif output_mode == 'compiled':
+ logging.warning("""\
+Closure Compiler now natively understands and orders Closure dependencies and
+is prefererred over using this script for performing JavaScript compilation.
+
+Please migrate your codebase.
+
+See:
+https://github.com/google/closure-compiler/wiki/Manage-Closure-Dependencies
+""")
+
+ # Make sure a .jar is specified.
+ if not options.compiler_jar:
+ logging.error('--compiler_jar flag must be specified if --output is '
+ '"compiled"')
+ sys.exit(2)
+
+ # Will throw an error if the compilation fails.
+ compiled_source = jscompiler.Compile(
+ options.compiler_jar,
+ [js_source.GetPath() for js_source in deps],
+ jvm_flags=options.jvm_flags,
+ compiler_flags=options.compiler_flags)
+
+ logging.info('JavaScript compilation succeeded.')
+ out.write(compiled_source)
+
+ else:
+ logging.error('Invalid value for --output flag.')
+ sys.exit(2)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py
new file mode 100755
index 0000000000..f288dd3aa6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py
@@ -0,0 +1,189 @@
+# Copyright 2009 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.
+
+
+"""Class to represent a full Closure Library dependency tree.
+
+Offers a queryable tree of dependencies of a given set of sources. The tree
+will also do logical validation to prevent duplicate provides and circular
+dependencies.
+"""
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+class DepsTree(object):
+ """Represents the set of dependencies between source files."""
+
+ def __init__(self, sources):
+ """Initializes the tree with a set of sources.
+
+ Args:
+ sources: A set of JavaScript sources.
+
+ Raises:
+ MultipleProvideError: A namespace is provided by muplitple sources.
+ NamespaceNotFoundError: A namespace is required but never provided.
+ """
+
+ self._sources = sources
+ self._provides_map = dict()
+
+ # Ensure nothing was provided twice.
+ for source in sources:
+ for provide in source.provides:
+ if provide in self._provides_map:
+ raise MultipleProvideError(
+ provide, [self._provides_map[provide], source])
+
+ self._provides_map[provide] = source
+
+ # Check that all required namespaces are provided.
+ for source in sources:
+ for require in source.requires:
+ if require not in self._provides_map:
+ raise NamespaceNotFoundError(require, source)
+
+ def GetDependencies(self, required_namespaces):
+ """Get source dependencies, in order, for the given namespaces.
+
+ Args:
+ required_namespaces: A string (for one) or list (for one or more) of
+ namespaces.
+
+ Returns:
+ A list of source objects that provide those namespaces and all
+ requirements, in dependency order.
+
+ Raises:
+ NamespaceNotFoundError: A namespace is requested but doesn't exist.
+ CircularDependencyError: A cycle is detected in the dependency tree.
+ """
+ if isinstance(required_namespaces, str):
+ required_namespaces = [required_namespaces]
+
+ deps_sources = []
+
+ for namespace in required_namespaces:
+ for source in DepsTree._ResolveDependencies(
+ namespace, [], self._provides_map, []):
+ if source not in deps_sources:
+ deps_sources.append(source)
+
+ return deps_sources
+
+ @staticmethod
+ def _ResolveDependencies(required_namespace, deps_list, provides_map,
+ traversal_path):
+ """Resolve dependencies for Closure source files.
+
+ Follows the dependency tree down and builds a list of sources in dependency
+ order. This function will recursively call itself to fill all dependencies
+ below the requested namespaces, and then append its sources at the end of
+ the list.
+
+ Args:
+ required_namespace: String of required namespace.
+ deps_list: List of sources in dependency order. This function will append
+ the required source once all of its dependencies are satisfied.
+ provides_map: Map from namespace to source that provides it.
+ traversal_path: List of namespaces of our path from the root down the
+ dependency/recursion tree. Used to identify cyclical dependencies.
+ This is a list used as a stack -- when the function is entered, the
+ current namespace is pushed and popped right before returning.
+ Each recursive call will check that the current namespace does not
+ appear in the list, throwing a CircularDependencyError if it does.
+
+ Returns:
+ The given deps_list object filled with sources in dependency order.
+
+ Raises:
+ NamespaceNotFoundError: A namespace is requested but doesn't exist.
+ CircularDependencyError: A cycle is detected in the dependency tree.
+ """
+
+ source = provides_map.get(required_namespace)
+ if not source:
+ raise NamespaceNotFoundError(required_namespace)
+
+ if required_namespace in traversal_path:
+ traversal_path.append(required_namespace) # do this *after* the test
+
+ # This must be a cycle.
+ raise CircularDependencyError(traversal_path)
+
+ # If we don't have the source yet, we'll have to visit this namespace and
+ # add the required dependencies to deps_list.
+ if source not in deps_list:
+ traversal_path.append(required_namespace)
+
+ for require in source.requires:
+
+ # Append all other dependencies before we append our own.
+ DepsTree._ResolveDependencies(require, deps_list, provides_map,
+ traversal_path)
+ deps_list.append(source)
+
+ traversal_path.pop()
+
+ return deps_list
+
+
+class BaseDepsTreeError(Exception):
+ """Base DepsTree error."""
+
+ def __init__(self):
+ Exception.__init__(self)
+
+
+class CircularDependencyError(BaseDepsTreeError):
+ """Raised when a dependency cycle is encountered."""
+
+ def __init__(self, dependency_list):
+ BaseDepsTreeError.__init__(self)
+ self._dependency_list = dependency_list
+
+ def __str__(self):
+ return ('Encountered circular dependency:\n%s\n' %
+ '\n'.join(self._dependency_list))
+
+
+class MultipleProvideError(BaseDepsTreeError):
+ """Raised when a namespace is provided more than once."""
+
+ def __init__(self, namespace, sources):
+ BaseDepsTreeError.__init__(self)
+ self._namespace = namespace
+ self._sources = sources
+
+ def __str__(self):
+ source_strs = map(str, self._sources)
+
+ return ('Namespace "%s" provided more than once in sources:\n%s\n' %
+ (self._namespace, '\n'.join(source_strs)))
+
+
+class NamespaceNotFoundError(BaseDepsTreeError):
+ """Raised when a namespace is requested but not provided."""
+
+ def __init__(self, namespace, source=None):
+ BaseDepsTreeError.__init__(self)
+ self._namespace = namespace
+ self._source = source
+
+ def __str__(self):
+ msg = 'Namespace "%s" never provided.' % self._namespace
+ if self._source:
+ msg += ' Required in %s' % self._source
+ return msg
diff --git a/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py
new file mode 100755
index 0000000000..bc3be88a35
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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.
+
+
+"""Generates out a Closure deps.js file given a list of JavaScript sources.
+
+Paths can be specified as arguments or (more commonly) specifying trees
+with the flags (call with --help for descriptions).
+
+Usage: depswriter.py [path/to/js1.js [path/to/js2.js] ...]
+"""
+
+import logging
+import optparse
+import os
+import posixpath
+import shlex
+import sys
+
+import source
+import treescan
+
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+def MakeDepsFile(source_map):
+ """Make a generated deps file.
+
+ Args:
+ source_map: A dict map of the source path to source.Source object.
+
+ Returns:
+ str, A generated deps file source.
+ """
+
+ # Write in path alphabetical order
+ paths = sorted(source_map.keys())
+
+ lines = []
+
+ for path in paths:
+ js_source = source_map[path]
+
+ # We don't need to add entries that don't provide anything.
+ if js_source.provides:
+ lines.append(_GetDepsLine(path, js_source))
+
+ return ''.join(lines)
+
+
+def _GetDepsLine(path, js_source):
+ """Get a deps.js file string for a source."""
+
+ provides = sorted(js_source.provides)
+ requires = sorted(js_source.requires)
+ module = 'true' if js_source.is_goog_module else 'false'
+
+ return 'goog.addDependency(\'%s\', %s, %s, %s);\n' % (
+ path, provides, requires, module)
+
+
+def _GetOptionsParser():
+ """Get the options parser."""
+
+ parser = optparse.OptionParser(__doc__)
+
+ parser.add_option('--output_file',
+ dest='output_file',
+ action='store',
+ help=('If specified, write output to this path instead of '
+ 'writing to standard output.'))
+ parser.add_option('--root',
+ dest='roots',
+ default=[],
+ action='append',
+ help='A root directory to scan for JS source files. '
+ 'Paths of JS files in generated deps file will be '
+ 'relative to this path. This flag may be specified '
+ 'multiple times.')
+ parser.add_option('--root_with_prefix',
+ dest='roots_with_prefix',
+ default=[],
+ action='append',
+ help='A root directory to scan for JS source files, plus '
+ 'a prefix (if either contains a space, surround with '
+ 'quotes). Paths in generated deps file will be relative '
+ 'to the root, but preceded by the prefix. This flag '
+ 'may be specified multiple times.')
+ parser.add_option('--path_with_depspath',
+ dest='paths_with_depspath',
+ default=[],
+ action='append',
+ help='A path to a source file and an alternate path to '
+ 'the file in the generated deps file (if either contains '
+ 'a space, surround with whitespace). This flag may be '
+ 'specified multiple times.')
+ return parser
+
+
+def _NormalizePathSeparators(path):
+ """Replaces OS-specific path separators with POSIX-style slashes.
+
+ Args:
+ path: str, A file path.
+
+ Returns:
+ str, The path with any OS-specific path separators (such as backslash on
+ Windows) replaced with URL-compatible forward slashes. A no-op on systems
+ that use POSIX paths.
+ """
+ return path.replace(os.sep, posixpath.sep)
+
+
+def _GetRelativePathToSourceDict(root, prefix=''):
+ """Scans a top root directory for .js sources.
+
+ Args:
+ root: str, Root directory.
+ prefix: str, Prefix for returned paths.
+
+ Returns:
+ dict, A map of relative paths (with prefix, if given), to source.Source
+ objects.
+ """
+ # Remember and restore the cwd when we're done. We work from the root so
+ # that paths are relative from the root.
+ start_wd = os.getcwd()
+ os.chdir(root)
+
+ path_to_source = {}
+ for path in treescan.ScanTreeForJsFiles('.'):
+ prefixed_path = _NormalizePathSeparators(os.path.join(prefix, path))
+ path_to_source[prefixed_path] = source.Source(source.GetFileContents(path))
+
+ os.chdir(start_wd)
+
+ return path_to_source
+
+
+def _GetPair(s):
+ """Return a string as a shell-parsed tuple. Two values expected."""
+ try:
+ # shlex uses '\' as an escape character, so they must be escaped.
+ s = s.replace('\\', '\\\\')
+ first, second = shlex.split(s)
+ return (first, second)
+ except:
+ raise Exception('Unable to parse input line as a pair: %s' % s)
+
+
+def main():
+ """CLI frontend to MakeDepsFile."""
+ logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
+ level=logging.INFO)
+ options, args = _GetOptionsParser().parse_args()
+
+ path_to_source = {}
+
+ # Roots without prefixes
+ for root in options.roots:
+ path_to_source.update(_GetRelativePathToSourceDict(root))
+
+ # Roots with prefixes
+ for root_and_prefix in options.roots_with_prefix:
+ root, prefix = _GetPair(root_and_prefix)
+ path_to_source.update(_GetRelativePathToSourceDict(root, prefix=prefix))
+
+ # Source paths
+ for path in args:
+ path_to_source[path] = source.Source(source.GetFileContents(path))
+
+ # Source paths with alternate deps paths
+ for path_with_depspath in options.paths_with_depspath:
+ srcpath, depspath = _GetPair(path_with_depspath)
+ path_to_source[depspath] = source.Source(source.GetFileContents(srcpath))
+
+ # Make our output pipe.
+ if options.output_file:
+ out = open(options.output_file, 'w')
+ else:
+ out = sys.stdout
+
+ out.write('// This file was autogenerated by %s.\n' % sys.argv[0])
+ out.write('// Please do not edit.\n')
+
+ out.write(MakeDepsFile(path_to_source))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/jscompiler.py b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/jscompiler.py
new file mode 100644
index 0000000000..cc6eb55f9e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/jscompiler.py
@@ -0,0 +1,135 @@
+# 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.
+
+"""Utility to use the Closure Compiler CLI from Python."""
+
+
+import logging
+import os
+import re
+import subprocess
+
+
+# Pulls just the major and minor version numbers from the first line of
+# 'java -version'. Versions are in the format of [0-9]+\.[0-9]+\..* See:
+# http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
+_VERSION_REGEX = re.compile(r'"([0-9]+)\.([0-9]+)')
+
+
+class JsCompilerError(Exception):
+ """Raised if there's an error in calling the compiler."""
+ pass
+
+
+def _GetJavaVersionString():
+ """Get the version string from the Java VM."""
+ return subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)
+
+
+def _ParseJavaVersion(version_string):
+ """Returns a 2-tuple for the current version of Java installed.
+
+ Args:
+ version_string: String of the Java version (e.g. '1.7.2-ea').
+
+ Returns:
+ The major and minor versions, as a 2-tuple (e.g. (1, 7)).
+ """
+ match = _VERSION_REGEX.search(version_string)
+ if match:
+ version = tuple(int(x, 10) for x in match.groups())
+ assert len(version) == 2
+ return version
+
+
+def _JavaSupports32BitMode():
+ """Determines whether the JVM supports 32-bit mode on the platform."""
+ # Suppresses process output to stderr and stdout from showing up in the
+ # console as we're only trying to determine 32-bit JVM support.
+ supported = False
+ try:
+ devnull = open(os.devnull, 'wb')
+ return subprocess.call(
+ ['java', '-d32', '-version'], stdout=devnull, stderr=devnull) == 0
+ except IOError:
+ pass
+ else:
+ devnull.close()
+ return supported
+
+
+def _GetJsCompilerArgs(compiler_jar_path, java_version, source_paths,
+ jvm_flags, compiler_flags):
+ """Assembles arguments for call to JsCompiler."""
+
+ if java_version < (1, 7):
+ raise JsCompilerError('Closure Compiler requires Java 1.7 or higher. '
+ 'Please visit http://www.java.com/getjava')
+
+ args = ['java']
+
+ # Add JVM flags we believe will produce the best performance. See
+ # https://groups.google.com/forum/#!topic/closure-library-discuss/7w_O9-vzlj4
+
+ # Attempt 32-bit mode if available (Java 7 on Mac OS X does not support 32-bit
+ # mode, for example).
+ if _JavaSupports32BitMode():
+ args += ['-d32']
+
+ # Prefer the "client" VM.
+ args += ['-client']
+
+ # Add JVM flags, if any
+ if jvm_flags:
+ args += jvm_flags
+
+ # Add the application JAR.
+ args += ['-jar', compiler_jar_path]
+
+ for path in source_paths:
+ args += ['--js', path]
+
+ # Add compiler flags, if any.
+ if compiler_flags:
+ args += compiler_flags
+
+ return args
+
+
+def Compile(compiler_jar_path, source_paths,
+ jvm_flags=None,
+ compiler_flags=None):
+ """Prepares command-line call to Closure Compiler.
+
+ Args:
+ compiler_jar_path: Path to the Closure compiler .jar file.
+ source_paths: Source paths to build, in order.
+ jvm_flags: A list of additional flags to pass on to JVM.
+ compiler_flags: A list of additional flags to pass on to Closure Compiler.
+
+ Returns:
+ The compiled source, as a string, or None if compilation failed.
+ """
+
+ java_version = _ParseJavaVersion(_GetJavaVersionString())
+
+ args = _GetJsCompilerArgs(
+ compiler_jar_path, java_version, source_paths, jvm_flags, compiler_flags)
+
+ logging.info('Compiling with the following command: %s', ' '.join(args))
+
+ try:
+ return subprocess.check_output(args)
+ except subprocess.CalledProcessError:
+ raise JsCompilerError('JavaScript compilation failed.')
diff --git a/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/source.py b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/source.py
new file mode 100644
index 0000000000..be5e0d8ad6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/source.py
@@ -0,0 +1,127 @@
+# Copyright 2009 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.
+
+
+"""Scans a source JS file for its provided and required namespaces.
+
+Simple class to scan a JavaScript file and express its dependencies.
+"""
+
+__author__ = 'nnaze@google.com'
+
+
+import re
+
+_BASE_REGEX_STRING = r'^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
+_MODULE_REGEX = re.compile(_BASE_REGEX_STRING % 'module')
+_PROVIDE_REGEX = re.compile(_BASE_REGEX_STRING % 'provide')
+
+_REQUIRE_REGEX_STRING = (r'^\s*(?:(?:var|let|const)\s+[a-zA-Z_$][a-zA-Z0-9$_]*'
+ r'\s*=\s*)?goog\.require\(\s*[\'"](.+)[\'"]\s*\)')
+_REQUIRES_REGEX = re.compile(_REQUIRE_REGEX_STRING)
+
+
+class Source(object):
+ """Scans a JavaScript source for its provided and required namespaces."""
+
+ # Matches a "/* ... */" comment.
+ # Note: We can't definitively distinguish a "/*" in a string literal without a
+ # state machine tokenizer. We'll assume that a line starting with whitespace
+ # and "/*" is a comment.
+ _COMMENT_REGEX = re.compile(
+ r"""
+ ^\s* # Start of a new line and whitespace
+ /\* # Opening "/*"
+ .*? # Non greedy match of any characters (including newlines)
+ \*/ # Closing "*/""",
+ re.MULTILINE | re.DOTALL | re.VERBOSE)
+
+ def __init__(self, source):
+ """Initialize a source.
+
+ Args:
+ source: str, The JavaScript source.
+ """
+
+ self.provides = set()
+ self.requires = set()
+ self.is_goog_module = False
+
+ self._source = source
+ self._ScanSource()
+
+ def GetSource(self):
+ """Get the source as a string."""
+ return self._source
+
+ @classmethod
+ def _StripComments(cls, source):
+ return cls._COMMENT_REGEX.sub('', source)
+
+ @classmethod
+ def _HasProvideGoogFlag(cls, source):
+ """Determines whether the @provideGoog flag is in a comment."""
+ for comment_content in cls._COMMENT_REGEX.findall(source):
+ if '@provideGoog' in comment_content:
+ return True
+
+ return False
+
+ def _ScanSource(self):
+ """Fill in provides and requires by scanning the source."""
+
+ stripped_source = self._StripComments(self.GetSource())
+
+ source_lines = stripped_source.splitlines()
+ for line in source_lines:
+ match = _PROVIDE_REGEX.match(line)
+ if match:
+ self.provides.add(match.group(1))
+ match = _MODULE_REGEX.match(line)
+ if match:
+ self.provides.add(match.group(1))
+ self.is_goog_module = True
+ match = _REQUIRES_REGEX.match(line)
+ if match:
+ self.requires.add(match.group(1))
+
+ # Closure's base file implicitly provides 'goog'.
+ # This is indicated with the @provideGoog flag.
+ if self._HasProvideGoogFlag(self.GetSource()):
+
+ if len(self.provides) or len(self.requires):
+ raise Exception(
+ 'Base file should not provide or require namespaces.')
+
+ self.provides.add('goog')
+
+
+def GetFileContents(path):
+ """Get a file's contents as a string.
+
+ Args:
+ path: str, Path to file.
+
+ Returns:
+ str, Contents of file.
+
+ Raises:
+ IOError: An error occurred opening or reading the file.
+
+ """
+ fileobj = open(path)
+ try:
+ return fileobj.read()
+ finally:
+ fileobj.close()
diff --git a/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/treescan.py b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/treescan.py
new file mode 100644
index 0000000000..6694593aab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/treescan.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+#
+# 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.
+
+
+"""Shared utility functions for scanning directory trees."""
+
+import os
+import re
+
+
+__author__ = 'nnaze@google.com (Nathan Naze)'
+
+
+# Matches a .js file path.
+_JS_FILE_REGEX = re.compile(r'^.+\.js$')
+
+
+def ScanTreeForJsFiles(root):
+ """Scans a directory tree for JavaScript files.
+
+ Args:
+ root: str, Path to a root directory.
+
+ Returns:
+ An iterable of paths to JS files, relative to cwd.
+ """
+ return ScanTree(root, path_filter=_JS_FILE_REGEX)
+
+
+def ScanTree(root, path_filter=None, ignore_hidden=True):
+ """Scans a directory tree for files.
+
+ Args:
+ root: str, Path to a root directory.
+ path_filter: A regular expression filter. If set, only paths matching
+ the path_filter are returned.
+ ignore_hidden: If True, do not follow or return hidden directories or files
+ (those starting with a '.' character).
+
+ Yields:
+ A string path to files, relative to cwd.
+ """
+
+ def OnError(os_error):
+ raise os_error
+
+ for dirpath, dirnames, filenames in os.walk(root, onerror=OnError):
+ # os.walk allows us to modify dirnames to prevent decent into particular
+ # directories. Avoid hidden directories.
+ for dirname in dirnames:
+ if ignore_hidden and dirname.startswith('.'):
+ dirnames.remove(dirname)
+
+ for filename in filenames:
+
+ # nothing that starts with '.'
+ if ignore_hidden and filename.startswith('.'):
+ continue
+
+ fullpath = os.path.join(dirpath, filename)
+
+ if path_filter and not path_filter.match(fullpath):
+ continue
+
+ yield os.path.normpath(fullpath)