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

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

Issue 369643002: Lay groudwork to Closure compile JavaScript (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more compiled Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import os
6 import re
7 import subprocess
8 import sys
9 import tempfile
10
11
12
13 class LineNumber(object):
14 def __init__(self, file, line_number):
15 self.file = file
16 self.line_number = line_number
17
18
19 class LineCount(object):
20 def __init__(self, file, line_count):
21 self.file = file
22 self.line_count = line_count
23
24
25 class Checker(object):
26 _common_closure_args = [
27 "--accept_const_keyword",
28 "--language_in=ECMASCRIPT5",
29 "--summary_detail_level=3",
30 "--warning_level=VERBOSE",
31 "--jscomp_error=accessControls",
32 "--jscomp_error=ambiguousFunctionDecl",
33 "--jscomp_error=checkEventfulObjectDisposal",
arv (Not doing code reviews) 2014/07/16 18:33:02 We do not depend on dispose pattern. It is a bad p
Dan Beam 2014/07/19 02:28:39 Done.
34 "--jscomp_error=checkStructDictInheritance",
35 "--jscomp_error=checkTypes",
36 "--jscomp_error=checkVars",
37 "--jscomp_error=constantProperty",
38 "--jscomp_error=deprecated",
39 "--jscomp_error=duplicateMessage",
arv (Not doing code reviews) 2014/07/16 18:33:02 We do not use the MSG system
Dan Beam 2014/07/19 02:28:39 Done.
40 "--jscomp_error=es3",
arv (Not doing code reviews) 2014/07/16 18:33:02 ?
Dan Beam 2014/07/19 02:28:39 Done.
41 "--jscomp_error=externsValidation",
42 "--jscomp_error=globalThis",
43 "--jscomp_error=invalidCasts",
44 "--jscomp_error=misplacedTypeAnnotation",
45 "--jscomp_error=missingProperties",
46 "--jscomp_error=missingReturn",
47 "--jscomp_error=nonStandardJsDocs",
48 "--jscomp_error=suspiciousCode",
49 "--jscomp_error=undefinedNames",
50 "--jscomp_error=undefinedVars",
51 "--jscomp_error=unknownDefines",
52 "--jscomp_error=uselessCode",
53 "--jscomp_error=visibility",
54 ]
55
56 _found_java = False
57
58 _jar_command = [
59 "java",
60 "-jar",
61 "-Xms1024m",
62 "-server",
63 "-XX:+TieredCompilation"
64 ]
65
66 def __init__(self, verbose=False):
67 self._current_dir = os.path.dirname(__file__)
68 self._compiler_jar = os.path.join(self._current_dir, "lib", "compiler.jar")
69 self._runner_jar = os.path.join(self._current_dir, "runner", "runner.jar")
70 self._temp_files = []
71 self._verbose = verbose
72
73 def _clean_up(self):
74 if not self._temp_files:
75 return
76
77 self._debug("Deleting temporary files: " + ", ".join(self._temp_files))
78 for f in self._temp_files:
79 os.remove(f)
80 self._temp_files = []
81
82 def _debug(self, msg, error=False):
83 if self._verbose:
84 print "(INFO) " + msg
85
86 def _fatal(self, msg):
87 print >> sys.stderr, "(FATAL) " + msg
88 self._clean_up()
89 sys.exit(1)
90
91 def _run_command(self, cmd):
92 cmd_str = " ".join(cmd)
93 self._debug("Running command: " + cmd_str)
94
95 devnull = open(os.devnull, "w")
96 return subprocess.Popen(
97 cmd_str, stdout=devnull, stderr=subprocess.PIPE, shell=True)
98
99 def _check_java_path(self):
100 if self._found_java:
101 return
102
103 proc = self._run_command(["which", "java"])
104 proc.communicate()
105 if proc.returncode == 0:
106 self._found_java = True
107 else:
108 self._fatal("Cannot find java (`which java` => %s)" % proc.returncode)
109
110 def _run_jar(self, jar, args=[]):
111 self._check_java_path()
112 return self._run_command(self._jar_command + [jar] + args)
113
114 def _real_line_number_from_temp_line(self, line_number):
115 line_number = int(line_number)
116
117 total = 0
118 for d in self._dep_lines:
119 if line_number <= total + d.line_count:
120 return LineNumber(d.file, line_number - total)
121 total += d.line_count
122
123 assert line_number <= total + self._line_info.line_count
124 return LineNumber(self._line_info.file, line_number - total)
125
126 def _fix_line_number(self, match):
127 real_file = self._real_line_number_from_temp_line(match.group(1))
128 return "%s:%d" % (real_file.file, real_file.line_number)
129
130 def _fix_up_error(self, error):
131 if " first declared in " in error:
132 # Ignore "Variable x first declared in /same/file".
133 return ""
134
135 file = self._line_info.file
136 line_number = re.search(":(\d+)", error).group(1)
137 if file != self._real_line_number_from_temp_line(line_number).file:
138 # Ignore errors in dependent files.
139 return ""
140
141 source_file = self._temp_files[0]
142 lines_fixed = re.sub("%s:(\d+)" % source_file, self._fix_line_number, error)
143 return lines_fixed.replace(source_file, file)
144
145 def _external_script_output(self, output):
146 contents = (os.linesep + "## ").join("\n".join(output).splitlines())
147 return "## " + contents if contents else ""
148
149 def check(self, file, depends=[], externs=[]):
150 self._debug("FILE: " + file)
151
152 if file.endswith("_externs.js"):
153 self._debug("Skipping externs")
154 return
155
156 temp_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
157 self._temp_files.append(temp_file.name)
158
159 self._dep_lines = []
160
161 for d in depends:
162 dep_contents = open(d, "r").read()
163 self._dep_lines.append(LineCount(d, len(dep_contents.splitlines())))
164 temp_file.write(dep_contents)
165
166 file_contents = open(file, "r").read()
167 self._line_info = LineCount(file, len(file_contents.splitlines()))
168 temp_file.write(file_contents)
169
170 temp_file.close()
171
172 args = ["--js=" + temp_file.name] + ["--externs=" + e for e in externs]
173 args_file_content = " " + " ".join(self._common_closure_args + args)
174 self._debug("Args: " + args_file_content.strip())
175
176 args_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
177 self._temp_files.append(args_file.name)
178
179 self._debug("Args file: " + args_file.name)
180 args_file.write(args_file_content)
181 args_file.close()
182
183 runner_args = ["--compiler-args-file=" + args_file.name]
184 runner_cmd = self._run_jar(self._runner_jar, args=runner_args)
185 (_, stderr) = runner_cmd.communicate()
186
187 errors = stderr.strip().split("\n\n")
188 self._debug("Summary: " + errors.pop())
189
190 output = self._external_script_output(map(self._fix_up_error, errors))
191 if runner_cmd.returncode:
192 self._fatal("Error in: " + file + (os.linesep + output if output else ""))
193 elif output:
194 self._debug("Output: " + output)
195
196 self._clean_up()
197
198 return runner_cmd.returncode == 0
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698