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

Side by Side Diff: Source/devtools/scripts/compile_frontend.py

Issue 573453004: DevTools: Get rid of frontend_modules.json (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 3 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
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 Google Inc. All rights reserved. 2 # Copyright (c) 2012 Google Inc. All rights reserved.
3 # 3 #
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 12 matching lines...) Expand all
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 import os 30 import os
31 import os.path as path 31 import os.path as path
32 import generate_protocol_externs 32 import generate_protocol_externs
33 import modular_build
33 import re 34 import re
34 import shutil 35 import shutil
35 import subprocess 36 import subprocess
36 import sys 37 import sys
37 import tempfile 38 import tempfile
38 try: 39 try:
39 import simplejson as json 40 import simplejson as json
40 except ImportError: 41 except ImportError:
41 import json 42 import json
42 43
43 scripts_path = path.dirname(path.abspath(__file__)) 44 scripts_path = path.dirname(path.abspath(__file__))
44 devtools_path = path.dirname(scripts_path) 45 devtools_path = path.dirname(scripts_path)
45 inspector_path = path.join(path.dirname(devtools_path), "core", "inspector") 46 inspector_path = path.join(path.dirname(devtools_path), "core", "inspector")
46 devtools_frontend_path = path.join(devtools_path, "front_end") 47 devtools_frontend_path = path.join(devtools_path, "front_end")
47 global_externs_file = path.join(devtools_frontend_path, "externs.js") 48 global_externs_file = path.join(devtools_frontend_path, "externs.js")
48 protocol_externs_file = path.join(devtools_frontend_path, "protocol_externs.js") 49 protocol_externs_file = path.join(devtools_frontend_path, "protocol_externs.js")
49 webgl_rendering_context_idl_path = path.join(path.dirname(devtools_path), "core" , "html", "canvas", "WebGLRenderingContextBase.idl") 50 webgl_rendering_context_idl_path = path.join(path.dirname(devtools_path), "core" , "html", "canvas", "WebGLRenderingContextBase.idl")
50 injected_script_source_name = path.join(inspector_path, "InjectedScriptSource.js ") 51 injected_script_source_name = path.join(inspector_path, "InjectedScriptSource.js ")
51 canvas_injected_script_source_name = path.join(inspector_path, "InjectedScriptCa nvasModuleSource.js") 52 canvas_injected_script_source_name = path.join(inspector_path, "InjectedScriptCa nvasModuleSource.js")
52 closure_compiler_jar = path.join(scripts_path, "closure", "compiler.jar") 53 closure_compiler_jar = path.join(scripts_path, "closure", "compiler.jar")
53 closure_runner_jar = path.join(scripts_path, "compiler-runner", "closure-runner. jar") 54 closure_runner_jar = path.join(scripts_path, "compiler-runner", "closure-runner. jar")
54 jsdoc_validator_jar = path.join(scripts_path, "jsdoc-validator", "jsdoc-validato r.jar") 55 jsdoc_validator_jar = path.join(scripts_path, "jsdoc-validator", "jsdoc-validato r.jar")
55 java_exec = "java -Xms1024m -server -XX:+TieredCompilation" 56 java_exec = "java -Xms1024m -server -XX:+TieredCompilation"
56 57
57 generate_protocol_externs.generate_protocol_externs(protocol_externs_file, path. join(devtools_path, "protocol.json")) 58 generate_protocol_externs.generate_protocol_externs(protocol_externs_file, path. join(devtools_path, "protocol.json"))
58 59
59 jsmodule_name_prefix = "jsmodule_" 60 jsmodule_name_prefix = "jsmodule_"
60 frontend_modules_name = "frontend_modules.json"
61 runtime_module_name = "_runtime" 61 runtime_module_name = "_runtime"
62 module_initializer_name = "_module.js" 62 module_initializer_name = "_module.js"
63 63
64 64
65 def log_error(message): 65 def log_error(message):
66 print "ERROR: " + message 66 print "ERROR: " + message
67 67
68 68
69 def error_excepthook(exctype, value, traceback): 69 def error_excepthook(exctype, value, traceback):
70 print "ERROR:" 70 print "ERROR:"
71 sys.__excepthook__(exctype, value, traceback) 71 sys.__excepthook__(exctype, value, traceback)
72 sys.excepthook = error_excepthook 72 sys.excepthook = error_excepthook
73 73
74 try: 74
75 with open(path.join(scripts_path, frontend_modules_name), "rt") as js_module s_file: 75 loader = modular_build.DescriptorLoader(devtools_frontend_path)
76 modules = json.loads(js_modules_file.read()) 76 descriptors = loader.load_application('devtools.json')
77 except: 77 modules_by_name = descriptors.modules
78 log_error("Failed to read %s" % frontend_modules_name)
79 raise
80 78
81 type_checked_jsdoc_tags_list = ["param", "return", "type", "enum"] 79 type_checked_jsdoc_tags_list = ["param", "return", "type", "enum"]
82 80
83 type_checked_jsdoc_tags_or = "|".join(type_checked_jsdoc_tags_list) 81 type_checked_jsdoc_tags_or = "|".join(type_checked_jsdoc_tags_list)
84 82
85 # Basic regex for invalid JsDoc types: an object type name ([A-Z][A-Za-z0-9.]+[A -Za-z0-9]) not preceded by '!', '?', ':' (this, new), or '.' (object property). 83 # Basic regex for invalid JsDoc types: an object type name ([A-Z][A-Za-z0-9.]+[A -Za-z0-9]) not preceded by '!', '?', ':' (this, new), or '.' (object property).
86 invalid_type_regex = re.compile(r"@(?:" + type_checked_jsdoc_tags_or + r")\s*\{. *(?<![!?:.A-Za-z0-9])([A-Z][A-Za-z0-9.]+[A-Za-z0-9])[^/]*\}") 84 invalid_type_regex = re.compile(r"@(?:" + type_checked_jsdoc_tags_or + r")\s*\{. *(?<![!?:.A-Za-z0-9])([A-Z][A-Za-z0-9.]+[A-Za-z0-9])[^/]*\}")
87 85
88 invalid_type_designator_regex = re.compile(r"@(?:" + type_checked_jsdoc_tags_or + r")\s*.*(?<![{: ])([?!])=?\}") 86 invalid_type_designator_regex = re.compile(r"@(?:" + type_checked_jsdoc_tags_or + r")\s*.*(?<![{: ])([?!])=?\}")
89 87
90 error_warning_regex = re.compile(r"(?:WARNING|ERROR)") 88 error_warning_regex = re.compile(r"(?:WARNING|ERROR)")
91 89
92 errors_found = False 90 errors_found = False
93 91
94 92
95 def run_in_shell(command_line): 93 def run_in_shell(command_line):
96 return subprocess.Popen(command_line, stdout=subprocess.PIPE, stderr=subproc ess.STDOUT, shell=True) 94 return subprocess.Popen(command_line, stdout=subprocess.PIPE, stderr=subproc ess.STDOUT, shell=True)
97 95
98 96
99 def hasErrors(output): 97 def hasErrors(output):
100 return re.search(error_warning_regex, output) != None 98 return re.search(error_warning_regex, output) != None
101 99
102 100
103 def dump_all_checked_files():
104 files = {}
105 for module in modules:
106 for source in module["sources"]:
107 files[path.join(devtools_frontend_path, source)] = True
108 return files.keys()
109
110
111 def verify_jsdoc_extra(additional_files): 101 def verify_jsdoc_extra(additional_files):
112 return run_in_shell("%s -jar %s %s" % (java_exec, jsdoc_validator_jar, " ".j oin(dump_all_checked_files() + additional_files))) 102 return run_in_shell("%s -jar %s %s" % (java_exec, jsdoc_validator_jar, " ".j oin(descriptors.all_compiled_files() + additional_files)))
113 103
114 104
115 def verify_jsdoc(additional_files): 105 def verify_jsdoc(additional_files):
116 def file_list(): 106 def file_list():
117 result = [] 107 return descriptors.all_compiled_files() + additional_files
118 for module in modules:
119 for file_name in module["sources"]:
120 result.append(path.join(devtools_frontend_path, file_name))
121 for file in additional_files:
122 result.append(file)
123 return result
124 108
125 errors_found = False 109 errors_found = False
126 for full_file_name in file_list(): 110 for full_file_name in file_list():
127 lineIndex = 0 111 lineIndex = 0
128 with open(full_file_name, "r") as sourceFile: 112 with open(full_file_name, "r") as sourceFile:
129 for line in sourceFile: 113 for line in sourceFile:
130 line = line.rstrip() 114 line = line.rstrip()
131 lineIndex += 1 115 lineIndex += 1
132 if not line: 116 if not line:
133 continue 117 continue
(...skipping 28 matching lines...) Expand all
162 sys.exit(1) 146 sys.exit(1)
163 print "Java executable: " + re.sub(r"\n$", "", javaPath) 147 print "Java executable: " + re.sub(r"\n$", "", javaPath)
164 148
165 check_java_path() 149 check_java_path()
166 150
167 modules_dir = tempfile.mkdtemp() 151 modules_dir = tempfile.mkdtemp()
168 common_closure_args = " --summary_detail_level 3 --jscomp_error visibility --com pilation_level SIMPLE_OPTIMIZATIONS --warning_level VERBOSE --language_in ECMASC RIPT5 --accept_const_keyword --module_output_path_prefix %s/" % modules_dir 152 common_closure_args = " --summary_detail_level 3 --jscomp_error visibility --com pilation_level SIMPLE_OPTIMIZATIONS --warning_level VERBOSE --language_in ECMASC RIPT5 --accept_const_keyword --module_output_path_prefix %s/" % modules_dir
169 153
170 spawned_compiler_command = "%s -jar %s %s \\\n" % (java_exec, closure_compiler_j ar, common_closure_args) 154 spawned_compiler_command = "%s -jar %s %s \\\n" % (java_exec, closure_compiler_j ar, common_closure_args)
171 155
172 modules_by_name = {}
173 standalone_modules_by_name = {} 156 standalone_modules_by_name = {}
174 dependents_by_module_name = {} 157 dependents_by_module_name = {}
175 158
176 for module in modules: 159 for name in modules_by_name:
177 name = module["name"] 160 module = modules_by_name[name]
178 modules_by_name[name] = module
179 if "standalone" in module: 161 if "standalone" in module:
180 standalone_modules_by_name[name] = module 162 standalone_modules_by_name[name] = module
181 for dep in module["dependencies"]: 163 for dep in module.get("dependencies", []):
182 list = dependents_by_module_name.get(dep) 164 list = dependents_by_module_name.get(dep)
183 if not list: 165 if not list:
184 list = [] 166 list = []
185 dependents_by_module_name[dep] = list 167 dependents_by_module_name[dep] = list
186 list.append(name) 168 list.append(name)
187 169
188 170
189 def verify_standalone_modules(): 171 def verify_standalone_modules():
190 for module in modules: 172 for name in modules_by_name:
191 for dependency in module["dependencies"]: 173 for dependency in modules_by_name[name].get("dependencies", []):
192 if dependency in standalone_modules_by_name: 174 if dependency in standalone_modules_by_name:
193 log_error("Standalone module '%s' may not be present among the d ependencies of '%s'" % (dependency, module["name"])) 175 log_error("Standalone module '%s' may not be present among the d ependencies of '%s'" % (dependency, name))
194 errors_found = True 176 errors_found = True
195 177
196 verify_standalone_modules() 178 verify_standalone_modules()
197 179
198 180
199 def check_duplicate_files(): 181 def check_duplicate_files():
200 182
201 def check_module(module, seen_files, seen_modules): 183 def check_module(module, seen_files, seen_modules):
202 name = module["name"] 184 name = module["name"]
203 seen_modules[name] = True 185 seen_modules[name] = True
204 for dep_name in module["dependencies"]: 186 for dep_name in module.get("dependencies", []):
205 if not dep_name in seen_modules: 187 if not dep_name in seen_modules:
206 check_module(modules_by_name[dep_name], seen_files, seen_modules ) 188 check_module(modules_by_name[dep_name], seen_files, seen_modules )
207 for source in module["sources"]: 189 for source in module.get("scripts", []):
208 referencing_module = seen_files.get(source) 190 referencing_module = seen_files.get(source)
209 if referencing_module: 191 if referencing_module:
210 log_error("Duplicate use of %s in '%s' (previously seen in '%s') " % (source, name, referencing_module)) 192 log_error("Duplicate use of %s in '%s' (previously seen in '%s') " % (source, name, referencing_module))
211 seen_files[source] = name 193 seen_files[source] = name
212 194
213 for module_name in standalone_modules_by_name: 195 for module_name in standalone_modules_by_name:
214 check_module(standalone_modules_by_name[module_name], {}, {}) 196 check_module(standalone_modules_by_name[module_name], {}, {})
215 197
216 print "Checking duplicate files across modules..." 198 print "Checking duplicate files across modules..."
217 check_duplicate_files() 199 check_duplicate_files()
218 200
219 201
220 def module_arg(module_name): 202 def module_arg(module_name):
221 return " --module " + jsmodule_name_prefix + module_name 203 return " --module " + jsmodule_name_prefix + module_name
222 204
223 205
224 def dump_module(name, recursively, processed_modules): 206 def dump_module(name, recursively, processed_modules):
225 if name in processed_modules: 207 if name in processed_modules:
226 return "" 208 return ""
227 processed_modules[name] = True 209 processed_modules[name] = True
228 module = modules_by_name[name] 210 module = modules_by_name[name]
211 skipped_scripts = set(module.get("skip_compilation", []))
212
213 def filter_scripts():
214 result = []
215 for script in module.get("scripts", []):
216 if script in skipped_scripts:
217 continue
218 result.append(script)
219 return result
220
229 command = "" 221 command = ""
230 if recursively: 222 if recursively:
231 for dependency in module["dependencies"]: 223 for dependency in module.get("dependencies", []):
232 command += dump_module(dependency, recursively, processed_modules) 224 command += dump_module(dependency, recursively, processed_modules)
233 command += module_arg(module["name"]) + ":" 225 command += module_arg(name) + ":"
234 command += str(len(module["sources"])) 226 filtered_scripts = filter_scripts()
227 command += str(len(filtered_scripts))
235 firstDependency = True 228 firstDependency = True
236 for dependency in module["dependencies"] + [runtime_module_name]: 229 for dependency in module.get("dependencies", []) + [runtime_module_name]:
237 if firstDependency: 230 if firstDependency:
238 command += ":" 231 command += ":"
239 else: 232 else:
240 command += "," 233 command += ","
241 firstDependency = False 234 firstDependency = False
242 command += jsmodule_name_prefix + dependency 235 command += jsmodule_name_prefix + dependency
243 for script in module["sources"]: 236 for script in filtered_scripts:
244 command += " --js " + path.join(devtools_frontend_path, script) 237 command += " --js " + path.join(devtools_frontend_path, name, script)
245 return command 238 return command
246 239
247 print "Compiling frontend..." 240 print "Compiling frontend..."
248 241
249 compiler_args_file = tempfile.NamedTemporaryFile(mode='wt', delete=False) 242 compiler_args_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
250 closure_runner_command = "%s -jar %s --compiler-args-file %s" % (java_exec, clos ure_runner_jar, compiler_args_file.name) 243 try:
244 closure_runner_command = "%s -jar %s --compiler-args-file %s" % (java_exec, closure_runner_jar, compiler_args_file.name)
245
246 for name in descriptors.sorted_modules():
247 closure_args = common_closure_args
248 closure_args += " --externs " + global_externs_file
249 closure_args += " --externs " + protocol_externs_file
250 runtime_module = module_arg(runtime_module_name) + ":1 --js " + path.joi n(devtools_frontend_path, "Runtime.js")
251 closure_args += runtime_module + dump_module(name, True, {})
252 compiler_args_file.write("%s %s\n" % (name, closure_args))
253 finally:
254 compiler_args_file.close()
251 255
252 for module in modules:
253 closure_args = common_closure_args
254 closure_args += " --externs " + global_externs_file
255 closure_args += " --externs " + protocol_externs_file
256 runtime_module = module_arg(runtime_module_name) + ":1 --js " + path.join(de vtools_frontend_path, "Runtime.js")
257 closure_args += runtime_module + dump_module(module["name"], True, {})
258 compiler_args_file.write("%s %s\n" % (module["name"], closure_args))
259
260 compiler_args_file.close()
261 modular_compiler_proc = run_in_shell(closure_runner_command) 256 modular_compiler_proc = run_in_shell(closure_runner_command)
262 257
263 258
264 def unclosure_injected_script(sourceFileName, outFileName): 259 def unclosure_injected_script(sourceFileName, outFileName):
265 with open(sourceFileName, "r") as sourceFile: 260 with open(sourceFileName, "r") as sourceFile:
266 source = sourceFile.read() 261 source = sourceFile.read()
267 262
268 def replace_function(matchobj): 263 def replace_function(matchobj):
269 return re.sub(r"@param", "param", matchobj.group(1) or "") + "\n//" + ma tchobj.group(2) 264 return re.sub(r"@param", "param", matchobj.group(1) or "") + "\n//" + ma tchobj.group(2)
270 265
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 errors_found |= hasErrors(validateInjectedScriptOut) 377 errors_found |= hasErrors(validateInjectedScriptOut)
383 378
384 if errors_found: 379 if errors_found:
385 print "ERRORS DETECTED" 380 print "ERRORS DETECTED"
386 381
387 os.remove(injectedScriptSourceTmpFile) 382 os.remove(injectedScriptSourceTmpFile)
388 os.remove(injectedScriptCanvasModuleSourceTmpFile) 383 os.remove(injectedScriptCanvasModuleSourceTmpFile)
389 os.remove(compiler_args_file.name) 384 os.remove(compiler_args_file.name)
390 os.remove(protocol_externs_file) 385 os.remove(protocol_externs_file)
391 shutil.rmtree(modules_dir, True) 386 shutil.rmtree(modules_dir, True)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698