blob: b5bf69cb64f24531d2bdefbe56a6a09304e815fe [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:json_rpc_2/json_rpc_2.dart' as rpc;
import 'breakpoint.dart';
import 'class.dart';
import 'code.dart';
import 'library.dart';
import 'object.dart';
import 'scope.dart';
import 'source_location.dart';
VMFunctionRef newVMFunctionRef(Scope scope, Map json) {
if (json == null) return null;
assert(json["type"] == "@Function" || json["type"] == "Function");
return new VMFunctionRef._(scope, json);
}
/// A reference to a Dart function or method.
class VMFunctionRef implements VMObjectRef {
final Scope _scope;
/// The ID for this function, which is unique relative to its isolate.
final String _id;
/// Whether [_id] is guaranteed to be the same for different VM service
/// function objects that refer to the same function.
final bool _fixedId;
Uri get observatoryUrl => _scope.observatoryUrlFor(_id);
/// The name of this function.
final String name;
/// The owner of this function.
///
/// This is either a [VMClassRef], a [VMLibraryRef], or another
/// [VMFunctionRef].
final VMObjectRef owner;
/// Whether this is a static function.
final bool isStatic;
/// Whether this is a const function—that is, a const constructor.
final bool isConst;
VMFunctionRef._(Scope scope, Map json)
: _scope = scope,
_id = json["id"],
_fixedId = json["fixedId"] ?? false,
name = json["name"],
owner = _owner(scope, json["owner"]),
isStatic = json["static"],
isConst = json["const"];
/// Parses and returns the a library, class, or function.
static VMObjectRef _owner(Scope scope, Map json) {
if (json == null) return null;
switch (json["type"]) {
case "@Library": return newVMLibraryRef(scope, json);
case "@Class": return newVMClassRef(scope, json);
case "@Function": return newVMFunctionRef(scope, json);
default: throw new StateError('Unknown owner type "${json["type"]}".');
}
}
Future<VMFunction> load() async =>
new VMFunction._(_scope, await _scope.loadObject(_id));
/// Adds a breakpoint at the entrypoint of this function.
///
/// If no breakpoint is possible for this function, this will throw an
/// [rpc.RpcException] with code `102`.
Future<VMBreakpoint> addBreakpoint() async {
try {
var response = await _scope.sendRequest(
"addBreakpointAtEntry", {"functionId": _id});
return newVMBreakpoint(_scope, response);
} on rpc.RpcException catch (error) {
// Error 102 indicates that the breakpoint couldn't be created.
if (error.code == 102) return null;
rethrow;
}
}
bool operator ==(other) => other is VMFunctionRef &&
(_fixedId ? _id == other._id : super == other);
int get hashCode => _fixedId ? _id.hashCode : super.hashCode;
String toString() {
var buffer = new StringBuffer();
if (isStatic && owner is VMClassRef) buffer.write("static ");
if (isConst) buffer.write("const ");
buffer.write(name);
return buffer.toString();
}
}
/// A Dart function or method.
class VMFunction extends VMFunctionRef implements VMObject {
final int size;
final VMClassRef klass;
/// The location of this function in the source code.
final VMSourceLocation location;
/// The function's code.
final VMCodeRef code;
VMFunction._(Scope scope, Map json)
: size = json["size"],
klass = newVMClassRef(scope, json["class"]),
location = newVMSourceLocation(scope, json["location"]),
code = newVMCodeRef(scope, json["code"]),
super._(scope, json);
}