| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 debugger_page_element; | 5 library debugger_page_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 'package:observatory/cli.dart'; | 10 import 'package:observatory/cli.dart'; |
| 11 import 'package:observatory/debugger.dart'; | 11 import 'package:observatory/debugger.dart'; |
| 12 import 'package:observatory/service.dart'; | 12 import 'package:observatory/service.dart'; |
| 13 import 'package:logging/logging.dart'; | 13 import 'package:logging/logging.dart'; |
| 14 import 'package:polymer/polymer.dart'; | 14 import 'package:polymer/polymer.dart'; |
| 15 | 15 |
| 16 // TODO(turnidge): Move Debugger, DebuggerCommand to debugger library. | 16 // TODO(turnidge): Move Debugger, DebuggerCommand to debugger library. |
| 17 abstract class DebuggerCommand extends Command { | 17 abstract class DebuggerCommand extends Command { |
| 18 ObservatoryDebugger debugger; | 18 ObservatoryDebugger debugger; |
| 19 | 19 |
| 20 DebuggerCommand(this.debugger, name, children) | 20 DebuggerCommand(this.debugger, name, children) |
| 21 : super(name, children); | 21 : super(name, children); |
| 22 | 22 |
| 23 String get helpShort; | 23 String get helpShort; |
| 24 String get helpLong; | 24 String get helpLong; |
| 25 } | 25 } |
| 26 | 26 |
| 27 // TODO(turnidge): Rewrite HelpCommand so that it is a general utility | 27 // TODO(turnidge): Rewrite HelpCommand so that it is a general utility |
| 28 // provided by the cli library. | 28 // provided by the cli library. |
| 29 class HelpCommand extends DebuggerCommand { | 29 class HelpCommand extends DebuggerCommand { |
| 30 HelpCommand(Debugger debugger) : super(debugger, 'help', []); | 30 HelpCommand(Debugger debugger) : super(debugger, 'help', [ |
| 31 new HelpHotkeysCommand(debugger), |
| 32 ]); |
| 31 | 33 |
| 32 String _nameAndAlias(Command cmd) { | 34 String _nameAndAlias(Command cmd) { |
| 33 if (cmd.alias == null) { | 35 if (cmd.alias == null) { |
| 34 return cmd.fullName; | 36 return cmd.fullName; |
| 35 } else { | 37 } else { |
| 36 return '${cmd.fullName}, ${cmd.alias}'; | 38 return '${cmd.fullName}, ${cmd.alias}'; |
| 37 } | 39 } |
| 38 } | 40 } |
| 39 | 41 |
| 40 Future run(List<String> args) { | 42 Future run(List<String> args) { |
| 41 var con = debugger.console; | 43 var con = debugger.console; |
| 42 if (args.length == 0) { | 44 if (args.length == 0) { |
| 43 // Print list of all top-level commands. | 45 // Print list of all top-level commands. |
| 44 var commands = debugger.cmd.matchCommand([], false); | 46 var commands = debugger.cmd.matchCommand([], false); |
| 45 commands.sort((a, b) => a.name.compareTo(b.name)); | 47 commands.sort((a, b) => a.name.compareTo(b.name)); |
| 46 con.print('List of commands:\n'); | 48 con.print('List of commands:\n'); |
| 47 for (var command in commands) { | 49 for (var command in commands) { |
| 48 con.print('${_nameAndAlias(command).padRight(12)} ' | 50 con.print('${_nameAndAlias(command).padRight(12)} ' |
| 49 '- ${command.helpShort}'); | 51 '- ${command.helpShort}'); |
| 50 } | 52 } |
| 51 con.print( | 53 con.print( |
| 52 "\nFor more information on a specific command type 'help <command>'\n" | 54 "\nFor more information on a specific command type 'help <command>'\n" |
| 55 "For a list of hotkeys type 'help hotkeys'\n" |
| 53 "\n" | 56 "\n" |
| 54 "Command prefixes are accepted (e.g. 'h' for 'help')\n" | 57 "Command prefixes are accepted (e.g. 'h' for 'help')\n" |
| 55 "Hit [TAB] to complete a command (try 'is[TAB][TAB]')\n" | 58 "Hit [TAB] to complete a command (try 'is[TAB][TAB]')\n" |
| 56 "Hit [ENTER] to repeat the last command\n" | 59 "Hit [ENTER] to repeat the last command\n" |
| 57 "Use up/down arrow for command history\n"); | 60 "Use up/down arrow for command history\n"); |
| 58 return new Future.value(null); | 61 return new Future.value(null); |
| 59 } else { | 62 } else { |
| 60 // Print any matching commands. | 63 // Print any matching commands. |
| 61 var commands = debugger.cmd.matchCommand(args, true); | 64 var commands = debugger.cmd.matchCommand(args, true); |
| 62 commands.sort((a, b) => a.name.compareTo(b.name)); | 65 commands.sort((a, b) => a.name.compareTo(b.name)); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 101 |
| 99 String helpShort = 'List commands or provide details about a specific command'
; | 102 String helpShort = 'List commands or provide details about a specific command'
; |
| 100 | 103 |
| 101 String helpLong = | 104 String helpLong = |
| 102 'List commands or provide details about a specific command.\n' | 105 'List commands or provide details about a specific command.\n' |
| 103 '\n' | 106 '\n' |
| 104 'Syntax: help - Show a list of all commands\n' | 107 'Syntax: help - Show a list of all commands\n' |
| 105 ' help <command> - Help for a specific command\n'; | 108 ' help <command> - Help for a specific command\n'; |
| 106 } | 109 } |
| 107 | 110 |
| 111 class HelpHotkeysCommand extends DebuggerCommand { |
| 112 HelpHotkeysCommand(Debugger debugger) : super(debugger, 'hotkeys', []); |
| 113 |
| 114 Future run(List<String> args) { |
| 115 var con = debugger.console; |
| 116 con.print("List of hotkeys:\n" |
| 117 "\n" |
| 118 "[TAB] - complete a command\n" |
| 119 "[Up Arrow] - history previous\n" |
| 120 "[Down Arrow] - history next\n" |
| 121 "\n" |
| 122 "[Page Up] - move up one frame\n" |
| 123 "[Page Down] - move down one frame\n" |
| 124 "\n" |
| 125 "[F7] - continue execution of the current isolate\n" |
| 126 "[Ctrl ;] - pause execution of the current isolate\n" |
| 127 "\n" |
| 128 "[F8] - toggle breakpoint at current location\n" |
| 129 "[F9] - next\n" |
| 130 "[F10] - step\n" |
| 131 "\n"); |
| 132 return new Future.value(null); |
| 133 } |
| 134 |
| 135 String helpShort = 'Provide a list of hotkeys'; |
| 136 |
| 137 String helpLong = |
| 138 'Provide a list of key hotkeys.\n' |
| 139 '\n' |
| 140 'Syntax: help hotkeys\n'; |
| 141 } |
| 142 |
| 108 class PrintCommand extends DebuggerCommand { | 143 class PrintCommand extends DebuggerCommand { |
| 109 PrintCommand(Debugger debugger) : super(debugger, 'print', []) { | 144 PrintCommand(Debugger debugger) : super(debugger, 'print', []) { |
| 110 alias = 'p'; | 145 alias = 'p'; |
| 111 } | 146 } |
| 112 | 147 |
| 113 Future run(List<String> args) async { | 148 Future run(List<String> args) async { |
| 114 if (args.length < 1) { | 149 if (args.length < 1) { |
| 115 debugger.console.print('print expects arguments'); | 150 debugger.console.print('print expects arguments'); |
| 116 return; | 151 return; |
| 117 } | 152 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 148 count = int.parse(args[0]); | 183 count = int.parse(args[0]); |
| 149 } else if (args.length > 1) { | 184 } else if (args.length > 1) { |
| 150 debugger.console.print('down expects 0 or 1 argument'); | 185 debugger.console.print('down expects 0 or 1 argument'); |
| 151 return new Future.value(null); | 186 return new Future.value(null); |
| 152 } | 187 } |
| 153 if (debugger.currentFrame == null) { | 188 if (debugger.currentFrame == null) { |
| 154 debugger.console.print('No stack'); | 189 debugger.console.print('No stack'); |
| 155 return new Future.value(null); | 190 return new Future.value(null); |
| 156 } | 191 } |
| 157 try { | 192 try { |
| 158 debugger.currentFrame -= count; | 193 debugger.currentFrame += count; |
| 159 debugger.console.print('frame = ${debugger.currentFrame}'); | 194 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 160 } catch (e) { | 195 } catch (e) { |
| 161 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); | 196 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 162 } | 197 } |
| 163 return new Future.value(null); | 198 return new Future.value(null); |
| 164 } | 199 } |
| 165 | 200 |
| 166 String helpShort = 'Move down one or more frames'; | 201 String helpShort = 'Move down one or more frames (hotkey: [Page Down])'; |
| 167 | 202 |
| 168 String helpLong = | 203 String helpLong = |
| 169 'Move down one or more frames.\n' | 204 'Move down one or more frames.\n' |
| 170 '\n' | 205 '\n' |
| 206 'Hotkey: [Page Down]\n' |
| 207 '\n' |
| 171 'Syntax: down\n' | 208 'Syntax: down\n' |
| 172 ' down <count>\n'; | 209 ' down <count>\n'; |
| 173 } | 210 } |
| 174 | 211 |
| 175 class UpCommand extends DebuggerCommand { | 212 class UpCommand extends DebuggerCommand { |
| 176 UpCommand(Debugger debugger) : super(debugger, 'up', []); | 213 UpCommand(Debugger debugger) : super(debugger, 'up', []); |
| 177 | 214 |
| 178 Future run(List<String> args) { | 215 Future run(List<String> args) { |
| 179 int count = 1; | 216 int count = 1; |
| 180 if (args.length == 1) { | 217 if (args.length == 1) { |
| 181 count = int.parse(args[0]); | 218 count = int.parse(args[0]); |
| 182 } else if (args.length > 1) { | 219 } else if (args.length > 1) { |
| 183 debugger.console.print('up expects 0 or 1 argument'); | 220 debugger.console.print('up expects 0 or 1 argument'); |
| 184 return new Future.value(null); | 221 return new Future.value(null); |
| 185 } | 222 } |
| 186 if (debugger.currentFrame == null) { | 223 if (debugger.currentFrame == null) { |
| 187 debugger.console.print('No stack'); | 224 debugger.console.print('No stack'); |
| 188 return new Future.value(null); | 225 return new Future.value(null); |
| 189 } | 226 } |
| 190 try { | 227 try { |
| 191 debugger.currentFrame += count; | 228 debugger.currentFrame -= count; |
| 192 debugger.console.print('frame = ${debugger.currentFrame}'); | 229 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 193 } on RangeError catch (e) { | 230 } on RangeError catch (e) { |
| 194 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); | 231 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 195 } | 232 } |
| 196 return new Future.value(null); | 233 return new Future.value(null); |
| 197 } | 234 } |
| 198 | 235 |
| 199 String helpShort = 'Move up one or more frames'; | 236 String helpShort = 'Move up one or more frames (hotkey: [Page Up])'; |
| 200 | 237 |
| 201 String helpLong = | 238 String helpLong = |
| 202 'Move up one or more frames.\n' | 239 'Move up one or more frames.\n' |
| 203 '\n' | 240 '\n' |
| 241 'Hotkey: [Page Up]\n' |
| 242 '\n' |
| 204 'Syntax: up\n' | 243 'Syntax: up\n' |
| 205 ' up <count>\n'; | 244 ' up <count>\n'; |
| 206 } | 245 } |
| 207 | 246 |
| 208 class FrameCommand extends DebuggerCommand { | 247 class FrameCommand extends DebuggerCommand { |
| 209 FrameCommand(Debugger debugger) : super(debugger, 'frame', []) { | 248 FrameCommand(Debugger debugger) : super(debugger, 'frame', []) { |
| 210 alias = 'f'; | 249 alias = 'f'; |
| 211 } | 250 } |
| 212 | 251 |
| 213 Future run(List<String> args) { | 252 Future run(List<String> args) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 237 'Set the current frame.\n' | 276 'Set the current frame.\n' |
| 238 '\n' | 277 '\n' |
| 239 'Syntax: frame <number>\n' | 278 'Syntax: frame <number>\n' |
| 240 ' f <count>\n'; | 279 ' f <count>\n'; |
| 241 } | 280 } |
| 242 | 281 |
| 243 class PauseCommand extends DebuggerCommand { | 282 class PauseCommand extends DebuggerCommand { |
| 244 PauseCommand(Debugger debugger) : super(debugger, 'pause', []); | 283 PauseCommand(Debugger debugger) : super(debugger, 'pause', []); |
| 245 | 284 |
| 246 Future run(List<String> args) { | 285 Future run(List<String> args) { |
| 247 if (!debugger.isolatePaused()) { | 286 return debugger.pause(); |
| 248 return debugger.isolate.pause(); | |
| 249 } else { | |
| 250 debugger.console.print('The program is already paused'); | |
| 251 return new Future.value(null); | |
| 252 } | |
| 253 } | 287 } |
| 254 | 288 |
| 255 String helpShort = 'Pause the isolate'; | 289 String helpShort = 'Pause the isolate (hotkey: [Ctrl ;])'; |
| 256 | 290 |
| 257 String helpLong = | 291 String helpLong = |
| 258 'Pause the isolate.\n' | 292 'Pause the isolate.\n' |
| 259 '\n' | 293 '\n' |
| 294 'Hotkey: [Ctrl ;]\n' |
| 295 '\n' |
| 260 'Syntax: pause\n'; | 296 'Syntax: pause\n'; |
| 261 } | 297 } |
| 262 | 298 |
| 263 class ContinueCommand extends DebuggerCommand { | 299 class ContinueCommand extends DebuggerCommand { |
| 264 ContinueCommand(Debugger debugger) : super(debugger, 'continue', []) { | 300 ContinueCommand(Debugger debugger) : super(debugger, 'continue', []) { |
| 265 alias = 'c'; | 301 alias = 'c'; |
| 266 } | 302 } |
| 267 | 303 |
| 268 Future run(List<String> args) { | 304 Future run(List<String> args) { |
| 269 if (debugger.isolatePaused()) { | 305 debugger.resume(); |
| 270 return debugger.isolate.resume().then((_) { | |
| 271 debugger.warnOutOfDate(); | |
| 272 }); | |
| 273 } else { | |
| 274 debugger.console.print('The program must be paused'); | |
| 275 return new Future.value(null); | |
| 276 } | |
| 277 } | 306 } |
| 278 | 307 |
| 279 String helpShort = 'Resume execution of the isolate'; | 308 String helpShort = 'Resume execution of the isolate (hotkey: [F7])'; |
| 280 | 309 |
| 281 String helpLong = | 310 String helpLong = |
| 282 'Continue running the isolate.\n' | 311 'Continue running the isolate.\n' |
| 283 '\n' | 312 '\n' |
| 313 'Hotkey: [F7]\n' |
| 314 '\n' |
| 284 'Syntax: continue\n' | 315 'Syntax: continue\n' |
| 285 ' c\n'; | 316 ' c\n'; |
| 286 } | 317 } |
| 287 | 318 |
| 288 class NextCommand extends DebuggerCommand { | 319 class NextCommand extends DebuggerCommand { |
| 289 NextCommand(Debugger debugger) : super(debugger, 'next', []); | 320 NextCommand(Debugger debugger) : super(debugger, 'next', []); |
| 290 | 321 |
| 291 Future run(List<String> args) { | 322 Future run(List<String> args) { |
| 292 if (debugger.isolatePaused()) { | 323 return debugger.next(); |
| 293 var event = debugger.isolate.pauseEvent; | |
| 294 if (event.kind == ServiceEvent.kPauseStart) { | |
| 295 debugger.console.print("Type 'continue' to start the isolate"); | |
| 296 return new Future.value(null); | |
| 297 } | |
| 298 if (event.kind == ServiceEvent.kPauseExit) { | |
| 299 debugger.console.print("Type 'continue' to exit the isolate"); | |
| 300 return new Future.value(null); | |
| 301 } | |
| 302 return debugger.isolate.stepOver(); | |
| 303 } else { | |
| 304 debugger.console.print('The program is already running'); | |
| 305 return new Future.value(null); | |
| 306 } | |
| 307 } | 324 } |
| 308 | 325 |
| 309 String helpShort = | 326 String helpShort = |
| 310 'Continue running the isolate until it reaches the next source location ' | 327 'Continue running the isolate until it reaches the next source location ' |
| 311 'in the current function'; | 328 'in the current function (hotkey: [F9])'; |
| 312 | 329 |
| 313 String helpLong = | 330 String helpLong = |
| 314 'Continue running the isolate until it reaches the next source location ' | 331 'Continue running the isolate until it reaches the next source location ' |
| 315 'in the current function.\n' | 332 'in the current function.\n' |
| 316 '\n' | 333 '\n' |
| 334 'Hotkey: [F9]\n' |
| 335 '\n' |
| 317 'Syntax: next\n'; | 336 'Syntax: next\n'; |
| 318 } | 337 } |
| 319 | 338 |
| 320 class StepCommand extends DebuggerCommand { | 339 class StepCommand extends DebuggerCommand { |
| 321 StepCommand(Debugger debugger) : super(debugger, 'step', []) { | 340 StepCommand(Debugger debugger) : super(debugger, 'step', []) { |
| 322 alias = 's'; | 341 alias = 's'; |
| 323 } | 342 } |
| 324 | 343 |
| 325 Future run(List<String> args) { | 344 Future run(List<String> args) { |
| 326 if (debugger.isolatePaused()) { | 345 return debugger.step(); |
| 327 var event = debugger.isolate.pauseEvent; | |
| 328 if (event.kind == ServiceEvent.kPauseStart) { | |
| 329 debugger.console.print("Type 'continue' to start the isolate"); | |
| 330 return new Future.value(null); | |
| 331 } | |
| 332 if (event.kind == ServiceEvent.kPauseExit) { | |
| 333 debugger.console.print("Type 'continue' to exit the isolate"); | |
| 334 return new Future.value(null); | |
| 335 } | |
| 336 return debugger.isolate.stepInto(); | |
| 337 } else { | |
| 338 debugger.console.print('The program is already running'); | |
| 339 return new Future.value(null); | |
| 340 } | |
| 341 } | 346 } |
| 342 | 347 |
| 343 String helpShort = | 348 String helpShort = |
| 344 'Continue running the isolate until it reaches the next source location'; | 349 'Continue running the isolate until it reaches the next source location' |
| 350 ' (hotkey: [F10]'; |
| 345 | 351 |
| 346 String helpLong = | 352 String helpLong = |
| 347 'Continue running the isolate until it reaches the next source ' | 353 'Continue running the isolate until it reaches the next source ' |
| 348 'location.\n' | 354 'location.\n' |
| 349 '\n' | 355 '\n' |
| 356 'Hotkey: [F10]\n' |
| 357 '\n' |
| 350 'Syntax: step\n'; | 358 'Syntax: step\n'; |
| 351 } | 359 } |
| 352 | 360 |
| 361 class ClsCommand extends DebuggerCommand { |
| 362 ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} |
| 363 |
| 364 Future run(List<String> args) { |
| 365 debugger.console.clear(); |
| 366 debugger.console.newline(); |
| 367 return new Future.value(null); |
| 368 } |
| 369 |
| 370 String helpShort = 'Clear the console'; |
| 371 |
| 372 String helpLong = |
| 373 'Clear the console.\n' |
| 374 '\n' |
| 375 'Syntax: cls\n'; |
| 376 } |
| 377 |
| 353 class LogCommand extends DebuggerCommand { | 378 class LogCommand extends DebuggerCommand { |
| 354 LogCommand(Debugger debugger) : super(debugger, 'log', []); | 379 LogCommand(Debugger debugger) : super(debugger, 'log', []); |
| 355 | 380 |
| 356 Future run(List<String> args) async { | 381 Future run(List<String> args) async { |
| 357 if (args.length == 0) { | 382 if (args.length == 0) { |
| 358 debugger.console.print( | 383 debugger.console.print( |
| 359 'Current log level: ' | 384 'Current log level: ' |
| 360 '${debugger._consolePrinter._minimumLogLevel.name}'); | 385 '${debugger._consolePrinter._minimumLogLevel.name}'); |
| 361 return new Future.value(null); | 386 return new Future.value(null); |
| 362 } | 387 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 } | 566 } |
| 542 | 567 |
| 543 Future<List<String>> complete(List<String> args) { | 568 Future<List<String>> complete(List<String> args) { |
| 544 if (args.length != 1) { | 569 if (args.length != 1) { |
| 545 return new Future.value([args.join('')]); | 570 return new Future.value([args.join('')]); |
| 546 } | 571 } |
| 547 // TODO - fix DebuggerLocation complete | 572 // TODO - fix DebuggerLocation complete |
| 548 return new Future.value(DebuggerLocation.complete(debugger, args[0])); | 573 return new Future.value(DebuggerLocation.complete(debugger, args[0])); |
| 549 } | 574 } |
| 550 | 575 |
| 551 String helpShort = 'Add a breakpoint by source location or function name'; | 576 String helpShort = 'Add a breakpoint by source location or function name' |
| 577 ' (hotkey: [F8])'; |
| 552 | 578 |
| 553 String helpLong = | 579 String helpLong = |
| 554 'Add a breakpoint by source location or function name.\n' | 580 'Add a breakpoint by source location or function name.\n' |
| 555 '\n' | 581 '\n' |
| 582 'Hotkey: [F8]\n' |
| 583 '\n' |
| 556 'Syntax: break ' | 584 'Syntax: break ' |
| 557 '# Break at the current position\n' | 585 '# Break at the current position\n' |
| 558 ' break <line> ' | 586 ' break <line> ' |
| 559 '# Break at a line in the current script\n' | 587 '# Break at a line in the current script\n' |
| 560 ' ' | 588 ' ' |
| 561 ' (e.g \'break 11\')\n' | 589 ' (e.g \'break 11\')\n' |
| 562 ' break <line>:<col> ' | 590 ' break <line>:<col> ' |
| 563 '# Break at a line:col in the current script\n' | 591 '# Break at a line:col in the current script\n' |
| 564 ' ' | 592 ' ' |
| 565 ' (e.g \'break 11:8\')\n' | 593 ' (e.g \'break 11:8\')\n' |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 }); | 652 }); |
| 625 } | 653 } |
| 626 | 654 |
| 627 Future<List<String>> complete(List<String> args) { | 655 Future<List<String>> complete(List<String> args) { |
| 628 if (args.length != 1) { | 656 if (args.length != 1) { |
| 629 return new Future.value([args.join('')]); | 657 return new Future.value([args.join('')]); |
| 630 } | 658 } |
| 631 return new Future.value(DebuggerLocation.complete(debugger, args[0])); | 659 return new Future.value(DebuggerLocation.complete(debugger, args[0])); |
| 632 } | 660 } |
| 633 | 661 |
| 634 String helpShort = 'Remove a breakpoint by source location or function name'; | 662 String helpShort = 'Remove a breakpoint by source location or function name' |
| 663 ' (hotkey: [F8])'; |
| 635 | 664 |
| 636 String helpLong = | 665 String helpLong = |
| 637 'Remove a breakpoint by source location or function name.\n' | 666 'Remove a breakpoint by source location or function name.\n' |
| 638 '\n' | 667 '\n' |
| 668 'Hotkey: [F8]\n' |
| 669 '\n' |
| 639 'Syntax: clear ' | 670 'Syntax: clear ' |
| 640 '# Clear at the current position\n' | 671 '# Clear at the current position\n' |
| 641 ' clear <line> ' | 672 ' clear <line> ' |
| 642 '# Clear at a line in the current script\n' | 673 '# Clear at a line in the current script\n' |
| 643 ' ' | 674 ' ' |
| 644 ' (e.g \'clear 11\')\n' | 675 ' (e.g \'clear 11\')\n' |
| 645 ' clear <line>:<col> ' | 676 ' clear <line>:<col> ' |
| 646 '# Clear at a line:col in the current script\n' | 677 '# Clear at a line:col in the current script\n' |
| 647 ' ' | 678 ' ' |
| 648 ' (e.g \'clear 11:8\')\n' | 679 ' (e.g \'clear 11:8\')\n' |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 new AsyncNextCommand(this), | 1090 new AsyncNextCommand(this), |
| 1060 new FinishCommand(this), | 1091 new FinishCommand(this), |
| 1061 new BreakCommand(this), | 1092 new BreakCommand(this), |
| 1062 new SetCommand(this), | 1093 new SetCommand(this), |
| 1063 new ClearCommand(this), | 1094 new ClearCommand(this), |
| 1064 new DeleteCommand(this), | 1095 new DeleteCommand(this), |
| 1065 new InfoCommand(this), | 1096 new InfoCommand(this), |
| 1066 new IsolateCommand(this), | 1097 new IsolateCommand(this), |
| 1067 new RefreshCommand(this), | 1098 new RefreshCommand(this), |
| 1068 new LogCommand(this), | 1099 new LogCommand(this), |
| 1100 new ClsCommand(this), |
| 1069 ]); | 1101 ]); |
| 1070 _consolePrinter = new _ConsoleStreamPrinter(this); | 1102 _consolePrinter = new _ConsoleStreamPrinter(this); |
| 1071 } | 1103 } |
| 1072 | 1104 |
| 1073 VM get vm => page.app.vm; | 1105 VM get vm => page.app.vm; |
| 1074 | 1106 |
| 1075 void updateIsolate(Isolate iso) { | 1107 void updateIsolate(Isolate iso) { |
| 1076 _isolate = iso; | 1108 _isolate = iso; |
| 1077 if (_isolate != null) { | 1109 if (_isolate != null) { |
| 1078 if ((exceptions != iso.exceptionsPauseInfo) && | 1110 if ((exceptions != iso.exceptionsPauseInfo) && |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 _reportPause(_isolate.pauseEvent); | 1211 _reportPause(_isolate.pauseEvent); |
| 1180 } else { | 1212 } else { |
| 1181 console.print('Isolate is in unknown state'); | 1213 console.print('Isolate is in unknown state'); |
| 1182 } | 1214 } |
| 1183 warnOutOfDate(); | 1215 warnOutOfDate(); |
| 1184 } | 1216 } |
| 1185 | 1217 |
| 1186 void _reportPause(ServiceEvent event) { | 1218 void _reportPause(ServiceEvent event) { |
| 1187 if (event.kind == ServiceEvent.kPauseStart) { | 1219 if (event.kind == ServiceEvent.kPauseStart) { |
| 1188 console.print( | 1220 console.print( |
| 1189 "Paused at isolate start (type 'continue' to start the isolate')"); | 1221 "Paused at isolate start (type 'continue' or [F7] to start the isolate
')"); |
| 1190 } else if (event.kind == ServiceEvent.kPauseExit) { | 1222 } else if (event.kind == ServiceEvent.kPauseExit) { |
| 1191 console.print( | 1223 console.print( |
| 1192 "Paused at isolate exit (type 'continue' to exit the isolate')"); | 1224 "Paused at isolate exit (type 'continue' or [F7] to exit the isolate')
"); |
| 1193 } | 1225 } |
| 1194 if (stack['frames'].length > 0) { | 1226 if (stack['frames'].length > 0) { |
| 1195 Frame frame = stack['frames'][0]; | 1227 Frame frame = stack['frames'][0]; |
| 1196 var script = frame.location.script; | 1228 var script = frame.location.script; |
| 1197 script.load().then((_) { | 1229 script.load().then((_) { |
| 1198 var line = script.tokenToLine(frame.location.tokenPos); | 1230 var line = script.tokenToLine(frame.location.tokenPos); |
| 1199 var col = script.tokenToCol(frame.location.tokenPos); | 1231 var col = script.tokenToCol(frame.location.tokenPos); |
| 1200 if (event.breakpoint != null) { | 1232 if (event.breakpoint != null) { |
| 1201 var bpId = event.breakpoint.number; | 1233 var bpId = event.breakpoint.number; |
| 1202 console.print('Paused at breakpoint ${bpId} at ' | 1234 console.print('Paused at breakpoint ${bpId} at ' |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 }); | 1437 }); |
| 1406 } | 1438 } |
| 1407 | 1439 |
| 1408 String historyPrev(String command) { | 1440 String historyPrev(String command) { |
| 1409 return cmd.historyPrev(command); | 1441 return cmd.historyPrev(command); |
| 1410 } | 1442 } |
| 1411 | 1443 |
| 1412 String historyNext(String command) { | 1444 String historyNext(String command) { |
| 1413 return cmd.historyNext(command); | 1445 return cmd.historyNext(command); |
| 1414 } | 1446 } |
| 1447 |
| 1448 Future pause() { |
| 1449 if (!isolatePaused()) { |
| 1450 return isolate.pause(); |
| 1451 } else { |
| 1452 console.print('The program is already paused'); |
| 1453 return new Future.value(null); |
| 1454 } |
| 1455 } |
| 1456 |
| 1457 Future resume() { |
| 1458 if (isolatePaused()) { |
| 1459 return isolate.resume().then((_) { |
| 1460 warnOutOfDate(); |
| 1461 }); |
| 1462 } else { |
| 1463 console.print('The program must be paused'); |
| 1464 return new Future.value(null); |
| 1465 } |
| 1466 } |
| 1467 |
| 1468 Future toggleBreakpoint() async { |
| 1469 var loc = await DebuggerLocation.parse(this, ''); |
| 1470 var script = loc.script; |
| 1471 var line = loc.line; |
| 1472 if (script != null && line != null) { |
| 1473 var bpts = script.getLine(line).breakpoints; |
| 1474 if (bpts == null || bpts.isEmpty) { |
| 1475 // Set a new breakpoint. |
| 1476 // TODO(turnidge): Set this breakpoint at current column. |
| 1477 await isolate.addBreakpoint(script, line); |
| 1478 } else { |
| 1479 // TODO(turnidge): Clear this breakpoint at current column. |
| 1480 var pending = []; |
| 1481 for (var bpt in bpts) { |
| 1482 pending.add(isolate.removeBreakpoint(bpt)); |
| 1483 } |
| 1484 await Future.wait(pending); |
| 1485 } |
| 1486 } |
| 1487 return new Future.value(null); |
| 1488 } |
| 1489 |
| 1490 Future next() { |
| 1491 if (isolatePaused()) { |
| 1492 var event = isolate.pauseEvent; |
| 1493 if (event.kind == ServiceEvent.kPauseStart) { |
| 1494 console.print("Type 'continue' or [F7] to start the isolate"); |
| 1495 return new Future.value(null); |
| 1496 } |
| 1497 if (event.kind == ServiceEvent.kPauseExit) { |
| 1498 console.print("Type 'continue' or [F7] to exit the isolate"); |
| 1499 return new Future.value(null); |
| 1500 } |
| 1501 return isolate.stepOver(); |
| 1502 } else { |
| 1503 console.print('The program is already running'); |
| 1504 return new Future.value(null); |
| 1505 } |
| 1506 } |
| 1507 |
| 1508 Future step() { |
| 1509 if (isolatePaused()) { |
| 1510 var event = isolate.pauseEvent; |
| 1511 if (event.kind == ServiceEvent.kPauseStart) { |
| 1512 console.print("Type 'continue' or [F7] to start the isolate"); |
| 1513 return new Future.value(null); |
| 1514 } |
| 1515 if (event.kind == ServiceEvent.kPauseExit) { |
| 1516 console.print("Type 'continue' or [F7] to exit the isolate"); |
| 1517 return new Future.value(null); |
| 1518 } |
| 1519 return isolate.stepInto(); |
| 1520 } else { |
| 1521 console.print('The program is already running'); |
| 1522 return new Future.value(null); |
| 1523 } |
| 1524 } |
| 1415 } | 1525 } |
| 1416 | 1526 |
| 1417 @CustomTag('debugger-page') | 1527 @CustomTag('debugger-page') |
| 1418 class DebuggerPageElement extends ObservatoryElement { | 1528 class DebuggerPageElement extends ObservatoryElement { |
| 1419 @published Isolate isolate; | 1529 @published Isolate isolate; |
| 1420 | 1530 |
| 1421 isolateChanged(oldValue) { | 1531 isolateChanged(oldValue) { |
| 1422 if (isolate != null) { | 1532 if (isolate != null) { |
| 1423 debugger.updateIsolate(isolate); | 1533 debugger.updateIsolate(isolate); |
| 1424 } | 1534 } |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1937 refElement.ref = ref; | 2047 refElement.ref = ref; |
| 1938 _append(refElement); | 2048 _append(refElement); |
| 1939 if (newline) { | 2049 if (newline) { |
| 1940 this.newline(); | 2050 this.newline(); |
| 1941 } | 2051 } |
| 1942 } | 2052 } |
| 1943 | 2053 |
| 1944 void newline() { | 2054 void newline() { |
| 1945 _append(new BRElement()); | 2055 _append(new BRElement()); |
| 1946 } | 2056 } |
| 2057 |
| 2058 void clear() { |
| 2059 var consoleTextElement = $['consoleText']; |
| 2060 consoleTextElement.children.clear(); |
| 2061 } |
| 1947 } | 2062 } |
| 1948 | 2063 |
| 1949 @CustomTag('debugger-input') | 2064 @CustomTag('debugger-input') |
| 1950 class DebuggerInputElement extends ObservatoryElement { | 2065 class DebuggerInputElement extends ObservatoryElement { |
| 1951 @published Isolate isolate; | 2066 @published Isolate isolate; |
| 1952 @published String text = ''; | 2067 @published String text = ''; |
| 1953 @observable ObservatoryDebugger debugger; | 2068 @observable ObservatoryDebugger debugger; |
| 1954 @observable bool busy = false; | 2069 @observable bool busy = false; |
| 1955 | 2070 |
| 1956 @override | 2071 @override |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1990 text = debugger.historyPrev(text); | 2105 text = debugger.historyPrev(text); |
| 1991 busy = false; | 2106 busy = false; |
| 1992 break; | 2107 break; |
| 1993 | 2108 |
| 1994 case KeyCode.DOWN: | 2109 case KeyCode.DOWN: |
| 1995 e.preventDefault(); | 2110 e.preventDefault(); |
| 1996 text = debugger.historyNext(text); | 2111 text = debugger.historyNext(text); |
| 1997 busy = false; | 2112 busy = false; |
| 1998 break; | 2113 break; |
| 1999 | 2114 |
| 2115 case KeyCode.PAGE_UP: |
| 2116 e.preventDefault(); |
| 2117 try { |
| 2118 debugger.currentFrame -= 1; |
| 2119 } on RangeError catch (e) { |
| 2120 // Ignore. |
| 2121 } |
| 2122 busy = false; |
| 2123 break; |
| 2124 |
| 2125 case KeyCode.PAGE_DOWN: |
| 2126 e.preventDefault(); |
| 2127 try { |
| 2128 debugger.currentFrame += 1; |
| 2129 } on RangeError catch (e) { |
| 2130 // Ignore. |
| 2131 } |
| 2132 busy = false; |
| 2133 break; |
| 2134 |
| 2135 case KeyCode.F7: |
| 2136 e.preventDefault(); |
| 2137 debugger.resume().whenComplete(() { |
| 2138 busy = false; |
| 2139 }); |
| 2140 break; |
| 2141 |
| 2142 case KeyCode.F8: |
| 2143 e.preventDefault(); |
| 2144 debugger.toggleBreakpoint().whenComplete(() { |
| 2145 busy = false; |
| 2146 }); |
| 2147 break; |
| 2148 |
| 2149 case KeyCode.F9: |
| 2150 e.preventDefault(); |
| 2151 debugger.next().whenComplete(() { |
| 2152 busy = false; |
| 2153 }); |
| 2154 break; |
| 2155 |
| 2156 case KeyCode.F10: |
| 2157 e.preventDefault(); |
| 2158 debugger.step().whenComplete(() { |
| 2159 busy = false; |
| 2160 }); |
| 2161 break; |
| 2162 |
| 2163 case KeyCode.SEMICOLON: |
| 2164 if (e.ctrlKey) { |
| 2165 e.preventDefault(); |
| 2166 debugger.console.printRed('^;'); |
| 2167 debugger.pause().whenComplete(() { |
| 2168 busy = false; |
| 2169 }); |
| 2170 } else { |
| 2171 busy = false; |
| 2172 } |
| 2173 break; |
| 2174 |
| 2000 default: | 2175 default: |
| 2001 busy = false; | 2176 busy = false; |
| 2002 break; | 2177 break; |
| 2003 } | 2178 } |
| 2004 }); | 2179 }); |
| 2005 } | 2180 } |
| 2006 | 2181 |
| 2007 void focus() { | 2182 void focus() { |
| 2008 $['textBox'].focus(); | 2183 $['textBox'].focus(); |
| 2009 } | 2184 } |
| 2010 | 2185 |
| 2011 DebuggerInputElement.created() : super.created(); | 2186 DebuggerInputElement.created() : super.created(); |
| 2012 } | 2187 } |
| OLD | NEW |