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

Side by Side Diff: samples/leap/leap_leg.dart

Issue 11085017: Move leap to lib/compiler/samples. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | « samples/leap/leap.dart ('k') | samples/leap/leap_script.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 compilerIsolate(port) {
6 Runner runner = new Runner();
7 runner.init();
8
9 port.receive((msg, replyTo) {
10 replyTo.send(runner.update(msg));
11 });
12 }
13
14 main() {
15 html.document.query('#status').innerHTML = 'Initializing...';
16 setOutline(msg) {
17 html.document.query('#out').innerHTML = msg;
18 }
19 final codeDiv = html.document.query('#code');
20 final popup = html.document.query('#popup');
21
22 // The port for communicating with the compiler isolate.
23 var port = null;
24
25 // Should be called when [codeDiv] has changed. For now, call it always
26 // on mouse up and key up events.
27 update() {
28 if (port === null) return;
29 port.call(codeDiv.text).then(setOutline);
30 }
31
32 hide(Element e) {
33 e.style.visibility = 'hidden';
34 }
35
36 show(Element e) {
37 e.style.visibility = 'visible';
38 }
39
40 insertTextAtPoint(Event e, String newText) {
41 e.preventDefault();
42 var selection = html.window.getSelection();
43 var range = selection.getRangeAt(0);
44 var offset = range.startOffset;
45 Text text = codeDiv.nodes[0];
46 text.insertData(offset, newText);
47 selection.setPosition(text, offset + newText.length);
48 }
49
50 // This prevents creating a new div element when hitting enter.
51 codeDiv.on.keyPress.add((Event e) {
52 if (e.keyIdentifier == 'Enter') {
53 // TODO(ahe): Is 'Enter' portable?
54 insertTextAtPoint(e, '\n');
55 }
56 });
57
58 // Override tab key.
59 codeDiv.on.keyDown.add((Event e) {
60 if (e.keyIdentifier == 'U+0009') {
61 // TODO(ahe): Find better way to detect tab key.
62 insertTextAtPoint(e, ' ');
63 }
64 });
65
66 // Called on keyUp and mouseUp to display a marker at the current
67 // insertion point (the selection's first range). This probably
68 // needs more work before it works really well, but seems to be good
69 // enough for now.
70 handleUp(Event e) {
71 var selection = html.window.getSelection();
72 var range = selection.getRangeAt(0);
73 var rects = range.getClientRects();
74 if (rects.length < 1) {
75 hide(popup);
76 return;
77 }
78 html.ClientRect rect = rects.item(rects.length - 1);
79 if (rect.width.toInt() != 0) {
80 // This is a selection of multiple characters, not a single
81 // point of insertion.
82 hide(popup);
83 return;
84 }
85 popup.style.top = "${rect.bottom.toInt()}px";
86 popup.style.left = "${rect.right.toInt()}px";
87 // Instead of displaying this immediately, we could set up a timer
88 // event and display it later. This is a matter of getting the UX
89 // just right, for now it simply demonstrates that we know where
90 // the insertion point is (in pixels) and what the character
91 // offset is.
92 show(popup);
93 popup.text = '''Code completion here...
94 Current character offset: ${range.startOffset}''';
95 // TODO(ahe): Better detection of when [codeDiv] has changed.
96 update();
97 }
98
99 codeDiv.on.keyUp.add(handleUp);
100 codeDiv.on.mouseUp.add(handleUp);
101
102 codeDiv.on.blur.add((Event e) => hide(popup));
103
104 // The event handlers are now set up. Allow editing.
105 codeDiv.contentEditable = "true";
106
107 // Creates a compiler isolate in its own iframe. This should prevent
108 // the compiler from blocking the UI.
109 spawnDomIsolate(html.document.query('#isolate').contentWindow,
110 'compilerIsolate').then((sendPort) {
111 // The compiler isolate is now ready to talk. Store the port so
112 // that the update function starts requesting outlines whenever
113 // [codeDiv] changes.
114 port = sendPort;
115 // Make sure that we get an initial outline.
116 update();
117 html.document.query('#status').innerHTML = 'Ready';
118 });
119 }
120
121 class Runner {
122 final LeapCompiler compiler;
123
124 Runner() : compiler = new LeapCompiler();
125
126 String init() {
127 Stopwatch sw = new Stopwatch()..start();
128 compiler.scanBuiltinLibraries();
129 sw.stop();
130 return 'Scanned core libraries in ${sw.elapsedInMs()}ms';
131 }
132
133 String update(String codeText) {
134 StringBuffer sb = new StringBuffer();
135
136 Stopwatch sw = new Stopwatch()..start();
137
138 LibraryElement e = compile(new LeapScript(codeText));
139
140 void printFunction(FunctionElement fe, [String indentation = ""]) {
141 var paramAcc = [];
142
143 FunctionType ft = fe.computeType(compiler);
144
145 sb.add("<div>${indentation}");
146 ft.returnType.name.printOn(sb);
147 sb.add(" ");
148 fe.name.printOn(sb);
149 sb.add("(");
150 ft.parameterTypes.printOn(sb, ", ");
151 sb.add(");</div>");
152
153 }
154
155 void printField(FieldElement fe, [String indentation = ""]) {
156 sb.add("<div>${indentation}var ");
157 fe.name.printOn(sb);
158 sb.add(";</div>");
159 }
160
161 void printClass(ClassElement ce) {
162 ce.parseNode(compiler);
163
164 sb.add("<div>class ");
165 ce.name.printOn(sb);
166 sb.add(" {");
167
168 for (Element e in ce.members.reverse()) {
169 switch(e.kind) {
170 case ElementKind.FUNCTION:
171
172 printFunction(e, "&nbsp; ");
173 break;
174
175 case ElementKind.FIELD:
176
177 printField(e, "&nbsp; ");
178 break;
179 }
180 }
181 sb.add("}</div>");
182 }
183
184 for (Element c in e.topLevelElements.reverse()) {
185 switch (c.kind) {
186 case ElementKind.FUNCTION:
187 printFunction (c);
188 break;
189
190 case ElementKind.CLASS:
191 printClass(c);
192 break;
193
194 case ElementKind.FIELD:
195 printField (c);
196 break;
197 }
198 }
199
200 compiler.log("Outline ${sw.elapsedInMs()}");
201 return sb.toString();
202 }
203
204 Element compile(String script) {
205 return compiler.runSelective(script);
206 }
207 }
208
209 class LeapCompiler extends Compiler {
210 HttpRequestCache cache;
211
212 final bool throwOnError = false;
213
214 final libDir = "../..";
215
216 LeapCompiler() : cache = new HttpRequestCache(), super() {
217 tasks = [scanner, dietParser, parser, resolver, checker];
218 }
219
220 void log(message) { print(message); }
221
222 String get legDirectory => libDir;
223
224 LibraryElement scanBuiltinLibrary(String path) {
225 Uri base = new Uri.fromString(html.window.location.toString());
226 Uri libraryRoot = base.resolve(libDir);
227 Uri resolved = libraryRoot.resolve(DART2JS_LIBRARY_MAP[path]);
228 LibraryElement library = scanner.loadLibrary(resolved, null);
229 return library;
230 }
231
232 currentScript() {
233 if (currentElement === null) return null;
234 CompilationUnitElement compilationUnit =
235 currentElement.getCompilationUnit();
236 if (compilationUnit === null) return null;
237 return compilationUnit.script;
238 }
239
240 Script readScript(Uri uri, [ScriptTag node]) {
241 String text = "";
242 try {
243 text = cache.readAll(uri.path.toString());
244 } catch (exception) {
245 cancel("${uri.path}: $exception", node: node);
246 }
247 SourceFile sourceFile = new SourceFile(uri.toString(), text);
248 return new Script(uri, sourceFile);
249 }
250
251 reportWarning(Node node, var message) {
252 print(message);
253 }
254
255 reportError(Node node, var message) {
256 cancel(message.toString(), node);
257 }
258
259 void cancel([String reason, Node node, token, instruction, element]) {
260 print(reason);
261 }
262
263 Element runSelective(Script script) {
264 Stopwatch sw = new Stopwatch()..start();
265 Element e;
266 try {
267 e = runCompilerSelective(script);
268 } on CompilerCancelledException catch (exception) {
269 log(exception.toString());
270 log('compilation failed');
271 return null;
272 }
273 log('compilation succeeded: ${sw.elapsedInMs()}ms');
274 return e;
275 }
276
277 LibraryElement runCompilerSelective(Script script) {
278 mainApp = new LibraryElement(script);
279
280 universe.libraries.remove(script.uri.toString());
281 Element element;
282 withCurrentElement(mainApp, () {
283 scanner.scan(mainApp);
284 });
285 return mainApp;
286 }
287 }
OLDNEW
« no previous file with comments | « samples/leap/leap.dart ('k') | samples/leap/leap_script.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698