| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 generator.addDeclaration(id, name, | 144 generator.addDeclaration(id, name, |
| 145 new TypeIdentifier('dart:core', 'Function'), isMethod: true, | 145 new TypeIdentifier('dart:core', 'Function'), isMethod: true, |
| 146 annotations: _copyAnnotations(m)); | 146 annotations: _copyAnnotations(m)); |
| 147 if (includeAccessors) _addAccessors(name, false); | 147 if (includeAccessors) _addAccessors(name, false); |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 /// Adds the declaration of [name] if it was found in [type]. If [recursive] | 152 /// Adds the declaration of [name] if it was found in [type]. If [recursive] |
| 153 /// is true, then we continue looking up [name] in the parent classes until we | 153 /// is true, then we continue looking up [name] in the parent classes until we |
| 154 /// find it or we reach Object. Returns whether the declaration was found. | 154 /// find it or we reach [includeUpTo] or Object. Returns whether the |
| 155 /// When a declaration is found, add also a symbol, getter, and setter if | 155 /// declaration was found. When a declaration is found, add also a symbol, |
| 156 /// [includeAccessors] is true. | 156 /// getter, and setter if [includeAccessors] is true. |
| 157 bool lookupMember(ClassElement type, String name, {bool recursive: false, | 157 bool lookupMember(ClassElement type, String name, {bool recursive: false, |
| 158 bool includeAccessors: true}) => | 158 bool includeAccessors: true, ClassElement includeUpTo}) => |
| 159 _lookupMemberInternal(type, _typeFor(type), name, recursive, | 159 _lookupMemberInternal(type, _typeFor(type), name, recursive, |
| 160 includeAccessors); | 160 includeAccessors, includeUpTo); |
| 161 | 161 |
| 162 /// Helper for [lookupMember] that walks up the type hierarchy including mixin | 162 /// Helper for [lookupMember] that walks up the type hierarchy including mixin |
| 163 /// classes. | 163 /// classes. |
| 164 bool _lookupMemberInternal(ClassElement type, TypeIdentifier id, String name, | 164 bool _lookupMemberInternal(ClassElement type, TypeIdentifier id, String name, |
| 165 bool recursive, bool includeAccessors) { | 165 bool recursive, bool includeAccessors, ClassElement includeUpTo) { |
| 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 && !f.isStatic) _addAccessors(name, !f.isFinal); | 175 if (includeAccessors && !f.isStatic) _addAccessors(name, !f.isFinal); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 203 } else { | 203 } else { |
| 204 _addAccessors(name, false); | 204 _addAccessors(name, false); |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 return true; | 207 return true; |
| 208 } | 208 } |
| 209 | 209 |
| 210 if (recursive) { | 210 if (recursive) { |
| 211 lookupParent(type); | 211 lookupParent(type); |
| 212 var parent = type.supertype != null ? type.supertype.element : null; | 212 var parent = type.supertype != null ? type.supertype.element : null; |
| 213 if (parent == null) return false; | 213 if (parent == null || parent == includeUpTo) return false; |
| 214 var parentId = _typeFor(parent); | 214 var parentId = _typeFor(parent); |
| 215 for (var m in type.mixins) { | 215 for (var m in type.mixins) { |
| 216 var mixinClass = m.element; | 216 var mixinClass = m.element; |
| 217 var mixinId = _mixins[parentId][mixinClass]; | 217 var mixinId = _mixins[parentId][mixinClass]; |
| 218 if (_lookupMemberInternal(mixinClass, mixinId, name, false, | 218 if (_lookupMemberInternal(mixinClass, mixinId, name, false, |
| 219 includeAccessors)) { | 219 includeAccessors, includeUpTo)) { |
| 220 return true; | 220 return true; |
| 221 } | 221 } |
| 222 parentId = mixinId; | 222 parentId = mixinId; |
| 223 } | 223 } |
| 224 return _lookupMemberInternal(parent, parentId, name, true, | 224 return _lookupMemberInternal(parent, parentId, name, true, |
| 225 includeAccessors); | 225 includeAccessors, includeUpTo); |
| 226 } | 226 } |
| 227 return false; | 227 return false; |
| 228 } | 228 } |
| 229 | 229 |
| 230 /// Add information so smoke can invoke the static method [type].[name]. | 230 /// Add information so smoke can invoke the static method [type].[name]. |
| 231 void addStaticMethod(ClassElement type, String name) { | 231 void addStaticMethod(ClassElement type, String name) { |
| 232 generator.addStaticMethod(_typeFor(type), name); | 232 generator.addStaticMethod(_typeFor(type), name); |
| 233 } | 233 } |
| 234 | 234 |
| 235 /// 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]. |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 this.includeInherited: true, | 387 this.includeInherited: true, |
| 388 this.includeUpTo: null, | 388 this.includeUpTo: null, |
| 389 this.excludeFinal: false, | 389 this.excludeFinal: false, |
| 390 this.includeMethods: false, | 390 this.includeMethods: false, |
| 391 this.withAnnotations: null, | 391 this.withAnnotations: null, |
| 392 this.matches: null}); | 392 this.matches: null}); |
| 393 } | 393 } |
| 394 | 394 |
| 395 /// Predicate that tells whether [name] should be included in query results. | 395 /// Predicate that tells whether [name] should be included in query results. |
| 396 typedef bool NameMatcher(String name); | 396 typedef bool NameMatcher(String name); |
| OLD | NEW |