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

Side by Side Diff: tools/testing/frogpad/frogpad.py

Issue 9422027: frogpad now uses vm to bootstrap instead of node (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: small fixes Created 8 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a 4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file. 5 # BSD-style license that can be found in the LICENSE file.
6 # 6 #
7 7
8 """ 8 """
9 Generates an html file (frogpad.html) that can be used to execute the frog 9 Generates an html file (frogpad.html) that can be used to execute the frog
10 compiler in a web browser or DumpRenderTree, 10 compiler in a web browser or DumpRenderTree,
11 11
12 The generated frogpad.html will contain: 12 The generated frogpad.html will contain:
13 13
14 1. all the dart files that compose a dart program 14 1. all the dart files that compose a dart program
15 2. all the dart files of dart:core and other standard dart libraries 15 2. all the dart files of dart:core and other standard dart libraries
16 3. frogpad.dart (compiled to javascript) 16 3. frogpad.dart (compiled to javascript)
17 17
18 The contents of each dart file is placed in a separate <script> tag. 18 The contents of each dart file is placed in a separate <script> tag.
19 19
20 When the html page is loaded by a browser, the frog compiler will be invoked 20 When the html page is loaded by a browser, the frog compiler will be invoked
21 and the user's dart program will be compiled to javascript. The generated 21 and the user's dart program will be compiled to javascript. The generated
22 javascript will be placed in the <pre> element with id "output". 22 javascript will be placed in the <pre> element with id "output".
23 23
24 If using DumpRenderTree, the output javascript can be obtained by dumping 24 If using DumpRenderTree, the output javascript can be obtained by dumping
25 the page as text and looking for the contents of the output textarea. 25 the page as text and looking for the contents of the output textarea.
26 """ 26 """
27 27
28 import logging
28 import optparse 29 import optparse
29 import os.path 30 import os.path
30 import re 31 import re
32 import subprocess
31 import sys 33 import sys
32 34
35 class FileNotFoundException(Exception):
36 def __init__(self, file_name):
37 self._name = file_name
38
39 def __str__(self):
40 return self._name
41
42
43 class CommandFailedException(Exception):
44 def __init__(self, message):
45 self._message = message
46
47 def GetMessage(self):
48 return self._message
49
50
51 # This file is produced by compiling frogpad.dart to javascript. To do this
52 # we run frogc.dart on the dart vm.
53 #
54 # Note, we use ".frogc.js" as the extension (instead of simply ".js"),
55 # because this file is generated by frogc and not by frogpad.
56 #
57 # (For testing, it's useful to be able to distinguish files that are generated
58 # by frogc from files that are generated by frogpad.)
59 #
60 FROGPAD_JS = "frogpad.dart.frogc.js"
61
33 # Template for the html page we're going to generate. 62 # Template for the html page we're going to generate.
34 HTML = """<html> 63 HTML = """<html>
35 <head> 64 <head>
36 <style type="text/css"> 65 <style type="text/css">
37 textarea { 66 textarea {
38 width: 100%; 67 width: 100%;
39 height: 200px; 68 height: 200px;
40 } 69 }
41 .label { 70 .label {
42 margin-top: 5px; 71 margin-top: 5px;
(...skipping 12 matching lines...) Expand all
55 <body> 84 <body>
56 <h1>Frogpad</h1> 85 <h1>Frogpad</h1>
57 <div class="label">Input:</div> 86 <div class="label">Input:</div>
58 <textarea id="input"></textarea> 87 <textarea id="input"></textarea>
59 <div class="label">Compiler Messages:</div> 88 <div class="label">Compiler Messages:</div>
60 <pre id="warnings"></pre> 89 <pre id="warnings"></pre>
61 <div class="label">Timing:</div> 90 <div class="label">Timing:</div>
62 <pre id="timing"></pre> 91 <pre id="timing"></pre>
63 <div class="label">Output:</div> 92 <div class="label">Output:</div>
64 <pre id="output"></pre> 93 <pre id="output"></pre>
65 <script type="text/javascript" src="frogpad.dart.js" ></script> 94 <script type="text/javascript" src={{FROGPAD_JS}} ></script>
66 </body> 95 </body>
67 </html> 96 </html>
68 """ 97 """
69 98
70 # We use "application/inert" here to make the browser ignore the 99 # We use "application/inert" here to make the browser ignore the
71 # these script tags. (frogpad.dart will fish out the contents as needed.) 100 # these script tags. (frogpad.dart will fish out the contents as needed.)
72 # 101 #
73 SCRIPT_TAG = """<script type="application/inert" id="{{id}}"> 102 SCRIPT_TAG = """<script type="application/inert" id="{{id}}">
74 {{contents}} 103 {{contents}}
75 </script> 104 </script>
(...skipping 17 matching lines...) Expand all
93 "json": "../lib/json/json_frog.dart" 122 "json": "../lib/json/json_frog.dart"
94 } 123 }
95 124
96 125
97 class Pad(object): 126 class Pad(object):
98 """ 127 """
99 Accumulates all source files that are needed to compile a dart program, 128 Accumulates all source files that are needed to compile a dart program,
100 and places them in <script> tags on an html page. 129 and places them in <script> tags on an html page.
101 """ 130 """
102 131
103 def __init__(self, frog_dir, main_file): 132 def __init__(self, argv):
133 parser = optparse.OptionParser()
134 parser.add_option("-r", "--rebuild", action="store_true",
135 help="forces rebuild of frogpad_js")
136 (options, args) = parser.parse_args(argv)
137
138 if len(args) < 2:
139 usage()
140
141 self.main_file = os.path.abspath(args[1])
142
143 # directory of this script
144 self.frogpad_dir = os.path.abspath(os.path.dirname(argv[0]))
145
146 # root of dart source repo
147 self.dart_dir = os.path.dirname(os.path.dirname(os.path.dirname(
148 self.frogpad_dir)))
149
104 # directory of frog compiler source code 150 # directory of frog compiler source code
105 self.frog_dir = frog_dir 151 self.frog_dir = os.path.join(self.dart_dir, "frog")
106 152
107 # which .dart file to compile 153 logging.debug("dartdir_dir: '%s'" % self.dart_dir)
108 self.main_file = main_file 154 logging.debug("frog_dir: '%s'" % self.frog_dir)
155 logging.debug("frogpad_dir: '%s'" % self.frogpad_dir)
156
157 # name of frogpad_js file
158 self.frogpad_js = os.path.join(self.frogpad_dir, FROGPAD_JS)
159
160 html_file = self.main_file + ".frogpad.html"
109 161
110 # map from file name to File object (contains entries for all corelib 162 # map from file name to File object (contains entries for all corelib
111 # and all other dart files needed to compile main_file) 163 # and all other dart files needed to compile main_file)
112 self.name_to_file = {} 164 self.name_to_file = {}
113 165
114 # map from script tag id to File object 166 # map from script tag id to File object
115 self.id_to_file = {} 167 self.id_to_file = {}
116 168
169 if not os.path.exists(self.frogpad_js):
170 options.rebuild = True
171
172 if options.rebuild:
173 self.build_frogpad_js()
174
117 self.load_libraries() 175 self.load_libraries()
118 self.load_file(self.main_file) 176 self.load_file(self.main_file)
119 177
178 html = self.generate_html()
179
180 with open(html_file, "w") as output:
181 output.write(html)
182 logging.info("generated '%s' (%d bytes)" % (html_file, len(html)))
183
184
185 def build_frogpad_js(self):
186 dart_vm = os.path.join(self.dart_dir, "out/Release_ia32/dart")
187 check_exists(dart_vm)
188
189 frogc_dart = os.path.join(self.frog_dir, "frogc.dart")
190 frogpad_dart = os.path.join(self.frogpad_dir, "frogpad.dart")
191 check_exists(frogc_dart)
192 check_exists(frogpad_dart)
193
194 args = []
195 args.append(dart_vm)
196
197 # command line arguments for the dart vm
198
199 # We leave out --enable_type_checks here for speed.
200 # args.append("--enable_type_checks")
201
202 args.append("--enable_asserts")
203
204 # The dart program we're going to run on the dart vm.
205 args.append(frogc_dart)
206
207 # Command line arguments for frogc.dart
208 args.append("--libdir=%s/lib" % self.frog_dir)
209 args.append("--compile-only")
210 args.append("--enable_type_checks")
211 args.append("--enable_asserts")
212 args.append("--out=%s" % self.frogpad_js)
213
214 # The dart program that we want frogc.dart to compile.
215 args.append(frogpad_dart)
216
217 run_command(args)
218 check_exists(self.frogpad_js)
219
120 def generate_html(self): 220 def generate_html(self):
121 tags = [] 221 tags = []
122 for f in self.id_to_file.values(): 222 for f in self.id_to_file.values():
123 tags.append(self._create_tag(f.id, f.contents)) 223 tags.append(self._create_tag(f.id, f.contents))
124 tags.append(self._create_tag(MAIN_ID, self.main_file)) 224 tags.append(self._create_tag(MAIN_ID, self.main_file))
125 html = HTML.replace("{{script_tags}}", "".join(tags)) 225 html = HTML.replace("{{script_tags}}", "".join(tags))
226 html = html.replace("{{FROGPAD_JS}}", FROGPAD_JS)
126 return html 227 return html
127 228
128 @staticmethod 229 @staticmethod
129 def _create_tag(id, contents): 230 def _create_tag(id, contents):
130 s = SCRIPT_TAG 231 s = SCRIPT_TAG
131 s = s.replace("{{id}}", id) 232 s = s.replace("{{id}}", id)
132 s = s.replace("{{contents}}", contents) 233 s = s.replace("{{contents}}", contents)
133 return s 234 return s
134 235
135 def dart_library(self, name): 236 def dart_library(self, name):
136 path = DART_LIBRARIES[name] 237 path = DART_LIBRARIES[name]
137 if not path: 238 if not path:
138 raise Exception("unrecognized 'dart:%s'", name) 239 raise Exception("unrecognized 'dart:%s'", name)
139 return os.path.join(self.frog_dir, path) 240 return os.path.join(self.frog_dir, path)
140 241
141 def load_libraries(self): 242 def load_libraries(self):
142 for name in DART_LIBRARIES: 243 for name in DART_LIBRARIES:
143 self.load_file(self.dart_library(name)) 244 self.load_file(self.dart_library(name))
144 245
145 def load_file(self, name): 246 def load_file(self, name):
247 logging.debug("load_file " + name)
146 name = os.path.abspath(name) 248 name = os.path.abspath(name)
147 if name in self.name_to_file: 249 if name in self.name_to_file:
148 print "already loaded %s, skipping" % name 250 logging.debug("already loaded %s, skipping" % name)
149 return 251 return
150 f = File(self, name) 252 f = File(self, name)
151 self.name_to_file[f.name] = f 253 self.name_to_file[f.name] = f
152 if f.id in self.id_to_file: 254 if f.id in self.id_to_file:
153 raise Exception("ambiguous id '%s'" % f.id) 255 raise Exception("ambiguous id '%s'" % f.id)
154 self.id_to_file[f.id] = f 256 self.id_to_file[f.id] = f
155 f.directives() 257 f.directives()
156 258
157 class File(object): 259 class File(object):
158 def __init__(self, pad, name): 260 def __init__(self, pad, name):
159 self.pad = pad 261 self.pad = pad
160 self.name = name 262 self.name = name
161 self.id = self._make_id() 263 self.id = self._make_id()
162 if not os.path.exists(name): 264 check_exists(name)
163 raise Exception("cannot find file '%s'" % name)
164 with open(self.name, "r") as f: 265 with open(self.name, "r") as f:
165 self.contents = f.read() 266 self.contents = f.read()
166 print "creating File '%s' (%d lines)" % (self.name, len(self.contents)) 267 logging.debug("creating File '%s' (%d lines)" %
268 (self.name, len(self.contents)))
167 269
168 def _make_id(self): 270 def _make_id(self):
169 """ 271 """
170 Generates an id (based on the file name) for the <script> tag that will 272 Generates an id (based on the file name) for the <script> tag that will
171 hold the contents of this file. 273 hold the contents of this file.
172 """ 274 """
173 (dirname, name) = os.path.split(self.name) 275 (dirname, name) = os.path.split(self.name)
174 dirname = os.path.basename(dirname) 276 dirname = os.path.basename(dirname)
175 name = name.replace(".", "_") 277 name = name.replace(".", "_")
176 return dirname + "_" + name 278 return dirname + "_" + name
(...skipping 11 matching lines...) Expand all
188 if not match: 290 if not match:
189 return 291 return
190 url = match.group(2) 292 url = match.group(2)
191 if url.startswith("dart:"): 293 if url.startswith("dart:"):
192 path = self.pad.dart_library(url[len("dart:"):]) 294 path = self.pad.dart_library(url[len("dart:"):])
193 else: 295 else:
194 path = os.path.join(os.path.dirname(self.name), url) 296 path = os.path.join(os.path.dirname(self.name), url)
195 self.pad.load_file(path) 297 self.pad.load_file(path)
196 298
197 299
300 def check_exists(file_name):
301 if not os.path.exists(file_name):
302 raise FileNotFoundException(file_name)
303
304
305 def format_command(args):
306 return ' '.join(args)
307
308
309 def run_command(args):
310 """
311 Args:
312 command: comamnd with arguments to exec
313 """
314
315 command = format_command(args)
316 logging.info("RUNNING " + command)
317 proc = subprocess.Popen(args)
318 exit_code = proc.wait()
319
320 if exit_code:
321 msg = "FAILURE (exit_code=%d): '%s'" % (exit_code, command)
322 logging.error(msg)
323 raise CommandFailedException(msg)
324
325 logging.debug("SUCCEEDED " + command)
326
327
328 def usage():
329 print("""
330 Usage:
331 frogpad.py hello.dart
332 """)
333 sys.exit(1)
334
335
198 def main(argv): 336 def main(argv):
199 parser = optparse.OptionParser() 337 logging.basicConfig(level=logging.INFO)
200 parser.add_option("-o", "--out", dest="out_file") 338 Pad(argv)
201
202 (options, args) = parser.parse_args(argv)
203 main_file = os.path.abspath(args[1])
204
205 script_dir = os.path.abspath(os.path.dirname(argv[0]))
206 frog_dir = os.path.abspath(os.path.join(script_dir, "../../../frog"))
207
208 pad = Pad(frog_dir, main_file)
209 html = pad.generate_html()
210
211 filename = "frogpad.html"
212 with open(filename, "w") as output:
213 output.write(html)
214 print "generated '%s' (%d bytes)" % (filename, len(html))
215 339
216 if __name__ == "__main__": 340 if __name__ == "__main__":
217 sys.exit(main(sys.argv)) 341 sys.exit(main(sys.argv))
218
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698