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

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: fixed arg named 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
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
31 import sys 32 import sys
32 33
34 import command
35
36 class Error(Exception):
37 """Base class for exceptions in this module."""
38 pass
39
40 class FileNotFoundException(Error):
41 def __init__(self, file_name):
42 self._name = file_name
43
44 def __str__(self):
45 return self._name
46
47 # This file is produced by compiling frogpad.dart to javascript. To do this
48 # we run frogc.dart on the dart vm.
49 #
50 # Note, we use ".frogc.js" as the extension (instead of simply ".js"),
51 # because this file is generated by frogc and not by frogpad.
52 #
53 # (For testing, it's useful to be able to distinguish files that are generated
54 # by frogc from files that are generated by frogpad.)
55 #
56 FROGPAD_JS = "frogpad.dart.frogc.js"
57
33 # Template for the html page we're going to generate. 58 # Template for the html page we're going to generate.
34 HTML = """<html> 59 HTML = """<html>
35 <head> 60 <head>
36 <style type="text/css"> 61 <style type="text/css">
37 textarea { 62 textarea {
38 width: 100%; 63 width: 100%;
39 height: 200px; 64 height: 200px;
40 } 65 }
41 .label { 66 .label {
42 margin-top: 5px; 67 margin-top: 5px;
(...skipping 12 matching lines...) Expand all
55 <body> 80 <body>
56 <h1>Frogpad</h1> 81 <h1>Frogpad</h1>
57 <div class="label">Input:</div> 82 <div class="label">Input:</div>
58 <textarea id="input"></textarea> 83 <textarea id="input"></textarea>
59 <div class="label">Compiler Messages:</div> 84 <div class="label">Compiler Messages:</div>
60 <pre id="warnings"></pre> 85 <pre id="warnings"></pre>
61 <div class="label">Timing:</div> 86 <div class="label">Timing:</div>
62 <pre id="timing"></pre> 87 <pre id="timing"></pre>
63 <div class="label">Output:</div> 88 <div class="label">Output:</div>
64 <pre id="output"></pre> 89 <pre id="output"></pre>
65 <script type="text/javascript" src="frogpad.dart.js" ></script> 90 <script type="text/javascript" src={{FROGPAD_JS}} ></script>
66 </body> 91 </body>
67 </html> 92 </html>
68 """ 93 """
69 94
70 # We use "application/inert" here to make the browser ignore the 95 # We use "application/inert" here to make the browser ignore the
71 # these script tags. (frogpad.dart will fish out the contents as needed.) 96 # these script tags. (frogpad.dart will fish out the contents as needed.)
72 # 97 #
73 SCRIPT_TAG = """<script type="application/inert" id="{{id}}"> 98 SCRIPT_TAG = """<script type="application/inert" id="{{id}}">
74 {{contents}} 99 {{contents}}
75 </script> 100 </script>
(...skipping 17 matching lines...) Expand all
93 "json": "../lib/json/json_frog.dart" 118 "json": "../lib/json/json_frog.dart"
94 } 119 }
95 120
96 121
97 class Pad(object): 122 class Pad(object):
98 """ 123 """
99 Accumulates all source files that are needed to compile a dart program, 124 Accumulates all source files that are needed to compile a dart program,
100 and places them in <script> tags on an html page. 125 and places them in <script> tags on an html page.
101 """ 126 """
102 127
103 def __init__(self, frog_dir, main_file): 128 def __init__(self, argv):
129 parser = optparse.OptionParser()
130 parser.add_option("-m", "--main", help="which dart file to compile")
131 parser.add_option("-r", "--rebuild", action="store_true",
132 help="forces rebuild of frogpad_js")
133 (options, args) = parser.parse_args(argv)
134
135 # directory of this script
136 self.frogpad_dir = os.path.abspath(os.path.dirname(argv[0]))
137
104 # directory of frog compiler source code 138 # directory of frog compiler source code
105 self.frog_dir = frog_dir 139 self.frog_dir = os.path.abspath(os.path.join(self.frogpad_dir, "../../../fro g"))
Emily Fortuna 2012/02/21 19:05:57 line break needed, > 80 char Also the combination
mattsh 2012/02/21 20:13:28 Good point. Switches to use dirname now.
106 140
107 # which .dart file to compile 141 # root of dart source repo
108 self.main_file = main_file 142 self.dart_dir = os.path.abspath(os.path.join(self.frog_dir, ".."))
Emily Fortuna 2012/02/21 19:05:57 Perhaps obtain location of the root of the dart so
mattsh 2012/02/21 20:13:28 Done.
143
144 # name of frogpad_js file
145 self.frogpad_js = os.path.join(self.frogpad_dir, FROGPAD_JS)
146
147 if not options.main:
148 usage()
149 self.main_file = os.path.abspath(options.main)
150
151 html_file = self.main_file + ".frogpad.html"
109 152
110 # map from file name to File object (contains entries for all corelib 153 # map from file name to File object (contains entries for all corelib
111 # and all other dart files needed to compile main_file) 154 # and all other dart files needed to compile main_file)
112 self.name_to_file = {} 155 self.name_to_file = {}
113 156
114 # map from script tag id to File object 157 # map from script tag id to File object
115 self.id_to_file = {} 158 self.id_to_file = {}
116 159
160 if not os.path.exists(self.frogpad_js):
161 options.rebuild = True
162
163 if options.rebuild:
164 self.build_frogpad_js()
165
117 self.load_libraries() 166 self.load_libraries()
118 self.load_file(self.main_file) 167 self.load_file(options.main)
168
169 html = self.generate_html()
170
171 with open(html_file, "w") as output:
172 output.write(html)
173 logging.info("generated '%s' (%d bytes)" % (html_file, len(html)))
174
175
176 def build_frogpad_js(self):
177 dart_vm = os.path.join(self.dart_dir, "out/Release_ia32/dart")
178 check_exists(dart_vm)
179
180 frogc_dart = os.path.join(self.frog_dir, "frogc.dart")
181 frogpad_dart = os.path.join(self.frogpad_dir, "frogpad.dart")
182 check_exists(frogc_dart)
183 check_exists(frogpad_dart)
184
185 # command line arguments for the dart vm
186 args = []
187 args.append(command.Arg("enable_type_checks", None, False))
188 args.append(command.Arg("enable_asserts", None, False))
189
190 # the dart program we're going to run on the dart vm
Emily Fortuna 2012/02/21 19:05:57 Capital letter for first word, here, and elsewhere
mattsh 2012/02/21 20:13:28 Done.
191 args.append(command.Arg(frogc_dart, None, True))
192
193 # command line arguments for frogc.dart
194 args.append(command.Arg("libdir", "%s/lib" % self.frog_dir, False))
Emily Fortuna 2012/02/21 19:05:57 is creating this command object really gain us any
mattsh 2012/02/21 20:13:28 Good suggestion. command.Arg removed now.
195 args.append(command.Arg("compile-only", None, False))
196 args.append(command.Arg("enable_type_checks", None, False))
197 args.append(command.Arg("enable_asserts", None, False))
198 args.append(command.Arg("out", self.frogpad_js, False))
199
200 # the dart program that we want frogc.dart to compile
201 args.append(command.Arg(frogpad_dart, None, True))
202
203 # Now run the dart vm.
204 command.RunCommand(dart_vm, args)
205 check_exists(self.frogpad_js)
119 206
120 def generate_html(self): 207 def generate_html(self):
121 tags = [] 208 tags = []
122 for f in self.id_to_file.values(): 209 for f in self.id_to_file.values():
123 tags.append(self._create_tag(f.id, f.contents)) 210 tags.append(self._create_tag(f.id, f.contents))
124 tags.append(self._create_tag(MAIN_ID, self.main_file)) 211 tags.append(self._create_tag(MAIN_ID, self.main_file))
125 html = HTML.replace("{{script_tags}}", "".join(tags)) 212 html = HTML.replace("{{script_tags}}", "".join(tags))
213 html = html.replace("{{FROGPAD_JS}}", FROGPAD_JS)
126 return html 214 return html
127 215
128 @staticmethod 216 @staticmethod
129 def _create_tag(id, contents): 217 def _create_tag(id, contents):
130 s = SCRIPT_TAG 218 s = SCRIPT_TAG
131 s = s.replace("{{id}}", id) 219 s = s.replace("{{id}}", id)
132 s = s.replace("{{contents}}", contents) 220 s = s.replace("{{contents}}", contents)
133 return s 221 return s
134 222
135 def dart_library(self, name): 223 def dart_library(self, name):
136 path = DART_LIBRARIES[name] 224 path = DART_LIBRARIES[name]
137 if not path: 225 if not path:
138 raise Exception("unrecognized 'dart:%s'", name) 226 raise Exception("unrecognized 'dart:%s'", name)
139 return os.path.join(self.frog_dir, path) 227 return os.path.join(self.frog_dir, path)
140 228
141 def load_libraries(self): 229 def load_libraries(self):
142 for name in DART_LIBRARIES: 230 for name in DART_LIBRARIES:
143 self.load_file(self.dart_library(name)) 231 self.load_file(self.dart_library(name))
144 232
145 def load_file(self, name): 233 def load_file(self, name):
146 name = os.path.abspath(name) 234 name = os.path.abspath(name)
147 if name in self.name_to_file: 235 if name in self.name_to_file:
148 print "already loaded %s, skipping" % name 236 logging.debug("already loaded %s, skipping" % name)
149 return 237 return
150 f = File(self, name) 238 f = File(self, name)
151 self.name_to_file[f.name] = f 239 self.name_to_file[f.name] = f
152 if f.id in self.id_to_file: 240 if f.id in self.id_to_file:
153 raise Exception("ambiguous id '%s'" % f.id) 241 raise Exception("ambiguous id '%s'" % f.id)
154 self.id_to_file[f.id] = f 242 self.id_to_file[f.id] = f
155 f.directives() 243 f.directives()
156 244
157 class File(object): 245 class File(object):
158 def __init__(self, pad, name): 246 def __init__(self, pad, name):
159 self.pad = pad 247 self.pad = pad
160 self.name = name 248 self.name = name
161 self.id = self._make_id() 249 self.id = self._make_id()
162 if not os.path.exists(name): 250 check_exists(name)
163 raise Exception("cannot find file '%s'" % name)
164 with open(self.name, "r") as f: 251 with open(self.name, "r") as f:
165 self.contents = f.read() 252 self.contents = f.read()
166 print "creating File '%s' (%d lines)" % (self.name, len(self.contents)) 253 logging.debug("creating File '%s' (%d lines)" % (self.name, len(self.content s)))
Emily Fortuna 2012/02/21 19:05:57 80 char
mattsh 2012/02/21 20:13:28 Done.
167 254
168 def _make_id(self): 255 def _make_id(self):
169 """ 256 """
170 Generates an id (based on the file name) for the <script> tag that will 257 Generates an id (based on the file name) for the <script> tag that will
171 hold the contents of this file. 258 hold the contents of this file.
172 """ 259 """
173 (dirname, name) = os.path.split(self.name) 260 (dirname, name) = os.path.split(self.name)
174 dirname = os.path.basename(dirname) 261 dirname = os.path.basename(dirname)
175 name = name.replace(".", "_") 262 name = name.replace(".", "_")
176 return dirname + "_" + name 263 return dirname + "_" + name
(...skipping 11 matching lines...) Expand all
188 if not match: 275 if not match:
189 return 276 return
190 url = match.group(2) 277 url = match.group(2)
191 if url.startswith("dart:"): 278 if url.startswith("dart:"):
192 path = self.pad.dart_library(url[len("dart:"):]) 279 path = self.pad.dart_library(url[len("dart:"):])
193 else: 280 else:
194 path = os.path.join(os.path.dirname(self.name), url) 281 path = os.path.join(os.path.dirname(self.name), url)
195 self.pad.load_file(path) 282 self.pad.load_file(path)
196 283
197 284
285 def usage():
286 print("""
287 Usage:
288 frogpad.py --main=hello.dart
Emily Fortuna 2012/02/21 19:05:57 Can we make hello.dart a required positional argum
mattsh 2012/02/21 20:13:28 Done.
289 """)
290 sys.exit(1)
291
292 def check_exists(file_name):
293 if not os.path.exists(file_name):
294 raise FileNotFoundException(file_name)
295
296
198 def main(argv): 297 def main(argv):
199 parser = optparse.OptionParser() 298 logging.basicConfig(level=logging.INFO)
200 parser.add_option("-o", "--out", dest="out_file") 299 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 300
216 if __name__ == "__main__": 301 if __name__ == "__main__":
217 sys.exit(main(sys.argv)) 302 sys.exit(main(sys.argv))
218 303
OLDNEW
« tools/testing/frogpad/command.py ('K') | « tools/testing/frogpad/command.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698