OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library script_inset_element; | 5 library script_inset_element; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:html'; | 8 import 'dart:html'; |
9 import 'observatory_element.dart'; | 9 import 'observatory_element.dart'; |
10 import 'service_ref.dart'; | 10 import 'service_ref.dart'; |
11 import 'package:observatory/service.dart'; | 11 import 'package:observatory/service.dart'; |
| 12 import 'package:observatory/utils.dart'; |
12 import 'package:polymer/polymer.dart'; | 13 import 'package:polymer/polymer.dart'; |
13 | 14 |
14 const nbsp = "\u00A0"; | 15 const nbsp = "\u00A0"; |
15 | 16 |
16 void addInfoBox(Element content, Function infoBoxGenerator) { | 17 void addInfoBox(Element content, Function infoBoxGenerator) { |
17 var infoBox; | 18 var infoBox; |
18 var show = false; | 19 var show = false; |
19 var originalBackground = content.style.backgroundColor; | 20 var originalBackground = content.style.backgroundColor; |
20 buildInfoBox() { | 21 buildInfoBox() { |
21 infoBox = infoBoxGenerator(); | 22 infoBox = infoBoxGenerator(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 class CurrentExecutionAnnotation extends Annotation { | 89 class CurrentExecutionAnnotation extends Annotation { |
89 void applyStyleTo(element) { | 90 void applyStyleTo(element) { |
90 if (element == null) { | 91 if (element == null) { |
91 return; // TODO(rmacnak): Handling overlapping annotations. | 92 return; // TODO(rmacnak): Handling overlapping annotations. |
92 } | 93 } |
93 element.classes.add("currentCol"); | 94 element.classes.add("currentCol"); |
94 element.title = "Current execution"; | 95 element.title = "Current execution"; |
95 } | 96 } |
96 } | 97 } |
97 | 98 |
| 99 class LocalVariableAnnotation extends Annotation { |
| 100 final value; |
| 101 |
| 102 LocalVariableAnnotation(LocalVarLocation location, this.value) { |
| 103 line = location.line; |
| 104 columnStart = location.column; |
| 105 columnStop = location.endColumn; |
| 106 } |
| 107 |
| 108 void applyStyleTo(element) { |
| 109 if (element == null) { |
| 110 return; // TODO(rmacnak): Handling overlapping annotations. |
| 111 } |
| 112 element.style.fontWeight = "bold"; |
| 113 element.title = "${value.shortName}"; |
| 114 } |
| 115 } |
| 116 |
98 class CallSiteAnnotation extends Annotation { | 117 class CallSiteAnnotation extends Annotation { |
99 CallSite callSite; | 118 CallSite callSite; |
100 | 119 |
101 CallSiteAnnotation(this.callSite) { | 120 CallSiteAnnotation(this.callSite) { |
102 line = callSite.line; | 121 line = callSite.line; |
103 columnStart = callSite.column - 1; // Call site is 1-origin. | 122 columnStart = callSite.column - 1; // Call site is 1-origin. |
104 var tokenLength = callSite.name.length; // Approximate. | 123 var tokenLength = callSite.name.length; // Approximate. |
105 if (callSite.name.startsWith("get:") || | 124 if (callSite.name.startsWith("get:") || |
106 callSite.name.startsWith("set:")) tokenLength -= 4; | 125 callSite.name.startsWith("set:")) tokenLength -= 4; |
107 columnStop = columnStart + tokenLength; | 126 columnStop = columnStart + tokenLength; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 @published Script script; | 231 @published Script script; |
213 | 232 |
214 /// Set the height to make the script inset scroll. Otherwise it | 233 /// Set the height to make the script inset scroll. Otherwise it |
215 /// will show from startPos to endPos. | 234 /// will show from startPos to endPos. |
216 @published String height = null; | 235 @published String height = null; |
217 | 236 |
218 @published int currentPos; | 237 @published int currentPos; |
219 @published int startPos; | 238 @published int startPos; |
220 @published int endPos; | 239 @published int endPos; |
221 @published bool inDebuggerContext = false; | 240 @published bool inDebuggerContext = false; |
| 241 @published ObservableList variables; |
222 | 242 |
223 int _currentLine; | 243 int _currentLine; |
224 int _currentCol; | 244 int _currentCol; |
225 int _startLine; | 245 int _startLine; |
226 int _endLine; | 246 int _endLine; |
227 | 247 |
228 var annotations = []; | 248 var annotations = []; |
229 var annotationsCursor; | 249 var annotationsCursor; |
230 | 250 |
231 StreamSubscription scriptChangeSubscription; | 251 StreamSubscription scriptChangeSubscription; |
(...skipping 12 matching lines...) Expand all Loading... |
244 void detached() { | 264 void detached() { |
245 if (scriptChangeSubscription != null) { | 265 if (scriptChangeSubscription != null) { |
246 // Don't leak. If only Dart and Javascript exposed weak references... | 266 // Don't leak. If only Dart and Javascript exposed weak references... |
247 scriptChangeSubscription.cancel(); | 267 scriptChangeSubscription.cancel(); |
248 scriptChangeSubscription = null; | 268 scriptChangeSubscription = null; |
249 } | 269 } |
250 super.detached(); | 270 super.detached(); |
251 } | 271 } |
252 | 272 |
253 void currentPosChanged(oldValue) { | 273 void currentPosChanged(oldValue) { |
254 update(); | 274 _updateTask.queue(); |
255 _scrollToCurrentPos(); | 275 _scrollToCurrentPos(); |
256 } | 276 } |
257 | 277 |
258 void startPosChanged(oldValue) { | 278 void startPosChanged(oldValue) { |
259 update(); | 279 _updateTask.queue(); |
260 } | 280 } |
261 | 281 |
262 void endPosChanged(oldValue) { | 282 void endPosChanged(oldValue) { |
263 update(); | 283 _updateTask.queue(); |
264 } | 284 } |
265 | 285 |
266 void scriptChanged(oldValue) { | 286 void scriptChanged(oldValue) { |
267 update(); | 287 _updateTask.queue(); |
| 288 } |
| 289 |
| 290 void variablesChanged(oldValue) { |
| 291 _updateTask.queue(); |
268 } | 292 } |
269 | 293 |
270 Element a(String text) => new AnchorElement()..text = text; | 294 Element a(String text) => new AnchorElement()..text = text; |
271 Element span(String text) => new SpanElement()..text = text; | 295 Element span(String text) => new SpanElement()..text = text; |
272 | 296 |
273 Element hitsUnknown(Element element) { | 297 Element hitsUnknown(Element element) { |
274 element.classes.add('hitsNone'); | 298 element.classes.add('hitsNone'); |
275 element.title = ""; | 299 element.title = ""; |
276 return element; | 300 return element; |
277 } | 301 } |
278 Element hitsNotExecuted(Element element) { | 302 Element hitsNotExecuted(Element element) { |
279 element.classes.add('hitsNotExecuted'); | 303 element.classes.add('hitsNotExecuted'); |
280 element.title = "Line did not execute"; | 304 element.title = "Line did not execute"; |
281 return element; | 305 return element; |
282 } | 306 } |
283 Element hitsExecuted(Element element) { | 307 Element hitsExecuted(Element element) { |
284 element.classes.add('hitsExecuted'); | 308 element.classes.add('hitsExecuted'); |
285 element.title = "Line did execute"; | 309 element.title = "Line did execute"; |
286 return element; | 310 return element; |
287 } | 311 } |
288 | 312 |
289 Element container; | 313 Element container; |
290 | 314 |
| 315 Task _updateTask; |
291 void update() { | 316 void update() { |
| 317 assert(_updateTask != null); |
292 if (script == null) { | 318 if (script == null) { |
293 // We may have previously had a script. | 319 // We may have previously had a script. |
294 if (container != null) { | 320 if (container != null) { |
295 container.children.clear(); | 321 container.children.clear(); |
296 } | 322 } |
297 return; | 323 return; |
298 } | 324 } |
299 if (!script.loaded) { | 325 if (!script.loaded) { |
300 script.load().then((_) => update()); | 326 script.load().then((_) => update()); |
301 return; | 327 return; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 annotations.add(new FunctionDeclarationAnnotation(func)); | 396 annotations.add(new FunctionDeclarationAnnotation(func)); |
371 } | 397 } |
372 } | 398 } |
373 } | 399 } |
374 | 400 |
375 for (var callSite in script.callSites) { | 401 for (var callSite in script.callSites) { |
376 annotations.add(new CallSiteAnnotation(callSite)); | 402 annotations.add(new CallSiteAnnotation(callSite)); |
377 } | 403 } |
378 } | 404 } |
379 | 405 |
| 406 // We have local variable information. |
| 407 if (variables != null) { |
| 408 // For each variable. |
| 409 for (var variable in variables) { |
| 410 // Find variable usage locations. |
| 411 var locations = script.scanForLocalVariableLocations( |
| 412 variable['name'], variable['tokenPos'], variable['endTokenPos']); |
| 413 |
| 414 // Annotate locations. |
| 415 for (var location in locations) { |
| 416 annotations.add(new LocalVariableAnnotation(location, |
| 417 variable['value'])); |
| 418 } |
| 419 } |
| 420 } |
| 421 |
380 annotations.sort(); | 422 annotations.sort(); |
381 } | 423 } |
382 | 424 |
383 Element linesTable() { | 425 Element linesTable() { |
384 var table = new DivElement(); | 426 var table = new DivElement(); |
385 table.classes.add("sourceTable"); | 427 table.classes.add("sourceTable"); |
386 | 428 |
387 annotationsCursor = 0; | 429 annotationsCursor = 0; |
388 | 430 |
389 int blankLineCount = 0; | 431 int blankLineCount = 0; |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 } | 596 } |
555 consumeUntil(line.text.length); | 597 consumeUntil(line.text.length); |
556 } | 598 } |
557 | 599 |
558 // So blank lines are included when copying script to the clipboard. | 600 // So blank lines are included when copying script to the clipboard. |
559 e.append(span('\n')); | 601 e.append(span('\n')); |
560 | 602 |
561 return e; | 603 return e; |
562 } | 604 } |
563 | 605 |
564 ScriptInsetElement.created() : super.created(); | 606 ScriptInsetElement.created() |
| 607 : super.created() { |
| 608 _updateTask = new Task(update); |
| 609 } |
565 } | 610 } |
OLD | NEW |