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 /// Collects services that can be used to access objects dynamically, inspect | 5 /// Collects services that can be used to access objects dynamically, inspect |
6 /// type information, and convert between symbols and strings. | 6 /// type information, and convert between symbols and strings. |
7 library smoke; | 7 library smoke; |
8 | 8 |
9 import 'src/implementation.dart' as implementation; | 9 import 'src/implementation.dart' as implementation; |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 /// Update the [value] of [field] in [object]. | 32 /// Update the [value] of [field] in [object]. |
33 void write(Object object, Symbol field, value) => | 33 void write(Object object, Symbol field, value) => |
34 implementation.objectAccessor.write(object, field, value); | 34 implementation.objectAccessor.write(object, field, value); |
35 | 35 |
36 /// Invoke [method] in [receiver] with [args]. The [receiver] can be either an | 36 /// Invoke [method] in [receiver] with [args]. The [receiver] can be either an |
37 /// object (to invoke instance methods) or a type (to invoke static methods). | 37 /// object (to invoke instance methods) or a type (to invoke static methods). |
38 /// This function optionally [adjust]s the list of arguments to match the number | 38 /// This function optionally [adjust]s the list of arguments to match the number |
39 /// of formal parameters by either adding nulls for missing arguments, or by | 39 /// of formal parameters by either adding nulls for missing arguments, or by |
40 /// truncating the list. | 40 /// truncating the list. |
41 invoke(receiver, Symbol method, List args, | 41 invoke(receiver, Symbol method, List args, |
42 {Map namedArgs, bool adjust: false}) => | 42 {Map namedArgs, bool adjust: false}) => implementation.objectAccessor |
43 implementation.objectAccessor.invoke( | 43 .invoke(receiver, method, args, namedArgs: namedArgs, adjust: adjust); |
44 receiver, method, args, namedArgs: namedArgs, adjust: adjust); | |
45 | 44 |
46 /// Tells whether [type] is transitively a subclass of [supertype]. | 45 /// Tells whether [type] is transitively a subclass of [supertype]. |
47 bool isSubclassOf(Type type, Type supertype) => | 46 bool isSubclassOf(Type type, Type supertype) => |
48 implementation.typeInspector.isSubclassOf(type, supertype); | 47 implementation.typeInspector.isSubclassOf(type, supertype); |
49 | 48 |
50 // TODO(sigmund): consider adding also: | 49 // TODO(sigmund): consider adding also: |
51 // * isImplementationOf(type, subtype) to tells whether [type] declares that it | 50 // * isImplementationOf(type, subtype) to tells whether [type] declares that it |
52 // implements the [supertype] interface. | 51 // implements the [supertype] interface. |
53 // * isSubtypeOf(type, subtype): Tells whether [type]'s interface is a sybtype | 52 // * isSubtypeOf(type, subtype): Tells whether [type]'s interface is a sybtype |
54 // of [supertype]. That is, whether it is a subclass or if [type] implements | 53 // of [supertype]. That is, whether it is a subclass or if [type] implements |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 118 |
120 /// If [withAnnotation] is not null, then it should be a list of types, so | 119 /// If [withAnnotation] is not null, then it should be a list of types, so |
121 /// only symbols that are annotated with instances of those types are | 120 /// only symbols that are annotated with instances of those types are |
122 /// included. | 121 /// included. |
123 final List withAnnotations; | 122 final List withAnnotations; |
124 | 123 |
125 /// If [matches] is not null, then include only those fields, properties, or | 124 /// If [matches] is not null, then include only those fields, properties, or |
126 /// methods that match the predicate. | 125 /// methods that match the predicate. |
127 final NameMatcher matches; | 126 final NameMatcher matches; |
128 | 127 |
129 const QueryOptions({ | 128 const QueryOptions({this.includeFields: true, this.includeProperties: true, |
130 this.includeFields: true, | 129 this.includeInherited: true, this.includeUpTo: Object, |
131 this.includeProperties: true, | 130 this.excludeFinal: false, this.includeMethods: false, |
132 this.includeInherited: true, | 131 this.withAnnotations: null, this.matches: null}); |
133 this.includeUpTo: Object, | |
134 this.excludeFinal: false, | |
135 this.includeMethods: false, | |
136 this.withAnnotations: null, | |
137 this.matches: null}); | |
138 | 132 |
139 String toString() => (new StringBuffer() | 133 String toString() => (new StringBuffer() |
140 ..write('(options:') | 134 ..write('(options:') |
141 ..write(includeFields ? 'fields ' : '') | 135 ..write(includeFields ? 'fields ' : '') |
142 ..write(includeProperties ? 'properties ' : '') | 136 ..write(includeProperties ? 'properties ' : '') |
143 ..write(includeMethods ? 'methods ' : '') | 137 ..write(includeMethods ? 'methods ' : '') |
144 ..write(includeInherited ? 'inherited ' : '_') | 138 ..write(includeInherited ? 'inherited ' : '_') |
145 ..write(excludeFinal ? 'no finals ' : '') | 139 ..write(excludeFinal ? 'no finals ' : '') |
146 ..write('annotations: $withAnnotations') | 140 ..write('annotations: $withAnnotations') |
147 ..write(matches != null ? 'with matcher' : '') | 141 ..write(matches != null ? 'with matcher' : '') |
148 ..write(')')).toString(); | 142 ..write(')')).toString(); |
149 } | 143 } |
150 | 144 |
151 /// Used to filter query results based on a predicate on [name]. Returns true if | 145 /// Used to filter query results based on a predicate on [name]. Returns true if |
152 /// [name] should be included in the query results. | 146 /// [name] should be included in the query results. |
153 typedef bool NameMatcher(Symbol name); | 147 typedef bool NameMatcher(Symbol name); |
154 | 148 |
155 /// Information associated with a symbol declaration (like a property or | 149 /// Information associated with a symbol declaration (like a property or |
156 /// method). | 150 /// method). |
157 class Declaration { | 151 class Declaration { |
158 /// Name of the property or method | 152 /// Name of the property or method |
(...skipping 22 matching lines...) Expand all Loading... |
181 /// Whether this symbol is static. | 175 /// Whether this symbol is static. |
182 final bool isStatic; | 176 final bool isStatic; |
183 | 177 |
184 /// List of annotations in this declaration. | 178 /// List of annotations in this declaration. |
185 final List annotations; | 179 final List annotations; |
186 | 180 |
187 const Declaration(this.name, this.type, {this.kind: FIELD, | 181 const Declaration(this.name, this.type, {this.kind: FIELD, |
188 this.isFinal: false, this.isStatic: false, this.annotations: const []}); | 182 this.isFinal: false, this.isStatic: false, this.annotations: const []}); |
189 | 183 |
190 int get hashCode => name.hashCode; | 184 int get hashCode => name.hashCode; |
191 operator ==(other) => other is Declaration && name == other.name && | 185 operator ==(other) => other is Declaration && |
192 kind == other.kind && isFinal == other.isFinal && | 186 name == other.name && |
193 type == other.type && isStatic == other.isStatic && | 187 kind == other.kind && |
| 188 isFinal == other.isFinal && |
| 189 type == other.type && |
| 190 isStatic == other.isStatic && |
194 compareLists(annotations, other.annotations); | 191 compareLists(annotations, other.annotations); |
195 | 192 |
196 String toString() { | 193 String toString() { |
197 return (new StringBuffer() | 194 return (new StringBuffer() |
198 ..write('(declaration ') | 195 ..write('(declaration ') |
199 ..write(name) | 196 ..write(name) |
200 ..write(isProperty ? ' (property) ' : ' (method) ') | 197 ..write(isProperty ? ' (property) ' : ' (method) ') |
201 ..write(isFinal ? 'final ' : '') | 198 ..write(isFinal ? 'final ' : '') |
202 ..write(isStatic ? 'static ' : '') | 199 ..write(isStatic ? 'static ' : '') |
203 ..write(annotations) | 200 ..write(annotations) |
204 ..write(')')).toString(); | 201 ..write(')')).toString(); |
205 } | 202 } |
206 } | 203 } |
207 | 204 |
208 /// Enumeration for declaration kinds (field, property, or method) | 205 /// Enumeration for declaration kinds (field, property, or method) |
209 class DeclarationKind { | 206 class DeclarationKind { |
210 final int kind; | 207 final int kind; |
211 const DeclarationKind(this.kind); | 208 const DeclarationKind(this.kind); |
212 } | 209 } |
213 | 210 |
214 /// Declaration kind used to denote a raw field. | 211 /// Declaration kind used to denote a raw field. |
215 const FIELD = const DeclarationKind(0); | 212 const FIELD = const DeclarationKind(0); |
216 | 213 |
217 /// Declaration kind used to denote a getter/setter. | 214 /// Declaration kind used to denote a getter/setter. |
218 const PROPERTY = const DeclarationKind(1); | 215 const PROPERTY = const DeclarationKind(1); |
219 | 216 |
220 /// Declaration kind used to denote a method. | 217 /// Declaration kind used to denote a method. |
221 const METHOD = const DeclarationKind(2); | 218 const METHOD = const DeclarationKind(2); |
222 | 219 |
223 | |
224 /// A service that provides a way to implement simple operations on objects like | 220 /// A service that provides a way to implement simple operations on objects like |
225 /// read, write, and invoke. | 221 /// read, write, and invoke. |
226 abstract class ObjectAccessorService { | 222 abstract class ObjectAccessorService { |
227 /// Return the value of [field] in [object]. | 223 /// Return the value of [field] in [object]. |
228 read(Object object, Symbol field); | 224 read(Object object, Symbol field); |
229 | 225 |
230 /// Update the [value] of [field] in [object]. | 226 /// Update the [value] of [field] in [object]. |
231 void write(Object object, Symbol field, value); | 227 void write(Object object, Symbol field, value); |
232 | 228 |
233 /// Invoke [method] in [object] with [args]. It optionally [adjust]s the list | 229 /// Invoke [method] in [object] with [args]. It optionally [adjust]s the list |
234 /// of arguments to match the number of formal parameters by either adding | 230 /// of arguments to match the number of formal parameters by either adding |
235 /// nulls for missing arguments, or by truncating the list. | 231 /// nulls for missing arguments, or by truncating the list. |
236 invoke(Object object, Symbol method, List args, | 232 invoke(Object object, Symbol method, List args, |
237 {Map namedArgs, bool adjust: false}); | 233 {Map namedArgs, bool adjust: false}); |
238 } | 234 } |
239 | 235 |
240 | |
241 /// A service that provides partial inspection into Dart types. | 236 /// A service that provides partial inspection into Dart types. |
242 abstract class TypeInspectorService { | 237 abstract class TypeInspectorService { |
243 /// Tells whether [type] is transitively a subclass of [supertype]. | 238 /// Tells whether [type] is transitively a subclass of [supertype]. |
244 bool isSubclassOf(Type type, Type supertype); | 239 bool isSubclassOf(Type type, Type supertype); |
245 | 240 |
246 /// Tells whether [type] has a field or getter for [name]. | 241 /// Tells whether [type] has a field or getter for [name]. |
247 bool hasGetter(Type type, Symbol name); | 242 bool hasGetter(Type type, Symbol name); |
248 | 243 |
249 /// Tells whether [type] has a field or setter for [name]. | 244 /// Tells whether [type] has a field or setter for [name]. |
250 bool hasSetter(Type type, Symbol name); | 245 bool hasSetter(Type type, Symbol name); |
251 | 246 |
252 /// Tells whether [type] has a specific instance [method]. | 247 /// Tells whether [type] has a specific instance [method]. |
253 bool hasInstanceMethod(Type type, Symbol method); | 248 bool hasInstanceMethod(Type type, Symbol method); |
254 | 249 |
255 /// Tells whether [type] has a specific static [method]. | 250 /// Tells whether [type] has a specific static [method]. |
256 bool hasStaticMethod(Type type, Symbol method); | 251 bool hasStaticMethod(Type type, Symbol method); |
257 | 252 |
258 /// Get the declaration associated with field [name] in [type]. | 253 /// Get the declaration associated with field [name] in [type]. |
259 Declaration getDeclaration(Type type, Symbol name); | 254 Declaration getDeclaration(Type type, Symbol name); |
260 | 255 |
261 /// Retrieve all symbols of [type] that match [options]. | 256 /// Retrieve all symbols of [type] that match [options]. |
262 List<Declaration> query(Type type, QueryOptions options); | 257 List<Declaration> query(Type type, QueryOptions options); |
263 } | 258 } |
264 | 259 |
265 | 260 /// A service that converts between [Symbol]s and [String]s. |
266 /// A service that converts between [Symbol]s and [String]s. | |
267 abstract class SymbolConverterService { | 261 abstract class SymbolConverterService { |
268 /// Returns the name associated with a [symbol]. | 262 /// Returns the name associated with a [symbol]. |
269 String symbolToName(Symbol symbol); | 263 String symbolToName(Symbol symbol); |
270 | 264 |
271 /// Returns the symbol associated with a [name]. | 265 /// Returns the symbol associated with a [name]. |
272 Symbol nameToSymbol(String name); | 266 Symbol nameToSymbol(String name); |
273 } | 267 } |
OLD | NEW |