Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: runtime/bin/vmservice/client/lib/src/service/service.dart

Issue 192443004: Complete the switch to ServiceObject (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of service;
6
7 /// A [ServiceObject] is an object known to the VM service and is tied
8 /// to an owning [Isolate].
9 abstract class ServiceObject extends Observable {
10 Isolate _isolate;
11
12 /// Owning isolate.
13 Isolate get isolate => _isolate;
14
15 /// Owning vm.
16 VM get vm => _isolate.vm;
17
18 /// The complete service url of this object.
19 String get link => isolate.relativeLink(_id);
20
21 /// The complete service url of this object with a '#/' prefix.
22 String get hashLink => isolate.relativeHashLink(_id);
23
24 String _id;
25 /// The id of this object.
26 String get id => _id;
27
28 String _serviceType;
29 /// The service type of this object.
30 String get serviceType => _serviceType;
31
32 bool _ref;
33
34 @observable String name;
35 @observable String vmName;
36
37 ServiceObject(this._isolate, this._id, this._serviceType) {
38 _ref = isRefType(_serviceType);
39 _serviceType = stripRef(_serviceType);
40 _created();
41 }
42
43 ServiceObject.fromMap(this._isolate, ObservableMap m) {
44 assert(isServiceMap(m));
45 _id = m['id'];
46 _ref = isRefType(m['type']);
47 _serviceType = stripRef(m['type']);
48 _created();
49 update(m);
50 }
51
52 /// If [this] was created from a reference, load the full object
53 /// from the service by calling [reload]. Else, return [this].
54 Future<ServiceObject> load() {
55 if (!_ref) {
56 // Not a reference.
57 return new Future.value(this);
58 }
59 // Call refresh which will fill in the entire object.
60 return reload();
61 }
62
63 /// Reload [this]. Returns a future which completes to [this] or
64 /// a [ServiceError].
65 Future<ServiceObject> reload() {
66 assert(isolate != null);
67 if (id == '') {
68 // Errors don't have ids.
69 assert(serviceType == 'Error');
70 return new Future.value(this);
71 }
72 return isolate.vm.getAsMap(link).then(update);
73 }
74
75 /// Update [this] using [m] as a source. [m] can be a reference.
76 ServiceObject update(ObservableMap m) {
77 // Assert that m is a service map.
78 assert(ServiceObject.isServiceMap(m));
79 if ((m['type'] == 'Error') && (_serviceType != 'Error')) {
80 // Got an unexpected error. Don't update the object.
81 return _upgradeToServiceObject(vm, isolate, m);
82 }
83 // TODO(johnmccutchan): Should we allow for a ServiceObject's id
84 // or type to change?
85 _id = m['id'];
86 _serviceType = stripRef(m['type']);
87 _update(m);
88 return this;
89 }
90
91 // update internal state from [map]. [map] can be a reference.
92 void _update(ObservableMap map);
93
94 /// Returns true if [this] has only been partially initialized via
95 /// a reference. See [load].
96 bool isRef() => _ref;
97
98 void _created() {
99 var refNotice = _ref ? ' Created from reference.' : '';
100 Logger.root.info('Created ServiceObject for \'${_id}\' with type '
101 '\'${_serviceType}\'.' + refNotice);
102 }
103
104 /// Returns true if [map] is a service map. i.e. it has the following keys:
105 /// 'id' and a 'type'.
106 static bool isServiceMap(ObservableMap m) {
107 return (m != null) && (m['id'] != null) && (m['type'] != null);
108 }
109
110 /// Returns true if [type] is a reference type. i.e. it begins with an
111 /// '@' character.
112 static bool isRefType(String type) {
113 return type.startsWith('@');
114 }
115
116 /// Returns the unreffed version of [type].
117 static String stripRef(String type) {
118 if (!isRefType(type)) {
119 return type;
120 }
121 // Strip off the '@' character.
122 return type.substring(1);
123 }
124 }
125
126 /// Recursively upgrades all [ServiceObject]s inside [collection] which must
127 /// be an [ObservableMap] or an [ObservableList]. Upgraded elements will be
128 /// associated with [vm] and [isolate].
129 void upgradeCollection(collection, VM vm, Isolate isolate) {
130 if (collection is ObservableMap) {
131 _upgradeObservableMap(collection, vm, isolate);
132 } else if (collection is ObservableList) {
133 _upgradeObservableList(collection, vm, isolate);
134 }
135 }
136
137 void _upgradeObservableMap(ObservableMap map, VM vm, Isolate isolate) {
138 map.forEach((k, v) {
139 if ((v is ObservableMap) && ServiceObject.isServiceMap(v)) {
140 map[k] = v = _upgradeToServiceObject(vm, isolate, v);
141 } else if (v is ObservableList) {
142 _upgradeObservableList(v, vm, isolate);
143 } else if (v is ObservableMap) {
144 _upgradeObservableMap(v, vm, isolate);
145 }
146 });
147 }
148
149 void _upgradeObservableList(ObservableList list, VM vm, Isolate isolate) {
150 for (var i = 0; i < list.length; i++) {
151 var v = list[i];
152 if ((v is ObservableMap) && ServiceObject.isServiceMap(v)) {
153 list[i] = _upgradeToServiceObject(vm, isolate, v);
154 } else if (v is ObservableList) {
155 _upgradeObservableList(v, vm, isolate);
156 } else if (v is ObservableMap) {
157 _upgradeObservableMap(v, vm, isolate);
158 }
159 }
160 }
161
162 /// Upgrades response ([m]) from [vm] and [isolate] to a [ServiceObject].
163 /// This acts like a factory which consumes an ObservableMap and returns
164 /// a fully upgraded ServiceObject.
165 ServiceObject _upgradeToServiceObject(VM vm, Isolate isolate, ObservableMap m) {
166 assert(ServiceObject.isServiceMap(m));
167 var type = ServiceObject.stripRef(m['type']);
168 switch (type) {
169 case 'Error':
170 return new ServiceError.fromMap(isolate, m);
171 case 'IsolateList':
172 vm.isolates.update(m);
173 return vm.isolates;
174 case 'Script':
175 return isolate.scripts.putIfAbsent(m);
176 case 'Code':
177 return isolate.codes.putIfAbsent(m);
178 case 'Isolate':
179 return vm.isolates.getIsolateFromMap(m);
180 case 'Class':
181 return isolate.classes.putIfAbsent(m);
182 }
183 return new ServiceMap.fromMap(isolate, m);
184 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698