Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: third_party/closure_compiler/compile_modules.py

Issue 421253006: Add ChromeCodingConvention.java to Closure Compiler to preserve getInstance() type (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@A_typechecking_about
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 import argparse 6 import argparse
7 import ast 7 import ast
8 from checker import Checker as Checker 8 from checker import Checker as Checker
9 import os 9 import os
10 10
11
12 def get_rel_path_generator(file_path):
13 current_dir = os.getcwd()
14 module_dir = os.path.dirname(file_path)
15
16 if current_dir and module_dir:
17 here_to_module_dir = os.path.relpath(module_dir, current_dir)
18 if here_to_module_dir:
19 return lambda f: os.path.join(here_to_module_dir, f)
20
21 return lambda f: f
22
23
11 class Module(object): 24 class Module(object):
12 def __init__(self, name, sources, depends=[], externs=[]): 25 def __init__(self, name, sources, depends=[], externs=[],
26 expected_output=None):
13 self.name = name 27 self.name = name
14 self.sources = sources 28 self.sources = sources
15 # TODO(dbeam): support depending on other modules/dependency flattening. 29 # TODO(dbeam): support depending on other modules/dependency flattening.
16 self.depends = depends 30 self.depends = depends
17 self.externs = externs 31 self.externs = externs
32 self.expected_output = expected_output
18 33
19 @staticmethod 34 @staticmethod
20 def from_dict(d): 35 def from_dict_and_rel_path_generator(d, rel_path_generator):
21 keys = d.keys() 36 keys = d.keys()
22 37
23 required = ["name", "sources"] 38 required = ["name", "sources"]
24 assert all(r in keys for r in required), "Module missing name or sources" 39 assert all(r in keys for r in required), "Module missing name or sources"
25 40
26 allowed = required + ["depends", "externs"] 41 allowed = required + ["depends", "externs", "expected_output"]
Dan Beam 2014/07/29 18:05:10 this should not be in production code, figure out
Vitaly Pavlenko 2014/07/29 18:53:46 Done.
27 assert all(k in allowed for k in keys), "Module has unknown key" 42 assert all(k in allowed for k in keys), "Module has unknown key"
28 43
29 depends = d["depends"] if "depends" in d else [] 44 depends = d["depends"] if "depends" in d else []
30 externs = d["externs"] if "externs" in d else [] 45 externs = d["externs"] if "externs" in d else []
31 return Module(d["name"], d["sources"], depends=depends, externs=externs) 46
47 sources = map(rel_path_generator, d["sources"])
48 depends = map(rel_path_generator, depends)
49 externs = map(rel_path_generator, externs)
50
51 expected_output = d["expected_output"] if "expected_output" in d else ""
52 return Module(d["name"], sources, depends=depends, externs=externs,
53 expected_output=expected_output)
32 54
33 55
34 # TODO(dbeam): should ModuleParser be internal to ModuleCompiler or should we 56 # TODO(dbeam): should ModuleParser be internal to ModuleCompiler or should we
35 # pass Modules into ModuleCompiler.compile()? Maybe this is fine? 57 # pass Modules into ModuleCompiler.compile()? Maybe this is fine?
36 class ModuleParser(object): 58 class ModuleParser(object):
37 _cache = {} 59 _cache = {}
38 60
39 def __init__(self, verbose=False): 61 def __init__(self, verbose=False):
40 self._verbose = verbose 62 self._verbose = verbose
41 63
42 def parse(self, file_path): 64 def parse(self, file_path):
43 if file_path in self._cache: 65 if file_path in self._cache:
44 print "(INFO) Found module file %s in the cache" % file_path 66 print "(INFO) Found module file %s in the cache" % file_path
45 return self._cache[file_path] 67 return self._cache[file_path]
46 68
69
47 file = open(file_path, "r") 70 file = open(file_path, "r")
48 file_content = file.read() 71 file_content = file.read()
49 data = ast.literal_eval(file_content) 72 data = ast.literal_eval(file_content)
50 file.close() 73 file.close()
51 74
52 if self._verbose: 75 if self._verbose:
53 print "(INFO) Layout: " + os.linesep + file_content + os.linesep 76 print "(INFO) Layout: " + os.linesep + file_content + os.linesep
54 77
55 self._cache[file_path] = [Module.from_dict(m) for m in data] 78 self._cache[file_path] = [Module.from_dict_and_rel_path_generator(
79 m, get_rel_path_generator(file_path)) for m in data]
56 return self._cache[file_path] 80 return self._cache[file_path]
57 81
58 82
59 class ModuleCompiler(object): 83 class ModuleCompiler(object):
60 _checker = None
61 _parser = None
62 84
63 def __init__(self, verbose=False): 85 def __init__(self, verbose=False, test_expected_output=False):
64 self._verbose = verbose 86 self._verbose = verbose
87 self._parser = ModuleParser(verbose=self._verbose)
88 self._checker = Checker(verbose=self._verbose,
89 return_output=test_expected_output)
90 self._test_expected_output = test_expected_output
65 91
66 def _debug(self, msg, prefix="(INFO) ", suffix=""): 92 def _debug(self, msg, prefix="(INFO) ", suffix=""):
67 if self._verbose: 93 if self._verbose:
68 print prefix + msg.strip() + suffix 94 print prefix + msg.strip() + suffix
69 95
70 def compile(self, module_file): 96 def compile_source(self, source_path, module):
97 output = self._checker.check(source_path,
98 depends=module.depends,
99 externs=module.externs)
100
101 if self._test_expected_output:
102 return output
103
104 def get_modules(self, module_file):
105 return self._parser.parse(module_file)
106
107 def compile_module_file(self, module_file):
71 self._debug("MODULE FILE: " + module_file, prefix="") 108 self._debug("MODULE FILE: " + module_file, prefix="")
72 109
73 # NOTE: It's possible but unlikely that |_checker| or |_parser|'s verbosity 110 modules = self.get_modules(module_file)
74 # isn't the same as |self._verbose| due to this class being called with
75 # verbose=False then verbose=True in the same program.
76 self._parser = self._parser or ModuleParser(verbose=self._verbose)
77 self._checker = self._checker or Checker(verbose=self._verbose)
78
79 current_dir = os.getcwd()
80 module_dir = os.path.dirname(module_file)
81 rel_path = lambda f: f
82
83 if current_dir and module_dir:
84 here_to_module_dir = os.path.relpath(module_dir, current_dir)
85 if here_to_module_dir:
86 rel_path = lambda f: os.path.join(here_to_module_dir, f)
87
88 modules = self._parser.parse(module_file)
89 111
90 for m in modules: 112 for m in modules:
91 self._debug("MODULE: " + m.name, prefix="", suffix=os.linesep) 113 self._debug("MODULE: " + m.name, prefix="", suffix=os.linesep)
92 114
93 for s in m.sources: 115 for s in m.sources:
94 depends = [rel_path(d) for d in m.depends] 116 self.compile_source(s, m)
95 externs = [rel_path(e) for e in m.externs]
96 self._checker.check(rel_path(s), depends=depends, externs=externs)
97 117
98 if s != m.sources[-1]: 118 if s != m.sources[-1]:
99 self._debug(os.linesep, prefix="") 119 self._debug(os.linesep, prefix="")
100 120
101 if m != modules[-1]: 121 if m != modules[-1]:
102 self._debug(os.linesep, prefix="") 122 self._debug(os.linesep, prefix="")
103 123
104 124
105 def main(opts): 125 def main(opts):
106 module_compiler = ModuleCompiler(verbose=opts.verbose) 126 module_compiler = ModuleCompiler(verbose=opts.verbose)
107 for module_file in opts.module_file: 127 for module_file in opts.module_file:
108 module_compiler.compile(module_file) 128 module_compiler.compile_module_file(module_file)
109 129
110 130
111 if __name__ == "__main__": 131 if __name__ == "__main__":
112 parser = argparse.ArgumentParser( 132 parser = argparse.ArgumentParser(
113 description="Typecheck JavaScript using Closure compiler") 133 description="Typecheck JavaScript using Closure compiler")
114 parser.add_argument("-v", "--verbose", action="store_true", 134 parser.add_argument("-v", "--verbose", action="store_true",
115 help="Show more information as this script runs") 135 help="Show more information as this script runs")
116 parser.add_argument("module_file", nargs=argparse.ONE_OR_MORE, 136 parser.add_argument("module_file", nargs=argparse.ONE_OR_MORE,
117 help="Path to a modules file to check") 137 help="Path to a modules file to check")
118 main(parser.parse_args()) 138 main(parser.parse_args())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698