| 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 /// Records accesses to Dart program declarations and generates code that will | 5 /// Records accesses to Dart program declarations and generates code that will |
| 6 /// allow to do the same accesses at runtime using `package:smoke/static.dart`. | 6 /// allow to do the same accesses at runtime using `package:smoke/static.dart`. |
| 7 /// Internally, this library relies on the `analyzer` to extract data from the | 7 /// Internally, this library relies on the `analyzer` to extract data from the |
| 8 /// program, and then uses [SmokeCodeGenerator] to produce the code needed by | 8 /// program, and then uses [SmokeCodeGenerator] to produce the code needed by |
| 9 /// the smoke system. | 9 /// the smoke system. |
| 10 /// | 10 /// |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 bool recursive, bool includeAccessors) { | 165 bool recursive, bool includeAccessors) { |
| 166 // Exclude members from [Object]. | 166 // Exclude members from [Object]. |
| 167 if (type.type.isObject) return false; | 167 if (type.type.isObject) return false; |
| 168 generator.addEmptyDeclaration(id); | 168 generator.addEmptyDeclaration(id); |
| 169 for (var f in type.fields) { | 169 for (var f in type.fields) { |
| 170 if (f.displayName != name) continue; | 170 if (f.displayName != name) continue; |
| 171 if (f.isSynthetic) continue; // exclude getters | 171 if (f.isSynthetic) continue; // exclude getters |
| 172 generator.addDeclaration(id, name, | 172 generator.addDeclaration(id, name, |
| 173 _typeFor(f.type.element), isField: true, isFinal: f.isFinal, | 173 _typeFor(f.type.element), isField: true, isFinal: f.isFinal, |
| 174 isStatic: f.isStatic, annotations: _copyAnnotations(f)); | 174 isStatic: f.isStatic, annotations: _copyAnnotations(f)); |
| 175 if (includeAccessors) _addAccessors(name, !f.isFinal); | 175 if (includeAccessors && !f.isStatic) _addAccessors(name, !f.isFinal); |
| 176 return true; | 176 return true; |
| 177 } | 177 } |
| 178 | 178 |
| 179 for (var a in type.accessors) { | 179 for (var a in type.accessors) { |
| 180 if (a is! PropertyAccessorElement) continue; | 180 if (a is! PropertyAccessorElement) continue; |
| 181 // TODO(sigmund): support setters without getters. | 181 // TODO(sigmund): support setters without getters. |
| 182 if (!a.isGetter) continue; | 182 if (!a.isGetter) continue; |
| 183 if (a.displayName != name) continue; | 183 if (a.displayName != name) continue; |
| 184 var v = a.variable; | 184 var v = a.variable; |
| 185 if (v is FieldElement && !v.isSynthetic) continue; // exclude fields | 185 if (v is FieldElement && !v.isSynthetic) continue; // exclude fields |
| 186 generator.addDeclaration(id, name, | 186 generator.addDeclaration(id, name, |
| 187 _typeFor(a.type.returnType.element), isProperty: true, | 187 _typeFor(a.type.returnType.element), isProperty: true, |
| 188 isFinal: v.isFinal, isStatic: a.isStatic, | 188 isFinal: v.isFinal, isStatic: a.isStatic, |
| 189 annotations: _copyAnnotations(a)); | 189 annotations: _copyAnnotations(a)); |
| 190 if (includeAccessors) _addAccessors(name, !v.isFinal); | 190 if (includeAccessors && !v.isStatic) _addAccessors(name, !v.isFinal); |
| 191 return true; | 191 return true; |
| 192 } | 192 } |
| 193 | 193 |
| 194 for (var m in type.methods) { | 194 for (var m in type.methods) { |
| 195 if (m.displayName != name) continue; | 195 if (m.displayName != name) continue; |
| 196 generator.addDeclaration(id, name, | 196 generator.addDeclaration(id, name, |
| 197 new TypeIdentifier('dart:core', 'Function'), isMethod: true, | 197 new TypeIdentifier('dart:core', 'Function'), isMethod: true, |
| 198 isStatic: m.isStatic, annotations: _copyAnnotations(m)); | 198 isStatic: m.isStatic, annotations: _copyAnnotations(m)); |
| 199 if (includeAccessors) _addAccessors(name, false); | 199 if (includeAccessors) { |
| 200 if (m.isStatic) { |
| 201 generator.addStaticMethod(id, name); |
| 202 generator.addSymbol(name); |
| 203 } else { |
| 204 _addAccessors(name, false); |
| 205 } |
| 206 } |
| 200 return true; | 207 return true; |
| 201 } | 208 } |
| 202 | 209 |
| 203 if (recursive) { | 210 if (recursive) { |
| 204 lookupParent(type); | 211 lookupParent(type); |
| 205 var parent = type.supertype != null ? type.supertype.element : null; | 212 var parent = type.supertype != null ? type.supertype.element : null; |
| 206 if (parent == null) return false; | 213 if (parent == null) return false; |
| 207 var parentId = _typeFor(parent); | 214 var parentId = _typeFor(parent); |
| 208 for (var m in type.mixins) { | 215 for (var m in type.mixins) { |
| 209 var mixinClass = m.element; | 216 var mixinClass = m.element; |
| 210 var mixinId = _mixins[parentId][mixinClass]; | 217 var mixinId = _mixins[parentId][mixinClass]; |
| 211 if (_lookupMemberInternal(mixinClass, mixinId, name, false, | 218 if (_lookupMemberInternal(mixinClass, mixinId, name, false, |
| 212 includeAccessors)) { | 219 includeAccessors)) { |
| 213 return true; | 220 return true; |
| 214 } | 221 } |
| 215 parentId = mixinId; | 222 parentId = mixinId; |
| 216 } | 223 } |
| 217 return _lookupMemberInternal(parent, parentId, name, true, | 224 return _lookupMemberInternal(parent, parentId, name, true, |
| 218 includeAccessors); | 225 includeAccessors); |
| 219 } | 226 } |
| 220 return false; | 227 return false; |
| 221 } | 228 } |
| 222 | 229 |
| 230 /// Add information so smoke can invoke the static method [type].[name]. |
| 231 void addStaticMethod(ClassElement type, String name) { |
| 232 generator.addStaticMethod(_typeFor(type), name); |
| 233 } |
| 223 | 234 |
| 224 /// Adds [name] as a symbol, a getter, and optionally a setter in [generator]. | 235 /// Adds [name] as a symbol, a getter, and optionally a setter in [generator]. |
| 225 _addAccessors(String name, bool includeSetter) { | 236 _addAccessors(String name, bool includeSetter) { |
| 226 generator.addSymbol(name); | 237 generator.addSymbol(name); |
| 227 generator.addGetter(name); | 238 generator.addGetter(name); |
| 228 if (includeSetter) generator.addSetter(name); | 239 if (includeSetter) generator.addSetter(name); |
| 229 } | 240 } |
| 230 | 241 |
| 231 /// Copy metadata associated with the declaration of [target]. | 242 /// Copy metadata associated with the declaration of [target]. |
| 232 List<ConstExpression> _copyAnnotations(Element target) { | 243 List<ConstExpression> _copyAnnotations(Element target) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 this.includeInherited: true, | 387 this.includeInherited: true, |
| 377 this.includeUpTo: null, | 388 this.includeUpTo: null, |
| 378 this.excludeFinal: false, | 389 this.excludeFinal: false, |
| 379 this.includeMethods: false, | 390 this.includeMethods: false, |
| 380 this.withAnnotations: null, | 391 this.withAnnotations: null, |
| 381 this.matches: null}); | 392 this.matches: null}); |
| 382 } | 393 } |
| 383 | 394 |
| 384 /// Predicate that tells whether [name] should be included in query results. | 395 /// Predicate that tells whether [name] should be included in query results. |
| 385 typedef bool NameMatcher(String name); | 396 typedef bool NameMatcher(String name); |
| OLD | NEW |