| 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:svg'; | 8 import 'dart:svg'; |
| 9 import 'dart:html'; | 9 import 'dart:html'; |
| 10 import 'dart:math'; | 10 import 'dart:math'; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 import 'package:observatory/src/elements/nav/vm_menu.dart'; | 27 import 'package:observatory/src/elements/nav/vm_menu.dart'; |
| 28 import 'package:observatory/src/elements/source_inset.dart'; | 28 import 'package:observatory/src/elements/source_inset.dart'; |
| 29 import 'package:observatory/src/elements/source_link.dart'; | 29 import 'package:observatory/src/elements/source_link.dart'; |
| 30 import 'package:observatory/service.dart' as S; | 30 import 'package:observatory/service.dart' as S; |
| 31 import 'package:logging/logging.dart'; | 31 import 'package:logging/logging.dart'; |
| 32 | 32 |
| 33 // TODO(turnidge): Move Debugger, DebuggerCommand to debugger library. | 33 // TODO(turnidge): Move Debugger, DebuggerCommand to debugger library. |
| 34 abstract class DebuggerCommand extends Command { | 34 abstract class DebuggerCommand extends Command { |
| 35 ObservatoryDebugger debugger; | 35 ObservatoryDebugger debugger; |
| 36 | 36 |
| 37 DebuggerCommand(this.debugger, name, children) | 37 DebuggerCommand(this.debugger, name, children) : super(name, children); |
| 38 : super(name, children); | |
| 39 | 38 |
| 40 String get helpShort; | 39 String get helpShort; |
| 41 String get helpLong; | 40 String get helpLong; |
| 42 } | 41 } |
| 43 | 42 |
| 44 // TODO(turnidge): Rewrite HelpCommand so that it is a general utility | 43 // TODO(turnidge): Rewrite HelpCommand so that it is a general utility |
| 45 // provided by the cli library. | 44 // provided by the cli library. |
| 46 class HelpCommand extends DebuggerCommand { | 45 class HelpCommand extends DebuggerCommand { |
| 47 HelpCommand(Debugger debugger) : super(debugger, 'help', [ | 46 HelpCommand(Debugger debugger) |
| 48 new HelpHotkeysCommand(debugger), | 47 : super(debugger, 'help', [ |
| 49 ]); | 48 new HelpHotkeysCommand(debugger), |
| 49 ]); |
| 50 | 50 |
| 51 String _nameAndAlias(Command cmd) { | 51 String _nameAndAlias(Command cmd) { |
| 52 if (cmd.alias == null) { | 52 if (cmd.alias == null) { |
| 53 return cmd.fullName; | 53 return cmd.fullName; |
| 54 } else { | 54 } else { |
| 55 return '${cmd.fullName}, ${cmd.alias}'; | 55 return '${cmd.fullName}, ${cmd.alias}'; |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 Future run(List<String> args) { | 59 Future run(List<String> args) { |
| 60 var con = debugger.console; | 60 var con = debugger.console; |
| 61 if (args.length == 0) { | 61 if (args.length == 0) { |
| 62 // Print list of all top-level commands. | 62 // Print list of all top-level commands. |
| 63 var commands = debugger.cmd.matchCommand([], false); | 63 var commands = debugger.cmd.matchCommand([], false); |
| 64 commands.sort((a, b) => a.name.compareTo(b.name)); | 64 commands.sort((a, b) => a.name.compareTo(b.name)); |
| 65 con.print('List of commands:\n'); | 65 con.print('List of commands:\n'); |
| 66 for (var command in commands) { | 66 for (var command in commands) { |
| 67 con.print('${_nameAndAlias(command).padRight(12)} ' | 67 con.print('${_nameAndAlias(command).padRight(12)} ' |
| 68 '- ${command.helpShort}'); | 68 '- ${command.helpShort}'); |
| 69 } | 69 } |
| 70 con.print( | 70 con.print( |
| 71 "\nFor more information on a specific command type 'help <command>'\n" | 71 "\nFor more information on a specific command type 'help <command>'\n" |
| 72 "For a list of hotkeys type 'help hotkeys'\n" | 72 "For a list of hotkeys type 'help hotkeys'\n" |
| 73 "\n" | 73 "\n" |
| 74 "Command prefixes are accepted (e.g. 'h' for 'help')\n" | 74 "Command prefixes are accepted (e.g. 'h' for 'help')\n" |
| 75 "Hit [TAB] to complete a command (try 'is[TAB][TAB]')\n" | 75 "Hit [TAB] to complete a command (try 'is[TAB][TAB]')\n" |
| 76 "Hit [ENTER] to repeat the last command\n" | 76 "Hit [ENTER] to repeat the last command\n" |
| 77 "Use up/down arrow for command history\n"); | 77 "Use up/down arrow for command history\n"); |
| 78 return new Future.value(null); | 78 return new Future.value(null); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 94 newArgs.addAll(args.take(args.length - 1)); | 94 newArgs.addAll(args.take(args.length - 1)); |
| 95 newArgs.add(command.name); | 95 newArgs.add(command.name); |
| 96 newArgs.add(''); | 96 newArgs.add(''); |
| 97 var subCommands = debugger.cmd.matchCommand(newArgs, false); | 97 var subCommands = debugger.cmd.matchCommand(newArgs, false); |
| 98 subCommands.remove(command); | 98 subCommands.remove(command); |
| 99 if (subCommands.isNotEmpty) { | 99 if (subCommands.isNotEmpty) { |
| 100 subCommands.sort((a, b) => a.name.compareTo(b.name)); | 100 subCommands.sort((a, b) => a.name.compareTo(b.name)); |
| 101 con.print('Subcommands:\n'); | 101 con.print('Subcommands:\n'); |
| 102 for (var subCommand in subCommands) { | 102 for (var subCommand in subCommands) { |
| 103 con.print(' ${subCommand.fullName.padRight(16)} ' | 103 con.print(' ${subCommand.fullName.padRight(16)} ' |
| 104 '- ${subCommand.helpShort}'); | 104 '- ${subCommand.helpShort}'); |
| 105 } | 105 } |
| 106 con.print(''); | 106 con.print(''); |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 return new Future.value(null); | 109 return new Future.value(null); |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| 113 Future<List<String>> complete(List<String> args) { | 113 Future<List<String>> complete(List<String> args) { |
| 114 var commands = debugger.cmd.matchCommand(args, false); | 114 var commands = debugger.cmd.matchCommand(args, false); |
| 115 var result = commands.map((command) => '${command.fullName} '); | 115 var result = commands.map((command) => '${command.fullName} '); |
| 116 return new Future.value(result); | 116 return new Future.value(result); |
| 117 } | 117 } |
| 118 | 118 |
| 119 String helpShort = 'List commands or provide details about a specific command'
; | 119 String helpShort = |
| 120 'List commands or provide details about a specific command'; |
| 120 | 121 |
| 121 String helpLong = | 122 String helpLong = |
| 122 'List commands or provide details about a specific command.\n' | 123 'List commands or provide details about a specific command.\n' |
| 123 '\n' | 124 '\n' |
| 124 'Syntax: help - Show a list of all commands\n' | 125 'Syntax: help - Show a list of all commands\n' |
| 125 ' help <command> - Help for a specific command\n'; | 126 ' help <command> - Help for a specific command\n'; |
| 126 } | 127 } |
| 127 | 128 |
| 128 class HelpHotkeysCommand extends DebuggerCommand { | 129 class HelpHotkeysCommand extends DebuggerCommand { |
| 129 HelpHotkeysCommand(Debugger debugger) : super(debugger, 'hotkeys', []); | 130 HelpHotkeysCommand(Debugger debugger) : super(debugger, 'hotkeys', []); |
| 130 | 131 |
| 131 Future run(List<String> args) { | 132 Future run(List<String> args) { |
| 132 var con = debugger.console; | 133 var con = debugger.console; |
| 133 con.print("List of hotkeys:\n" | 134 con.print("List of hotkeys:\n" |
| 134 "\n" | 135 "\n" |
| 135 "[TAB] - complete a command\n" | 136 "[TAB] - complete a command\n" |
| 136 "[Up Arrow] - history previous\n" | 137 "[Up Arrow] - history previous\n" |
| 137 "[Down Arrow] - history next\n" | 138 "[Down Arrow] - history next\n" |
| 138 "\n" | 139 "\n" |
| 139 "[Page Up] - move up one frame\n" | 140 "[Page Up] - move up one frame\n" |
| 140 "[Page Down] - move down one frame\n" | 141 "[Page Down] - move down one frame\n" |
| 141 "\n" | 142 "\n" |
| 142 "[F7] - continue execution of the current isolate\n" | 143 "[F7] - continue execution of the current isolate\n" |
| 143 "[Ctrl ;] - pause execution of the current isolate\n" | 144 "[Ctrl ;] - pause execution of the current isolate\n" |
| 144 "\n" | 145 "\n" |
| 145 "[F8] - toggle breakpoint at current location\n" | 146 "[F8] - toggle breakpoint at current location\n" |
| 146 "[F9] - next\n" | 147 "[F9] - next\n" |
| 147 "[F10] - step\n" | 148 "[F10] - step\n" |
| 148 "\n"); | 149 "\n"); |
| 149 return new Future.value(null); | 150 return new Future.value(null); |
| 150 } | 151 } |
| 151 | 152 |
| 152 String helpShort = 'Provide a list of hotkeys'; | 153 String helpShort = 'Provide a list of hotkeys'; |
| 153 | 154 |
| 154 String helpLong = | 155 String helpLong = 'Provide a list of key hotkeys.\n' |
| 155 'Provide a list of key hotkeys.\n' | |
| 156 '\n' | 156 '\n' |
| 157 'Syntax: help hotkeys\n'; | 157 'Syntax: help hotkeys\n'; |
| 158 } | 158 } |
| 159 | 159 |
| 160 class PrintCommand extends DebuggerCommand { | 160 class PrintCommand extends DebuggerCommand { |
| 161 PrintCommand(Debugger debugger) : super(debugger, 'print', []) { | 161 PrintCommand(Debugger debugger) : super(debugger, 'print', []) { |
| 162 alias = 'p'; | 162 alias = 'p'; |
| 163 } | 163 } |
| 164 | 164 |
| 165 Future run(List<String> args) async { | 165 Future run(List<String> args) async { |
| 166 if (args.length < 1) { | 166 if (args.length < 1) { |
| 167 debugger.console.print('print expects arguments'); | 167 debugger.console.print('print expects arguments'); |
| 168 return; | 168 return; |
| 169 } | 169 } |
| 170 if (debugger.currentFrame == null) { | 170 if (debugger.currentFrame == null) { |
| 171 debugger.console.print('No stack'); | 171 debugger.console.print('No stack'); |
| 172 return; | 172 return; |
| 173 } | 173 } |
| 174 var expression = args.join(''); | 174 var expression = args.join(''); |
| 175 var response = await debugger.isolate.evalFrame(debugger.currentFrame, | 175 var response = |
| 176 expression); | 176 await debugger.isolate.evalFrame(debugger.currentFrame, expression); |
| 177 if (response is S.DartError) { | 177 if (response is S.DartError) { |
| 178 debugger.console.print(response.message); | 178 debugger.console.print(response.message); |
| 179 } else { | 179 } else { |
| 180 debugger.console.print('= ', newline:false); | 180 debugger.console.print('= ', newline: false); |
| 181 debugger.console.printRef(debugger.isolate, response, debugger.instances); | 181 debugger.console.printRef(debugger.isolate, response, debugger.instances); |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 String helpShort = 'Evaluate and print an expression in the current frame'; | 185 String helpShort = 'Evaluate and print an expression in the current frame'; |
| 186 | 186 |
| 187 String helpLong = | 187 String helpLong = 'Evaluate and print an expression in the current frame.\n' |
| 188 'Evaluate and print an expression in the current frame.\n' | |
| 189 '\n' | 188 '\n' |
| 190 'Syntax: print <expression>\n' | 189 'Syntax: print <expression>\n' |
| 191 ' p <expression>\n'; | 190 ' p <expression>\n'; |
| 192 } | 191 } |
| 193 | 192 |
| 194 class DownCommand extends DebuggerCommand { | 193 class DownCommand extends DebuggerCommand { |
| 195 DownCommand(Debugger debugger) : super(debugger, 'down', []); | 194 DownCommand(Debugger debugger) : super(debugger, 'down', []); |
| 196 | 195 |
| 197 Future run(List<String> args) { | 196 Future run(List<String> args) { |
| 198 int count = 1; | 197 int count = 1; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 210 debugger.downFrame(count); | 209 debugger.downFrame(count); |
| 211 debugger.console.print('frame = ${debugger.currentFrame}'); | 210 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 212 } catch (e) { | 211 } catch (e) { |
| 213 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); | 212 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 214 } | 213 } |
| 215 return new Future.value(null); | 214 return new Future.value(null); |
| 216 } | 215 } |
| 217 | 216 |
| 218 String helpShort = 'Move down one or more frames (hotkey: [Page Down])'; | 217 String helpShort = 'Move down one or more frames (hotkey: [Page Down])'; |
| 219 | 218 |
| 220 String helpLong = | 219 String helpLong = 'Move down one or more frames.\n' |
| 221 'Move down one or more frames.\n' | |
| 222 '\n' | 220 '\n' |
| 223 'Hotkey: [Page Down]\n' | 221 'Hotkey: [Page Down]\n' |
| 224 '\n' | 222 '\n' |
| 225 'Syntax: down\n' | 223 'Syntax: down\n' |
| 226 ' down <count>\n'; | 224 ' down <count>\n'; |
| 227 } | 225 } |
| 228 | 226 |
| 229 class UpCommand extends DebuggerCommand { | 227 class UpCommand extends DebuggerCommand { |
| 230 UpCommand(Debugger debugger) : super(debugger, 'up', []); | 228 UpCommand(Debugger debugger) : super(debugger, 'up', []); |
| 231 | 229 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 245 debugger.upFrame(count); | 243 debugger.upFrame(count); |
| 246 debugger.console.print('frame = ${debugger.currentFrame}'); | 244 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 247 } on RangeError catch (e) { | 245 } on RangeError catch (e) { |
| 248 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); | 246 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 249 } | 247 } |
| 250 return new Future.value(null); | 248 return new Future.value(null); |
| 251 } | 249 } |
| 252 | 250 |
| 253 String helpShort = 'Move up one or more frames (hotkey: [Page Up])'; | 251 String helpShort = 'Move up one or more frames (hotkey: [Page Up])'; |
| 254 | 252 |
| 255 String helpLong = | 253 String helpLong = 'Move up one or more frames.\n' |
| 256 'Move up one or more frames.\n' | |
| 257 '\n' | 254 '\n' |
| 258 'Hotkey: [Page Up]\n' | 255 'Hotkey: [Page Up]\n' |
| 259 '\n' | 256 '\n' |
| 260 'Syntax: up\n' | 257 'Syntax: up\n' |
| 261 ' up <count>\n'; | 258 ' up <count>\n'; |
| 262 } | 259 } |
| 263 | 260 |
| 264 class FrameCommand extends DebuggerCommand { | 261 class FrameCommand extends DebuggerCommand { |
| 265 FrameCommand(Debugger debugger) : super(debugger, 'frame', []) { | 262 FrameCommand(Debugger debugger) : super(debugger, 'frame', []) { |
| 266 alias = 'f'; | 263 alias = 'f'; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 282 debugger.currentFrame = frame; | 279 debugger.currentFrame = frame; |
| 283 debugger.console.print('frame = ${debugger.currentFrame}'); | 280 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 284 } on RangeError catch (e) { | 281 } on RangeError catch (e) { |
| 285 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); | 282 debugger.console.print('frame must be in range [${e.start},${e.end-1}]'); |
| 286 } | 283 } |
| 287 return new Future.value(null); | 284 return new Future.value(null); |
| 288 } | 285 } |
| 289 | 286 |
| 290 String helpShort = 'Set the current frame'; | 287 String helpShort = 'Set the current frame'; |
| 291 | 288 |
| 292 String helpLong = | 289 String helpLong = 'Set the current frame.\n' |
| 293 'Set the current frame.\n' | |
| 294 '\n' | 290 '\n' |
| 295 'Syntax: frame <number>\n' | 291 'Syntax: frame <number>\n' |
| 296 ' f <count>\n'; | 292 ' f <count>\n'; |
| 297 } | 293 } |
| 298 | 294 |
| 299 class PauseCommand extends DebuggerCommand { | 295 class PauseCommand extends DebuggerCommand { |
| 300 PauseCommand(Debugger debugger) : super(debugger, 'pause', []); | 296 PauseCommand(Debugger debugger) : super(debugger, 'pause', []); |
| 301 | 297 |
| 302 Future run(List<String> args) { | 298 Future run(List<String> args) { |
| 303 return debugger.pause(); | 299 return debugger.pause(); |
| 304 } | 300 } |
| 305 | 301 |
| 306 String helpShort = 'Pause the isolate (hotkey: [Ctrl ;])'; | 302 String helpShort = 'Pause the isolate (hotkey: [Ctrl ;])'; |
| 307 | 303 |
| 308 String helpLong = | 304 String helpLong = 'Pause the isolate.\n' |
| 309 'Pause the isolate.\n' | |
| 310 '\n' | 305 '\n' |
| 311 'Hotkey: [Ctrl ;]\n' | 306 'Hotkey: [Ctrl ;]\n' |
| 312 '\n' | 307 '\n' |
| 313 'Syntax: pause\n'; | 308 'Syntax: pause\n'; |
| 314 } | 309 } |
| 315 | 310 |
| 316 class ContinueCommand extends DebuggerCommand { | 311 class ContinueCommand extends DebuggerCommand { |
| 317 ContinueCommand(Debugger debugger) : super(debugger, 'continue', []) { | 312 ContinueCommand(Debugger debugger) : super(debugger, 'continue', []) { |
| 318 alias = 'c'; | 313 alias = 'c'; |
| 319 } | 314 } |
| 320 | 315 |
| 321 Future run(List<String> args) { | 316 Future run(List<String> args) { |
| 322 return debugger.resume(); | 317 return debugger.resume(); |
| 323 } | 318 } |
| 324 | 319 |
| 325 String helpShort = 'Resume execution of the isolate (hotkey: [F7])'; | 320 String helpShort = 'Resume execution of the isolate (hotkey: [F7])'; |
| 326 | 321 |
| 327 String helpLong = | 322 String helpLong = 'Continue running the isolate.\n' |
| 328 'Continue running the isolate.\n' | |
| 329 '\n' | 323 '\n' |
| 330 'Hotkey: [F7]\n' | 324 'Hotkey: [F7]\n' |
| 331 '\n' | 325 '\n' |
| 332 'Syntax: continue\n' | 326 'Syntax: continue\n' |
| 333 ' c\n'; | 327 ' c\n'; |
| 334 } | 328 } |
| 335 | 329 |
| 336 class SmartNextCommand extends DebuggerCommand { | 330 class SmartNextCommand extends DebuggerCommand { |
| 337 SmartNextCommand(Debugger debugger) : super(debugger, 'next', []) { | 331 SmartNextCommand(Debugger debugger) : super(debugger, 'next', []) { |
| 338 alias = 'n'; | 332 alias = 'n'; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 355 'Syntax: next\n'; | 349 'Syntax: next\n'; |
| 356 } | 350 } |
| 357 | 351 |
| 358 class SyncNextCommand extends DebuggerCommand { | 352 class SyncNextCommand extends DebuggerCommand { |
| 359 SyncNextCommand(Debugger debugger) : super(debugger, 'next-sync', []); | 353 SyncNextCommand(Debugger debugger) : super(debugger, 'next-sync', []); |
| 360 | 354 |
| 361 Future run(List<String> args) { | 355 Future run(List<String> args) { |
| 362 return debugger.syncNext(); | 356 return debugger.syncNext(); |
| 363 } | 357 } |
| 364 | 358 |
| 365 String helpShort = | 359 String helpShort = 'Run until return/unwind to current activation.'; |
| 366 'Run until return/unwind to current activation.'; | |
| 367 | 360 |
| 368 String helpLong = | 361 String helpLong = |
| 369 'Continue running the isolate until control returns to the current ' | 362 'Continue running the isolate until control returns to the current ' |
| 370 'activation or one of its callers.\n' | 363 'activation or one of its callers.\n' |
| 371 '\n' | 364 '\n' |
| 372 'Syntax: next-sync\n'; | 365 'Syntax: next-sync\n'; |
| 373 } | 366 } |
| 374 | 367 |
| 375 class AsyncNextCommand extends DebuggerCommand { | 368 class AsyncNextCommand extends DebuggerCommand { |
| 376 AsyncNextCommand(Debugger debugger) : super(debugger, 'next-async', []); | 369 AsyncNextCommand(Debugger debugger) : super(debugger, 'next-async', []); |
| 377 | 370 |
| 378 Future run(List<String> args) { | 371 Future run(List<String> args) { |
| 379 return debugger.asyncNext(); | 372 return debugger.asyncNext(); |
| 380 } | 373 } |
| 381 | 374 |
| 382 String helpShort = | 375 String helpShort = 'Step over await or yield'; |
| 383 'Step over await or yield'; | |
| 384 | 376 |
| 385 String helpLong = | 377 String helpLong = |
| 386 'Continue running the isolate until control returns to the current ' | 378 'Continue running the isolate until control returns to the current ' |
| 387 'activation of an async or async* function.\n' | 379 'activation of an async or async* function.\n' |
| 388 '\n' | 380 '\n' |
| 389 'Syntax: next-async\n'; | 381 'Syntax: next-async\n'; |
| 390 } | 382 } |
| 391 | 383 |
| 392 class StepCommand extends DebuggerCommand { | 384 class StepCommand extends DebuggerCommand { |
| 393 StepCommand(Debugger debugger) : super(debugger, 'step', []) { | 385 StepCommand(Debugger debugger) : super(debugger, 'step', []) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 415 ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} | 407 ClsCommand(Debugger debugger) : super(debugger, 'cls', []) {} |
| 416 | 408 |
| 417 Future run(List<String> args) { | 409 Future run(List<String> args) { |
| 418 debugger.console.clear(); | 410 debugger.console.clear(); |
| 419 debugger.console.newline(); | 411 debugger.console.newline(); |
| 420 return new Future.value(null); | 412 return new Future.value(null); |
| 421 } | 413 } |
| 422 | 414 |
| 423 String helpShort = 'Clear the console'; | 415 String helpShort = 'Clear the console'; |
| 424 | 416 |
| 425 String helpLong = | 417 String helpLong = 'Clear the console.\n' |
| 426 'Clear the console.\n' | |
| 427 '\n' | 418 '\n' |
| 428 'Syntax: cls\n'; | 419 'Syntax: cls\n'; |
| 429 } | 420 } |
| 430 | 421 |
| 431 class LogCommand extends DebuggerCommand { | 422 class LogCommand extends DebuggerCommand { |
| 432 LogCommand(Debugger debugger) : super(debugger, 'log', []); | 423 LogCommand(Debugger debugger) : super(debugger, 'log', []); |
| 433 | 424 |
| 434 Future run(List<String> args) async { | 425 Future run(List<String> args) async { |
| 435 if (args.length == 0) { | 426 if (args.length == 0) { |
| 436 debugger.console.print( | 427 debugger.console.print('Current log level: ' |
| 437 'Current log level: ' | |
| 438 '${debugger._consolePrinter._minimumLogLevel.name}'); | 428 '${debugger._consolePrinter._minimumLogLevel.name}'); |
| 439 return new Future.value(null); | 429 return new Future.value(null); |
| 440 } | 430 } |
| 441 if (args.length > 1) { | 431 if (args.length > 1) { |
| 442 debugger.console.print("log expects zero or one arguments"); | 432 debugger.console.print("log expects zero or one arguments"); |
| 443 return new Future.value(null); | 433 return new Future.value(null); |
| 444 } | 434 } |
| 445 var level = _findLevel(args[0]); | 435 var level = _findLevel(args[0]); |
| 446 if (level == null) { | 436 if (level == null) { |
| 447 debugger.console.print('No such log level: ${args[0]}'); | 437 debugger.console.print('No such log level: ${args[0]}'); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 469 var prefix = args[0].toUpperCase(); | 459 var prefix = args[0].toUpperCase(); |
| 470 var result = <String>[]; | 460 var result = <String>[]; |
| 471 for (var level in Level.LEVELS) { | 461 for (var level in Level.LEVELS) { |
| 472 if (level.name.startsWith(prefix)) { | 462 if (level.name.startsWith(prefix)) { |
| 473 result.add(level.name); | 463 result.add(level.name); |
| 474 } | 464 } |
| 475 } | 465 } |
| 476 return new Future.value(result); | 466 return new Future.value(result); |
| 477 } | 467 } |
| 478 | 468 |
| 479 String helpShort = | 469 String helpShort = 'Control which log messages are displayed'; |
| 480 'Control which log messages are displayed'; | |
| 481 | 470 |
| 482 String helpLong = | 471 String helpLong = |
| 483 'Get or set the minimum log level that should be displayed.\n' | 472 'Get or set the minimum log level that should be displayed.\n' |
| 484 '\n' | 473 '\n' |
| 485 'Log levels (in ascending order): ALL, FINEST, FINER, FINE, CONFIG, ' | 474 'Log levels (in ascending order): ALL, FINEST, FINER, FINE, CONFIG, ' |
| 486 'INFO, WARNING, SEVERE, SHOUT, OFF\n' | 475 'INFO, WARNING, SEVERE, SHOUT, OFF\n' |
| 487 '\n' | 476 '\n' |
| 488 'Default: OFF\n' | 477 'Default: OFF\n' |
| 489 '\n' | 478 '\n' |
| 490 'Syntax: log ' | 479 'Syntax: log ' |
| 491 '# Display the current minimum log level.\n' | 480 '# Display the current minimum log level.\n' |
| 492 ' log <level> ' | 481 ' log <level> ' |
| 493 '# Set the minimum log level to <level>.\n' | 482 '# Set the minimum log level to <level>.\n' |
| 494 ' log OFF ' | 483 ' log OFF ' |
| 495 '# Display no log messages.\n' | 484 '# Display no log messages.\n' |
| 496 ' log ALL ' | 485 ' log ALL ' |
| 497 '# Display all log messages.\n'; | 486 '# Display all log messages.\n'; |
| 498 } | 487 } |
| 499 | 488 |
| 500 class FinishCommand extends DebuggerCommand { | 489 class FinishCommand extends DebuggerCommand { |
| 501 FinishCommand(Debugger debugger) : super(debugger, 'finish', []); | 490 FinishCommand(Debugger debugger) : super(debugger, 'finish', []); |
| 502 | 491 |
| 503 Future run(List<String> args) { | 492 Future run(List<String> args) { |
| 504 if (debugger.isolatePaused()) { | 493 if (debugger.isolatePaused()) { |
| 505 var event = debugger.isolate.pauseEvent; | 494 var event = debugger.isolate.pauseEvent; |
| 506 if (event is M.PauseStartEvent) { | 495 if (event is M.PauseStartEvent) { |
| 507 debugger.console.print( | 496 debugger.console |
| 508 "Type 'continue' [F7] or 'step' [F10] to start the isolate"); | 497 .print("Type 'continue' [F7] or 'step' [F10] to start the isolate"); |
| 509 return new Future.value(null); | 498 return new Future.value(null); |
| 510 } | 499 } |
| 511 if (event is M.PauseExitEvent) { | 500 if (event is M.PauseExitEvent) { |
| 512 debugger.console.print("Type 'continue' [F7] to exit the isolate"); | 501 debugger.console.print("Type 'continue' [F7] to exit the isolate"); |
| 513 return new Future.value(null); | 502 return new Future.value(null); |
| 514 } | 503 } |
| 515 return debugger.isolate.stepOut(); | 504 return debugger.isolate.stepOut(); |
| 516 } else { | 505 } else { |
| 517 debugger.console.print('The program is already running'); | 506 debugger.console.print('The program is already running'); |
| 518 return new Future.value(null); | 507 return new Future.value(null); |
| 519 } | 508 } |
| 520 } | 509 } |
| 521 | 510 |
| 522 String helpShort = | 511 String helpShort = |
| 523 'Continue running the isolate until the current function exits'; | 512 'Continue running the isolate until the current function exits'; |
| 524 | 513 |
| 525 String helpLong = | 514 String helpLong = |
| 526 'Continue running the isolate until the current function exits.\n' | 515 'Continue running the isolate until the current function exits.\n' |
| 527 '\n' | 516 '\n' |
| 528 'Syntax: finish\n'; | 517 'Syntax: finish\n'; |
| 529 } | 518 } |
| 530 | 519 |
| 531 class SetCommand extends DebuggerCommand { | 520 class SetCommand extends DebuggerCommand { |
| 532 SetCommand(Debugger debugger) | 521 SetCommand(Debugger debugger) : super(debugger, 'set', []); |
| 533 : super(debugger, 'set', []); | |
| 534 | 522 |
| 535 static var _boeValues = ['All', 'None', 'Unhandled']; | 523 static var _boeValues = ['All', 'None', 'Unhandled']; |
| 536 static var _boolValues = ['false', 'true']; | 524 static var _boolValues = ['false', 'true']; |
| 537 | 525 |
| 538 static var _options = { | 526 static var _options = { |
| 539 'break-on-exception': [_boeValues, | 527 'break-on-exception': [ |
| 540 _setBreakOnException, | 528 _boeValues, |
| 541 (debugger, _) => debugger.breakOnException], | 529 _setBreakOnException, |
| 542 'up-is-down': [_boolValues, | 530 (debugger, _) => debugger.breakOnException |
| 543 _setUpIsDown, | 531 ], |
| 544 (debugger, _) => debugger.upIsDown], | 532 'up-is-down': [ |
| 533 _boolValues, |
| 534 _setUpIsDown, |
| 535 (debugger, _) => debugger.upIsDown |
| 536 ], |
| 545 }; | 537 }; |
| 546 | 538 |
| 547 static Future _setBreakOnException(debugger, name, value) async { | 539 static Future _setBreakOnException(debugger, name, value) async { |
| 548 var result = await debugger.isolate.setExceptionPauseMode(value); | 540 var result = await debugger.isolate.setExceptionPauseMode(value); |
| 549 if (result.isError) { | 541 if (result.isError) { |
| 550 debugger.console.print(result.toString()); | 542 debugger.console.print(result.toString()); |
| 551 } else { | 543 } else { |
| 552 // Printing will occur elsewhere. | 544 // Printing will occur elsewhere. |
| 553 debugger.breakOnException = value; | 545 debugger.breakOnException = value; |
| 554 } | 546 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 for (var value in validValues) { | 615 for (var value in validValues) { |
| 624 if (value.startsWith(prefix)) { | 616 if (value.startsWith(prefix)) { |
| 625 result.add('${args[0]}${value} '); | 617 result.add('${args[0]}${value} '); |
| 626 } | 618 } |
| 627 } | 619 } |
| 628 } | 620 } |
| 629 } | 621 } |
| 630 return new Future.value(result); | 622 return new Future.value(result); |
| 631 } | 623 } |
| 632 | 624 |
| 633 String helpShort = | 625 String helpShort = 'Set a debugger option'; |
| 634 'Set a debugger option'; | |
| 635 | 626 |
| 636 String helpLong = | 627 String helpLong = 'Set a debugger option.\n' |
| 637 'Set a debugger option.\n' | |
| 638 '\n' | 628 '\n' |
| 639 'Known options:\n' | 629 'Known options:\n' |
| 640 ' break-on-exception # Should the debugger break on exceptions?\n' | 630 ' break-on-exception # Should the debugger break on exceptions?\n' |
| 641 " # ${_boeValues}\n" | 631 " # ${_boeValues}\n" |
| 642 ' up-is-down # Reverse meaning of up/down commands?\n' | 632 ' up-is-down # Reverse meaning of up/down commands?\n' |
| 643 " # ${_boolValues}\n" | 633 " # ${_boolValues}\n" |
| 644 '\n' | 634 '\n' |
| 645 'Syntax: set # Display all option settings\n' | 635 'Syntax: set # Display all option settings\n' |
| 646 ' set <option> # Get current value for option\n' | 636 ' set <option> # Get current value for option\n' |
| 647 ' set <option> <value> # Set value for option'; | 637 ' set <option> <value> # Set value for option'; |
| 648 } | 638 } |
| 649 | 639 |
| 650 class BreakCommand extends DebuggerCommand { | 640 class BreakCommand extends DebuggerCommand { |
| 651 BreakCommand(Debugger debugger) : super(debugger, 'break', []); | 641 BreakCommand(Debugger debugger) : super(debugger, 'break', []); |
| 652 | 642 |
| 653 Future run(List<String> args) async { | 643 Future run(List<String> args) async { |
| 654 if (args.length > 1) { | 644 if (args.length > 1) { |
| 655 debugger.console.print('not implemented'); | 645 debugger.console.print('not implemented'); |
| 656 return; | 646 return; |
| 657 } | 647 } |
| 658 var arg = (args.length == 0 ? '' : args[0]); | 648 var arg = (args.length == 0 ? '' : args[0]); |
| 659 var loc = await DebuggerLocation.parse(debugger, arg); | 649 var loc = await DebuggerLocation.parse(debugger, arg); |
| 660 if (loc.valid) { | 650 if (loc.valid) { |
| 661 if (loc.function != null) { | 651 if (loc.function != null) { |
| 662 try { | 652 try { |
| 663 await debugger.isolate.addBreakpointAtEntry(loc.function); | 653 await debugger.isolate.addBreakpointAtEntry(loc.function); |
| 664 } on S.ServerRpcException catch(e) { | 654 } on S.ServerRpcException catch (e) { |
| 665 if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { | 655 if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { |
| 666 debugger.console.print('Unable to set breakpoint at ${loc}'); | 656 debugger.console.print('Unable to set breakpoint at ${loc}'); |
| 667 } else { | 657 } else { |
| 668 rethrow; | 658 rethrow; |
| 669 } | 659 } |
| 670 } | 660 } |
| 671 } else { | 661 } else { |
| 672 assert(loc.script != null); | 662 assert(loc.script != null); |
| 673 var script = loc.script; | 663 var script = loc.script; |
| 674 await script.load(); | 664 await script.load(); |
| 675 if (loc.line < 1 || loc.line > script.lines.length) { | 665 if (loc.line < 1 || loc.line > script.lines.length) { |
| 676 debugger.console.print( | 666 debugger.console |
| 677 'line number must be in range [1,${script.lines.length}]'); | 667 .print('line number must be in range [1,${script.lines.length}]'); |
| 678 return; | 668 return; |
| 679 } | 669 } |
| 680 try { | 670 try { |
| 681 await debugger.isolate.addBreakpoint(script, loc.line, loc.col); | 671 await debugger.isolate.addBreakpoint(script, loc.line, loc.col); |
| 682 } on S.ServerRpcException catch(e) { | 672 } on S.ServerRpcException catch (e) { |
| 683 if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { | 673 if (e.code == S.ServerRpcException.kCannotAddBreakpoint) { |
| 684 debugger.console.print('Unable to set breakpoint at ${loc}'); | 674 debugger.console.print('Unable to set breakpoint at ${loc}'); |
| 685 } else { | 675 } else { |
| 686 rethrow; | 676 rethrow; |
| 687 } | 677 } |
| 688 } | 678 } |
| 689 } | 679 } |
| 690 } else { | 680 } else { |
| 691 debugger.console.print(loc.errorMessage); | 681 debugger.console.print(loc.errorMessage); |
| 692 } | 682 } |
| 693 } | 683 } |
| 694 | 684 |
| 695 Future<List<String>> complete(List<String> args) { | 685 Future<List<String>> complete(List<String> args) { |
| 696 if (args.length != 1) { | 686 if (args.length != 1) { |
| 697 return new Future.value([args.join('')]); | 687 return new Future.value([args.join('')]); |
| 698 } | 688 } |
| 699 // TODO - fix DebuggerLocation complete | 689 // TODO - fix DebuggerLocation complete |
| 700 return new Future.value(DebuggerLocation.complete(debugger, args[0])); | 690 return new Future.value(DebuggerLocation.complete(debugger, args[0])); |
| 701 } | 691 } |
| 702 | 692 |
| 703 String helpShort = 'Add a breakpoint by source location or function name' | 693 String helpShort = 'Add a breakpoint by source location or function name' |
| 704 ' (hotkey: [F8])'; | 694 ' (hotkey: [F8])'; |
| 705 | 695 |
| 706 String helpLong = | 696 String helpLong = 'Add a breakpoint by source location or function name.\n' |
| 707 'Add a breakpoint by source location or function name.\n' | |
| 708 '\n' | 697 '\n' |
| 709 'Hotkey: [F8]\n' | 698 'Hotkey: [F8]\n' |
| 710 '\n' | 699 '\n' |
| 711 'Syntax: break ' | 700 'Syntax: break ' |
| 712 '# Break at the current position\n' | 701 '# Break at the current position\n' |
| 713 ' break <line> ' | 702 ' break <line> ' |
| 714 '# Break at a line in the current script\n' | 703 '# Break at a line in the current script\n' |
| 715 ' ' | 704 ' ' |
| 716 ' (e.g \'break 11\')\n' | 705 ' (e.g \'break 11\')\n' |
| 717 ' break <line>:<col> ' | 706 ' break <line>:<col> ' |
| (...skipping 22 matching lines...) Expand all Loading... |
| 740 debugger.console.print('not implemented'); | 729 debugger.console.print('not implemented'); |
| 741 return; | 730 return; |
| 742 } | 731 } |
| 743 var arg = (args.length == 0 ? '' : args[0]); | 732 var arg = (args.length == 0 ? '' : args[0]); |
| 744 var loc = await DebuggerLocation.parse(debugger, arg); | 733 var loc = await DebuggerLocation.parse(debugger, arg); |
| 745 if (!loc.valid) { | 734 if (!loc.valid) { |
| 746 debugger.console.print(loc.errorMessage); | 735 debugger.console.print(loc.errorMessage); |
| 747 return; | 736 return; |
| 748 } | 737 } |
| 749 if (loc.function != null) { | 738 if (loc.function != null) { |
| 750 debugger.console.print( | 739 debugger.console.print('Ignoring breakpoint at $loc: ' |
| 751 'Ignoring breakpoint at $loc: ' | |
| 752 'Clearing function breakpoints not yet implemented'); | 740 'Clearing function breakpoints not yet implemented'); |
| 753 return; | 741 return; |
| 754 } | 742 } |
| 755 | 743 |
| 756 var script = loc.script; | 744 var script = loc.script; |
| 757 if (loc.line < 1 || loc.line > script.lines.length) { | 745 if (loc.line < 1 || loc.line > script.lines.length) { |
| 758 debugger.console.print( | 746 debugger.console |
| 759 'line number must be in range [1,${script.lines.length}]'); | 747 .print('line number must be in range [1,${script.lines.length}]'); |
| 760 return; | 748 return; |
| 761 } | 749 } |
| 762 var lineInfo = script.getLine(loc.line); | 750 var lineInfo = script.getLine(loc.line); |
| 763 var bpts = lineInfo.breakpoints; | 751 var bpts = lineInfo.breakpoints; |
| 764 var foundBreakpoint = false; | 752 var foundBreakpoint = false; |
| 765 if (bpts != null) { | 753 if (bpts != null) { |
| 766 var bptList = bpts.toList(); | 754 var bptList = bpts.toList(); |
| 767 for (var bpt in bptList) { | 755 for (var bpt in bptList) { |
| 768 if (loc.col == null || | 756 if (loc.col == null || |
| 769 loc.col == script.tokenToCol(bpt.location.tokenPos)) { | 757 loc.col == script.tokenToCol(bpt.location.tokenPos)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 784 Future<List<String>> complete(List<String> args) { | 772 Future<List<String>> complete(List<String> args) { |
| 785 if (args.length != 1) { | 773 if (args.length != 1) { |
| 786 return new Future.value([args.join('')]); | 774 return new Future.value([args.join('')]); |
| 787 } | 775 } |
| 788 return new Future.value(DebuggerLocation.complete(debugger, args[0])); | 776 return new Future.value(DebuggerLocation.complete(debugger, args[0])); |
| 789 } | 777 } |
| 790 | 778 |
| 791 String helpShort = 'Remove a breakpoint by source location or function name' | 779 String helpShort = 'Remove a breakpoint by source location or function name' |
| 792 ' (hotkey: [F8])'; | 780 ' (hotkey: [F8])'; |
| 793 | 781 |
| 794 String helpLong = | 782 String helpLong = 'Remove a breakpoint by source location or function name.\n' |
| 795 'Remove a breakpoint by source location or function name.\n' | |
| 796 '\n' | 783 '\n' |
| 797 'Hotkey: [F8]\n' | 784 'Hotkey: [F8]\n' |
| 798 '\n' | 785 '\n' |
| 799 'Syntax: clear ' | 786 'Syntax: clear ' |
| 800 '# Clear at the current position\n' | 787 '# Clear at the current position\n' |
| 801 ' clear <line> ' | 788 ' clear <line> ' |
| 802 '# Clear at a line in the current script\n' | 789 '# Clear at a line in the current script\n' |
| 803 ' ' | 790 ' ' |
| 804 ' (e.g \'clear 11\')\n' | 791 ' (e.g \'clear 11\')\n' |
| 805 ' clear <line>:<col> ' | 792 ' clear <line>:<col> ' |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 } | 834 } |
| 848 List pending = []; | 835 List pending = []; |
| 849 for (var bpt in toRemove) { | 836 for (var bpt in toRemove) { |
| 850 pending.add(debugger.isolate.removeBreakpoint(bpt)); | 837 pending.add(debugger.isolate.removeBreakpoint(bpt)); |
| 851 } | 838 } |
| 852 return Future.wait(pending); | 839 return Future.wait(pending); |
| 853 } | 840 } |
| 854 | 841 |
| 855 String helpShort = 'Remove a breakpoint by breakpoint id'; | 842 String helpShort = 'Remove a breakpoint by breakpoint id'; |
| 856 | 843 |
| 857 String helpLong = | 844 String helpLong = 'Remove a breakpoint by breakpoint id.\n' |
| 858 'Remove a breakpoint by breakpoint id.\n' | |
| 859 '\n' | 845 '\n' |
| 860 'Syntax: delete <bp-id>\n' | 846 'Syntax: delete <bp-id>\n' |
| 861 ' delete <bp-id> <bp-id> ...\n'; | 847 ' delete <bp-id> <bp-id> ...\n'; |
| 862 } | 848 } |
| 863 | 849 |
| 864 class InfoBreakpointsCommand extends DebuggerCommand { | 850 class InfoBreakpointsCommand extends DebuggerCommand { |
| 865 InfoBreakpointsCommand(Debugger debugger) | 851 InfoBreakpointsCommand(Debugger debugger) |
| 866 : super(debugger, 'breakpoints', []); | 852 : super(debugger, 'breakpoints', []); |
| 867 | 853 |
| 868 Future run(List<String> args) async { | 854 Future run(List<String> args) async { |
| 869 if (debugger.isolate.breakpoints.isEmpty) { | 855 if (debugger.isolate.breakpoints.isEmpty) { |
| 870 debugger.console.print('No breakpoints'); | 856 debugger.console.print('No breakpoints'); |
| 871 } | 857 } |
| 872 List bpts = debugger.isolate.breakpoints.values.toList(); | 858 List bpts = debugger.isolate.breakpoints.values.toList(); |
| 873 bpts.sort((a, b) => a.number - b.number); | 859 bpts.sort((a, b) => a.number - b.number); |
| 874 for (var bpt in bpts) { | 860 for (var bpt in bpts) { |
| 875 var bpId = bpt.number; | 861 var bpId = bpt.number; |
| 876 var locString = await bpt.location.toUserString(); | 862 var locString = await bpt.location.toUserString(); |
| 877 if (!bpt.resolved) { | 863 if (!bpt.resolved) { |
| 878 debugger.console.print( | 864 debugger.console.print('Future breakpoint ${bpId} at ${locString}'); |
| 879 'Future breakpoint ${bpId} at ${locString}'); | |
| 880 } else { | 865 } else { |
| 881 debugger.console.print( | 866 debugger.console.print('Breakpoint ${bpId} at ${locString}'); |
| 882 'Breakpoint ${bpId} at ${locString}'); | |
| 883 } | 867 } |
| 884 } | 868 } |
| 885 } | 869 } |
| 886 | 870 |
| 887 String helpShort = 'List all breakpoints'; | 871 String helpShort = 'List all breakpoints'; |
| 888 | 872 |
| 889 String helpLong = | 873 String helpLong = 'List all breakpoints.\n' |
| 890 'List all breakpoints.\n' | |
| 891 '\n' | 874 '\n' |
| 892 'Syntax: info breakpoints\n'; | 875 'Syntax: info breakpoints\n'; |
| 893 } | 876 } |
| 894 | 877 |
| 895 class InfoFrameCommand extends DebuggerCommand { | 878 class InfoFrameCommand extends DebuggerCommand { |
| 896 InfoFrameCommand(Debugger debugger) : super(debugger, 'frame', []); | 879 InfoFrameCommand(Debugger debugger) : super(debugger, 'frame', []); |
| 897 | 880 |
| 898 Future run(List<String> args) { | 881 Future run(List<String> args) { |
| 899 if (args.length > 0) { | 882 if (args.length > 0) { |
| 900 debugger.console.print('info frame expects no arguments'); | 883 debugger.console.print('info frame expects no arguments'); |
| 901 return new Future.value(null); | 884 return new Future.value(null); |
| 902 } | 885 } |
| 903 debugger.console.print('frame = ${debugger.currentFrame}'); | 886 debugger.console.print('frame = ${debugger.currentFrame}'); |
| 904 return new Future.value(null); | 887 return new Future.value(null); |
| 905 } | 888 } |
| 906 | 889 |
| 907 String helpShort = 'Show current frame'; | 890 String helpShort = 'Show current frame'; |
| 908 | 891 |
| 909 String helpLong = | 892 String helpLong = 'Show current frame.\n' |
| 910 'Show current frame.\n' | |
| 911 '\n' | 893 '\n' |
| 912 'Syntax: info frame\n'; | 894 'Syntax: info frame\n'; |
| 913 } | 895 } |
| 914 | 896 |
| 915 class IsolateCommand extends DebuggerCommand { | 897 class IsolateCommand extends DebuggerCommand { |
| 916 IsolateCommand(Debugger debugger) : super(debugger, 'isolate', [ | 898 IsolateCommand(Debugger debugger) |
| 917 new IsolateListCommand(debugger), | 899 : super(debugger, 'isolate', [ |
| 918 new IsolateNameCommand(debugger), | 900 new IsolateListCommand(debugger), |
| 919 new IsolateReloadCommand(debugger), | 901 new IsolateNameCommand(debugger), |
| 920 ]) { | 902 new IsolateReloadCommand(debugger), |
| 903 ]) { |
| 921 alias = 'i'; | 904 alias = 'i'; |
| 922 } | 905 } |
| 923 | 906 |
| 924 Future run(List<String> args) { | 907 Future run(List<String> args) { |
| 925 if (args.length != 1) { | 908 if (args.length != 1) { |
| 926 debugger.console.print('isolate expects one argument'); | 909 debugger.console.print('isolate expects one argument'); |
| 927 return new Future.value(null); | 910 return new Future.value(null); |
| 928 } | 911 } |
| 929 var arg = args[0].trim(); | 912 var arg = args[0].trim(); |
| 930 var num = int.parse(arg, onError:(_) => null); | 913 var num = int.parse(arg, onError: (_) => null); |
| 931 | 914 |
| 932 var candidate; | 915 var candidate; |
| 933 for (var isolate in debugger.vm.isolates) { | 916 for (var isolate in debugger.vm.isolates) { |
| 934 if (num != null && num == isolate.number) { | 917 if (num != null && num == isolate.number) { |
| 935 candidate = isolate; | 918 candidate = isolate; |
| 936 break; | 919 break; |
| 937 } else if (arg == isolate.name) { | 920 } else if (arg == isolate.name) { |
| 938 if (candidate != null) { | 921 if (candidate != null) { |
| 939 debugger.console.print( | 922 debugger.console.print("Isolate identifier '${arg}' is ambiguous: " |
| 940 "Isolate identifier '${arg}' is ambiguous: " | |
| 941 'use the isolate number instead'); | 923 'use the isolate number instead'); |
| 942 return new Future.value(null); | 924 return new Future.value(null); |
| 943 } | 925 } |
| 944 candidate = isolate; | 926 candidate = isolate; |
| 945 } | 927 } |
| 946 } | 928 } |
| 947 if (candidate == null) { | 929 if (candidate == null) { |
| 948 debugger.console.print("Invalid isolate identifier '${arg}'"); | 930 debugger.console.print("Invalid isolate identifier '${arg}'"); |
| 949 } else { | 931 } else { |
| 950 if (candidate == debugger.isolate) { | 932 if (candidate == debugger.isolate) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 968 result.add('$str '); | 950 result.add('$str '); |
| 969 } | 951 } |
| 970 } | 952 } |
| 971 for (var isolate in debugger.vm.isolates) { | 953 for (var isolate in debugger.vm.isolates) { |
| 972 if (isolate.name.startsWith(args[0])) { | 954 if (isolate.name.startsWith(args[0])) { |
| 973 result.add('${isolate.name} '); | 955 result.add('${isolate.name} '); |
| 974 } | 956 } |
| 975 } | 957 } |
| 976 return new Future.value(result); | 958 return new Future.value(result); |
| 977 } | 959 } |
| 960 |
| 978 String helpShort = 'Switch, list, rename, or reload isolates'; | 961 String helpShort = 'Switch, list, rename, or reload isolates'; |
| 979 | 962 |
| 980 String helpLong = | 963 String helpLong = 'Switch the current isolate.\n' |
| 981 'Switch the current isolate.\n' | |
| 982 '\n' | 964 '\n' |
| 983 'Syntax: isolate <number>\n' | 965 'Syntax: isolate <number>\n' |
| 984 ' isolate <name>\n'; | 966 ' isolate <name>\n'; |
| 985 } | 967 } |
| 986 | 968 |
| 987 String _isolateRunState(S.Isolate isolate) { | 969 String _isolateRunState(S.Isolate isolate) { |
| 988 if (isolate.paused) { | 970 if (isolate.paused) { |
| 989 return 'paused'; | 971 return 'paused'; |
| 990 } else if (isolate.running) { | 972 } else if (isolate.running) { |
| 991 return 'running'; | 973 return 'running'; |
| 992 } else if (isolate.idle) { | 974 } else if (isolate.idle) { |
| 993 return 'idle'; | 975 return 'idle'; |
| 994 } else { | 976 } else { |
| 995 return 'unknown'; | 977 return 'unknown'; |
| 996 } | 978 } |
| 997 } | 979 } |
| 998 | 980 |
| 999 class IsolateListCommand extends DebuggerCommand { | 981 class IsolateListCommand extends DebuggerCommand { |
| 1000 IsolateListCommand(Debugger debugger) : super(debugger, 'list', []); | 982 IsolateListCommand(Debugger debugger) : super(debugger, 'list', []); |
| 1001 | 983 |
| 1002 Future run(List<String> args) async { | 984 Future run(List<String> args) async { |
| 1003 if (debugger.vm == null) { | 985 if (debugger.vm == null) { |
| 1004 debugger.console.print( | 986 debugger.console.print("Internal error: vm has not been set"); |
| 1005 "Internal error: vm has not been set"); | |
| 1006 return; | 987 return; |
| 1007 } | 988 } |
| 1008 | 989 |
| 1009 // Refresh all isolates first. | 990 // Refresh all isolates first. |
| 1010 var pending = []; | 991 var pending = []; |
| 1011 for (var isolate in debugger.vm.isolates) { | 992 for (var isolate in debugger.vm.isolates) { |
| 1012 pending.add(isolate.reload()); | 993 pending.add(isolate.reload()); |
| 1013 } | 994 } |
| 1014 await Future.wait(pending); | 995 await Future.wait(pending); |
| 1015 | 996 |
| 1016 const maxIdLen = 10; | 997 const maxIdLen = 10; |
| 1017 const maxRunStateLen = 7; | 998 const maxRunStateLen = 7; |
| 1018 var maxNameLen = 'NAME'.length; | 999 var maxNameLen = 'NAME'.length; |
| 1019 for (var isolate in debugger.vm.isolates) { | 1000 for (var isolate in debugger.vm.isolates) { |
| 1020 maxNameLen = max(maxNameLen, isolate.name.length); | 1001 maxNameLen = max(maxNameLen, isolate.name.length); |
| 1021 } | 1002 } |
| 1022 debugger.console.print("${'ID'.padLeft(maxIdLen, ' ')} " | 1003 debugger.console.print("${'ID'.padLeft(maxIdLen, ' ')} " |
| 1023 "${'ORIGIN'.padLeft(maxIdLen, ' ')} " | 1004 "${'ORIGIN'.padLeft(maxIdLen, ' ')} " |
| 1024 "${'NAME'.padRight(maxNameLen, ' ')} " | 1005 "${'NAME'.padRight(maxNameLen, ' ')} " |
| 1025 "${'STATE'.padRight(maxRunStateLen, ' ')} " | 1006 "${'STATE'.padRight(maxRunStateLen, ' ')} " |
| 1026 "CURRENT"); | 1007 "CURRENT"); |
| 1027 for (var isolate in debugger.vm.isolates) { | 1008 for (var isolate in debugger.vm.isolates) { |
| 1028 String current = (isolate == debugger.isolate ? '*' : ''); | 1009 String current = (isolate == debugger.isolate ? '*' : ''); |
| 1029 debugger.console.print( | 1010 debugger.console |
| 1030 "${isolate.number.toString().padLeft(maxIdLen, ' ')} " | 1011 .print("${isolate.number.toString().padLeft(maxIdLen, ' ')} " |
| 1031 "${isolate.originNumber.toString().padLeft(maxIdLen, ' ')} " | 1012 "${isolate.originNumber.toString().padLeft(maxIdLen, ' ')} " |
| 1032 "${isolate.name.padRight(maxNameLen, ' ')} " | 1013 "${isolate.name.padRight(maxNameLen, ' ')} " |
| 1033 "${_isolateRunState(isolate).padRight(maxRunStateLen, ' ')} " | 1014 "${_isolateRunState(isolate).padRight(maxRunStateLen, ' ')} " |
| 1034 "${current}"); | 1015 "${current}"); |
| 1035 } | 1016 } |
| 1036 debugger.console.newline(); | 1017 debugger.console.newline(); |
| 1037 } | 1018 } |
| 1038 | 1019 |
| 1039 String helpShort = 'List all isolates'; | 1020 String helpShort = 'List all isolates'; |
| 1040 | 1021 |
| 1041 String helpLong = | 1022 String helpLong = 'List all isolates.\n' |
| 1042 'List all isolates.\n' | |
| 1043 '\n' | 1023 '\n' |
| 1044 'Syntax: isolate list\n'; | 1024 'Syntax: isolate list\n'; |
| 1045 } | 1025 } |
| 1046 | 1026 |
| 1047 class IsolateNameCommand extends DebuggerCommand { | 1027 class IsolateNameCommand extends DebuggerCommand { |
| 1048 IsolateNameCommand(Debugger debugger) : super(debugger, 'name', []); | 1028 IsolateNameCommand(Debugger debugger) : super(debugger, 'name', []); |
| 1049 | 1029 |
| 1050 Future run(List<String> args) { | 1030 Future run(List<String> args) { |
| 1051 if (args.length != 1) { | 1031 if (args.length != 1) { |
| 1052 debugger.console.print('isolate name expects one argument'); | 1032 debugger.console.print('isolate name expects one argument'); |
| 1053 return new Future.value(null); | 1033 return new Future.value(null); |
| 1054 } | 1034 } |
| 1055 return debugger.isolate.setName(args[0]); | 1035 return debugger.isolate.setName(args[0]); |
| 1056 } | 1036 } |
| 1057 | 1037 |
| 1058 String helpShort = 'Rename the current isolate'; | 1038 String helpShort = 'Rename the current isolate'; |
| 1059 | 1039 |
| 1060 String helpLong = | 1040 String helpLong = 'Rename the current isolate.\n' |
| 1061 'Rename the current isolate.\n' | |
| 1062 '\n' | 1041 '\n' |
| 1063 'Syntax: isolate name <name>\n'; | 1042 'Syntax: isolate name <name>\n'; |
| 1064 } | 1043 } |
| 1065 | 1044 |
| 1066 class IsolateReloadCommand extends DebuggerCommand { | 1045 class IsolateReloadCommand extends DebuggerCommand { |
| 1067 IsolateReloadCommand(Debugger debugger) : super(debugger, 'reload', []); | 1046 IsolateReloadCommand(Debugger debugger) : super(debugger, 'reload', []); |
| 1068 | 1047 |
| 1069 Future run(List<String> args) async { | 1048 Future run(List<String> args) async { |
| 1070 if (debugger.isolate == null) { | 1049 if (debugger.isolate == null) { |
| 1071 debugger.console.print('There is no current vm'); | 1050 debugger.console.print('There is no current vm'); |
| 1072 return; | 1051 return; |
| 1073 } | 1052 } |
| 1074 | 1053 |
| 1075 await debugger.isolate.reloadSources(); | 1054 await debugger.isolate.reloadSources(); |
| 1076 | 1055 |
| 1077 debugger.console.print('Isolate reloading....'); | 1056 debugger.console.print('Isolate reloading....'); |
| 1078 } | 1057 } |
| 1079 | 1058 |
| 1080 String helpShort = 'Reload the sources for the current isolate.'; | 1059 String helpShort = 'Reload the sources for the current isolate.'; |
| 1081 | 1060 |
| 1082 String helpLong = | 1061 String helpLong = 'Reload the sources for the current isolate.\n' |
| 1083 'Reload the sources for the current isolate.\n' | |
| 1084 '\n' | 1062 '\n' |
| 1085 'Syntax: reload\n'; | 1063 'Syntax: reload\n'; |
| 1086 } | 1064 } |
| 1087 | 1065 |
| 1088 class InfoCommand extends DebuggerCommand { | 1066 class InfoCommand extends DebuggerCommand { |
| 1089 InfoCommand(Debugger debugger) : super(debugger, 'info', [ | 1067 InfoCommand(Debugger debugger) |
| 1090 new InfoBreakpointsCommand(debugger), | 1068 : super(debugger, 'info', [ |
| 1091 new InfoFrameCommand(debugger)]); | 1069 new InfoBreakpointsCommand(debugger), |
| 1070 new InfoFrameCommand(debugger) |
| 1071 ]); |
| 1092 | 1072 |
| 1093 Future run(List<String> args) { | 1073 Future run(List<String> args) { |
| 1094 debugger.console.print("'info' expects a subcommand (see 'help info')"); | 1074 debugger.console.print("'info' expects a subcommand (see 'help info')"); |
| 1095 return new Future.value(null); | 1075 return new Future.value(null); |
| 1096 } | 1076 } |
| 1097 | 1077 |
| 1098 String helpShort = 'Show information on a variety of topics'; | 1078 String helpShort = 'Show information on a variety of topics'; |
| 1099 | 1079 |
| 1100 String helpLong = | 1080 String helpLong = 'Show information on a variety of topics.\n' |
| 1101 'Show information on a variety of topics.\n' | |
| 1102 '\n' | 1081 '\n' |
| 1103 'Syntax: info <subcommand>\n'; | 1082 'Syntax: info <subcommand>\n'; |
| 1104 } | 1083 } |
| 1105 | 1084 |
| 1106 class RefreshStackCommand extends DebuggerCommand { | 1085 class RefreshStackCommand extends DebuggerCommand { |
| 1107 RefreshStackCommand(Debugger debugger) : super(debugger, 'stack', []); | 1086 RefreshStackCommand(Debugger debugger) : super(debugger, 'stack', []); |
| 1108 | 1087 |
| 1109 Future run(List<String> args) { | 1088 Future run(List<String> args) { |
| 1110 return debugger.refreshStack(); | 1089 return debugger.refreshStack(); |
| 1111 } | 1090 } |
| 1112 | 1091 |
| 1113 String helpShort = 'Refresh isolate stack'; | 1092 String helpShort = 'Refresh isolate stack'; |
| 1114 | 1093 |
| 1115 String helpLong = | 1094 String helpLong = 'Refresh isolate stack.\n' |
| 1116 'Refresh isolate stack.\n' | |
| 1117 '\n' | 1095 '\n' |
| 1118 'Syntax: refresh stack\n'; | 1096 'Syntax: refresh stack\n'; |
| 1119 } | 1097 } |
| 1120 | 1098 |
| 1121 class RefreshCommand extends DebuggerCommand { | 1099 class RefreshCommand extends DebuggerCommand { |
| 1122 RefreshCommand(Debugger debugger) : super(debugger, 'refresh', [ | 1100 RefreshCommand(Debugger debugger) |
| 1123 new RefreshStackCommand(debugger), | 1101 : super(debugger, 'refresh', [ |
| 1124 ]); | 1102 new RefreshStackCommand(debugger), |
| 1103 ]); |
| 1125 | 1104 |
| 1126 Future run(List<String> args) { | 1105 Future run(List<String> args) { |
| 1127 debugger.console.print("'refresh' expects a subcommand (see 'help refresh')"
); | 1106 debugger.console |
| 1107 .print("'refresh' expects a subcommand (see 'help refresh')"); |
| 1128 return new Future.value(null); | 1108 return new Future.value(null); |
| 1129 } | 1109 } |
| 1130 | 1110 |
| 1131 String helpShort = 'Refresh debugging information of various sorts'; | 1111 String helpShort = 'Refresh debugging information of various sorts'; |
| 1132 | 1112 |
| 1133 String helpLong = | 1113 String helpLong = 'Refresh debugging information of various sorts.\n' |
| 1134 'Refresh debugging information of various sorts.\n' | |
| 1135 '\n' | 1114 '\n' |
| 1136 'Syntax: refresh <subcommand>\n'; | 1115 'Syntax: refresh <subcommand>\n'; |
| 1137 } | 1116 } |
| 1138 | 1117 |
| 1139 class VmListCommand extends DebuggerCommand { | 1118 class VmListCommand extends DebuggerCommand { |
| 1140 VmListCommand(Debugger debugger) : super(debugger, 'list', []); | 1119 VmListCommand(Debugger debugger) : super(debugger, 'list', []); |
| 1141 | 1120 |
| 1142 Future run(List<String> args) async { | 1121 Future run(List<String> args) async { |
| 1143 if (args.length > 0) { | 1122 if (args.length > 0) { |
| 1144 debugger.console.print('vm list expects no arguments'); | 1123 debugger.console.print('vm list expects no arguments'); |
| 1145 return; | 1124 return; |
| 1146 } | 1125 } |
| 1147 if (debugger.vm == null) { | 1126 if (debugger.vm == null) { |
| 1148 debugger.console.print("No connected VMs"); | 1127 debugger.console.print("No connected VMs"); |
| 1149 return; | 1128 return; |
| 1150 } | 1129 } |
| 1151 // TODO(turnidge): Right now there is only one vm listed. | 1130 // TODO(turnidge): Right now there is only one vm listed. |
| 1152 var vmList = [debugger.vm]; | 1131 var vmList = [debugger.vm]; |
| 1153 | 1132 |
| 1154 var maxAddrLen = 'ADDRESS'.length; | 1133 var maxAddrLen = 'ADDRESS'.length; |
| 1155 var maxNameLen = 'NAME'.length; | 1134 var maxNameLen = 'NAME'.length; |
| 1156 | 1135 |
| 1157 for (var vm in vmList) { | 1136 for (var vm in vmList) { |
| 1158 maxAddrLen = max(maxAddrLen, vm.target.networkAddress.length); | 1137 maxAddrLen = max(maxAddrLen, vm.target.networkAddress.length); |
| 1159 maxNameLen = max(maxNameLen, vm.name.length); | 1138 maxNameLen = max(maxNameLen, vm.name.length); |
| 1160 } | 1139 } |
| 1161 | 1140 |
| 1162 debugger.console.print("${'ADDRESS'.padRight(maxAddrLen, ' ')} " | 1141 debugger.console.print("${'ADDRESS'.padRight(maxAddrLen, ' ')} " |
| 1163 "${'NAME'.padRight(maxNameLen, ' ')} " | 1142 "${'NAME'.padRight(maxNameLen, ' ')} " |
| 1164 "CURRENT"); | 1143 "CURRENT"); |
| 1165 for (var vm in vmList) { | 1144 for (var vm in vmList) { |
| 1166 String current = (vm == debugger.vm ? '*' : ''); | 1145 String current = (vm == debugger.vm ? '*' : ''); |
| 1167 debugger.console.print( | 1146 debugger.console |
| 1168 "${vm.target.networkAddress.padRight(maxAddrLen, ' ')} " | 1147 .print("${vm.target.networkAddress.padRight(maxAddrLen, ' ')} " |
| 1169 "${vm.name.padRight(maxNameLen, ' ')} " | 1148 "${vm.name.padRight(maxNameLen, ' ')} " |
| 1170 "${current}"); | 1149 "${current}"); |
| 1171 } | 1150 } |
| 1172 } | 1151 } |
| 1173 | 1152 |
| 1174 String helpShort = 'List all connected Dart virtual machines'; | 1153 String helpShort = 'List all connected Dart virtual machines'; |
| 1175 | 1154 |
| 1176 String helpLong = | 1155 String helpLong = 'List all connected Dart virtual machines..\n' |
| 1177 'List all connected Dart virtual machines..\n' | |
| 1178 '\n' | 1156 '\n' |
| 1179 'Syntax: vm list\n'; | 1157 'Syntax: vm list\n'; |
| 1180 } | 1158 } |
| 1181 | 1159 |
| 1182 class VmNameCommand extends DebuggerCommand { | 1160 class VmNameCommand extends DebuggerCommand { |
| 1183 VmNameCommand(Debugger debugger) : super(debugger, 'name', []); | 1161 VmNameCommand(Debugger debugger) : super(debugger, 'name', []); |
| 1184 | 1162 |
| 1185 Future run(List<String> args) async { | 1163 Future run(List<String> args) async { |
| 1186 if (args.length != 1) { | 1164 if (args.length != 1) { |
| 1187 debugger.console.print('vm name expects one argument'); | 1165 debugger.console.print('vm name expects one argument'); |
| 1188 return; | 1166 return; |
| 1189 } | 1167 } |
| 1190 if (debugger.vm == null) { | 1168 if (debugger.vm == null) { |
| 1191 debugger.console.print('There is no current vm'); | 1169 debugger.console.print('There is no current vm'); |
| 1192 return; | 1170 return; |
| 1193 } | 1171 } |
| 1194 await debugger.vm.setName(args[0]); | 1172 await debugger.vm.setName(args[0]); |
| 1195 } | 1173 } |
| 1196 | 1174 |
| 1197 String helpShort = 'Rename the current Dart virtual machine'; | 1175 String helpShort = 'Rename the current Dart virtual machine'; |
| 1198 | 1176 |
| 1199 String helpLong = | 1177 String helpLong = 'Rename the current Dart virtual machine.\n' |
| 1200 'Rename the current Dart virtual machine.\n' | |
| 1201 '\n' | 1178 '\n' |
| 1202 'Syntax: vm name <name>\n'; | 1179 'Syntax: vm name <name>\n'; |
| 1203 } | 1180 } |
| 1204 | 1181 |
| 1205 class VmRestartCommand extends DebuggerCommand { | 1182 class VmRestartCommand extends DebuggerCommand { |
| 1206 VmRestartCommand(Debugger debugger) : super(debugger, 'restart', []); | 1183 VmRestartCommand(Debugger debugger) : super(debugger, 'restart', []); |
| 1207 | 1184 |
| 1208 Future handleModalInput(String line) async { | 1185 Future handleModalInput(String line) async { |
| 1209 if (line == 'yes') { | 1186 if (line == 'yes') { |
| 1210 debugger.console.printRed('Restarting VM...'); | 1187 debugger.console.printRed('Restarting VM...'); |
| 1211 await debugger.vm.restart(); | 1188 await debugger.vm.restart(); |
| 1212 debugger.input.exitMode(); | 1189 debugger.input.exitMode(); |
| 1213 } else if (line == 'no') { | 1190 } else if (line == 'no') { |
| 1214 debugger.console.printRed('VM restart canceled.'); | 1191 debugger.console.printRed('VM restart canceled.'); |
| 1215 debugger.input.exitMode(); | 1192 debugger.input.exitMode(); |
| 1216 } else { | 1193 } else { |
| 1217 debugger.console.printRed("Please type 'yes' or 'no'"); | 1194 debugger.console.printRed("Please type 'yes' or 'no'"); |
| 1218 } | 1195 } |
| 1219 } | 1196 } |
| 1220 | 1197 |
| 1221 Future run(List<String> args) async { | 1198 Future run(List<String> args) async { |
| 1222 debugger.input.enterMode('Restart vm? (yes/no)', handleModalInput); | 1199 debugger.input.enterMode('Restart vm? (yes/no)', handleModalInput); |
| 1223 } | 1200 } |
| 1224 | 1201 |
| 1225 String helpShort = 'Restart a Dart virtual machine'; | 1202 String helpShort = 'Restart a Dart virtual machine'; |
| 1226 | 1203 |
| 1227 String helpLong = | 1204 String helpLong = 'Restart a Dart virtual machine.\n' |
| 1228 'Restart a Dart virtual machine.\n' | |
| 1229 '\n' | 1205 '\n' |
| 1230 'Syntax: vm restart\n'; | 1206 'Syntax: vm restart\n'; |
| 1231 } | 1207 } |
| 1232 | 1208 |
| 1233 class VmCommand extends DebuggerCommand { | 1209 class VmCommand extends DebuggerCommand { |
| 1234 VmCommand(Debugger debugger) : super(debugger, 'vm', [ | 1210 VmCommand(Debugger debugger) |
| 1235 new VmListCommand(debugger), | 1211 : super(debugger, 'vm', [ |
| 1236 new VmNameCommand(debugger), | 1212 new VmListCommand(debugger), |
| 1237 new VmRestartCommand(debugger), | 1213 new VmNameCommand(debugger), |
| 1238 ]); | 1214 new VmRestartCommand(debugger), |
| 1215 ]); |
| 1239 | 1216 |
| 1240 Future run(List<String> args) async { | 1217 Future run(List<String> args) async { |
| 1241 debugger.console.print("'vm' expects a subcommand (see 'help vm')"); | 1218 debugger.console.print("'vm' expects a subcommand (see 'help vm')"); |
| 1242 } | 1219 } |
| 1243 | 1220 |
| 1244 String helpShort = 'Manage a Dart virtual machine'; | 1221 String helpShort = 'Manage a Dart virtual machine'; |
| 1245 | 1222 |
| 1246 String helpLong = | 1223 String helpLong = 'Manage a Dart virtual machine.\n' |
| 1247 'Manage a Dart virtual machine.\n' | |
| 1248 '\n' | 1224 '\n' |
| 1249 'Syntax: vm <subcommand>\n'; | 1225 'Syntax: vm <subcommand>\n'; |
| 1250 } | 1226 } |
| 1251 | 1227 |
| 1252 class _ConsoleStreamPrinter { | 1228 class _ConsoleStreamPrinter { |
| 1253 ObservatoryDebugger _debugger; | 1229 ObservatoryDebugger _debugger; |
| 1254 | 1230 |
| 1255 _ConsoleStreamPrinter(this._debugger); | 1231 _ConsoleStreamPrinter(this._debugger); |
| 1256 Level _minimumLogLevel = Level.OFF; | 1232 Level _minimumLogLevel = Level.OFF; |
| 1257 String _savedStream; | 1233 String _savedStream; |
| 1258 String _savedIsolate; | 1234 String _savedIsolate; |
| 1259 String _savedLine; | 1235 String _savedLine; |
| 1260 List<String> _buffer = []; | 1236 List<String> _buffer = []; |
| 1261 | 1237 |
| 1262 void onEvent(String streamName, S.ServiceEvent event) { | 1238 void onEvent(String streamName, S.ServiceEvent event) { |
| 1263 if (event.kind == S.ServiceEvent.kLogging) { | 1239 if (event.kind == S.ServiceEvent.kLogging) { |
| 1264 // Check if we should print this log message. | 1240 // Check if we should print this log message. |
| 1265 if (event.logRecord['level'].value < _minimumLogLevel.value) { | 1241 if (event.logRecord['level'].value < _minimumLogLevel.value) { |
| 1266 return; | 1242 return; |
| 1267 } | 1243 } |
| 1268 } | 1244 } |
| 1269 String isolateName = event.isolate.name; | 1245 String isolateName = event.isolate.name; |
| 1270 // If we get a line from a different isolate/stream, flush | 1246 // If we get a line from a different isolate/stream, flush |
| 1271 // any pending output, even if it is not newline-terminated. | 1247 // any pending output, even if it is not newline-terminated. |
| 1272 if ((_savedIsolate != null && isolateName != _savedIsolate) || | 1248 if ((_savedIsolate != null && isolateName != _savedIsolate) || |
| 1273 (_savedStream != null && streamName != _savedStream)) { | 1249 (_savedStream != null && streamName != _savedStream)) { |
| 1274 flush(); | 1250 flush(); |
| 1275 } | 1251 } |
| 1276 String data; | 1252 String data; |
| 1277 bool hasNewline; | 1253 bool hasNewline; |
| 1278 if (event.kind == S.ServiceEvent.kLogging) { | 1254 if (event.kind == S.ServiceEvent.kLogging) { |
| 1279 data = event.logRecord["message"].valueAsString; | 1255 data = event.logRecord["message"].valueAsString; |
| 1280 hasNewline = true; | 1256 hasNewline = true; |
| 1281 } else { | 1257 } else { |
| 1282 data = event.bytesAsString; | 1258 data = event.bytesAsString; |
| 1283 hasNewline = data.endsWith('\n'); | 1259 hasNewline = data.endsWith('\n'); |
| 1284 } | 1260 } |
| 1285 if (_savedLine != null) { | 1261 if (_savedLine != null) { |
| 1286 data = _savedLine + data; | 1262 data = _savedLine + data; |
| 1287 _savedIsolate = null; | 1263 _savedIsolate = null; |
| 1288 _savedStream = null; | 1264 _savedStream = null; |
| 1289 _savedLine = null; | 1265 _savedLine = null; |
| 1290 } | 1266 } |
| 1291 var lines = data.split('\n').where((line) => line != '').toList(); | 1267 var lines = data.split('\n').where((line) => line != '').toList(); |
| 1292 if (lines.isEmpty) { | 1268 if (lines.isEmpty) { |
| 1293 return; | 1269 return; |
| 1294 } | 1270 } |
| 1295 int limit = (hasNewline ? lines.length : lines.length - 1); | 1271 int limit = (hasNewline ? lines.length : lines.length - 1); |
| 1296 for (int i = 0; i < limit; i++) { | 1272 for (int i = 0; i < limit; i++) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1326 // Tracks the state for an isolate debugging session. | 1302 // Tracks the state for an isolate debugging session. |
| 1327 class ObservatoryDebugger extends Debugger { | 1303 class ObservatoryDebugger extends Debugger { |
| 1328 final SettingsGroup settings = new SettingsGroup('debugger'); | 1304 final SettingsGroup settings = new SettingsGroup('debugger'); |
| 1329 RootCommand cmd; | 1305 RootCommand cmd; |
| 1330 DebuggerPageElement page; | 1306 DebuggerPageElement page; |
| 1331 DebuggerConsoleElement console; | 1307 DebuggerConsoleElement console; |
| 1332 DebuggerInputElement input; | 1308 DebuggerInputElement input; |
| 1333 DebuggerStackElement stackElement; | 1309 DebuggerStackElement stackElement; |
| 1334 S.ServiceMap stack; | 1310 S.ServiceMap stack; |
| 1335 final S.Isolate isolate; | 1311 final S.Isolate isolate; |
| 1336 String breakOnException = "none"; // Last known setting. | 1312 String breakOnException = "none"; // Last known setting. |
| 1337 | 1313 |
| 1338 int get currentFrame => _currentFrame; | 1314 int get currentFrame => _currentFrame; |
| 1339 | 1315 |
| 1340 void set currentFrame(int value) { | 1316 void set currentFrame(int value) { |
| 1341 if (value != null && (value < 0 || value >= stackDepth)) { | 1317 if (value != null && (value < 0 || value >= stackDepth)) { |
| 1342 throw new RangeError.range(value, 0, stackDepth); | 1318 throw new RangeError.range(value, 0, stackDepth); |
| 1343 } | 1319 } |
| 1344 _currentFrame = value; | 1320 _currentFrame = value; |
| 1345 if (stackElement != null) { | 1321 if (stackElement != null) { |
| 1346 stackElement.setCurrentFrame(value); | 1322 stackElement.setCurrentFrame(value); |
| 1347 } | 1323 } |
| 1348 } | 1324 } |
| 1325 |
| 1349 int _currentFrame = null; | 1326 int _currentFrame = null; |
| 1350 | 1327 |
| 1351 bool get upIsDown => _upIsDown; | 1328 bool get upIsDown => _upIsDown; |
| 1352 void set upIsDown(bool value) { | 1329 void set upIsDown(bool value) { |
| 1353 settings.set('up-is-down', value); | 1330 settings.set('up-is-down', value); |
| 1354 _upIsDown = value; | 1331 _upIsDown = value; |
| 1355 } | 1332 } |
| 1333 |
| 1356 bool _upIsDown; | 1334 bool _upIsDown; |
| 1357 | 1335 |
| 1358 void upFrame(int count) { | 1336 void upFrame(int count) { |
| 1359 if (_upIsDown) { | 1337 if (_upIsDown) { |
| 1360 currentFrame += count; | 1338 currentFrame += count; |
| 1361 } else { | 1339 } else { |
| 1362 currentFrame -= count; | 1340 currentFrame -= count; |
| 1363 } | 1341 } |
| 1364 } | 1342 } |
| 1365 | 1343 |
| 1366 void downFrame(int count) { | 1344 void downFrame(int count) { |
| 1367 if (_upIsDown) { | 1345 if (_upIsDown) { |
| 1368 currentFrame -= count; | 1346 currentFrame -= count; |
| 1369 } else { | 1347 } else { |
| 1370 currentFrame += count; | 1348 currentFrame += count; |
| 1371 } | 1349 } |
| 1372 } | 1350 } |
| 1373 | 1351 |
| 1374 int get stackDepth => stack['frames'].length; | 1352 int get stackDepth => stack['frames'].length; |
| 1375 | 1353 |
| 1376 static final _history = ['']; | 1354 static final _history = ['']; |
| 1377 | 1355 |
| 1378 ObservatoryDebugger(this.isolate) { | 1356 ObservatoryDebugger(this.isolate) { |
| 1379 _loadSettings(); | 1357 _loadSettings(); |
| 1380 cmd = new RootCommand([ | 1358 cmd = new RootCommand([ |
| 1381 new AsyncNextCommand(this), | 1359 new AsyncNextCommand(this), |
| 1382 new BreakCommand(this), | 1360 new BreakCommand(this), |
| 1383 new ClearCommand(this), | 1361 new ClearCommand(this), |
| 1384 new ClsCommand(this), | 1362 new ClsCommand(this), |
| 1385 new ContinueCommand(this), | 1363 new ContinueCommand(this), |
| 1386 new DeleteCommand(this), | 1364 new DeleteCommand(this), |
| 1387 new DownCommand(this), | 1365 new DownCommand(this), |
| 1388 new FinishCommand(this), | 1366 new FinishCommand(this), |
| 1389 new FrameCommand(this), | 1367 new FrameCommand(this), |
| 1390 new HelpCommand(this), | 1368 new HelpCommand(this), |
| 1391 new InfoCommand(this), | 1369 new InfoCommand(this), |
| 1392 new IsolateCommand(this), | 1370 new IsolateCommand(this), |
| 1393 new LogCommand(this), | 1371 new LogCommand(this), |
| 1394 new PauseCommand(this), | 1372 new PauseCommand(this), |
| 1395 new PrintCommand(this), | 1373 new PrintCommand(this), |
| 1396 new RefreshCommand(this), | 1374 new RefreshCommand(this), |
| 1397 new SetCommand(this), | 1375 new SetCommand(this), |
| 1398 new SmartNextCommand(this), | 1376 new SmartNextCommand(this), |
| 1399 new StepCommand(this), | 1377 new StepCommand(this), |
| 1400 new SyncNextCommand(this), | 1378 new SyncNextCommand(this), |
| 1401 new UpCommand(this), | 1379 new UpCommand(this), |
| 1402 new VmCommand(this), | 1380 new VmCommand(this), |
| 1403 ], _history); | 1381 ], _history); |
| 1404 _consolePrinter = new _ConsoleStreamPrinter(this); | 1382 _consolePrinter = new _ConsoleStreamPrinter(this); |
| 1405 } | 1383 } |
| 1406 | 1384 |
| 1407 void _loadSettings() { | 1385 void _loadSettings() { |
| 1408 _upIsDown = settings.get('up-is-down'); | 1386 _upIsDown = settings.get('up-is-down'); |
| 1409 } | 1387 } |
| 1410 | 1388 |
| 1411 S.VM get vm => page.app.vm; | 1389 S.VM get vm => page.app.vm; |
| 1412 | 1390 |
| 1413 void init() { | 1391 void init() { |
| 1414 console.printBold('Debugging isolate isolate ${isolate.number} ' | 1392 console.printBold('Debugging isolate isolate ${isolate.number} ' |
| 1415 '\'${isolate.name}\' '); | 1393 '\'${isolate.name}\' '); |
| 1416 console.printBold('Type \'h\' for help'); | 1394 console.printBold('Type \'h\' for help'); |
| 1417 // Wait a bit and if polymer still hasn't set up the isolate, | 1395 // Wait a bit and if polymer still hasn't set up the isolate, |
| 1418 // report this to the user. | 1396 // report this to the user. |
| 1419 new Timer(const Duration(seconds:1), () { | 1397 new Timer(const Duration(seconds: 1), () { |
| 1420 if (isolate == null) { | 1398 if (isolate == null) { |
| 1421 reportStatus(); | 1399 reportStatus(); |
| 1422 } | 1400 } |
| 1423 }); | 1401 }); |
| 1424 | 1402 |
| 1425 if ((breakOnException != isolate.exceptionsPauseInfo) && | 1403 if ((breakOnException != isolate.exceptionsPauseInfo) && |
| 1426 (isolate.exceptionsPauseInfo != null)) { | 1404 (isolate.exceptionsPauseInfo != null)) { |
| 1427 breakOnException = isolate.exceptionsPauseInfo; | 1405 breakOnException = isolate.exceptionsPauseInfo; |
| 1428 } | 1406 } |
| 1429 | 1407 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 | 1442 |
| 1465 bool isolatePaused() { | 1443 bool isolatePaused() { |
| 1466 // TODO(turnidge): Stop relying on the isolate to track the last | 1444 // TODO(turnidge): Stop relying on the isolate to track the last |
| 1467 // pause event. Since we listen to events directly in the | 1445 // pause event. Since we listen to events directly in the |
| 1468 // debugger, this could introduce a race. | 1446 // debugger, this could introduce a race. |
| 1469 return isolate.status == M.IsolateStatus.paused; | 1447 return isolate.status == M.IsolateStatus.paused; |
| 1470 } | 1448 } |
| 1471 | 1449 |
| 1472 void warnOutOfDate() { | 1450 void warnOutOfDate() { |
| 1473 // Wait a bit, then tell the user that the stack may be out of date. | 1451 // Wait a bit, then tell the user that the stack may be out of date. |
| 1474 new Timer(const Duration(seconds:2), () { | 1452 new Timer(const Duration(seconds: 2), () { |
| 1475 if (!isolatePaused()) { | 1453 if (!isolatePaused()) { |
| 1476 stackElement.isSampled = true; | 1454 stackElement.isSampled = true; |
| 1477 } | 1455 } |
| 1478 }); | 1456 }); |
| 1479 } | 1457 } |
| 1480 | 1458 |
| 1481 Future<S.ServiceMap> _refreshStack(M.DebugEvent pauseEvent) { | 1459 Future<S.ServiceMap> _refreshStack(M.DebugEvent pauseEvent) { |
| 1482 return isolate.getStack().then((result) { | 1460 return isolate.getStack().then((result) { |
| 1483 if (result.isSentinel) { | 1461 if (result.isSentinel) { |
| 1484 // The isolate has gone away. The IsolateExit event will | 1462 // The isolate has gone away. The IsolateExit event will |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 return; | 1499 return; |
| 1522 } | 1500 } |
| 1523 console.newline(); | 1501 console.newline(); |
| 1524 if (event is M.PauseExceptionEvent) { | 1502 if (event is M.PauseExceptionEvent) { |
| 1525 console.printBold('Isolate will exit due to an unhandled exception:'); | 1503 console.printBold('Isolate will exit due to an unhandled exception:'); |
| 1526 } else { | 1504 } else { |
| 1527 console.printBold('Isolate has exited due to an unhandled exception:'); | 1505 console.printBold('Isolate has exited due to an unhandled exception:'); |
| 1528 } | 1506 } |
| 1529 console.print(error.message); | 1507 console.print(error.message); |
| 1530 console.newline(); | 1508 console.newline(); |
| 1531 if (event is M.PauseExceptionEvent && | 1509 if (event is M.PauseExceptionEvent && |
| 1532 (error.exception.isStackOverflowError || | 1510 (error.exception.isStackOverflowError || |
| 1533 error.exception.isOutOfMemoryError)) { | 1511 error.exception.isOutOfMemoryError)) { |
| 1534 console.printBold( | 1512 console.printBold( |
| 1535 'When an unhandled stack overflow or OOM exception occurs, the VM ' | 1513 'When an unhandled stack overflow or OOM exception occurs, the VM ' |
| 1536 'has run out of memory and cannot keep the stack alive while ' | 1514 'has run out of memory and cannot keep the stack alive while ' |
| 1537 'paused.'); | 1515 'paused.'); |
| 1538 } else { | 1516 } else { |
| 1539 console.printBold("Type 'set break-on-exception Unhandled' to pause the" | 1517 console.printBold("Type 'set break-on-exception Unhandled' to pause the" |
| 1540 " isolate when an unhandled exception occurs."); | 1518 " isolate when an unhandled exception occurs."); |
| 1541 console.printBold("You can make this the default by running with " | 1519 console.printBold("You can make this the default by running with " |
| 1542 "--pause-isolates-on-unhandled-exceptions"); | 1520 "--pause-isolates-on-unhandled-exceptions"); |
| 1543 } | 1521 } |
| 1544 } | 1522 } |
| 1545 | 1523 |
| 1546 void _reportPause(M.DebugEvent event) { | 1524 void _reportPause(M.DebugEvent event) { |
| 1547 if (event is M.NoneEvent) { | 1525 if (event is M.NoneEvent) { |
| 1548 console.print("Paused until embedder makes the isolate runnable."); | 1526 console.print("Paused until embedder makes the isolate runnable."); |
| 1549 } else if (event is M.PauseStartEvent) { | 1527 } else if (event is M.PauseStartEvent) { |
| 1550 console.print( | 1528 console.print("Paused at isolate start " |
| 1551 "Paused at isolate start " | |
| 1552 "(type 'continue' [F7] or 'step' [F10] to start the isolate')"); | 1529 "(type 'continue' [F7] or 'step' [F10] to start the isolate')"); |
| 1553 } else if (event is M.PauseExitEvent) { | 1530 } else if (event is M.PauseExitEvent) { |
| 1554 console.print( | 1531 console.print("Paused at isolate exit " |
| 1555 "Paused at isolate exit " | |
| 1556 "(type 'continue' or [F7] to exit the isolate')"); | 1532 "(type 'continue' or [F7] to exit the isolate')"); |
| 1557 _reportIsolateError(isolate, event); | 1533 _reportIsolateError(isolate, event); |
| 1558 } else if (event is M.PauseExceptionEvent) { | 1534 } else if (event is M.PauseExceptionEvent) { |
| 1559 console.print( | 1535 console.print("Paused at an unhandled exception " |
| 1560 "Paused at an unhandled exception " | |
| 1561 "(type 'continue' or [F7] to exit the isolate')"); | 1536 "(type 'continue' or [F7] to exit the isolate')"); |
| 1562 _reportIsolateError(isolate, event); | 1537 _reportIsolateError(isolate, event); |
| 1563 } else if (stack['frames'].length > 0) { | 1538 } else if (stack['frames'].length > 0) { |
| 1564 S.Frame frame = stack['frames'][0]; | 1539 S.Frame frame = stack['frames'][0]; |
| 1565 var script = frame.location.script; | 1540 var script = frame.location.script; |
| 1566 script.load().then((_) { | 1541 script.load().then((_) { |
| 1567 var line = script.tokenToLine(frame.location.tokenPos); | 1542 var line = script.tokenToLine(frame.location.tokenPos); |
| 1568 var col = script.tokenToCol(frame.location.tokenPos); | 1543 var col = script.tokenToCol(frame.location.tokenPos); |
| 1569 if ((event is M.PauseBreakpointEvent) && | 1544 if ((event is M.PauseBreakpointEvent) && (event.breakpoint != null)) { |
| 1570 (event.breakpoint != null)) { | 1545 var bpId = event.breakpoint.number; |
| 1571 var bpId = event.breakpoint.number; | 1546 console.print('Paused at breakpoint ${bpId} at ' |
| 1572 console.print('Paused at breakpoint ${bpId} at ' | 1547 '${script.name}:${line}:${col}'); |
| 1573 '${script.name}:${line}:${col}'); | |
| 1574 } else if ((event is M.PauseExceptionEvent) && | 1548 } else if ((event is M.PauseExceptionEvent) && |
| 1575 (event.exception != null)) { | 1549 (event.exception != null)) { |
| 1576 console.print('Paused due to exception at ' | 1550 console.print('Paused due to exception at ' |
| 1577 '${script.name}:${line}:${col}'); | 1551 '${script.name}:${line}:${col}'); |
| 1578 // This seems to be missing if we are paused-at-exception after | 1552 // This seems to be missing if we are paused-at-exception after |
| 1579 // paused-at-isolate-exit. Maybe we shutdown part of the debugger too | 1553 // paused-at-isolate-exit. Maybe we shutdown part of the debugger too |
| 1580 // soon? | 1554 // soon? |
| 1581 console.printRef(isolate, event.exception, instances); | 1555 console.printRef(isolate, event.exception, instances); |
| 1582 } else { | 1556 } else { |
| 1583 console.print('Paused at ${script.name}:${line}:${col}'); | 1557 console.print('Paused at ${script.name}:${line}:${col}'); |
| 1584 } | 1558 } |
| 1585 }); | 1559 }); |
| 1586 } else { | 1560 } else { |
| 1587 console.print("Paused in message loop (type 'continue' or [F7] " | 1561 console.print("Paused in message loop (type 'continue' or [F7] " |
| 1588 "to resume processing messages)"); | 1562 "to resume processing messages)"); |
| 1589 } | 1563 } |
| 1590 } | 1564 } |
| 1591 | 1565 |
| 1592 Future _reportBreakpointEvent(S.ServiceEvent event) async { | 1566 Future _reportBreakpointEvent(S.ServiceEvent event) async { |
| 1593 var bpt = event.breakpoint; | 1567 var bpt = event.breakpoint; |
| 1594 var verb = null; | 1568 var verb = null; |
| 1595 switch (event.kind) { | 1569 switch (event.kind) { |
| 1596 case S.ServiceEvent.kBreakpointAdded: | 1570 case S.ServiceEvent.kBreakpointAdded: |
| 1597 verb = 'added'; | 1571 verb = 'added'; |
| 1598 break; | 1572 break; |
| 1599 case S.ServiceEvent.kBreakpointResolved: | 1573 case S.ServiceEvent.kBreakpointResolved: |
| 1600 verb = 'resolved'; | 1574 verb = 'resolved'; |
| 1601 break; | 1575 break; |
| 1602 case S.ServiceEvent.kBreakpointRemoved: | 1576 case S.ServiceEvent.kBreakpointRemoved: |
| 1603 verb = 'removed'; | 1577 verb = 'removed'; |
| 1604 break; | 1578 break; |
| 1605 default: | 1579 default: |
| 1606 break; | 1580 break; |
| 1607 } | 1581 } |
| 1608 var script = bpt.location.script; | 1582 var script = bpt.location.script; |
| 1609 await script.load(); | 1583 await script.load(); |
| 1610 | 1584 |
| 1611 var bpId = bpt.number; | 1585 var bpId = bpt.number; |
| 1612 var locString = await bpt.location.toUserString(); | 1586 var locString = await bpt.location.toUserString(); |
| 1613 if (bpt.resolved) { | 1587 if (bpt.resolved) { |
| 1614 console.print( | 1588 console.print('Breakpoint ${bpId} ${verb} at ${locString}'); |
| 1615 'Breakpoint ${bpId} ${verb} at ${locString}'); | |
| 1616 } else { | 1589 } else { |
| 1617 console.print( | 1590 console.print('Future breakpoint ${bpId} ${verb} at ${locString}'); |
| 1618 'Future breakpoint ${bpId} ${verb} at ${locString}'); | |
| 1619 } | 1591 } |
| 1620 } | 1592 } |
| 1621 | 1593 |
| 1622 void onEvent(S.ServiceEvent event) { | 1594 void onEvent(S.ServiceEvent event) { |
| 1623 switch(event.kind) { | 1595 switch (event.kind) { |
| 1624 case S.ServiceEvent.kVMUpdate: | 1596 case S.ServiceEvent.kVMUpdate: |
| 1625 var vm = event.owner; | 1597 var vm = event.owner; |
| 1626 console.print("VM ${vm.target.networkAddress} renamed to '${vm.name}'"); | 1598 console.print("VM ${vm.target.networkAddress} renamed to '${vm.name}'"); |
| 1627 break; | 1599 break; |
| 1628 | 1600 |
| 1629 case S.ServiceEvent.kIsolateStart: | 1601 case S.ServiceEvent.kIsolateStart: |
| 1630 { | 1602 { |
| 1631 var iso = event.owner; | 1603 var iso = event.owner; |
| 1632 console.print( | 1604 console.print("Isolate ${iso.number} '${iso.name}' has been created"); |
| 1633 "Isolate ${iso.number} '${iso.name}' has been created"); | |
| 1634 } | 1605 } |
| 1635 break; | 1606 break; |
| 1636 | 1607 |
| 1637 case S.ServiceEvent.kIsolateExit: | 1608 case S.ServiceEvent.kIsolateExit: |
| 1638 { | 1609 { |
| 1639 var iso = event.owner; | 1610 var iso = event.owner; |
| 1640 if (iso == isolate) { | 1611 if (iso == isolate) { |
| 1641 console.print("The current isolate ${iso.number} '${iso.name}' " | 1612 console.print("The current isolate ${iso.number} '${iso.name}' " |
| 1642 "has exited"); | 1613 "has exited"); |
| 1643 var isolates = vm.isolates; | 1614 var isolates = vm.isolates; |
| 1644 if (isolates.length > 0) { | 1615 if (isolates.length > 0) { |
| 1645 var newIsolate = isolates.first; | 1616 var newIsolate = isolates.first; |
| 1646 new AnchorElement(href: Uris.debugger(newIsolate)).click(); | 1617 new AnchorElement(href: Uris.debugger(newIsolate)).click(); |
| 1647 } else { | 1618 } else { |
| 1648 new AnchorElement(href: Uris.vm()).click(); | 1619 new AnchorElement(href: Uris.vm()).click(); |
| 1649 } | 1620 } |
| 1650 } else { | 1621 } else { |
| 1651 console.print( | 1622 console.print("Isolate ${iso.number} '${iso.name}' has exited"); |
| 1652 "Isolate ${iso.number} '${iso.name}' has exited"); | |
| 1653 } | 1623 } |
| 1654 } | 1624 } |
| 1655 break; | 1625 break; |
| 1656 | 1626 |
| 1657 case S.ServiceEvent.kDebuggerSettingsUpdate: | 1627 case S.ServiceEvent.kDebuggerSettingsUpdate: |
| 1658 if (breakOnException != event.exceptions) { | 1628 if (breakOnException != event.exceptions) { |
| 1659 breakOnException = event.exceptions; | 1629 breakOnException = event.exceptions; |
| 1660 console.print("Now pausing for exceptions: $breakOnException"); | 1630 console.print("Now pausing for exceptions: $breakOnException"); |
| 1661 } | 1631 } |
| 1662 break; | 1632 break; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1783 Future run(String command) { | 1753 Future run(String command) { |
| 1784 if (command == '' && lastCommand != null) { | 1754 if (command == '' && lastCommand != null) { |
| 1785 command = lastCommand; | 1755 command = lastCommand; |
| 1786 } | 1756 } |
| 1787 console.printBold('\$ $command'); | 1757 console.printBold('\$ $command'); |
| 1788 return cmd.runCommand(command).then((_) { | 1758 return cmd.runCommand(command).then((_) { |
| 1789 lastCommand = command; | 1759 lastCommand = command; |
| 1790 }).catchError((e, s) { | 1760 }).catchError((e, s) { |
| 1791 if (e is S.NetworkRpcException) { | 1761 if (e is S.NetworkRpcException) { |
| 1792 console.printRed('Unable to execute command because the connection ' | 1762 console.printRed('Unable to execute command because the connection ' |
| 1793 'to the VM has been closed'); | 1763 'to the VM has been closed'); |
| 1794 } else { | 1764 } else { |
| 1795 if (s != null) { | 1765 if (s != null) { |
| 1796 console.printRed('Internal error: $e\n$s'); | 1766 console.printRed('Internal error: $e\n$s'); |
| 1797 } else { | 1767 } else { |
| 1798 console.printRed('Internal error: $e\n'); | 1768 console.printRed('Internal error: $e\n'); |
| 1799 } | 1769 } |
| 1800 } | 1770 } |
| 1801 }); | 1771 }); |
| 1802 } | 1772 } |
| 1803 | 1773 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1814 return isolate.pause(); | 1784 return isolate.pause(); |
| 1815 } else { | 1785 } else { |
| 1816 console.print('The program is already paused'); | 1786 console.print('The program is already paused'); |
| 1817 return new Future.value(null); | 1787 return new Future.value(null); |
| 1818 } | 1788 } |
| 1819 } | 1789 } |
| 1820 | 1790 |
| 1821 Future resume() { | 1791 Future resume() { |
| 1822 if (isolatePaused()) { | 1792 if (isolatePaused()) { |
| 1823 return isolate.resume().then((_) { | 1793 return isolate.resume().then((_) { |
| 1824 warnOutOfDate(); | 1794 warnOutOfDate(); |
| 1825 }); | 1795 }); |
| 1826 } else { | 1796 } else { |
| 1827 console.print('The program must be paused'); | 1797 console.print('The program must be paused'); |
| 1828 return new Future.value(null); | 1798 return new Future.value(null); |
| 1829 } | 1799 } |
| 1830 } | 1800 } |
| 1831 | 1801 |
| 1832 Future toggleBreakpoint() async { | 1802 Future toggleBreakpoint() async { |
| 1833 var loc = await DebuggerLocation.parse(this, ''); | 1803 var loc = await DebuggerLocation.parse(this, ''); |
| 1834 var script = loc.script; | 1804 var script = loc.script; |
| 1835 var line = loc.line; | 1805 var line = loc.line; |
| 1836 if (script != null && line != null) { | 1806 if (script != null && line != null) { |
| 1837 var bpts = script.getLine(line).breakpoints; | 1807 var bpts = script.getLine(line).breakpoints; |
| 1838 if (bpts == null || bpts.isEmpty) { | 1808 if (bpts == null || bpts.isEmpty) { |
| 1839 // Set a new breakpoint. | 1809 // Set a new breakpoint. |
| 1840 // TODO(turnidge): Set this breakpoint at current column. | 1810 // TODO(turnidge): Set this breakpoint at current column. |
| 1841 await isolate.addBreakpoint(script, line); | 1811 await isolate.addBreakpoint(script, line); |
| 1842 } else { | 1812 } else { |
| 1843 // TODO(turnidge): Clear this breakpoint at current column. | 1813 // TODO(turnidge): Clear this breakpoint at current column. |
| 1844 var pending = []; | 1814 var pending = []; |
| 1845 for (var bpt in bpts) { | 1815 for (var bpt in bpts) { |
| 1846 pending.add(isolate.removeBreakpoint(bpt)); | 1816 pending.add(isolate.removeBreakpoint(bpt)); |
| 1847 } | 1817 } |
| 1848 await Future.wait(pending); | 1818 await Future.wait(pending); |
| 1849 } | 1819 } |
| 1850 } | 1820 } |
| 1851 return new Future.value(null); | 1821 return new Future.value(null); |
| 1852 } | 1822 } |
| 1853 | 1823 |
| 1854 | |
| 1855 Future smartNext() async { | 1824 Future smartNext() async { |
| 1856 if (isolatePaused()) { | 1825 if (isolatePaused()) { |
| 1857 var event = isolate.pauseEvent; | 1826 var event = isolate.pauseEvent; |
| 1858 if (event.atAsyncSuspension) { | 1827 if (event.atAsyncSuspension) { |
| 1859 return asyncNext(); | 1828 return asyncNext(); |
| 1860 } else { | 1829 } else { |
| 1861 return syncNext(); | 1830 return syncNext(); |
| 1862 } | 1831 } |
| 1863 } else { | 1832 } else { |
| 1864 console.print('The program is already running'); | 1833 console.print('The program is already running'); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1875 } | 1844 } |
| 1876 } else { | 1845 } else { |
| 1877 console.print('The program is already running'); | 1846 console.print('The program is already running'); |
| 1878 } | 1847 } |
| 1879 } | 1848 } |
| 1880 | 1849 |
| 1881 Future syncNext() async { | 1850 Future syncNext() async { |
| 1882 if (isolatePaused()) { | 1851 if (isolatePaused()) { |
| 1883 var event = isolate.pauseEvent; | 1852 var event = isolate.pauseEvent; |
| 1884 if (event is M.PauseStartEvent) { | 1853 if (event is M.PauseStartEvent) { |
| 1885 console.print("Type 'continue' [F7] or 'step' [F10] to start the isolate
"); | 1854 console |
| 1855 .print("Type 'continue' [F7] or 'step' [F10] to start the isolate"); |
| 1886 return null; | 1856 return null; |
| 1887 } | 1857 } |
| 1888 if (event is M.PauseExitEvent) { | 1858 if (event is M.PauseExitEvent) { |
| 1889 console.print("Type 'continue' [F7] to exit the isolate"); | 1859 console.print("Type 'continue' [F7] to exit the isolate"); |
| 1890 return null; | 1860 return null; |
| 1891 } | 1861 } |
| 1892 return isolate.stepOver(); | 1862 return isolate.stepOver(); |
| 1893 } else { | 1863 } else { |
| 1894 console.print('The program is already running'); | 1864 console.print('The program is already running'); |
| 1895 return null; | 1865 return null; |
| 1896 } | 1866 } |
| 1897 } | 1867 } |
| 1898 | 1868 |
| 1899 Future step() { | 1869 Future step() { |
| 1900 if (isolatePaused()) { | 1870 if (isolatePaused()) { |
| 1901 var event = isolate.pauseEvent; | 1871 var event = isolate.pauseEvent; |
| 1902 if (event is M.PauseExitEvent) { | 1872 if (event is M.PauseExitEvent) { |
| 1903 console.print("Type 'continue' [F7] to exit the isolate"); | 1873 console.print("Type 'continue' [F7] to exit the isolate"); |
| 1904 return new Future.value(null); | 1874 return new Future.value(null); |
| 1905 } | 1875 } |
| 1906 return isolate.stepInto(); | 1876 return isolate.stepInto(); |
| 1907 } else { | 1877 } else { |
| 1908 console.print('The program is already running'); | 1878 console.print('The program is already running'); |
| 1909 return new Future.value(null); | 1879 return new Future.value(null); |
| 1910 } | 1880 } |
| 1911 } | 1881 } |
| 1912 } | 1882 } |
| 1913 | 1883 |
| 1914 class DebuggerPageElement extends HtmlElement implements Renderable { | 1884 class DebuggerPageElement extends HtmlElement implements Renderable { |
| 1915 static const tag = const Tag<DebuggerPageElement>('debugger-page', | 1885 static const tag = |
| 1916 dependencies: const [ | 1886 const Tag<DebuggerPageElement>('debugger-page', dependencies: const [ |
| 1917 NavTopMenuElement.tag, | 1887 NavTopMenuElement.tag, |
| 1918 NavVMMenuElement.tag, | 1888 NavVMMenuElement.tag, |
| 1919 NavIsolateMenuElement.tag, | 1889 NavIsolateMenuElement.tag, |
| 1920 NavNotifyElement.tag, | 1890 NavNotifyElement.tag, |
| 1921 ]); | 1891 ]); |
| 1922 | 1892 |
| 1923 S.Isolate _isolate; | 1893 S.Isolate _isolate; |
| 1924 ObservatoryDebugger _debugger; | 1894 ObservatoryDebugger _debugger; |
| 1925 M.InstanceRepository _instances; | 1895 M.InstanceRepository _instances; |
| 1926 M.ScriptRepository _scripts; | 1896 M.ScriptRepository _scripts; |
| 1927 M.EventRepository _events; | 1897 M.EventRepository _events; |
| 1928 | 1898 |
| 1929 factory DebuggerPageElement(S.Isolate isolate, | 1899 factory DebuggerPageElement(S.Isolate isolate, M.InstanceRepository instances, |
| 1930 M.InstanceRepository instances, | 1900 M.ScriptRepository scripts, M.EventRepository events) { |
| 1931 M.ScriptRepository scripts, | |
| 1932 M.EventRepository events) { | |
| 1933 assert(isolate != null); | 1901 assert(isolate != null); |
| 1934 assert(instances != null); | 1902 assert(instances != null); |
| 1935 assert(scripts != null); | 1903 assert(scripts != null); |
| 1936 assert(events != null); | 1904 assert(events != null); |
| 1937 final e = document.createElement(tag.name); | 1905 final e = document.createElement(tag.name); |
| 1938 final debugger = new ObservatoryDebugger(isolate); | 1906 final debugger = new ObservatoryDebugger(isolate); |
| 1939 debugger.page = e; | 1907 debugger.page = e; |
| 1940 e._isolate = isolate; | 1908 e._isolate = isolate; |
| 1941 e._debugger = debugger; | 1909 e._debugger = debugger; |
| 1942 e._instances = instances; | 1910 e._instances = instances; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1958 | 1926 |
| 1959 Timer _timer; | 1927 Timer _timer; |
| 1960 | 1928 |
| 1961 static final consoleElement = new DebuggerConsoleElement(); | 1929 static final consoleElement = new DebuggerConsoleElement(); |
| 1962 | 1930 |
| 1963 @override | 1931 @override |
| 1964 void attached() { | 1932 void attached() { |
| 1965 super.attached(); | 1933 super.attached(); |
| 1966 | 1934 |
| 1967 final stackDiv = new DivElement()..classes = ['stack']; | 1935 final stackDiv = new DivElement()..classes = ['stack']; |
| 1968 final stackElement = new DebuggerStackElement(_isolate, _debugger, stackDiv, | 1936 final stackElement = new DebuggerStackElement( |
| 1969 _instances, _scripts, | 1937 _isolate, _debugger, stackDiv, _instances, _scripts, _events); |
| 1970 _events); | |
| 1971 stackDiv.children = [stackElement]; | 1938 stackDiv.children = [stackElement]; |
| 1972 final consoleDiv = new DivElement()..classes = ['console'] | 1939 final consoleDiv = new DivElement() |
| 1940 ..classes = ['console'] |
| 1973 ..children = [consoleElement]; | 1941 ..children = [consoleElement]; |
| 1974 final commandElement = new DebuggerInputElement(_isolate, _debugger); | 1942 final commandElement = new DebuggerInputElement(_isolate, _debugger); |
| 1975 final commandDiv = new DivElement()..classes = ['commandline'] | 1943 final commandDiv = new DivElement() |
| 1944 ..classes = ['commandline'] |
| 1976 ..children = [commandElement]; | 1945 ..children = [commandElement]; |
| 1977 | 1946 |
| 1978 children = [ | 1947 children = [ |
| 1979 navBar([ | 1948 navBar([ |
| 1980 new NavTopMenuElement(queue: app.queue), | 1949 new NavTopMenuElement(queue: app.queue), |
| 1981 new NavVMMenuElement(app.vm, app.events, queue: app.queue), | 1950 new NavVMMenuElement(app.vm, app.events, queue: app.queue), |
| 1982 new NavIsolateMenuElement(_isolate, app.events, queue: app.queue), | 1951 new NavIsolateMenuElement(_isolate, app.events, queue: app.queue), |
| 1983 navMenu('debugger'), | 1952 navMenu('debugger'), |
| 1984 new NavNotifyElement(app.notifications, notifyOnPause: false, | 1953 new NavNotifyElement(app.notifications, |
| 1985 queue: app.queue) | 1954 notifyOnPause: false, queue: app.queue) |
| 1986 ]), | 1955 ]), |
| 1987 new DivElement()..classes = ['variable'] | 1956 new DivElement() |
| 1957 ..classes = ['variable'] |
| 1988 ..children = [ | 1958 ..children = [ |
| 1989 stackDiv, | 1959 stackDiv, |
| 1990 new DivElement() | 1960 new DivElement() |
| 1991 ..children = [ | 1961 ..children = [ |
| 1992 new HRElement()..classes = ['splitter'] | 1962 new HRElement()..classes = ['splitter'] |
| 1993 ], | 1963 ], |
| 1994 consoleDiv, | 1964 consoleDiv, |
| 1995 ], | 1965 ], |
| 1996 commandDiv | 1966 commandDiv |
| 1997 ]; | 1967 ]; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2025 if (_stderrSubscriptionFuture != null) { | 1995 if (_stderrSubscriptionFuture != null) { |
| 2026 // TODO(turnidge): How do we want to handle this in general? | 1996 // TODO(turnidge): How do we want to handle this in general? |
| 2027 _stderrSubscriptionFuture.catchError((e, st) { | 1997 _stderrSubscriptionFuture.catchError((e, st) { |
| 2028 Logger.root.info('Failed to subscribe to stderr: $e\n$st\n'); | 1998 Logger.root.info('Failed to subscribe to stderr: $e\n$st\n'); |
| 2029 _stderrSubscriptionFuture = null; | 1999 _stderrSubscriptionFuture = null; |
| 2030 }); | 2000 }); |
| 2031 } | 2001 } |
| 2032 _logSubscriptionFuture = | 2002 _logSubscriptionFuture = |
| 2033 app.vm.listenEventStream(S.Isolate.kLoggingStream, _debugger.onEvent); | 2003 app.vm.listenEventStream(S.Isolate.kLoggingStream, _debugger.onEvent); |
| 2034 // Turn on the periodic poll timer for this page. | 2004 // Turn on the periodic poll timer for this page. |
| 2035 _timer = new Timer.periodic(const Duration(milliseconds:100), (_) { | 2005 _timer = new Timer.periodic(const Duration(milliseconds: 100), (_) { |
| 2036 _debugger.flushStdio(); | 2006 _debugger.flushStdio(); |
| 2037 }); | 2007 }); |
| 2038 | 2008 |
| 2039 onClick.listen((event) { | 2009 onClick.listen((event) { |
| 2040 // Random clicks should focus on the text box. If the user selects | 2010 // Random clicks should focus on the text box. If the user selects |
| 2041 // a range, don't interfere. | 2011 // a range, don't interfere. |
| 2042 var selection = window.getSelection(); | 2012 var selection = window.getSelection(); |
| 2043 if (selection == null || | 2013 if (selection == null || |
| 2044 (selection.type != 'Range' && selection.type != 'text')) { | 2014 (selection.type != 'Range' && selection.type != 'text')) { |
| 2045 _debugger.input.focus(); | 2015 _debugger.input.focus(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2080 M.ScriptRepository _scripts; | 2050 M.ScriptRepository _scripts; |
| 2081 M.EventRepository _events; | 2051 M.EventRepository _events; |
| 2082 Element _scroller; | 2052 Element _scroller; |
| 2083 DivElement _isSampled; | 2053 DivElement _isSampled; |
| 2084 bool get isSampled => !_isSampled.classes.contains('hidden'); | 2054 bool get isSampled => !_isSampled.classes.contains('hidden'); |
| 2085 set isSampled(bool value) { | 2055 set isSampled(bool value) { |
| 2086 if (value != isSampled) { | 2056 if (value != isSampled) { |
| 2087 _isSampled.classes.toggle('hidden'); | 2057 _isSampled.classes.toggle('hidden'); |
| 2088 } | 2058 } |
| 2089 } | 2059 } |
| 2060 |
| 2090 DivElement _hasStack; | 2061 DivElement _hasStack; |
| 2091 bool get hasStack => _hasStack.classes.contains('hidden'); | 2062 bool get hasStack => _hasStack.classes.contains('hidden'); |
| 2092 set hasStack(bool value) { | 2063 set hasStack(bool value) { |
| 2093 if (value != hasStack) { | 2064 if (value != hasStack) { |
| 2094 _hasStack.classes.toggle('hidden'); | 2065 _hasStack.classes.toggle('hidden'); |
| 2095 } | 2066 } |
| 2096 } | 2067 } |
| 2068 |
| 2097 DivElement _hasMessages; | 2069 DivElement _hasMessages; |
| 2098 bool get hasMessages => _hasMessages.classes.contains('hidden'); | 2070 bool get hasMessages => _hasMessages.classes.contains('hidden'); |
| 2099 set hasMessages(bool value) { | 2071 set hasMessages(bool value) { |
| 2100 if (value != hasMessages) { | 2072 if (value != hasMessages) { |
| 2101 _hasMessages.classes.toggle('hidden'); | 2073 _hasMessages.classes.toggle('hidden'); |
| 2102 } | 2074 } |
| 2103 } | 2075 } |
| 2076 |
| 2104 UListElement _frameList; | 2077 UListElement _frameList; |
| 2105 UListElement _messageList; | 2078 UListElement _messageList; |
| 2106 int currentFrame; | 2079 int currentFrame; |
| 2107 ObservatoryDebugger _debugger; | 2080 ObservatoryDebugger _debugger; |
| 2108 | 2081 |
| 2109 factory DebuggerStackElement(S.Isolate isolate, | 2082 factory DebuggerStackElement( |
| 2110 ObservatoryDebugger debugger, | 2083 S.Isolate isolate, |
| 2111 Element scroller, | 2084 ObservatoryDebugger debugger, |
| 2112 M.InstanceRepository instances, | 2085 Element scroller, |
| 2113 M.ScriptRepository scripts, | 2086 M.InstanceRepository instances, |
| 2114 M.EventRepository events) { | 2087 M.ScriptRepository scripts, |
| 2088 M.EventRepository events) { |
| 2115 assert(isolate != null); | 2089 assert(isolate != null); |
| 2116 assert(debugger != null); | 2090 assert(debugger != null); |
| 2117 assert(scroller != null); | 2091 assert(scroller != null); |
| 2118 assert(instances != null); | 2092 assert(instances != null); |
| 2119 assert(scripts != null); | 2093 assert(scripts != null); |
| 2120 assert(events != null); | 2094 assert(events != null); |
| 2121 final e = document.createElement(tag.name); | 2095 final e = document.createElement(tag.name); |
| 2122 e._isolate = isolate; | 2096 e._isolate = isolate; |
| 2123 e._debugger = debugger; | 2097 e._debugger = debugger; |
| 2124 e._scroller = scroller; | 2098 e._scroller = scroller; |
| 2125 e._instances = instances; | 2099 e._instances = instances; |
| 2126 e._scripts = scripts; | 2100 e._scripts = scripts; |
| 2127 e._events = events; | 2101 e._events = events; |
| 2128 | 2102 |
| 2129 var btnPause; | 2103 var btnPause; |
| 2130 var btnRefresh; | 2104 var btnRefresh; |
| 2131 e.children = [ | 2105 e.children = [ |
| 2132 e._isSampled = new DivElement()..classes = ['sampledMessage', 'hidden'] | 2106 e._isSampled = new DivElement() |
| 2107 ..classes = ['sampledMessage', 'hidden'] |
| 2133 ..children = [ | 2108 ..children = [ |
| 2134 new SpanElement() | 2109 new SpanElement() |
| 2135 ..text = 'The program is not paused. ' | 2110 ..text = 'The program is not paused. ' |
| 2136 'The stack trace below may be out of date.', | 2111 'The stack trace below may be out of date.', |
| 2137 new BRElement(), | 2112 new BRElement(), |
| 2138 new BRElement(), | 2113 new BRElement(), |
| 2139 btnPause = new ButtonElement() | 2114 btnPause = new ButtonElement() |
| 2140 ..text = '[Pause Isolate]' | 2115 ..text = '[Pause Isolate]' |
| 2141 ..onClick.listen((_) async { | 2116 ..onClick.listen((_) async { |
| 2142 btnPause.disabled = true; | 2117 btnPause.disabled = true; |
| 2143 try { | 2118 try { |
| 2144 await debugger.isolate.pause(); | 2119 await debugger.isolate.pause(); |
| 2145 } | 2120 } finally { |
| 2146 finally { | |
| 2147 btnPause.disabled = false; | 2121 btnPause.disabled = false; |
| 2148 } | 2122 } |
| 2149 }), | 2123 }), |
| 2150 btnRefresh = new ButtonElement() | 2124 btnRefresh = new ButtonElement() |
| 2151 ..text = '[Refresh Stack]' | 2125 ..text = '[Refresh Stack]' |
| 2152 ..onClick.listen((_) async { | 2126 ..onClick.listen((_) async { |
| 2153 btnRefresh.disabled = true; | 2127 btnRefresh.disabled = true; |
| 2154 try { | 2128 try { |
| 2155 await debugger.refreshStack(); | 2129 await debugger.refreshStack(); |
| 2156 } | 2130 } finally { |
| 2157 finally { | |
| 2158 btnRefresh.disabled = false; | 2131 btnRefresh.disabled = false; |
| 2159 } | 2132 } |
| 2160 }), | 2133 }), |
| 2161 new BRElement(), | 2134 new BRElement(), |
| 2162 new BRElement(), | 2135 new BRElement(), |
| 2163 new HRElement()..classes = ['splitter'] | 2136 new HRElement()..classes = ['splitter'] |
| 2164 ], | 2137 ], |
| 2165 e._hasStack = new DivElement()..classes = ['noStack', 'hidden'] | 2138 e._hasStack = new DivElement() |
| 2139 ..classes = ['noStack', 'hidden'] |
| 2166 ..text = 'No stack', | 2140 ..text = 'No stack', |
| 2167 e._frameList = new UListElement()..classes = ['list-group'], | 2141 e._frameList = new UListElement()..classes = ['list-group'], |
| 2168 new HRElement(), | 2142 new HRElement(), |
| 2169 e._hasMessages = new DivElement()..classes = ['noMessages', 'hidden'] | 2143 e._hasMessages = new DivElement() |
| 2144 ..classes = ['noMessages', 'hidden'] |
| 2170 ..text = 'No pending messages', | 2145 ..text = 'No pending messages', |
| 2171 e._messageList = new UListElement()..classes = ['messageList'] | 2146 e._messageList = new UListElement()..classes = ['messageList'] |
| 2172 ]; | 2147 ]; |
| 2173 return e; | 2148 return e; |
| 2174 } | 2149 } |
| 2175 | 2150 |
| 2176 void render() { | 2151 void render() { |
| 2177 /* nothing to do */ | 2152 /* nothing to do */ |
| 2178 } | 2153 } |
| 2179 | 2154 |
| 2180 _addFrame(List frameList, S.Frame frameInfo) { | 2155 _addFrame(List frameList, S.Frame frameInfo) { |
| 2181 final frameElement = new DebuggerFrameElement(_isolate, | 2156 final frameElement = new DebuggerFrameElement( |
| 2182 frameInfo, | 2157 _isolate, frameInfo, _scroller, _instances, _scripts, _events, |
| 2183 _scroller, | 2158 queue: app.queue); |
| 2184 _instances, | |
| 2185 _scripts, | |
| 2186 _events, | |
| 2187 queue: app.queue); | |
| 2188 | 2159 |
| 2189 if (frameInfo.index == currentFrame) { | 2160 if (frameInfo.index == currentFrame) { |
| 2190 frameElement.setCurrent(true); | 2161 frameElement.setCurrent(true); |
| 2191 } else { | 2162 } else { |
| 2192 frameElement.setCurrent(false); | 2163 frameElement.setCurrent(false); |
| 2193 } | 2164 } |
| 2194 | 2165 |
| 2195 var li = new LIElement(); | 2166 var li = new LIElement(); |
| 2196 li.classes.add('list-group-item'); | 2167 li.classes.add('list-group-item'); |
| 2197 li.children.insert(0, frameElement); | 2168 li.children.insert(0, frameElement); |
| 2198 | 2169 |
| 2199 frameList.insert(0, li); | 2170 frameList.insert(0, li); |
| 2200 } | 2171 } |
| 2201 | 2172 |
| 2202 _addMessage(List messageList, S.ServiceMessage messageInfo) { | 2173 _addMessage(List messageList, S.ServiceMessage messageInfo) { |
| 2203 final messageElement = new DebuggerMessageElement(_isolate, | 2174 final messageElement = new DebuggerMessageElement( |
| 2204 messageInfo, | 2175 _isolate, messageInfo, _instances, _scripts, _events, |
| 2205 _instances, | 2176 queue: app.queue); |
| 2206 _scripts, | |
| 2207 _events, | |
| 2208 queue: app.queue); | |
| 2209 | 2177 |
| 2210 var li = new LIElement(); | 2178 var li = new LIElement(); |
| 2211 li.classes.add('list-group-item'); | 2179 li.classes.add('list-group-item'); |
| 2212 li.children.insert(0, messageElement); | 2180 li.children.insert(0, messageElement); |
| 2213 | 2181 |
| 2214 messageList.add(li); | 2182 messageList.add(li); |
| 2215 } | 2183 } |
| 2216 | 2184 |
| 2217 ObservatoryApplication get app => ObservatoryApplication.app; | 2185 ObservatoryApplication get app => ObservatoryApplication.app; |
| 2218 | 2186 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2244 for (int i = 0; i < removeCount; i++) { | 2212 for (int i = 0; i < removeCount; i++) { |
| 2245 frameElements.removeAt(0); | 2213 frameElements.removeAt(0); |
| 2246 } | 2214 } |
| 2247 } | 2215 } |
| 2248 | 2216 |
| 2249 // Add any new frames. | 2217 // Add any new frames. |
| 2250 int newCount = 0; | 2218 int newCount = 0; |
| 2251 if (frameElements.length < newFrames.length) { | 2219 if (frameElements.length < newFrames.length) { |
| 2252 // Add new frames to the top of stack. | 2220 // Add new frames to the top of stack. |
| 2253 newCount = newFrames.length - frameElements.length; | 2221 newCount = newFrames.length - frameElements.length; |
| 2254 for (int i = newCount-1; i >= 0; i--) { | 2222 for (int i = newCount - 1; i >= 0; i--) { |
| 2255 _addFrame(frameElements, newFrames[i]); | 2223 _addFrame(frameElements, newFrames[i]); |
| 2256 } | 2224 } |
| 2257 } | 2225 } |
| 2258 assert(frameElements.length == newFrames.length); | 2226 assert(frameElements.length == newFrames.length); |
| 2259 | 2227 |
| 2260 if (frameElements.isNotEmpty) { | 2228 if (frameElements.isNotEmpty) { |
| 2261 for (int i = newCount; i < frameElements.length; i++) { | 2229 for (int i = newCount; i < frameElements.length; i++) { |
| 2262 frameElements[i].children[0].updateFrame(newFrames[i]); | 2230 frameElements[i].children[0].updateFrame(newFrames[i]); |
| 2263 } | 2231 } |
| 2264 } | 2232 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2354 } else { | 2322 } else { |
| 2355 if (_pinned) { | 2323 if (_pinned) { |
| 2356 _expand(); | 2324 _expand(); |
| 2357 } else { | 2325 } else { |
| 2358 _unexpand(); | 2326 _unexpand(); |
| 2359 } | 2327 } |
| 2360 } | 2328 } |
| 2361 }); | 2329 }); |
| 2362 } | 2330 } |
| 2363 | 2331 |
| 2364 factory DebuggerFrameElement(M.Isolate isolate, | 2332 factory DebuggerFrameElement( |
| 2365 S.Frame frame, | 2333 M.Isolate isolate, |
| 2366 Element scroller, | 2334 S.Frame frame, |
| 2367 M.InstanceRepository instances, | 2335 Element scroller, |
| 2368 M.ScriptRepository scripts, | 2336 M.InstanceRepository instances, |
| 2369 M.EventRepository events, | 2337 M.ScriptRepository scripts, |
| 2370 {RenderingQueue queue}) { | 2338 M.EventRepository events, |
| 2339 {RenderingQueue queue}) { |
| 2371 assert(isolate != null); | 2340 assert(isolate != null); |
| 2372 assert(frame != null); | 2341 assert(frame != null); |
| 2373 assert(scroller != null); | 2342 assert(scroller != null); |
| 2374 assert(instances != null); | 2343 assert(instances != null); |
| 2375 assert(scripts != null); | 2344 assert(scripts != null); |
| 2376 assert(events != null); | 2345 assert(events != null); |
| 2377 final DebuggerFrameElement e = document.createElement(tag.name); | 2346 final DebuggerFrameElement e = document.createElement(tag.name); |
| 2378 e._r = new RenderingScheduler(e, queue: queue); | 2347 e._r = new RenderingScheduler(e, queue: queue); |
| 2379 e._isolate = isolate; | 2348 e._isolate = isolate; |
| 2380 e._frame = frame; | 2349 e._frame = frame; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2414 if (_expanded) { | 2383 if (_expanded) { |
| 2415 final homeMethod = _frame.function.homeMethod; | 2384 final homeMethod = _frame.function.homeMethod; |
| 2416 String homeMethodName; | 2385 String homeMethodName; |
| 2417 if ((homeMethod.dartOwner is S.Class) && homeMethod.isStatic) { | 2386 if ((homeMethod.dartOwner is S.Class) && homeMethod.isStatic) { |
| 2418 homeMethodName = '<class>'; | 2387 homeMethodName = '<class>'; |
| 2419 } else if (homeMethod.dartOwner is S.Library) { | 2388 } else if (homeMethod.dartOwner is S.Library) { |
| 2420 homeMethodName = '<library>'; | 2389 homeMethodName = '<library>'; |
| 2421 } | 2390 } |
| 2422 ButtonElement collapseButton; | 2391 ButtonElement collapseButton; |
| 2423 content.addAll([ | 2392 content.addAll([ |
| 2424 new DivElement()..classes = ['frameDetails'] | 2393 new DivElement() |
| 2394 ..classes = ['frameDetails'] |
| 2425 ..children = [ | 2395 ..children = [ |
| 2426 new DivElement()..classes = ['flex-row-wrap'] | 2396 new DivElement() |
| 2397 ..classes = ['flex-row-wrap'] |
| 2427 ..children = [ | 2398 ..children = [ |
| 2428 new DivElement()..classes = ['flex-item-script'] | 2399 new DivElement() |
| 2429 ..children = _frame.function?.location == null ? const [] | 2400 ..classes = ['flex-item-script'] |
| 2430 : [ | 2401 ..children = _frame.function?.location == null |
| 2431 new SourceInsetElement(_isolate, | 2402 ? const [] |
| 2432 _frame.function.location, _scripts, _instances, | 2403 : [ |
| 2433 _events, currentPos: _frame.location.tokenPos, | 2404 new SourceInsetElement( |
| 2434 variables: _frame.variables, inDebuggerContext: true, | 2405 _isolate, |
| 2435 queue: _r.queue) | 2406 _frame.function.location, |
| 2436 ], | 2407 _scripts, |
| 2437 new DivElement()..classes = ['flex-item-vars'] | 2408 _instances, |
| 2409 _events, |
| 2410 currentPos: _frame.location.tokenPos, |
| 2411 variables: _frame.variables, |
| 2412 inDebuggerContext: true, |
| 2413 queue: _r.queue) |
| 2414 ], |
| 2415 new DivElement() |
| 2416 ..classes = ['flex-item-vars'] |
| 2438 ..children = [ | 2417 ..children = [ |
| 2439 _varsDiv = new DivElement() | 2418 _varsDiv = new DivElement() |
| 2440 ..classes = ['memberList', 'frameVars'] | 2419 ..classes = ['memberList', 'frameVars'] |
| 2441 ..children = ([ | 2420 ..children = ([ |
| 2442 new DivElement()..classes = ['memberItem'] | 2421 new DivElement() |
| 2443 ..children = homeMethodName == null ? const [] | 2422 ..classes = ['memberItem'] |
| 2444 : [ | 2423 ..children = homeMethodName == null |
| 2445 new DivElement()..classes = ['memberName'] | 2424 ? const [] |
| 2446 ..text = homeMethodName, | 2425 : [ |
| 2447 new DivElement()..classes = ['memberName'] | 2426 new DivElement() |
| 2448 ..children = [ | 2427 ..classes = ['memberName'] |
| 2449 anyRef(_isolate, homeMethod.dartOwner, | 2428 ..text = homeMethodName, |
| 2450 _instances, queue: _r.queue) | 2429 new DivElement() |
| 2430 ..classes = ['memberName'] |
| 2431 ..children = [ |
| 2432 anyRef(_isolate, homeMethod.dartOwner, |
| 2433 _instances, |
| 2434 queue: _r.queue) |
| 2435 ] |
| 2451 ] | 2436 ] |
| 2452 ] | 2437 ] |
| 2453 ]..addAll(_frame.variables.map((v) => | 2438 ..addAll(_frame.variables |
| 2454 new DivElement()..classes = ['memberItem'] | 2439 .map((v) => new DivElement() |
| 2455 ..children = [ | 2440 ..classes = ['memberItem'] |
| 2456 new DivElement()..classes = ['memberName'] | |
| 2457 ..text = v.name, | |
| 2458 new DivElement()..classes = ['memberName'] | |
| 2459 ..children = [ | 2441 ..children = [ |
| 2460 anyRef(_isolate, v['value'], _instances, | 2442 new DivElement() |
| 2461 queue: _r.queue) | 2443 ..classes = ['memberName'] |
| 2462 ] | 2444 ..text = v.name, |
| 2463 ] | 2445 new DivElement() |
| 2464 ).toList())) | 2446 ..classes = ['memberName'] |
| 2447 ..children = [ |
| 2448 anyRef(_isolate, v['value'], _instances, |
| 2449 queue: _r.queue) |
| 2450 ] |
| 2451 ]) |
| 2452 .toList())) |
| 2465 ] | 2453 ] |
| 2466 ], | 2454 ], |
| 2467 new DivElement()..classes = ['frameContractor'] | 2455 new DivElement() |
| 2456 ..classes = ['frameContractor'] |
| 2468 ..children = [ | 2457 ..children = [ |
| 2469 collapseButton = new ButtonElement() | 2458 collapseButton = new ButtonElement() |
| 2470 ..onClick.listen((e) async { | 2459 ..onClick.listen((e) async { |
| 2471 collapseButton.disabled = true; | 2460 collapseButton.disabled = true; |
| 2472 await _toggleExpand(); | 2461 await _toggleExpand(); |
| 2473 collapseButton.disabled = false; | 2462 collapseButton.disabled = false; |
| 2474 }) | 2463 }) |
| 2475 ..children = [ | 2464 ..children = [iconExpandLess.clone(true)] |
| 2476 iconExpandLess.clone(true) | |
| 2477 ] | |
| 2478 ] | 2465 ] |
| 2479 ] | 2466 ] |
| 2480 ]); | 2467 ]); |
| 2481 } | 2468 } |
| 2482 children = content; | 2469 children = content; |
| 2483 } | 2470 } |
| 2484 | 2471 |
| 2485 List<Element> _createHeader() { | 2472 List<Element> _createHeader() { |
| 2486 final content = [ | 2473 final content = [ |
| 2487 new DivElement()..classes = ['frameSummaryText'] | 2474 new DivElement() |
| 2475 ..classes = ['frameSummaryText'] |
| 2488 ..children = [ | 2476 ..children = [ |
| 2489 new DivElement()..classes = ['frameId'] | 2477 new DivElement() |
| 2478 ..classes = ['frameId'] |
| 2490 ..text = 'Frame ${_frame.index}', | 2479 ..text = 'Frame ${_frame.index}', |
| 2491 new SpanElement() | 2480 new SpanElement() |
| 2492 ..children = _frame.function == null ? const [] | 2481 ..children = _frame.function == null |
| 2493 : [ | 2482 ? const [] |
| 2494 new FunctionRefElement(_isolate, _frame.function, | 2483 : [ |
| 2495 queue: _r.queue) | 2484 new FunctionRefElement(_isolate, _frame.function, |
| 2496 ], | 2485 queue: _r.queue) |
| 2486 ], |
| 2497 new SpanElement()..text = ' ( ', | 2487 new SpanElement()..text = ' ( ', |
| 2498 new SpanElement() | 2488 new SpanElement() |
| 2499 ..children = _frame.function?.location == null ? const [] | 2489 ..children = _frame.function?.location == null |
| 2500 : [ | 2490 ? const [] |
| 2501 new SourceLinkElement(_isolate, _frame.function.location, | 2491 : [ |
| 2502 _scripts, | 2492 new SourceLinkElement( |
| 2503 queue: _r.queue) | 2493 _isolate, _frame.function.location, _scripts, |
| 2504 ], | 2494 queue: _r.queue) |
| 2495 ], |
| 2505 new SpanElement()..text = ' )' | 2496 new SpanElement()..text = ' )' |
| 2506 ] | 2497 ] |
| 2507 ]; | 2498 ]; |
| 2508 if (!_expanded) { | 2499 if (!_expanded) { |
| 2509 content.add(new DivElement()..classes = ['frameExpander'] | 2500 content.add(new DivElement() |
| 2510 ..children = [ | 2501 ..classes = ['frameExpander'] |
| 2511 iconExpandMore.clone(true) | 2502 ..children = [iconExpandMore.clone(true)]); |
| 2512 ]); | |
| 2513 } | 2503 } |
| 2514 return [ | 2504 return [ |
| 2515 new DivElement()..classes = ['frameSummary'] | 2505 new DivElement() |
| 2506 ..classes = ['frameSummary'] |
| 2516 ..children = content | 2507 ..children = content |
| 2517 ]; | 2508 ]; |
| 2518 } | 2509 } |
| 2519 | 2510 |
| 2520 String makeExpandKey(String key) { | 2511 String makeExpandKey(String key) { |
| 2521 return '${_frame.function.qualifiedName}/${key}'; | 2512 return '${_frame.function.qualifiedName}/${key}'; |
| 2522 } | 2513 } |
| 2523 | 2514 |
| 2524 bool matchFrame(S.Frame newFrame) { | 2515 bool matchFrame(S.Frame newFrame) { |
| 2525 return newFrame.function.id == _frame.function.id; | 2516 return newFrame.function.id == _frame.function.id; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2634 M.EventRepository _events; | 2625 M.EventRepository _events; |
| 2635 | 2626 |
| 2636 // Is this the current message? | 2627 // Is this the current message? |
| 2637 bool _current = false; | 2628 bool _current = false; |
| 2638 | 2629 |
| 2639 // Has this message been pinned open? | 2630 // Has this message been pinned open? |
| 2640 bool _pinned = false; | 2631 bool _pinned = false; |
| 2641 | 2632 |
| 2642 bool _expanded = false; | 2633 bool _expanded = false; |
| 2643 | 2634 |
| 2644 factory DebuggerMessageElement(S.Isolate isolate, | 2635 factory DebuggerMessageElement( |
| 2645 S.ServiceMessage message, | 2636 S.Isolate isolate, |
| 2646 M.InstanceRepository instances, | 2637 S.ServiceMessage message, |
| 2647 M.ScriptRepository scripts, | 2638 M.InstanceRepository instances, |
| 2648 M.EventRepository events, | 2639 M.ScriptRepository scripts, |
| 2649 {RenderingQueue queue}) { | 2640 M.EventRepository events, |
| 2641 {RenderingQueue queue}) { |
| 2650 assert(isolate != null); | 2642 assert(isolate != null); |
| 2651 assert(message != null); | 2643 assert(message != null); |
| 2652 assert(instances != null); | 2644 assert(instances != null); |
| 2653 assert(instances != null); | 2645 assert(instances != null); |
| 2654 assert(events != null); | 2646 assert(events != null); |
| 2655 final DebuggerMessageElement e = document.createElement(tag.name); | 2647 final DebuggerMessageElement e = document.createElement(tag.name); |
| 2656 e._r = new RenderingScheduler(e, queue: queue); | 2648 e._r = new RenderingScheduler(e, queue: queue); |
| 2657 e._isolate = isolate; | 2649 e._isolate = isolate; |
| 2658 e._message = message; | 2650 e._message = message; |
| 2659 e._instances = instances; | 2651 e._instances = instances; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2685 } | 2677 } |
| 2686 expandButton.disabled = true; | 2678 expandButton.disabled = true; |
| 2687 await _toggleExpand(); | 2679 await _toggleExpand(); |
| 2688 expandButton.disabled = false; | 2680 expandButton.disabled = false; |
| 2689 }) | 2681 }) |
| 2690 ]; | 2682 ]; |
| 2691 if (_expanded) { | 2683 if (_expanded) { |
| 2692 ButtonElement collapseButton; | 2684 ButtonElement collapseButton; |
| 2693 ButtonElement previewButton; | 2685 ButtonElement previewButton; |
| 2694 content.addAll([ | 2686 content.addAll([ |
| 2695 new DivElement()..classes = ['messageDetails'] | 2687 new DivElement() |
| 2688 ..classes = ['messageDetails'] |
| 2696 ..children = [ | 2689 ..children = [ |
| 2697 new DivElement()..classes = ['flex-row-wrap'] | 2690 new DivElement() |
| 2691 ..classes = ['flex-row-wrap'] |
| 2698 ..children = [ | 2692 ..children = [ |
| 2699 new DivElement()..classes = ['flex-item-script'] | 2693 new DivElement() |
| 2700 ..children = _message.handler == null ? const [] | 2694 ..classes = ['flex-item-script'] |
| 2701 : [ | 2695 ..children = _message.handler == null |
| 2702 new SourceInsetElement(_isolate, | 2696 ? const [] |
| 2703 _message.handler.location, | 2697 : [ |
| 2704 _scripts, | 2698 new SourceInsetElement( |
| 2705 _instances, | 2699 _isolate, |
| 2706 _events, | 2700 _message.handler.location, |
| 2707 inDebuggerContext: true, | 2701 _scripts, |
| 2708 queue: _r.queue) | 2702 _instances, |
| 2709 ], | 2703 _events, |
| 2710 new DivElement()..classes = ['flex-item-vars'] | 2704 inDebuggerContext: true, |
| 2705 queue: _r.queue) |
| 2706 ], |
| 2707 new DivElement() |
| 2708 ..classes = ['flex-item-vars'] |
| 2711 ..children = [ | 2709 ..children = [ |
| 2712 new DivElement()..classes = ['memberItem'] | 2710 new DivElement() |
| 2711 ..classes = ['memberItem'] |
| 2713 ..children = [ | 2712 ..children = [ |
| 2714 new DivElement()..classes = ['memberName'], | 2713 new DivElement()..classes = ['memberName'], |
| 2715 new DivElement()..classes = ['memberValue'] | 2714 new DivElement() |
| 2715 ..classes = ['memberValue'] |
| 2716 ..children = ([ | 2716 ..children = ([ |
| 2717 previewButton = new ButtonElement() | 2717 previewButton = new ButtonElement() |
| 2718 ..text = 'preview' | 2718 ..text = 'preview' |
| 2719 ..onClick.listen((_) { | 2719 ..onClick.listen((_) { |
| 2720 previewButton.disabled = true; | 2720 previewButton.disabled = true; |
| 2721 | |
| 2722 }) | 2721 }) |
| 2723 ]..addAll( | 2722 ] |
| 2724 _preview == null ? const [] | 2723 ..addAll(_preview == null |
| 2725 : [ | 2724 ? const [] |
| 2726 anyRef(_isolate, _preview, _instances, | 2725 : [ |
| 2727 queue: _r.queue) | 2726 anyRef(_isolate, _preview, _instances, |
| 2728 ] | 2727 queue: _r.queue) |
| 2729 )) | 2728 ])) |
| 2730 ] | 2729 ] |
| 2731 ] | 2730 ] |
| 2732 ], | 2731 ], |
| 2733 new DivElement()..classes = ['messageContractor'] | 2732 new DivElement() |
| 2733 ..classes = ['messageContractor'] |
| 2734 ..children = [ | 2734 ..children = [ |
| 2735 collapseButton = new ButtonElement() | 2735 collapseButton = new ButtonElement() |
| 2736 ..onClick.listen((e) async { | 2736 ..onClick.listen((e) async { |
| 2737 collapseButton.disabled = true; | 2737 collapseButton.disabled = true; |
| 2738 await _toggleExpand(); | 2738 await _toggleExpand(); |
| 2739 collapseButton.disabled = false; | 2739 collapseButton.disabled = false; |
| 2740 }) | 2740 }) |
| 2741 ..children = [ | 2741 ..children = [iconExpandLess.clone(true)] |
| 2742 iconExpandLess.clone(true) | |
| 2743 ] | |
| 2744 ] | 2742 ] |
| 2745 ] | 2743 ] |
| 2746 ]); | 2744 ]); |
| 2747 } | 2745 } |
| 2748 children = content; | 2746 children = content; |
| 2749 } | 2747 } |
| 2750 | 2748 |
| 2751 void updateMessage(S.ServiceMessage message) { | 2749 void updateMessage(S.ServiceMessage message) { |
| 2752 assert(_message != null); | 2750 assert(_message != null); |
| 2753 _message = message; | 2751 _message = message; |
| 2754 _r.dirty(); | 2752 _r.dirty(); |
| 2755 } | 2753 } |
| 2756 | 2754 |
| 2757 List<Element> _createHeader() { | 2755 List<Element> _createHeader() { |
| 2758 final content = [ | 2756 final content = [ |
| 2759 new DivElement()..classes = ['messageSummaryText'] | 2757 new DivElement() |
| 2758 ..classes = ['messageSummaryText'] |
| 2760 ..children = [ | 2759 ..children = [ |
| 2761 new DivElement()..classes = ['messageId'] | 2760 new DivElement() |
| 2761 ..classes = ['messageId'] |
| 2762 ..text = 'message ${_message.index}', | 2762 ..text = 'message ${_message.index}', |
| 2763 new SpanElement() | 2763 new SpanElement() |
| 2764 ..children = _message.handler == null ? const [] | 2764 ..children = _message.handler == null |
| 2765 : [ | 2765 ? const [] |
| 2766 new FunctionRefElement(_isolate, _message.handler, | 2766 : [ |
| 2767 queue: _r.queue) | 2767 new FunctionRefElement(_isolate, _message.handler, |
| 2768 ], | 2768 queue: _r.queue) |
| 2769 ], |
| 2769 new SpanElement()..text = ' ( ', | 2770 new SpanElement()..text = ' ( ', |
| 2770 new SpanElement() | 2771 new SpanElement() |
| 2771 ..children = _message.location == null ? const [] | 2772 ..children = _message.location == null |
| 2772 : [ | 2773 ? const [] |
| 2773 new SourceLinkElement(_isolate, _message.location, _scripts, | 2774 : [ |
| 2774 queue: _r.queue) | 2775 new SourceLinkElement(_isolate, _message.location, _scripts, |
| 2775 ], | 2776 queue: _r.queue) |
| 2777 ], |
| 2776 new SpanElement()..text = ' )' | 2778 new SpanElement()..text = ' )' |
| 2777 ] | 2779 ] |
| 2778 ]; | 2780 ]; |
| 2779 if (!_expanded) { | 2781 if (!_expanded) { |
| 2780 content.add(new DivElement()..classes = ['messageExpander'] | 2782 content.add(new DivElement() |
| 2781 ..children = [ | 2783 ..classes = ['messageExpander'] |
| 2782 iconExpandMore.clone(true) | 2784 ..children = [iconExpandMore.clone(true)]); |
| 2783 ]); | |
| 2784 } | 2785 } |
| 2785 return [ | 2786 return [ |
| 2786 new DivElement()..classes = ['messageSummary'] | 2787 new DivElement() |
| 2788 ..classes = ['messageSummary'] |
| 2787 ..children = content | 2789 ..children = content |
| 2788 ]; | 2790 ]; |
| 2789 } | 2791 } |
| 2790 | 2792 |
| 2791 void setCurrent(bool value) { | 2793 void setCurrent(bool value) { |
| 2792 _current = value; | 2794 _current = value; |
| 2793 if (_current) { | 2795 if (_current) { |
| 2794 _expanded = true; | 2796 _expanded = true; |
| 2795 scrollIntoView(); | 2797 scrollIntoView(); |
| 2796 _r.dirty(); | 2798 _r.dirty(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2828 return result; | 2830 return result; |
| 2829 }); | 2831 }); |
| 2830 } | 2832 } |
| 2831 } | 2833 } |
| 2832 | 2834 |
| 2833 class DebuggerConsoleElement extends HtmlElement implements Renderable { | 2835 class DebuggerConsoleElement extends HtmlElement implements Renderable { |
| 2834 static const tag = const Tag<DebuggerConsoleElement>('debugger-console'); | 2836 static const tag = const Tag<DebuggerConsoleElement>('debugger-console'); |
| 2835 | 2837 |
| 2836 factory DebuggerConsoleElement() { | 2838 factory DebuggerConsoleElement() { |
| 2837 final DebuggerConsoleElement e = document.createElement(tag.name); | 2839 final DebuggerConsoleElement e = document.createElement(tag.name); |
| 2838 e.children = [ | 2840 e.children = [new BRElement()]; |
| 2839 new BRElement() | |
| 2840 ]; | |
| 2841 return e; | 2841 return e; |
| 2842 } | 2842 } |
| 2843 | 2843 |
| 2844 DebuggerConsoleElement.created() : super.created(); | 2844 DebuggerConsoleElement.created() : super.created(); |
| 2845 | 2845 |
| 2846 /// Is [container] scrolled to the within [threshold] pixels of the bottom? | 2846 /// Is [container] scrolled to the within [threshold] pixels of the bottom? |
| 2847 static bool _isScrolledToBottom(DivElement container, [int threshold = 2]) { | 2847 static bool _isScrolledToBottom(DivElement container, [int threshold = 2]) { |
| 2848 if (container == null) { | 2848 if (container == null) { |
| 2849 return false; | 2849 return false; |
| 2850 } | 2850 } |
| 2851 // scrollHeight -> complete height of element including scrollable area. | 2851 // scrollHeight -> complete height of element including scrollable area. |
| 2852 // clientHeight -> height of element on page. | 2852 // clientHeight -> height of element on page. |
| 2853 // scrollTop -> how far is an element scrolled (from 0 to scrollHeight). | 2853 // scrollTop -> how far is an element scrolled (from 0 to scrollHeight). |
| 2854 final distanceFromBottom = | 2854 final distanceFromBottom = |
| 2855 container.scrollHeight - container.clientHeight - container.scrollTop; | 2855 container.scrollHeight - container.clientHeight - container.scrollTop; |
| 2856 const threshold = 2; // 2 pixel slop. | 2856 const threshold = 2; // 2 pixel slop. |
| 2857 return distanceFromBottom <= threshold; | 2857 return distanceFromBottom <= threshold; |
| 2858 } | 2858 } |
| 2859 | 2859 |
| 2860 /// Scroll [container] so the bottom content is visible. | 2860 /// Scroll [container] so the bottom content is visible. |
| 2861 static _scrollToBottom(DivElement container) { | 2861 static _scrollToBottom(DivElement container) { |
| 2862 if (container == null) { | 2862 if (container == null) { |
| 2863 return; | 2863 return; |
| 2864 } | 2864 } |
| 2865 // Adjust scroll so that the bottom of the content is visible. | 2865 // Adjust scroll so that the bottom of the content is visible. |
| 2866 container.scrollTop = container.scrollHeight - container.clientHeight; | 2866 container.scrollTop = container.scrollHeight - container.clientHeight; |
| 2867 } | 2867 } |
| 2868 | 2868 |
| 2869 void _append(HtmlElement span) { | 2869 void _append(HtmlElement span) { |
| 2870 bool autoScroll = _isScrolledToBottom(parent); | 2870 bool autoScroll = _isScrolledToBottom(parent); |
| 2871 children.add(span); | 2871 children.add(span); |
| 2872 if (autoScroll) { | 2872 if (autoScroll) { |
| 2873 _scrollToBottom(parent); | 2873 _scrollToBottom(parent); |
| 2874 } | 2874 } |
| 2875 } | 2875 } |
| 2876 | 2876 |
| 2877 void print(String line, { bool newline:true }) { | 2877 void print(String line, {bool newline: true}) { |
| 2878 var span = new SpanElement(); | 2878 var span = new SpanElement(); |
| 2879 span.classes.add('normal'); | 2879 span.classes.add('normal'); |
| 2880 span.appendText(line); | 2880 span.appendText(line); |
| 2881 if (newline) { | 2881 if (newline) { |
| 2882 span.appendText('\n'); | 2882 span.appendText('\n'); |
| 2883 } | 2883 } |
| 2884 _append(span); | 2884 _append(span); |
| 2885 } | 2885 } |
| 2886 | 2886 |
| 2887 void printBold(String line, { bool newline:true }) { | 2887 void printBold(String line, {bool newline: true}) { |
| 2888 var span = new SpanElement(); | 2888 var span = new SpanElement(); |
| 2889 span.classes.add('bold'); | 2889 span.classes.add('bold'); |
| 2890 span.appendText(line); | 2890 span.appendText(line); |
| 2891 if (newline) { | 2891 if (newline) { |
| 2892 span.appendText('\n'); | 2892 span.appendText('\n'); |
| 2893 } | 2893 } |
| 2894 _append(span); | 2894 _append(span); |
| 2895 } | 2895 } |
| 2896 | 2896 |
| 2897 void printRed(String line, { bool newline:true }) { | 2897 void printRed(String line, {bool newline: true}) { |
| 2898 var span = new SpanElement(); | 2898 var span = new SpanElement(); |
| 2899 span.classes.add('red'); | 2899 span.classes.add('red'); |
| 2900 span.appendText(line); | 2900 span.appendText(line); |
| 2901 if (newline) { | 2901 if (newline) { |
| 2902 span.appendText('\n'); | 2902 span.appendText('\n'); |
| 2903 } | 2903 } |
| 2904 _append(span); | 2904 _append(span); |
| 2905 } | 2905 } |
| 2906 | 2906 |
| 2907 void printStdio(List<String> lines) { | 2907 void printStdio(List<String> lines) { |
| 2908 bool autoScroll = _isScrolledToBottom(parent); | 2908 bool autoScroll = _isScrolledToBottom(parent); |
| 2909 for (var line in lines) { | 2909 for (var line in lines) { |
| 2910 var span = new SpanElement(); | 2910 var span = new SpanElement(); |
| 2911 span.classes.add('green'); | 2911 span.classes.add('green'); |
| 2912 span.appendText(line); | 2912 span.appendText(line); |
| 2913 span.appendText('\n'); | 2913 span.appendText('\n'); |
| 2914 children.add(span); | 2914 children.add(span); |
| 2915 } | 2915 } |
| 2916 if (autoScroll) { | 2916 if (autoScroll) { |
| 2917 _scrollToBottom(parent); | 2917 _scrollToBottom(parent); |
| 2918 } | 2918 } |
| 2919 } | 2919 } |
| 2920 | 2920 |
| 2921 void printRef(S.Isolate isolate, S.Instance ref, | 2921 void printRef( |
| 2922 M.InstanceRepository instances,{ bool newline:true }) { | 2922 S.Isolate isolate, S.Instance ref, M.InstanceRepository instances, |
| 2923 _append(new InstanceRefElement(isolate, ref, instances, | 2923 {bool newline: true}) { |
| 2924 queue: app.queue)); | 2924 _append(new InstanceRefElement(isolate, ref, instances, queue: app.queue)); |
| 2925 if (newline) { | 2925 if (newline) { |
| 2926 this.newline(); | 2926 this.newline(); |
| 2927 } | 2927 } |
| 2928 } | 2928 } |
| 2929 | 2929 |
| 2930 void newline() { | 2930 void newline() { |
| 2931 _append(new BRElement()); | 2931 _append(new BRElement()); |
| 2932 } | 2932 } |
| 2933 | 2933 |
| 2934 void clear() { | 2934 void clear() { |
| 2935 children.clear(); | 2935 children.clear(); |
| 2936 } | 2936 } |
| 2937 | 2937 |
| 2938 void render() { | 2938 void render() { |
| 2939 /* nothing to do */ | 2939 /* nothing to do */ |
| 2940 } | 2940 } |
| 2941 | 2941 |
| 2942 ObservatoryApplication get app => ObservatoryApplication.app; | 2942 ObservatoryApplication get app => ObservatoryApplication.app; |
| 2943 } | 2943 } |
| 2944 | 2944 |
| 2945 class DebuggerInputElement extends HtmlElement implements Renderable { | 2945 class DebuggerInputElement extends HtmlElement implements Renderable { |
| 2946 static const tag = const Tag<DebuggerInputElement>('debugger-input'); | 2946 static const tag = const Tag<DebuggerInputElement>('debugger-input'); |
| 2947 | 2947 |
| 2948 S.Isolate _isolate; | 2948 S.Isolate _isolate; |
| 2949 ObservatoryDebugger _debugger; | 2949 ObservatoryDebugger _debugger; |
| 2950 bool _busy = false; | 2950 bool _busy = false; |
| 2951 final _modalPromptDiv = new DivElement() | 2951 final _modalPromptDiv = new DivElement()..classes = ['modalPrompt', 'hidden']; |
| 2952 ..classes = ['modalPrompt', 'hidden']; | |
| 2953 final _textBox = new TextInputElement() | 2952 final _textBox = new TextInputElement() |
| 2954 ..classes = ['textBox'] | 2953 ..classes = ['textBox'] |
| 2955 ..autofocus = true; | 2954 ..autofocus = true; |
| 2956 String get modalPrompt => _modalPromptDiv.text; | 2955 String get modalPrompt => _modalPromptDiv.text; |
| 2957 set modalPrompt(String value) { | 2956 set modalPrompt(String value) { |
| 2958 if (_modalPromptDiv.text == '') { | 2957 if (_modalPromptDiv.text == '') { |
| 2959 _modalPromptDiv.classes.remove('hidden'); | 2958 _modalPromptDiv.classes.remove('hidden'); |
| 2960 } | 2959 } |
| 2961 _modalPromptDiv.text = value; | 2960 _modalPromptDiv.text = value; |
| 2962 if (_modalPromptDiv.text == '') { | 2961 if (_modalPromptDiv.text == '') { |
| 2963 _modalPromptDiv.classes.add('hidden'); | 2962 _modalPromptDiv.classes.add('hidden'); |
| 2964 } | 2963 } |
| 2965 } | 2964 } |
| 2965 |
| 2966 String get text => _textBox.value; | 2966 String get text => _textBox.value; |
| 2967 set text(String value) => _textBox.value = value; | 2967 set text(String value) => _textBox.value = value; |
| 2968 var modalCallback = null; | 2968 var modalCallback = null; |
| 2969 | 2969 |
| 2970 factory DebuggerInputElement(S.Isolate isolate, | 2970 factory DebuggerInputElement( |
| 2971 ObservatoryDebugger debugger) { | 2971 S.Isolate isolate, ObservatoryDebugger debugger) { |
| 2972 final DebuggerInputElement e = document.createElement(tag.name); | 2972 final DebuggerInputElement e = document.createElement(tag.name); |
| 2973 e.children = [ | 2973 e.children = [e._modalPromptDiv, e._textBox]; |
| 2974 e._modalPromptDiv, | |
| 2975 e._textBox | |
| 2976 ]; | |
| 2977 e._textBox.select(); | 2974 e._textBox.select(); |
| 2978 e._textBox.onKeyDown.listen(e._onKeyDown); | 2975 e._textBox.onKeyDown.listen(e._onKeyDown); |
| 2979 return e; | 2976 return e; |
| 2980 } | 2977 } |
| 2981 | 2978 |
| 2982 DebuggerInputElement.created() : super.created(); | 2979 DebuggerInputElement.created() : super.created(); |
| 2983 | 2980 |
| 2984 void _onKeyDown(KeyboardEvent e) { | 2981 void _onKeyDown(KeyboardEvent e) { |
| 2985 if (_busy) { | 2982 if (_busy) { |
| 2986 e.preventDefault(); | 2983 e.preventDefault(); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3113 void focus() { | 3110 void focus() { |
| 3114 _textBox.focus(); | 3111 _textBox.focus(); |
| 3115 } | 3112 } |
| 3116 | 3113 |
| 3117 void render() { | 3114 void render() { |
| 3118 // Nothing to do. | 3115 // Nothing to do. |
| 3119 } | 3116 } |
| 3120 } | 3117 } |
| 3121 | 3118 |
| 3122 final SvgSvgElement iconExpandLess = new SvgSvgElement() | 3119 final SvgSvgElement iconExpandLess = new SvgSvgElement() |
| 3123 ..setAttribute('width', '24') | 3120 ..setAttribute('width', '24') |
| 3124 ..setAttribute('height', '24') | 3121 ..setAttribute('height', '24') |
| 3125 ..children = [ | 3122 ..children = [ |
| 3126 new PolygonElement() | 3123 new PolygonElement() |
| 3127 ..setAttribute('points', '12,8 6,14 7.4,15.4 12,10.8 16.6,15.4 18,14 ') | 3124 ..setAttribute('points', '12,8 6,14 7.4,15.4 12,10.8 16.6,15.4 18,14 ') |
| 3128 ]; | 3125 ]; |
| 3129 | 3126 |
| 3130 final SvgSvgElement iconExpandMore = new SvgSvgElement() | 3127 final SvgSvgElement iconExpandMore = new SvgSvgElement() |
| 3131 ..setAttribute('width', '24') | 3128 ..setAttribute('width', '24') |
| 3132 ..setAttribute('height', '24') | 3129 ..setAttribute('height', '24') |
| 3133 ..children = [ | 3130 ..children = [ |
| 3134 new PolygonElement() | 3131 new PolygonElement() |
| 3135 ..setAttribute('points', '16.6,8.6 12,13.2 7.4,8.6 6,10 12,16 18,10 ') | 3132 ..setAttribute('points', '16.6,8.6 12,13.2 7.4,8.6 6,10 12,16 18,10 ') |
| 3136 ]; | 3133 ]; |
| 3137 | 3134 |
| 3138 final SvgSvgElement iconChevronRight = new SvgSvgElement() | 3135 final SvgSvgElement iconChevronRight = new SvgSvgElement() |
| 3139 ..setAttribute('width', '24') | 3136 ..setAttribute('width', '24') |
| 3140 ..setAttribute('height', '24') | 3137 ..setAttribute('height', '24') |
| 3141 ..children = [ | 3138 ..children = [ |
| 3142 new PathElement() | 3139 new PathElement() |
| 3143 ..setAttribute('d', 'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z') | 3140 ..setAttribute('d', 'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z') |
| 3144 ]; | 3141 ]; |
| 3145 | 3142 |
| 3146 final SvgSvgElement iconChevronLeft = new SvgSvgElement() | 3143 final SvgSvgElement iconChevronLeft = new SvgSvgElement() |
| 3147 ..setAttribute('width', '24') | 3144 ..setAttribute('width', '24') |
| 3148 ..setAttribute('height', '24') | 3145 ..setAttribute('height', '24') |
| 3149 ..children = [ | 3146 ..children = [ |
| 3150 new PathElement() | 3147 new PathElement() |
| 3151 ..setAttribute('d', 'M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z') | 3148 ..setAttribute('d', 'M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z') |
| 3152 ]; | 3149 ]; |
| 3153 | 3150 |
| 3154 final SvgSvgElement iconHorizontalThreeDot = new SvgSvgElement() | 3151 final SvgSvgElement iconHorizontalThreeDot = new SvgSvgElement() |
| 3155 ..setAttribute('width', '24') | 3152 ..setAttribute('width', '24') |
| 3156 ..setAttribute('height', '24') | 3153 ..setAttribute('height', '24') |
| 3157 ..children = [ | 3154 ..children = [ |
| 3158 new PathElement() | 3155 new PathElement() |
| 3159 ..setAttribute('d', 'M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' | 3156 ..setAttribute( |
| 3160 '2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' | 3157 'd', |
| 3161 '2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' | 3158 'M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' |
| 3162 '2-2-.9-2-2-2z') | 3159 '2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' |
| 3163 ]; | 3160 '2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' |
| 3161 '2-2-.9-2-2-2z') |
| 3162 ]; |
| 3164 | 3163 |
| 3165 final SvgSvgElement iconVerticalThreeDot = new SvgSvgElement() | 3164 final SvgSvgElement iconVerticalThreeDot = new SvgSvgElement() |
| 3166 ..setAttribute('width', '24') | 3165 ..setAttribute('width', '24') |
| 3167 ..setAttribute('height', '24') | 3166 ..setAttribute('height', '24') |
| 3168 ..children = [ | 3167 ..children = [ |
| 3169 new PathElement() | 3168 new PathElement() |
| 3170 ..setAttribute('d', 'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 ' | 3169 ..setAttribute( |
| 3171 '2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' | 3170 'd', |
| 3172 '2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 ' | 3171 'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 ' |
| 3173 '2-.9 2-2-.9-2-2-2z') | 3172 '2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 ' |
| 3174 ]; | 3173 '2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 ' |
| 3174 '2-.9 2-2-.9-2-2-2z') |
| 3175 ]; |
| 3175 | 3176 |
| 3176 final SvgSvgElement iconInfo = new SvgSvgElement() | 3177 final SvgSvgElement iconInfo = new SvgSvgElement() |
| 3177 ..setAttribute('width', '24') | 3178 ..setAttribute('width', '24') |
| 3178 ..setAttribute('height', '24') | 3179 ..setAttribute('height', '24') |
| 3179 ..children = [ | 3180 ..children = [ |
| 3180 new PathElement() | 3181 new PathElement() |
| 3181 ..setAttribute('d', 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 ' | 3182 ..setAttribute( |
| 3182 '10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z') | 3183 'd', |
| 3183 ]; | 3184 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 ' |
| 3185 '10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z') |
| 3186 ]; |
| 3184 | 3187 |
| 3185 final SvgSvgElement iconInfoOutline = new SvgSvgElement() | 3188 final SvgSvgElement iconInfoOutline = new SvgSvgElement() |
| 3186 ..setAttribute('width', '24') | 3189 ..setAttribute('width', '24') |
| 3187 ..setAttribute('height', '24') | 3190 ..setAttribute('height', '24') |
| 3188 ..children = [ | 3191 ..children = [ |
| 3189 new PathElement() | 3192 new PathElement() |
| 3190 ..setAttribute('d', 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' | 3193 ..setAttribute( |
| 3191 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' | 3194 'd', |
| 3192 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' | 3195 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 ' |
| 3193 '9h2V7h-2v2z') | 3196 '10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 ' |
| 3194 ]; | 3197 '0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 ' |
| 3198 '9h2V7h-2v2z') |
| 3199 ]; |
| OLD | NEW |