Chromium Code Reviews| 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 |