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

Side by Side Diff: pkg/smoke/lib/static.dart

Issue 169913004: Adding package:smoke. This CL includes the intial APIs, a mirror-based (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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 /// Static implementation of smoke services using code-generated data.
6 library smoke.static;
7
8 import 'package:smoke/smoke.dart';
9 import 'package:logging/logging.dart';
10 import 'src/common.dart';
11
12 import 'dart:math' as math;
Jennifer Messerly 2014/02/20 21:24:47 super duper trivial nit, feel free to ignore: I us
Siggi Cherem (dart-lang) 2014/02/20 22:19:48 oops, me too, thanks!
13
14 typedef T Getter<T>(object);
15 typedef void Setter<T>(object, value);
16
17 StaticConfiguration _configuration;
18 var _logger = new Logger('smoke.static');
19
20 class StaticConfiguration {
21 /// Maps symbol to a function that reads that symbol of an object. For
22 /// instance, `#i: (o) => o.i`.
23 final Map<Symbol, Getter> getters;
24
25 /// Maps symbol to a function that updates that symbol of an object. For
26 /// instance, `#i: (o, v) { o.i = v; }`.
27 final Map<Symbol, Setter> setters;
28
29 /// Maps a type to it's super class. For example, String: Object.
30 final Map<Type, Type> parents;
31
32 /// For each type, a map of declarations per symbol (property or method).
33 final Map<Type, Map<Symbol, Declaration>> declarations;
34
35 /// A map from symbol to strings.
36 final Map<Symbol, String> names;
37
38 /// A map from strings to symbols (the reverse of [names]).
39 final Map<String, Symbol> symbols;
40 StaticConfiguration({
41 this.getters: const {}, this.setters: const {}, this.parents: const {},
42 this.declarations: const {}, this.names: const {}})
43 : this.symbols = {} {
44 names.forEach((k, v) { symbols[v] = k; });
45 }
46 }
47
48 /// Set up the smoke package to use a static implementation based on the given
49 /// [configuration].
50 useGeneratedCode(StaticConfiguration configuration) {
51 _configuration = configuration;
52 configure(new _GeneratedObjectAccessorService(),
53 new _GeneratedTypeInspectorService(),
54 new _GeneratedSymbolConverterService());
55 }
56
57 /// Implements [ObjectAccessorService] using a static configuration.
58 class _GeneratedObjectAccessorService implements ObjectAccessorService {
59 read(Object object, Symbol name) {
60 var getter = _configuration.getters[name];
61 if (getter == null) {
62 throw new MissingCodeException('getter "$name" in $object');
63 }
64 return getter(object);
65 }
66 void write(Object object, Symbol name, value) {
67 var setter = _configuration.setters[name];
68 if (setter == null) {
69 throw new MissingCodeException('setter "$name" in $object');
70 }
71 setter(object, value);
72 }
73
74 invoke(object, Symbol name, List args, {Map namedArgs, bool adjust: false}) {
75 var method;
76 if (object is Type) {
77 } else {
78 var getter = _configuration.getters[name];
79 method = getter == null ? null : getter(object);
80 }
81 if (method == null) {
82 throw new MissingCodeException('method "$name" in $object');
83 }
84 if (adjust) {
85 var min = minArgs(method);
86 if (min > SUPPORTED_ARGS) {
87 _logger.warning('we tried to adjust the arguments for calling "$name"'
Jennifer Messerly 2014/02/20 21:24:47 hmm, this might be a case where try+catch+rethrow
Siggi Cherem (dart-lang) 2014/02/20 22:19:48 good call. Done. Now we only show the warning/erro
88 ', but we couldn\'t determine the exact number of arguments it '
89 'expects (it is more than $SUPPORTED_ARGS).');
90 // The argument list might be correct, so we still invoke the function,
91 // but and let the user see the error.
92 args = adjustList(args, min, math.max(min, args.length));
93 } else {
94 var max = maxArgs(method);
95 args = adjustList(args, min, max >= 0 ? max : args.length);
96 }
97 }
98 if (namedArgs != null) {
99 throw new UnsupportedError(
100 'smoke.static doesn\'t support namedArguments in invoke');
101 }
102 return Function.apply(method, args);
103 }
104 }
105
106 /// Implements [TypeInspectorService] using a static configuration.
107 class _GeneratedTypeInspectorService implements TypeInspectorService {
108 bool hasGetter(Type type, Symbol name) {
109 var decl = _findDeclaration(type, name);
110 // No need to check decl.isProperty because methods are also automatically
111 // considered getters (auto-closures).
112 return (decl != null && !decl.isStatic);
Jennifer Messerly 2014/02/20 21:24:47 fyi ... parens are not needed here or in other met
Siggi Cherem (dart-lang) 2014/02/20 22:19:48 Done.
113 }
114
115 bool hasSetter(Type type, Symbol name) {
116 var decl = _findDeclaration(type, name);
117 return (decl != null && !decl.isMethod && !decl.isFinal && !decl.isStatic);
118 }
119
120 bool hasInstanceMethod(Type type, Symbol name) {
121 var decl = _findDeclaration(type, name);
122 return (decl != null && decl.isMethod && !decl.isStatic);
123 }
124
125 bool hasStaticMethod(Type type, Symbol name) {
126 final map = _configuration.declarations[type];
127 if (map == null) {
128 throw new MissingCodeException('declarations for $type');
129 }
130 final decl = map[name];
131 return decl != null && decl.isMethod && decl.isStatic;
132 }
133
134 Declaration getDeclaration(Type type, Symbol name) {
135 var decl = _findDeclaration(type, name);
136 if (decl == null) {
137 throw new MissingCodeException('declaration for $type.$name');
138 }
139 return decl;
140 }
141
142 List<Declaration> query(Type type, QueryOptions options) {
143 var result;
144 if (options.includeInherited) {
145 var superclass = _configuration.parents[type];
146 if (superclass == null) {
147 throw new MissingCodeException('superclass of "$type"');
148 }
149 result = (superclass == Object) ? [] : query(superclass, options);
150 } else {
151 result = [];
152 }
153 var map = _configuration.declarations[type];
154 if (map == null) {
155 throw new MissingCodeException('declarations for $type');
156 }
157 for (var decl in map.values) {
158 if (!options.includeProperties && decl.isProperty) continue;
159 if (options.excludeFinal && decl.isFinal) continue;
160 if (!options.includeMethods && decl.isMethod) continue;
161 if (options.withAnnotations != null &&
162 !matchesAnnotation(decl.annotations, options.withAnnotations)) {
163 continue;
164 }
165 result.add(decl);
166 }
167 return result;
168 }
169 }
170
171 /// Implements [SymbolConverterService] using a static configuration.
172 class _GeneratedSymbolConverterService implements SymbolConverterService {
173 String symbolToName(Symbol symbol) => _configuration.names[symbol];
174 Symbol nameToSymbol(String name) => _configuration.symbols[name];
175 }
176
177
178 /// Exception thrown when trynig to access something that should be there, but
179 /// the code generator didn't include it.
180 class MissingCodeException implements Exception {
181 final String description;
182 MissingCodeException(this.description);
183
184 String toString() => 'Missing $description. '
185 'Code generation for the smoke package seems incomplete.';
186 }
187
188 Declaration _findDeclaration(Type type, Symbol name) {
189 while (type != Object) {
190 final declarations = _configuration.declarations[type];
191 if (declarations != null) {
192 final declaration = declarations[name];
193 if (declaration != null) return declaration;
194 }
195 var parentType = _configuration.parents[type];
196 if (parentType == null) {
197 throw new MissingCodeException('superclass of "$type"');
198 }
199 type = parentType;
200 }
201 return null;
202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698