@@ -246,51 +246,80 @@ require("dart_sdk").developer.invokeExtension(
246246 @override
247247 Future evaluate (String isolateId, String targetId, String expression,
248248 {Map <String , String > scope, bool disableBreakpoints}) async {
249+ scope ?? = {};
250+ disableBreakpoints ?? = false ;
249251 var library = await _getLibrary (isolateId, targetId);
250252 if (library == null ) {
251253 throw UnsupportedError (
252254 'Evaluate is only supported when `targetId` is a library.' );
253255 }
254- var evalExpression = '''
256+ WipResponse result;
257+
258+ // If there is scope, we use `callFunctionOn` because that accepts the
259+ // `arguments` option.
260+ //
261+ // If there is no scope we run a normal evaluate call.
262+ if (scope.isEmpty) {
263+ var evalExpression = '''
255264(function() {
256265 ${_getLibrarySnippet (library .uri )};
257266 return library.$expression ;
258267})();
259268 ''' ;
260- var result = await tabConnection.runtime.sendCommand ('Runtime.evaluate' ,
261- params: {'expression' : evalExpression, 'returnByValue' : true });
262- _handleErrorIfPresent (result,
263- evalContents: evalExpression,
264- additionalDetails: {
265- 'Dart expression' : expression,
266- 'scope' : scope,
267- });
269+ result = await tabConnection.runtime.sendCommand ('Runtime.evaluate' ,
270+ params: {'expression' : evalExpression});
271+ _handleErrorIfPresent (result,
272+ evalContents: evalExpression,
273+ additionalDetails: {
274+ 'Dart expression' : expression,
275+ });
276+ } else {
277+ var argsString = scope.keys.join (', ' );
278+ var arguments = scope.values.map ((id) => {'objectId' : id}).toList ();
279+ var evalExpression = '''
280+ function($argsString ) {
281+ ${_getLibrarySnippet (library .uri )};
282+ return library.$expression ;
283+ }
284+ ''' ;
285+ result = await tabConnection.runtime
286+ .sendCommand ('Runtime.callFunctionOn' , params: {
287+ 'functionDeclaration' : evalExpression,
288+ 'arguments' : arguments,
289+ // TODO(jakemac): Use the executionContext instead, or possibly the
290+ // library object. This will get weird if people try to use `this` in
291+ // their expression.
292+ 'objectId' : scope.values.first,
293+ });
294+ _handleErrorIfPresent (result,
295+ evalContents: evalExpression,
296+ additionalDetails: {
297+ 'Dart expression' : expression,
298+ 'scope' : scope,
299+ });
300+ }
268301 var remoteObject =
269302 RemoteObject (result.result['result' ] as Map <String , dynamic >);
270303
271- String kind;
272- var classRef = ClassRef ()
273- ..id = 'dart:core:${remoteObject .type }'
274- ..name = remoteObject.type;
275304 switch (remoteObject.type) {
276305 case 'string' :
277- kind = InstanceKind .kString;
278- break ;
306+ return _primitiveInstance (InstanceKind .kString, remoteObject);
279307 case 'number' :
280- kind = InstanceKind .kDouble;
281- break ;
308+ return _primitiveInstance (InstanceKind .kDouble, remoteObject);
282309 case 'boolean' :
283- kind = InstanceKind .kBool;
284- break ;
310+ return _primitiveInstance (InstanceKind .kBool, remoteObject);
311+ case 'object' :
312+ return InstanceRef ()
313+ ..kind = InstanceKind .kPlainInstance
314+ ..id = remoteObject.objectId
315+ // TODO(jakemac): Create a real ClassRef, we need a way of looking
316+ // up the library for a given instance to create it though.
317+ // https://github.com/dart-lang/sdk/issues/36771.
318+ ..classRef = ClassRef ();
285319 default :
286320 throw UnsupportedError (
287321 'Unsupported response type ${remoteObject .type }' );
288322 }
289-
290- return InstanceRef ()
291- ..valueAsString = '${remoteObject .value }'
292- ..classRef = classRef
293- ..kind = kind;
294323 }
295324
296325 @override
@@ -765,8 +794,9 @@ require("dart_sdk").developer.invokeExtension(
765794 var inspectee = InstanceRef ()
766795 ..kind = InstanceKind .kPlainInstance
767796 ..id = event.args[1 ].objectId
768- // TODO: A real classref? we need something here so it can properly
769- // serialize, but it isn't used by the widget inspector.
797+ // TODO(jakemac): Create a real ClassRef, we need a way of looking
798+ // up the library for a given instance to create it though.
799+ // https://github.com/dart-lang/sdk/issues/36771.
770800 ..classRef = ClassRef ();
771801 _streamNotify (
772802 'Debug' ,
@@ -870,3 +900,14 @@ const _pauseModePauseStates = {
870900 'all' : PauseState .all,
871901 'unhandled' : PauseState .uncaught,
872902};
903+
904+ /// Creates an [InstanceRef] for a primitive [RemoteObject] .
905+ InstanceRef _primitiveInstance (String kind, RemoteObject remoteObject) {
906+ var classRef = ClassRef ()
907+ ..id = 'dart:core:${remoteObject .type }'
908+ ..name = kind;
909+ return InstanceRef ()
910+ ..valueAsString = '${remoteObject .value }'
911+ ..classRef = classRef
912+ ..kind = kind;
913+ }
0 commit comments