OLD | NEW |
---|---|
(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 /// Collects services that can be used to access objects dynamically, inspect | |
6 /// type information, and convert between symbols and strings. | |
7 library smoke; | |
8 | |
9 import 'src/implementation.dart' as implementation; | |
10 | |
11 export 'src/common.dart' show minArgs, maxArgs, SUPPORTED_ARGS; | |
12 | |
13 /// Configures this library to use [objectAccessor] for all read/write/invoke | |
14 /// APIs, [typeInspector] for all type query APIs, and [symbolConverter] for all | |
15 /// symbol convertion operations. | |
16 /// | |
17 /// This function doesn't need to be called during development, but frameworks | |
18 /// should autogenerate a call to this function when running in deployment. | |
19 void configure(ObjectAccessorService objectAccessor, | |
20 TypeInspectorService typeInspector, | |
21 SymbolConverterService symbolConverter) { | |
22 implementation.objectAccessor = objectAccessor; | |
23 implementation.typeInspector = typeInspector; | |
24 implementation.symbolConverter = symbolConverter; | |
25 } | |
26 | |
27 /// Return the value of [field] in [object]. | |
28 read(Object object, Symbol field) => | |
29 implementation.objectAccessor.read(object, field); | |
30 | |
31 /// Update the [value] of [field] in [object]. | |
32 void write(Object object, Symbol field, value) => | |
33 implementation.objectAccessor.write(object, field, value); | |
34 | |
35 /// Invoke [method] in [receiver] with [args]. The [receiver] can be either an | |
36 /// object (to invoke instance methods) or a type (to invoke static methods). | |
37 /// This function optionally [adjust]s the list of arguments to match the number | |
38 /// of formal parameters by either adding nulls for missing arguments, or by | |
39 /// truncating the list. | |
40 invoke(receiver, Symbol method, List args, | |
41 {Map namedArgs, bool adjust: false}) => | |
42 implementation.objectAccessor.invoke( | |
43 receiver, method, args, namedArgs: namedArgs, adjust: adjust); | |
44 | |
45 /// Tells whether [type] has a field or getter for [field]. | |
46 bool hasGetter(Type type, Symbol field) => | |
47 implementation.typeInspector.hasGetter(type, field); | |
48 | |
49 /// Tells whether [type] has a field or setter for [field]. | |
50 bool hasSetter(Type type, Symbol field) => | |
51 implementation.typeInspector.hasSetter(type, field); | |
52 | |
53 /// Tells whether [type] or a superclass (other than [Object]) defines | |
54 /// `noSuchMethod`. | |
55 bool hasNoSuchMethod(Type type) => hasInstanceMethod(type, #noSuchMethod); | |
56 | |
57 /// Tells whether [type] has or a superclass contains a specific instance | |
58 /// [method] (excluding methods in [Object]). | |
59 bool hasInstanceMethod(Type type, Symbol method) => | |
60 implementation.typeInspector.hasInstanceMethod(type, method); | |
61 | |
62 /// Tells whether [type] has a specific static [method]. | |
63 bool hasStaticMethod(Type type, Symbol method) => | |
64 implementation.typeInspector.hasStaticMethod(type, method); | |
65 | |
66 /// Get the declaration associated with field [name] found in [type] or a | |
67 /// superclass of [type]. | |
68 Declaration getDeclaration(Type type, Symbol name) => | |
69 implementation.typeInspector.getDeclaration(type, name); | |
70 | |
71 /// Retrieve all symbols of [type] that match [options]. | |
72 List<Declaration> query(Type type, QueryOptions options) => | |
73 implementation.typeInspector.query(type, options); | |
74 | |
75 /// Returns the name associated with a [symbol]. | |
76 String symbolToName(Symbol symbol) => | |
77 implementation.symbolConverter.symbolToName(symbol); | |
78 | |
79 /// Returns the symbol associated with a [name]. | |
80 Symbol nameToSymbol(String name) => | |
81 implementation.symbolConverter.nameToSymbol(name); | |
82 | |
83 /// Establishes the parameters for [query] to search for symbols in a type | |
84 /// hierarchy. For now only public instance symbols can be queried (no private, | |
85 /// no static). | |
86 class QueryOptions { | |
87 /// Whether to include fields, getters, and setters. | |
88 final bool includeProperties; | |
89 | |
90 /// Whether to include symbols from the given type and its superclasses | |
91 /// (except [Object]). | |
92 final bool includeInherited; | |
93 | |
94 /// Whether to include final fields. | |
95 // TODO(sigmund): should this exclude getter-only properties too? | |
96 final bool excludeFinal; | |
97 | |
98 /// Whether to include methods (default is false). | |
99 final bool includeMethods; | |
100 | |
101 /// If [withAnnotation] is not null, then it should be a list of types, so | |
102 /// only symbols that are annotated with instances of those types are | |
103 /// included. | |
104 final List withAnnotations; | |
105 | |
106 const QueryOptions({this.includeProperties: true, this.includeInherited: true, | |
107 this.excludeFinal: false, this.includeMethods: false, | |
108 this.withAnnotations: null}); | |
109 } | |
110 | |
111 /// Information associated with a symbol declaration (like a property or | |
112 /// method). | |
113 class Declaration { | |
114 /// Name of the property or method | |
115 final Symbol name; | |
116 | |
117 /// Whether the symbol is a property (either this or [isMethod] is true). | |
118 bool get isProperty => !isMethod; | |
119 | |
120 /// Whether the symbol is a method (either this or [isProperty] is true) | |
121 final bool isMethod; | |
122 | |
123 /// If this is a property, whether it's read only (final fields or properties | |
124 /// with no setter). | |
125 final bool isFinal; | |
126 | |
127 /// If this is a property, it's declared type (including dynamic if it's not | |
128 /// declared). For methods, the returned type. | |
129 final Type type; | |
130 | |
131 /// Whether this symbol is static. | |
132 final bool isStatic; | |
133 | |
134 /// List of annotations in this declaration. | |
135 final List annotations; | |
136 | |
137 const Declaration(this.name, this.type, {this.isMethod:false, | |
138 this.isFinal: false, this.isStatic: false, this.annotations: const []}); | |
139 | |
140 String toString() { | |
141 return (new StringBuffer() | |
142 ..write('[declaration ') | |
143 ..write(name) | |
144 ..write(isProperty ? ' (property) ' : ' (method) ') | |
145 ..write(isFinal ? 'final ' : '') | |
146 ..write(isStatic ? 'static ' : '') | |
147 ..write(annotations) | |
148 ..write(']')).toString(); | |
149 } | |
150 } | |
151 | |
152 | |
153 /// A service that provides a way to implement simple operations on objects like | |
154 /// read, write, and invoke. | |
155 abstract class ObjectAccessorService { | |
Siggi Cherem (dart-lang)
2014/02/20 04:54:36
FYI - I am not convinced about the right design pr
Jennifer Messerly
2014/02/20 21:24:47
seems reasonable to me. I don't have a strong feel
| |
156 /// Return the value of [field] in [object]. | |
157 read(Object object, Symbol field); | |
158 | |
159 /// Update the [value] of [field] in [object]. | |
160 void write(Object object, Symbol field, value); | |
161 | |
162 /// Invoke [method] in [object] with [args]. It optionally [adjust]s the list | |
163 /// of arguments to match the number of formal parameters by either adding | |
164 /// nulls for missing arguments, or by truncating the list. | |
165 invoke(Object object, Symbol method, List args, | |
166 {Map namedArgs, bool adjust: false}); | |
167 } | |
168 | |
169 | |
170 /// A service that provides partial inspection into Dart types. | |
171 abstract class TypeInspectorService { | |
172 /// Tells whether [type] has a field or getter for [name]. | |
173 bool hasGetter(Type type, Symbol name); | |
174 | |
175 /// Tells whether [type] has a field or setter for [name]. | |
176 bool hasSetter(Type type, Symbol name); | |
177 | |
178 /// Tells whether [type] has a specific instance [method]. | |
179 bool hasInstanceMethod(Type type, Symbol method); | |
180 | |
181 /// Tells whether [type] has a specific static [method]. | |
182 bool hasStaticMethod(Type type, Symbol method); | |
183 | |
184 /// Get the declaration associated with field [name] in [type]. | |
185 Declaration getDeclaration(Type type, Symbol name); | |
186 | |
187 /// Retrieve all symbols of [type] that match [options]. | |
188 List<Declaration> query(Type type, QueryOptions options); | |
189 } | |
190 | |
191 | |
192 /// A service that converts between [Symbol]s and [String]s. | |
193 abstract class SymbolConverterService { | |
194 /// Returns the name associated with a [symbol]. | |
195 String symbolToName(Symbol symbol); | |
196 | |
197 /// Returns the symbol associated with a [name]. | |
198 Symbol nameToSymbol(String name); | |
199 } | |
OLD | NEW |