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 { |
| 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 |