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

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

Issue 958383003: Output closure-compiled JavaScript files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Little bit of clean up Created 5 years, 9 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/python 1 #!/usr/bin/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 """Runs Closure compiler on a JavaScript file to check for errors.""" 6 """Runs Closure compiler on a JavaScript file to check for errors."""
7 7
8 import argparse 8 import argparse
9 import os 9 import os
10 import re 10 import re
(...skipping 26 matching lines...) Expand all
37 "--jscomp_error=missingReturn", 37 "--jscomp_error=missingReturn",
38 "--jscomp_error=nonStandardJsDocs", 38 "--jscomp_error=nonStandardJsDocs",
39 "--jscomp_error=suspiciousCode", 39 "--jscomp_error=suspiciousCode",
40 "--jscomp_error=undefinedNames", 40 "--jscomp_error=undefinedNames",
41 "--jscomp_error=undefinedVars", 41 "--jscomp_error=undefinedVars",
42 "--jscomp_error=unknownDefines", 42 "--jscomp_error=unknownDefines",
43 "--jscomp_error=uselessCode", 43 "--jscomp_error=uselessCode",
44 "--jscomp_error=visibility", 44 "--jscomp_error=visibility",
45 "--language_in=ECMASCRIPT5_STRICT", 45 "--language_in=ECMASCRIPT5_STRICT",
46 "--summary_detail_level=3", 46 "--summary_detail_level=3",
47 '--compilation_level=WHITESPACE_ONLY'
47 ] 48 ]
48 49
49 # These are the extra flags used when compiling in 'strict' mode. 50 # These are the extra flags used when compiling in 'strict' mode.
50 # Flags that are normally disabled are turned on for strict mode. 51 # Flags that are normally disabled are turned on for strict mode.
51 _STRICT_CLOSURE_ARGS = [ 52 _STRICT_CLOSURE_ARGS = [
52 "--jscomp_error=reportUnknownTypes", 53 "--jscomp_error=reportUnknownTypes",
53 "--jscomp_error=duplicate", 54 "--jscomp_error=duplicate",
54 "--jscomp_error=misplacedTypeAnnotation", 55 "--jscomp_error=misplacedTypeAnnotation",
55 ] 56 ]
56 57
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 errors = filter(None, errors) 171 errors = filter(None, errors)
171 contents = "\n## ".join("\n\n".join(errors).splitlines()) 172 contents = "\n## ".join("\n\n".join(errors).splitlines())
172 return "## %s" % contents if contents else "" 173 return "## %s" % contents if contents else ""
173 174
174 def _create_temp_file(self, contents): 175 def _create_temp_file(self, contents):
175 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file: 176 with tempfile.NamedTemporaryFile(mode="wt", delete=False) as tmp_file:
176 self._temp_files.append(tmp_file.name) 177 self._temp_files.append(tmp_file.name)
177 tmp_file.write(contents) 178 tmp_file.write(contents)
178 return tmp_file.name 179 return tmp_file.name
179 180
180 def run_js_check(self, sources, externs=None): 181 def run_js_check(self, sources, externs=None, out_file=None,
182 generate_output=False, create_source_map=False):
181 if not self._check_java_path(): 183 if not self._check_java_path():
182 return 1, "" 184 return 1, ""
183 185
184 args = ["--js=%s" % s for s in sources] 186 args = ["--js=%s" % s for s in sources]
187
188 if generate_output:
189 args += ["--js_output_file=%s" % out_file]
190 if create_source_map:
Dan Beam 2015/03/06 02:57:28 i think we should always create source maps
Theresa 2015/03/06 03:07:18 Done.
191 args += ["--source_map_format=V3"]
192 args += ["--create_source_map=%s.map" % out_file]
193
185 if externs: 194 if externs:
186 args += ["--externs=%s" % e for e in externs] 195 args += ["--externs=%s" % e for e in externs]
187 args_file_content = " %s" % " ".join(self._common_args() + args) 196 args_file_content = " %s" % " ".join(self._common_args() + args)
188 self._debug("Args: %s" % args_file_content.strip()) 197 self._debug("Args: %s" % args_file_content.strip())
189 198
190 args_file = self._create_temp_file(args_file_content) 199 args_file = self._create_temp_file(args_file_content)
191 self._debug("Args file: %s" % args_file) 200 self._debug("Args file: %s" % args_file)
192 201
193 runner_args = ["--compiler-args-file=%s" % args_file] 202 runner_args = ["--compiler-args-file=%s" % args_file]
194 runner_cmd = self._run_jar(self._runner_jar, args=runner_args) 203 runner_cmd = self._run_jar(self._runner_jar, args=runner_args)
195 _, stderr = runner_cmd.communicate() 204 _, stderr = runner_cmd.communicate()
196 205
197 errors = stderr.strip().split("\n\n") 206 errors = stderr.strip().split("\n\n")
198 self._debug("Summary: %s" % errors.pop()) 207 self._debug("Summary: %s" % errors.pop())
199 208
200 self._clean_up() 209 self._clean_up()
201 210
202 return errors, stderr 211 return errors, stderr
203 212
204 def check(self, source_file, depends=None, externs=None): 213 def check(self, source_file, depends=None, externs=None,
214 out_file=None, generate_output=False, create_source_map=False):
205 """Closure compile a file and check for errors. 215 """Closure compile a file and check for errors.
206 216
207 Args: 217 Args:
208 source_file: A file to check. 218 source_file: A file to check.
209 depends: Other files that would be included with a <script> earlier in 219 depends: Other files that would be included with a <script> earlier in
210 the page. 220 the page.
211 externs: @extern files that inform the compiler about custom globals. 221 externs: @extern files that inform the compiler about custom globals.
212 222
213 Returns: 223 Returns:
214 (has_errors, output) A boolean indicating if there were errors and the 224 (has_errors, output) A boolean indicating if there were errors and the
(...skipping 18 matching lines...) Expand all
233 243
234 includes = [rel_path(f) for f in depends + [source_file]] 244 includes = [rel_path(f) for f in depends + [source_file]]
235 contents = ['<include src="%s">' % i for i in includes] 245 contents = ['<include src="%s">' % i for i in includes]
236 meta_file = self._create_temp_file("\n".join(contents)) 246 meta_file = self._create_temp_file("\n".join(contents))
237 self._debug("Meta file: %s" % meta_file) 247 self._debug("Meta file: %s" % meta_file)
238 248
239 self._processor = processor.Processor(meta_file) 249 self._processor = processor.Processor(meta_file)
240 self._expanded_file = self._create_temp_file(self._processor.contents) 250 self._expanded_file = self._create_temp_file(self._processor.contents)
241 self._debug("Expanded file: %s" % self._expanded_file) 251 self._debug("Expanded file: %s" % self._expanded_file)
242 252
243 errors, stderr = self.run_js_check([self._expanded_file], externs) 253 errors, stderr = self.run_js_check([self._expanded_file], externs,
254 out_file, generate_output, create_source_ map)
244 255
245 # Filter out false-positive promise chain errors. 256 # Filter out false-positive promise chain errors.
246 # See https://github.com/google/closure-compiler/issues/715 for details. 257 # See https://github.com/google/closure-compiler/issues/715 for details.
247 errors = self._error_filter.filter(errors); 258 errors = self._error_filter.filter(errors);
248 259
249 output = self._format_errors(map(self._fix_up_error, errors)) 260 output = self._format_errors(map(self._fix_up_error, errors))
250 if errors: 261 if errors:
251 prefix = "\n" if output else "" 262 prefix = "\n" if output else ""
252 self._error("Error in: %s%s%s" % (source_file, prefix, output)) 263 self._error("Error in: %s%s%s" % (source_file, prefix, output))
253 elif output: 264 elif output:
(...skipping 23 matching lines...) Expand all
277 single_file_group = parser.add_mutually_exclusive_group() 288 single_file_group = parser.add_mutually_exclusive_group()
278 single_file_group.add_argument("--single-file", dest="single_file", 289 single_file_group.add_argument("--single-file", dest="single_file",
279 action="store_true", 290 action="store_true",
280 help="Process each source file individually") 291 help="Process each source file individually")
281 single_file_group.add_argument("--no-single-file", dest="single_file", 292 single_file_group.add_argument("--no-single-file", dest="single_file",
282 action="store_false", 293 action="store_false",
283 help="Process all source files as a group") 294 help="Process all source files as a group")
284 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE) 295 parser.add_argument("-d", "--depends", nargs=argparse.ZERO_OR_MORE)
285 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE) 296 parser.add_argument("-e", "--externs", nargs=argparse.ZERO_OR_MORE)
286 parser.add_argument("-o", "--out_file", help="A place to output results") 297 parser.add_argument("-o", "--out_file", help="A place to output results")
298 parser.add_argument("-g", "--generate_output",
299 help="Whether or not an output file should be generated")
300 parser.add_argument("-c", "--configuration_name",
301 help="The build configuration")
287 parser.add_argument("-v", "--verbose", action="store_true", 302 parser.add_argument("-v", "--verbose", action="store_true",
288 help="Show more information as this script runs") 303 help="Show more information as this script runs")
289 parser.add_argument("--strict", action="store_true", 304 parser.add_argument("--strict", action="store_true",
290 help="Enable strict type checking") 305 help="Enable strict type checking")
291 parser.add_argument("--success-stamp", 306 parser.add_argument("--success-stamp",
292 help="Timestamp file to update upon success") 307 help="Timestamp file to update upon success")
293 308
294 parser.set_defaults(single_file=True, strict=False) 309 parser.set_defaults(single_file=True, strict=False)
295 opts = parser.parse_args() 310 opts = parser.parse_args()
296 311
297 depends = opts.depends or [] 312 depends = opts.depends or []
298 externs = opts.externs or set() 313 externs = opts.externs or set()
299 314
315 generate_output = False if (opts.generate_output == '0') else True
316 create_source_map = True
317 if opts.configuration_name == 'Release' or not generate_output:
318 create_source_map = False
319
320 # Clean up intermediate folders that get created by output.py or create the di rs if needed
321 out_dir = os.path.dirname(opts.out_file)
322 if not generate_output:
323 if os.path.exists(out_dir) and os.listdir(out_dir) == []:
324 os.removedirs(out_dir)
325 else:
326 if not os.path.exists(out_dir):
327 os.makedirs(out_dir)
328
300 checker = Checker(verbose=opts.verbose, strict=opts.strict) 329 checker = Checker(verbose=opts.verbose, strict=opts.strict)
301 if opts.single_file: 330 if opts.single_file:
302 for source in opts.sources: 331 for source in opts.sources:
303 depends, externs = build.inputs.resolve_recursive_dependencies( 332 depends, externs = build.inputs.resolve_recursive_dependencies(
304 source, 333 source,
305 depends, 334 depends,
306 externs) 335 externs)
307 has_errors, _ = checker.check(source, depends=depends, externs=externs) 336 has_errors, _ = checker.check(source, depends=depends, externs=externs,
337 out_file=opts.out_file, generate_output=gene rate_output,
338 create_source_map=create_source_map)
308 if has_errors: 339 if has_errors:
309 sys.exit(1) 340 sys.exit(1)
310 341
311 if opts.out_file:
312 out_dir = os.path.dirname(opts.out_file)
313 if not os.path.exists(out_dir):
314 os.makedirs(out_dir)
315 # TODO(dbeam): write compiled file to |opts.out_file|.
316 open(opts.out_file, "w").write("")
317 else: 342 else:
318 has_errors, errors = checker.check_multiple(opts.sources) 343 has_errors, errors = checker.check_multiple(opts.sources)
319 if has_errors: 344 if has_errors:
320 print errors 345 print errors
321 sys.exit(1) 346 sys.exit(1)
322 347
323 if opts.success_stamp: 348 if opts.success_stamp:
324 with open(opts.success_stamp, 'w'): 349 with open(opts.success_stamp, 'w'):
325 os.utime(opts.success_stamp, None) 350 os.utime(opts.success_stamp, None)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698