Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // (c) 2015, the Dart Team. All rights reserved. Use of this | 1 // (c) 2015, the Dart Team. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in | 2 // source code is governed by a BSD-style license that can be found in |
| 3 // the LICENSE file. | 3 // the LICENSE file. |
| 4 | 4 |
| 5 library reflectable.src.transformer_implementation; | 5 library reflectable.src.transformer_implementation; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| 11 import 'package:analyzer/src/generated/constant.dart'; | 11 import 'package:analyzer/src/generated/constant.dart'; |
| 12 import 'package:analyzer/src/generated/element.dart'; | 12 import 'package:analyzer/src/generated/element.dart'; |
| 13 import 'package:analyzer/src/generated/utilities_dart.dart'; | |
| 13 import 'package:barback/barback.dart'; | 14 import 'package:barback/barback.dart'; |
| 14 import 'package:code_transformers/resolver.dart'; | 15 import 'package:code_transformers/resolver.dart'; |
| 15 import 'element_capability.dart' as ec; | 16 import 'element_capability.dart' as ec; |
| 16 import 'encoding_constants.dart' as constants; | 17 import 'encoding_constants.dart' as constants; |
| 17 import "reflectable_class_constants.dart" as reflectable_class_constants; | 18 import "reflectable_class_constants.dart" as reflectable_class_constants; |
| 18 import 'source_manager.dart'; | 19 import 'source_manager.dart'; |
| 19 import 'transformer_errors.dart' as errors; | 20 import 'transformer_errors.dart' as errors; |
| 20 | 21 |
| 21 class ReflectionWorld { | 22 class ReflectionWorld { |
| 22 final List<_ReflectorDomain> reflectors = new List<_ReflectorDomain>(); | 23 final List<_ReflectorDomain> reflectors = new List<_ReflectorDomain>(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 47 })); | 48 })); |
| 48 } | 49 } |
| 49 } | 50 } |
| 50 | 51 |
| 51 /// Similar to a `Set<T>` but also keeps track of the index of the first | 52 /// Similar to a `Set<T>` but also keeps track of the index of the first |
| 52 /// insertion of each item. | 53 /// insertion of each item. |
| 53 class Enumerator<T> { | 54 class Enumerator<T> { |
| 54 final Map<T, int> _map = new Map<T, int>(); | 55 final Map<T, int> _map = new Map<T, int>(); |
| 55 int _count = 0; | 56 int _count = 0; |
| 56 | 57 |
| 58 bool _contains(T t) => _map.containsKey(t); | |
|
floitsch
2015/08/13 17:33:36
I don't think it's worth having this redirection j
eernst
2015/08/14 12:05:34
The reason why I created the abstraction is that i
| |
| 59 | |
| 57 get length => _count; | 60 get length => _count; |
| 58 | 61 |
| 59 /// Tries to insert [t]. If it was already there return false, else insert it | 62 /// Tries to insert [t]. If it was already there return false, else insert it |
| 60 /// and return true. | 63 /// and return true. |
| 61 bool add(T t) { | 64 bool add(T t) { |
| 62 if (_map.containsKey(t)) return false; | 65 if (_contains(t)) return false; |
| 63 _map[t] = _count; | 66 _map[t] = _count; |
| 64 ++_count; | 67 ++_count; |
| 65 return true; | 68 return true; |
| 66 } | 69 } |
| 67 | 70 |
| 68 /// Returns the index of a given item. | 71 /// Returns the index of a given item. |
| 69 int indexOf(T t) { | 72 int indexOf(T t) { |
| 70 return _map[t]; | 73 return _map[t]; |
| 71 } | 74 } |
| 72 | 75 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 | 119 |
| 117 List<String> parameterNames = type.parameters | 120 List<String> parameterNames = type.parameters |
| 118 .map((ParameterElement parameter) => parameter.name) | 121 .map((ParameterElement parameter) => parameter.name) |
| 119 .toList(); | 122 .toList(); |
| 120 | 123 |
| 121 List<String> NamedParameterNames = type.namedParameterTypes.keys.toList(); | 124 List<String> NamedParameterNames = type.namedParameterTypes.keys.toList(); |
| 122 | 125 |
| 123 String positionals = new Iterable.generate( | 126 String positionals = new Iterable.generate( |
| 124 requiredPositionalCount, (int i) => parameterNames[i]).join(", "); | 127 requiredPositionalCount, (int i) => parameterNames[i]).join(", "); |
| 125 | 128 |
| 126 String optionalsWithDefaults = new Iterable.generate( | 129 String optionalsWithDefaults = |
| 127 optionalPositionalCount, (int i) { | 130 new Iterable.generate(optionalPositionalCount, (int i) { |
| 128 String defaultValueCode = | 131 String defaultValueCode = |
| 129 constructor.parameters[requiredPositionalCount + i].defaultValueCode; | 132 constructor.parameters[requiredPositionalCount + i].defaultValueCode; |
| 130 String defaultValueString = | 133 String defaultValueString = |
| 131 defaultValueCode == null ? "" : " = $defaultValueCode"; | 134 defaultValueCode == null ? "" : " = $defaultValueCode"; |
| 132 return "${parameterNames[i + requiredPositionalCount]}" | 135 return "${parameterNames[i + requiredPositionalCount]}" |
| 133 "$defaultValueString"; | 136 "$defaultValueString"; |
| 134 }).join(", "); | 137 }).join(", "); |
| 135 | 138 |
| 136 String namedWithDefaults = new Iterable.generate(NamedParameterNames.length, | 139 String namedWithDefaults = |
| 137 (int i) { | 140 new Iterable.generate(NamedParameterNames.length, (int i) { |
| 138 // TODO(#8) future: Recreate default values. | 141 // TODO(#8) future: Recreate default values. |
| 139 // TODO(#8) implement: Until that is done, recognize | 142 // TODO(#8) implement: Until that is done, recognize |
| 140 // unhandled cases, and emit error/warning. | 143 // unhandled cases, and emit error/warning. |
| 141 String defaultValueCode = | 144 String defaultValueCode = |
| 142 constructor.parameters[requiredPositionalCount + i].defaultValueCode; | 145 constructor.parameters[requiredPositionalCount + i].defaultValueCode; |
| 143 String defaultValueString = | 146 String defaultValueString = |
| 144 defaultValueCode == null ? "" : ": $defaultValueCode"; | 147 defaultValueCode == null ? "" : ": $defaultValueCode"; |
| 145 return "${NamedParameterNames[i]}$defaultValueString"; | 148 return "${NamedParameterNames[i]}$defaultValueString"; |
| 146 }).join(", "); | 149 }).join(", "); |
| 147 | 150 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 176 String _constConstructionCode(_ImportCollector importCollector) { | 179 String _constConstructionCode(_ImportCollector importCollector) { |
| 177 String prefix = importCollector._getPrefix(_reflector.library); | 180 String prefix = importCollector._getPrefix(_reflector.library); |
| 178 return "const $prefix.${_reflector.name}()"; | 181 return "const $prefix.${_reflector.name}()"; |
| 179 } | 182 } |
| 180 | 183 |
| 181 String _generateCode(Resolver resolver, _ImportCollector importCollector, | 184 String _generateCode(Resolver resolver, _ImportCollector importCollector, |
| 182 TransformLogger logger, AssetId dataId) { | 185 TransformLogger logger, AssetId dataId) { |
| 183 Enumerator<ClassElement> classes = new Enumerator<ClassElement>(); | 186 Enumerator<ClassElement> classes = new Enumerator<ClassElement>(); |
| 184 Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>(); | 187 Enumerator<ExecutableElement> members = new Enumerator<ExecutableElement>(); |
| 185 Enumerator<FieldElement> fields = new Enumerator<FieldElement>(); | 188 Enumerator<FieldElement> fields = new Enumerator<FieldElement>(); |
| 189 Enumerator<ParameterElement> parameters = | |
| 190 new Enumerator<ParameterElement>(); | |
| 186 Set<String> instanceGetterNames = new Set<String>(); | 191 Set<String> instanceGetterNames = new Set<String>(); |
| 187 Set<String> instanceSetterNames = new Set<String>(); | 192 Set<String> instanceSetterNames = new Set<String>(); |
| 188 | 193 |
| 189 // Fill in [classes], [members], [fields], [instanceGetterNames], | 194 // Fill in [classes], [members], [fields], [parameters], |
| 190 // and [instanceSetterNames]. | 195 // [instanceGetterNames], and [instanceSetterNames]. |
| 191 for (_ClassDomain classDomain in _annotatedClasses) { | 196 for (_ClassDomain classDomain in _annotatedClasses) { |
| 192 // Gather all annotated classes. | 197 // Gather all annotated classes. |
| 193 classes.add(classDomain._classElement); | 198 classes.add(classDomain._classElement); |
| 194 | 199 |
| 195 // Gather the behavioral interface into [members]. Note that | 200 // Gather the behavioral interface into [members]. Note that |
| 196 // this includes implicitly generated getters and setters, but | 201 // this includes implicitly generated getters and setters, but |
| 197 // omits fields. Also note that this does not match the | 202 // omits fields. Also note that this does not match the |
| 198 // semantics of the `declarations` method in a [ClassMirror]. | 203 // semantics of the `declarations` method in a [ClassMirror]. |
| 199 classDomain._declarations.forEach(members.add); | 204 classDomain._declarations.forEach(members.add); |
| 200 | 205 |
| 201 // Add the behavioral interface from this class (redundantly) and | 206 // Add the behavioral interface from this class (redundantly) and |
| 202 // all superclasses (which matters) to [members], such that it | 207 // all superclasses (which matters) to [members], such that it |
| 203 // contains both the behavioral parts for the target class and its | 208 // contains both the behavioral parts for the target class and its |
| 204 // superclasses, and the program structure oriented parts for the | 209 // superclasses, and the program structure oriented parts for the |
| 205 // target class (omitting those from its superclasses). | 210 // target class (omitting those from its superclasses). |
| 206 classDomain._instanceMembers.forEach(members.add); | 211 classDomain._instanceMembers.forEach(members.add); |
| 207 | 212 |
| 213 // Add all the formal parameters (as a single, global set) which | |
| 214 // are declared by any of the methods in `classDomain._declarations`. | |
| 215 classDomain._declaredParameters.forEach(parameters.add); | |
| 216 | |
| 208 // Gather the fields declared in the target class (not inherited | 217 // Gather the fields declared in the target class (not inherited |
| 209 // ones) in [fields], i.e., the elements missing from [members] | 218 // ones) in [fields], i.e., the elements missing from [members] |
| 210 // at this point, in order to support `declarations` in a | 219 // at this point, in order to support `declarations` in a |
| 211 // [ClassMirror]. | 220 // [ClassMirror]. |
| 212 classDomain._declaredFields.forEach(fields.add); | 221 classDomain._declaredFields.forEach(fields.add); |
| 213 | 222 |
| 214 // Gather all getters and setters based on [instanceMembers], including | 223 // Gather all getters and setters based on [instanceMembers], including |
| 215 // both explicitly declared ones, implicitly generated ones for fields, | 224 // both explicitly declared ones, implicitly generated ones for fields, |
| 216 // and the implicitly generated ones that correspond to method tear-offs. | 225 // and the implicitly generated ones that correspond to method tear-offs. |
| 217 classDomain._instanceMembers.forEach((ExecutableElement instanceMember) { | 226 classDomain._instanceMembers.forEach((ExecutableElement instanceMember) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 String name = setterName.substring(0, setterName.length - 1); | 279 String name = setterName.substring(0, setterName.length - 1); |
| 271 String className = classElement.name; | 280 String className = classElement.name; |
| 272 String prefix = importCollector._getPrefix(classElement.library); | 281 String prefix = importCollector._getPrefix(classElement.library); |
| 273 return 'r"$setterName": (value) => $prefix.$className.$name = value'; | 282 return 'r"$setterName": (value) => $prefix.$className.$name = value'; |
| 274 } | 283 } |
| 275 | 284 |
| 276 // Compute `includedClasses`, i.e., the set of classes which are | 285 // Compute `includedClasses`, i.e., the set of classes which are |
| 277 // annotated, or the upwards-closed completion of that set. | 286 // annotated, or the upwards-closed completion of that set. |
| 278 Set<_ClassDomain> includedClasses = new Set<_ClassDomain>(); | 287 Set<_ClassDomain> includedClasses = new Set<_ClassDomain>(); |
| 279 includedClasses.addAll(_annotatedClasses); | 288 includedClasses.addAll(_annotatedClasses); |
| 289 if (_capabilities._impliesParameterTypes) { | |
| 290 parameters.items.forEach((ParameterElement parameterElement) { | |
| 291 Element parameterType = parameterElement.type.element; | |
| 292 if (parameterType is ClassElement) { | |
| 293 includedClasses.add(_createClassDomain(parameterType, this)); | |
| 294 classes.add(parameterType); | |
| 295 } | |
| 296 }); | |
| 297 } | |
| 280 if (_capabilities._impliesUpwardsClosure) { | 298 if (_capabilities._impliesUpwardsClosure) { |
| 281 Set<_ClassDomain> workingSetOfClasses = includedClasses; | 299 Set<_ClassDomain> workingSetOfClasses = includedClasses; |
| 282 while (true) { | 300 while (true) { |
| 283 // Invariant for `workingSetOfClasses`: Every class from | 301 // Invariant for `workingSetOfClasses`: Every class from |
| 284 // `includedClasses` for which it is possible that its superclass | 302 // `includedClasses` for which it is possible that its superclass |
| 285 // is not yet in `includedClasses` must be a member of | 303 // is not yet in `includedClasses` must be a member of |
| 286 // `workingSetOfClasses`. | 304 // `workingSetOfClasses`. |
| 287 Set<_ClassDomain> additionalClasses = new Set<_ClassDomain>(); | 305 Set<_ClassDomain> additionalClasses = new Set<_ClassDomain>(); |
| 288 workingSetOfClasses.forEach((_ClassDomain workingClass) { | 306 workingSetOfClasses.forEach((_ClassDomain workingClass) { |
| 289 InterfaceType workingSuperType = workingClass._classElement.supertype; | 307 InterfaceType workingSuperType = workingClass._classElement.supertype; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 302 includedClasses.addAll(additionalClasses); | 320 includedClasses.addAll(additionalClasses); |
| 303 additionalClasses.forEach((_ClassDomain classDomain) { | 321 additionalClasses.forEach((_ClassDomain classDomain) { |
| 304 classes.add(classDomain._classElement); | 322 classes.add(classDomain._classElement); |
| 305 }); | 323 }); |
| 306 workingSetOfClasses = additionalClasses; | 324 workingSetOfClasses = additionalClasses; |
| 307 } | 325 } |
| 308 } | 326 } |
| 309 | 327 |
| 310 // Generate the class mirrors. | 328 // Generate the class mirrors. |
| 311 int classIndex = 0; | 329 int classIndex = 0; |
| 312 String classMirrorsCode = _formatAsList(includedClasses | 330 String classMirrorsCode = |
| 313 .map((_ClassDomain classDomain) { | 331 _formatAsList(includedClasses.map((_ClassDomain classDomain) { |
| 314 | |
| 315 // Fields go first in [memberMirrors], so they will get the | 332 // Fields go first in [memberMirrors], so they will get the |
| 316 // same index as in [fields]. | 333 // same index as in [fields]. |
| 317 Iterable<int> fieldsIndices = classDomain._declaredFields | 334 Iterable<int> fieldsIndices = |
| 318 .map((FieldElement element) { | 335 classDomain._declaredFields.map((FieldElement element) { |
| 319 return fields.indexOf(element); | 336 return fields.indexOf(element); |
| 320 }); | 337 }); |
| 321 | 338 |
| 322 int fieldsLength = fields.length; | 339 int fieldsLength = fields.length; |
| 323 | 340 |
| 324 // All the elements in the behavioral interface go after the | 341 // All the elements in the behavioral interface go after the |
| 325 // fields in [memberMirrors], so they must get an offset of | 342 // fields in [memberMirrors], so they must get an offset of |
| 326 // `fields.length` on the index. | 343 // `fields.length` on the index. |
| 327 Iterable<int> methodsIndices = classDomain._declarations | 344 Iterable<int> methodsIndices = classDomain._declarations |
| 328 .where(_executableIsntImplicitGetterOrSetter) | 345 .where(_executableIsntImplicitGetterOrSetter) |
| 329 .map((ExecutableElement element) { | 346 .map((ExecutableElement element) { |
| 330 // TODO(eernst) implement: The "magic" default constructor in `Object` | 347 // TODO(eernst) implement: The "magic" default constructor in `Object` |
| 331 // (the one that ultimately allocates the memory for _every_ new object) | 348 // (the one that ultimately allocates the memory for _every_ new object) |
| 332 // has no index, which creates the need to catch a `null` here. | 349 // has no index, which creates the need to catch a `null` here. |
| 333 // Search for "magic" to find other occurrences of the same issue. | 350 // Search for "magic" to find other occurrences of the same issue. |
| 334 // For now, we provide the index -1 for this declaration, because | 351 // For now, we provide the index -1 for this declaration, because |
| 335 // it is not yet supported. Need to find the correct solution, though! | 352 // it is not yet supported. Need to find the correct solution, though! |
| 336 int index = members.indexOf(element); | 353 int index = members.indexOf(element); |
| 337 return index == null ? -1 : index + fieldsLength; | 354 return index == null ? -1 : index + fieldsLength; |
| 338 }); | 355 }); |
| 339 | 356 |
| 340 List<int> declarationsIndices = <int>[] | 357 List<int> declarationsIndices = <int>[] |
| 341 ..addAll(fieldsIndices) | 358 ..addAll(fieldsIndices) |
| 342 ..addAll(methodsIndices); | 359 ..addAll(methodsIndices); |
| 343 String declarationsCode = _formatAsList(declarationsIndices); | 360 String declarationsCode = _formatAsList(declarationsIndices); |
| 344 | 361 |
| 345 // All instance members belong to the behavioral interface, so they | 362 // All instance members belong to the behavioral interface, so they |
| 346 // also get an offset of `fields.length`. | 363 // also get an offset of `fields.length`. |
| 347 String instanceMembersCode = _formatAsList(classDomain._instanceMembers | 364 String instanceMembersCode = _formatAsList( |
| 348 .map((ExecutableElement element) { | 365 classDomain._instanceMembers.map((ExecutableElement element) { |
| 349 // TODO(eernst) implement: The "magic" default constructor has | 366 // TODO(eernst) implement: The "magic" default constructor has |
| 350 // index: -1; adjust this when support for it has been implemented. | 367 // index: -1; adjust this when support for it has been implemented. |
| 351 int index = members.indexOf(element); | 368 int index = members.indexOf(element); |
| 352 return index == null ? -1 : index + fieldsLength; | 369 return index == null ? -1 : index + fieldsLength; |
| 353 })); | 370 })); |
| 354 | 371 |
| 355 InterfaceType superType = classDomain._classElement.supertype; | 372 InterfaceType superType = classDomain._classElement.supertype; |
| 356 ClassElement superclass = superType == null ? null : superType.element; | 373 ClassElement superclass = superType == null ? null : superType.element; |
| 357 String superclassIndex; | 374 String superclassIndex; |
| 358 if (superclass == null) { | 375 if (superclass == null) { |
| 359 superclassIndex = null; | 376 superclassIndex = null; |
| 360 } else { | 377 } else { |
| 361 int index = classes.indexOf(superclass); | 378 int index = classes.indexOf(superclass); |
| 362 if (index == null) { | 379 if (index == null) { |
| 363 // There is a superclass, but we have no capability for it. | 380 // There is a superclass, but we have no capability for it. |
| 364 index = -1; | 381 index = -1; |
| 365 } | 382 } |
| 366 superclassIndex = "$index"; | 383 superclassIndex = "$index"; |
| 367 } | 384 } |
| 368 | 385 |
| 369 String constructorsCode; | 386 String constructorsCode; |
| 370 | 387 |
| 371 if (classDomain._classElement.isAbstract) { | 388 if (classDomain._classElement.isAbstract) { |
| 372 constructorsCode = '{}'; | 389 constructorsCode = '{}'; |
| 373 } else { | 390 } else { |
| 374 constructorsCode = _formatAsMap(classDomain._constructors | 391 constructorsCode = _formatAsMap( |
| 375 .map((ConstructorElement constructor) { | 392 classDomain._constructors.map((ConstructorElement constructor) { |
| 376 String code = _constructorCode(constructor, importCollector); | 393 String code = _constructorCode(constructor, importCollector); |
| 377 return 'r"${constructor.name}": $code'; | 394 return 'r"${constructor.name}": $code'; |
| 378 })); | 395 })); |
| 379 } | 396 } |
| 380 | 397 |
| 381 String classMetadataCode; | 398 String classMetadataCode; |
| 382 if (_capabilities._supportsMetadata) { | 399 if (_capabilities._supportsMetadata) { |
| 383 classMetadataCode = _extractMetadataCode(classDomain._classElement, | 400 classMetadataCode = _extractMetadataCode(classDomain._classElement, |
| 384 resolver, importCollector, logger, dataId); | 401 resolver, importCollector, logger, dataId); |
| 385 } else { | 402 } else { |
| 386 classMetadataCode = "null"; | 403 classMetadataCode = "null"; |
| 387 } | 404 } |
| 388 | 405 |
| 389 String staticGettersCode = _formatAsMap([ | 406 String staticGettersCode = _formatAsMap([ |
| 390 classDomain._declaredMethods | 407 classDomain._declaredMethods |
| 391 .where((ExecutableElement element) => element.isStatic), | 408 .where((ExecutableElement element) => element.isStatic), |
| 392 classDomain._declaredAndImplicitAccessors.where( | 409 classDomain._declaredAndImplicitAccessors.where( |
| 393 (PropertyAccessorElement element) => | 410 (PropertyAccessorElement element) => |
| 394 element.isStatic && element.isGetter) | 411 element.isStatic && element.isGetter) |
| 395 ].expand((x) => x).map((ExecutableElement element) => | 412 ].expand((x) => x).map((ExecutableElement element) => |
| 396 staticGettingClosure(classDomain._classElement, element.name))); | 413 staticGettingClosure(classDomain._classElement, element.name))); |
| 397 String staticSettersCode = _formatAsMap( | 414 String staticSettersCode = _formatAsMap(classDomain |
| 398 classDomain._declaredAndImplicitAccessors | 415 ._declaredAndImplicitAccessors |
| 399 .where((PropertyAccessorElement element) => | 416 .where((PropertyAccessorElement element) => |
| 400 element.isStatic && element.isSetter) | 417 element.isStatic && element.isSetter) |
| 401 .map((PropertyAccessorElement element) => _staticSettingClosure( | 418 .map((PropertyAccessorElement element) => |
| 402 classDomain._classElement, element.name))); | 419 _staticSettingClosure(classDomain._classElement, element.name))); |
| 403 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' | 420 String result = 'new r.ClassMirrorImpl(r"${classDomain._simpleName}", ' |
| 404 'r"${classDomain._qualifiedName}", $classIndex, ' | 421 'r"${classDomain._qualifiedName}", $classIndex, ' |
| 405 '${_constConstructionCode(importCollector)}, ' | 422 '${_constConstructionCode(importCollector)}, ' |
| 406 '$declarationsCode, $instanceMembersCode, $superclassIndex, ' | 423 '$declarationsCode, $instanceMembersCode, $superclassIndex, ' |
| 407 '$staticGettersCode, $staticSettersCode, $constructorsCode, ' | 424 '$staticGettersCode, $staticSettersCode, $constructorsCode, ' |
| 408 '$classMetadataCode)'; | 425 '$classMetadataCode)'; |
| 409 classIndex++; | 426 classIndex++; |
| 410 return result; | 427 return result; |
| 411 })); | 428 })); |
| 412 | 429 |
| 413 String gettersCode = _formatAsMap(instanceGetterNames.map(gettingClosure)); | 430 String gettersCode = _formatAsMap(instanceGetterNames.map(gettingClosure)); |
| 414 String settersCode = _formatAsMap(instanceSetterNames.map(settingClosure)); | 431 String settersCode = _formatAsMap(instanceSetterNames.map(settingClosure)); |
| 415 | 432 |
| 416 Iterable<String> methodsList = members.items | 433 Iterable<String> methodsList = |
| 417 .map((ExecutableElement element) { | 434 members.items.map((ExecutableElement element) { |
| 418 int descriptor = _declarationDescriptor(element); | 435 int descriptor = _declarationDescriptor(element); |
| 419 int ownerIndex = classes.indexOf(element.enclosingElement); | 436 int ownerIndex = classes.indexOf(element.enclosingElement); |
| 437 List<int> parameterIndices = | |
| 438 element.parameters.map((ParameterElement parameterElement) { | |
| 439 return parameters.indexOf(parameterElement); | |
| 440 }); | |
| 441 String parameterIndicesCode = _formatAsList(parameterIndices); | |
| 420 String metadataCode; | 442 String metadataCode; |
| 421 if (_capabilities._supportsMetadata) { | 443 if (_capabilities._supportsMetadata) { |
| 422 metadataCode = _extractMetadataCode( | 444 metadataCode = _extractMetadataCode( |
| 423 element, resolver, importCollector, logger, dataId); | 445 element, resolver, importCollector, logger, dataId); |
| 424 } else { | 446 } else { |
| 425 metadataCode = null; | 447 metadataCode = null; |
| 426 } | 448 } |
| 427 return 'new r.MethodMirrorImpl(r"${element.name}", $descriptor, ' | 449 return 'new r.MethodMirrorImpl(r"${element.name}", $descriptor, ' |
| 428 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' | 450 '$ownerIndex, $parameterIndicesCode, ' |
| 429 '$metadataCode)'; | 451 '${_constConstructionCode(importCollector)}, $metadataCode)'; |
| 430 }); | 452 }); |
| 431 | 453 |
| 432 Iterable<String> fieldsList = fields.items.map((FieldElement element) { | 454 Iterable<String> fieldsList = fields.items.map((FieldElement element) { |
| 433 int descriptor = _fieldDescriptor(element); | 455 int descriptor = _fieldDescriptor(element); |
| 434 int ownerIndex = classes.indexOf(element.enclosingElement); | 456 int ownerIndex = classes.indexOf(element.enclosingElement); |
| 435 String metadataCode; | 457 String metadataCode; |
| 436 if (_capabilities._supportsMetadata) { | 458 if (_capabilities._supportsMetadata) { |
| 437 metadataCode = _extractMetadataCode( | 459 metadataCode = _extractMetadataCode( |
| 438 element, resolver, importCollector, logger, dataId); | 460 element, resolver, importCollector, logger, dataId); |
| 439 } else { | 461 } else { |
| 440 metadataCode = null; | 462 metadataCode = null; |
| 441 } | 463 } |
| 442 return 'new r.VariableMirrorImpl("${element.name}", $descriptor, ' | 464 return 'new r.VariableMirrorImpl("${element.name}", $descriptor, ' |
| 443 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' | 465 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' |
| 444 '$metadataCode)'; | 466 '$metadataCode)'; |
| 445 }); | 467 }); |
| 446 | 468 |
| 447 List<String> membersList = <String>[] | 469 List<String> membersList = <String>[] |
| 448 ..addAll(fieldsList) | 470 ..addAll(fieldsList) |
| 449 ..addAll(methodsList); | 471 ..addAll(methodsList); |
| 450 String membersCode = _formatAsList(membersList); | 472 String membersCode = _formatAsList(membersList); |
| 451 | 473 |
| 452 String typesCode = _formatAsList(classes.items | 474 String typesCode = |
| 453 .map((ClassElement classElement) { | 475 _formatAsList(classes.items.map((ClassElement classElement) { |
| 454 String prefix = importCollector._getPrefix(classElement.library); | 476 String prefix = importCollector._getPrefix(classElement.library); |
| 455 return "$prefix.${classElement.name}"; | 477 return "$prefix.${classElement.name}"; |
| 456 })); | 478 })); |
| 457 | 479 |
| 458 return "new r.ReflectorData($classMirrorsCode, $membersCode, $typesCode, " | 480 Iterable<String> parametersList = |
| 459 "$gettersCode, $settersCode)"; | 481 parameters.items.map((ParameterElement element) { |
| 482 int descriptor = _parameterDescriptor(element); | |
| 483 int ownerIndex = members.indexOf(element.enclosingElement); | |
| 484 int classMirrorIndex = classes._contains(element.type.element) | |
| 485 ? classes.indexOf(element.type.element) | |
| 486 : -1; | |
| 487 String metadataCode; | |
| 488 if (_capabilities._supportsMetadata) { | |
| 489 metadataCode = _extractMetadataCode( | |
| 490 element, resolver, importCollector, logger, dataId); | |
| 491 } else { | |
| 492 metadataCode = null; | |
| 493 } | |
| 494 // TODO(eernst) implement: Detect and, if possible, handle the case | |
| 495 // where it is incorrect to move element.defaultValueCode out of its | |
| 496 // original scope. If we cannot solve the problem we should issue | |
| 497 // a warning (it's worse than `new UndefinedClass()`, because it | |
| 498 // might "work" with a different semantics at runtime, rather than just | |
| 499 // failing if ever executed). | |
| 500 return 'new r.ParameterMirrorImpl(r"${element.name}", $descriptor, ' | |
| 501 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' | |
| 502 '$metadataCode, ${element.defaultValueCode}, $classMirrorIndex)'; | |
| 503 }); | |
| 504 String parameterMirrorsCode = _formatAsList(parametersList); | |
| 505 | |
| 506 return "new r.ReflectorData($classMirrorsCode, $membersCode, " | |
| 507 "$parameterMirrorsCode, $typesCode, $gettersCode, $settersCode)"; | |
| 460 } | 508 } |
| 461 } | 509 } |
| 462 | 510 |
| 463 /// Information about reflectability for a given class. | 511 /// Information about reflectability for a given class. |
| 464 class _ClassDomain { | 512 class _ClassDomain { |
| 465 /// Element describing the target class. | 513 /// Element describing the target class. |
| 466 final ClassElement _classElement; | 514 final ClassElement _classElement; |
| 467 | 515 |
| 468 /// Fields declared by [classElement] and included for reflection support, | 516 /// Fields declared by [classElement] and included for reflection support, |
| 469 /// according to the reflector described by the [reflectorDomain]; | 517 /// according to the reflector described by the [reflectorDomain]; |
| 470 /// obtained by filtering `classElement.fields`. | 518 /// obtained by filtering `classElement.fields`. |
| 471 final Iterable<FieldElement> _declaredFields; | 519 final Iterable<FieldElement> _declaredFields; |
| 472 | 520 |
| 473 /// Methods which are declared by [classElement] and included for | 521 /// Methods which are declared by [classElement] and included for |
| 474 /// reflection support, according to the reflector described by | 522 /// reflection support, according to the reflector described by |
| 475 /// [reflectorDomain]; obtained by filtering `classElement.methods`. | 523 /// [reflectorDomain]; obtained by filtering `classElement.methods`. |
| 476 final Iterable<MethodElement> _declaredMethods; | 524 final Iterable<MethodElement> _declaredMethods; |
| 477 | 525 |
| 526 /// Formal parameters declared by one of the [_declaredMethods]. | |
| 527 final Iterable<ParameterElement> _declaredParameters; | |
| 528 | |
| 478 /// Getters and setters possessed by [classElement] and included for | 529 /// Getters and setters possessed by [classElement] and included for |
| 479 /// reflection support, according to the reflector described by | 530 /// reflection support, according to the reflector described by |
| 480 /// [reflectorDomain]; obtained by filtering `classElement.accessors`. | 531 /// [reflectorDomain]; obtained by filtering `classElement.accessors`. |
| 481 /// Note that it includes declared as well as synthetic accessors, | 532 /// Note that it includes declared as well as synthetic accessors, |
| 482 /// implicitly created as getters/setters for fields. | 533 /// implicitly created as getters/setters for fields. |
| 483 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; | 534 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; |
| 484 | 535 |
| 485 /// Constructors declared by [classElement] and included for reflection | 536 /// Constructors declared by [classElement] and included for reflection |
| 486 /// support, according to the reflector described by [reflectorDomain]; | 537 /// support, according to the reflector described by [reflectorDomain]; |
| 487 /// obtained by filtering `classElement.constructors`. | 538 /// obtained by filtering `classElement.constructors`. |
| 488 final Iterable<ConstructorElement> _constructors; | 539 final Iterable<ConstructorElement> _constructors; |
| 489 | 540 |
| 490 /// The reflector domain that holds [this] object as one of its | 541 /// The reflector domain that holds [this] object as one of its |
| 491 /// class domains. | 542 /// class domains. |
| 492 final _ReflectorDomain _reflectorDomain; | 543 final _ReflectorDomain _reflectorDomain; |
| 493 | 544 |
| 494 _ClassDomain(this._classElement, this._declaredFields, this._declaredMethods, | 545 _ClassDomain( |
| 495 this._declaredAndImplicitAccessors, this._constructors, | 546 this._classElement, |
| 547 this._declaredFields, | |
| 548 this._declaredMethods, | |
| 549 this._declaredParameters, | |
| 550 this._declaredAndImplicitAccessors, | |
| 551 this._constructors, | |
| 496 this._reflectorDomain); | 552 this._reflectorDomain); |
| 497 | 553 |
| 498 String get _simpleName => _classElement.name; | 554 String get _simpleName => _classElement.name; |
| 499 String get _qualifiedName { | 555 String get _qualifiedName { |
| 500 return "${_classElement.library.name}.${_classElement.name}"; | 556 return "${_classElement.library.name}.${_classElement.name}"; |
| 501 } | 557 } |
| 502 | 558 |
| 503 /// Returns the declared methods, accessors and constructors in | 559 /// Returns the declared methods, accessors and constructors in |
| 504 /// [classElement]. Note that this includes synthetic getters and | 560 /// [classElement]. Note that this includes synthetic getters and |
| 505 /// setters, and omits fields; in other words, it provides the | 561 /// setters, and omits fields; in other words, it provides the |
| 506 /// behavioral point of view on the class. Also note that this is not | 562 /// behavioral point of view on the class. Also note that this is not |
| 507 /// the same semantics as that of `declarations` in [ClassMirror]. | 563 /// the same semantics as that of `declarations` in [ClassMirror]. |
| 508 Iterable<ExecutableElement> get _declarations { | 564 Iterable<ExecutableElement> get _declarations { |
| 509 // TODO(sigurdm) feature: Include type variables (if we keep them). | 565 // TODO(sigurdm) feature: Include type variables (if we keep them). |
| 510 return [ | 566 return [_declaredMethods, _declaredAndImplicitAccessors, _constructors] |
| 511 _declaredMethods, | 567 .expand((x) => x); |
| 512 _declaredAndImplicitAccessors, | |
| 513 _constructors | |
| 514 ].expand((x) => x); | |
| 515 } | 568 } |
| 516 | 569 |
| 517 /// Finds all instance members by going through the class hierarchy. | 570 /// Finds all instance members by going through the class hierarchy. |
| 518 Iterable<ExecutableElement> get _instanceMembers { | 571 Iterable<ExecutableElement> get _instanceMembers { |
| 519 Map<String, ExecutableElement> helper(ClassElement classElement) { | 572 Map<String, ExecutableElement> helper(ClassElement classElement) { |
| 520 if (_reflectorDomain._instanceMemberCache[classElement] != null) { | 573 if (_reflectorDomain._instanceMemberCache[classElement] != null) { |
| 521 return _reflectorDomain._instanceMemberCache[classElement]; | 574 return _reflectorDomain._instanceMemberCache[classElement]; |
| 522 } | 575 } |
| 523 Map<String, ExecutableElement> result = | 576 Map<String, ExecutableElement> result = |
| 524 new Map<String, ExecutableElement>(); | 577 new Map<String, ExecutableElement>(); |
| 525 | 578 |
| 526 void addIfCapable(ExecutableElement member) { | 579 void addIfCapable(ExecutableElement member) { |
| 527 // If [member] is a synthetic accessor created from a field, search for | 580 // If [member] is a synthetic accessor created from a field, search for |
| 528 // the metadata on the original field. | 581 // the metadata on the original field. |
| 529 List<ElementAnnotation> metadata = (member is PropertyAccessorElement && | 582 List<ElementAnnotation> metadata = (member is PropertyAccessorElement && |
| 530 member.isSynthetic) ? member.variable.metadata : member.metadata; | 583 member.isSynthetic) ? member.variable.metadata : member.metadata; |
| 531 if (_reflectorDomain._capabilities.supportsInstanceInvoke( | 584 if (_reflectorDomain._capabilities |
| 532 member.name, metadata)) { | 585 .supportsInstanceInvoke(member.name, metadata)) { |
| 533 result[member.name] = member; | 586 result[member.name] = member; |
| 534 } | 587 } |
| 535 } | 588 } |
| 536 if (classElement.supertype != null) { | 589 if (classElement.supertype != null) { |
| 537 helper(classElement.supertype.element) | 590 helper(classElement.supertype.element) |
| 538 .forEach((String name, ExecutableElement member) { | 591 .forEach((String name, ExecutableElement member) { |
| 539 addIfCapable(member); | 592 addIfCapable(member); |
| 540 }); | 593 }); |
| 541 } | 594 } |
| 542 for (InterfaceType mixin in classElement.mixins) { | 595 for (InterfaceType mixin in classElement.mixins) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 737 } | 790 } |
| 738 | 791 |
| 739 // Returns [true] iff these [Capabilities] specify reflection support where | 792 // Returns [true] iff these [Capabilities] specify reflection support where |
| 740 // the set of included classes must be upwards closed, i.e., extra classes | 793 // the set of included classes must be upwards closed, i.e., extra classes |
| 741 // must be added beyond the ones that are directly included as reflectable | 794 // must be added beyond the ones that are directly included as reflectable |
| 742 // because we must support operations like `superclass`. | 795 // because we must support operations like `superclass`. |
| 743 bool get _impliesUpwardsClosure { | 796 bool get _impliesUpwardsClosure { |
| 744 return _capabilities.any((ec.ReflectCapability capability) => | 797 return _capabilities.any((ec.ReflectCapability capability) => |
| 745 capability == ec.typeRelationsCapability); | 798 capability == ec.typeRelationsCapability); |
| 746 } | 799 } |
| 800 | |
| 801 bool get _impliesParameterTypes { | |
| 802 bool haveDeclarations = | |
| 803 _capabilities.any((ec.ReflectCapability capability) { | |
| 804 return capability == ec.declarationsCapability; | |
| 805 }); | |
| 806 if (!haveDeclarations) return false; | |
| 807 return _capabilities.any((ec.ReflectCapability capability) { | |
| 808 return capability is ec.TypeCapability || | |
| 809 capability is ec.TypingCapability; | |
| 810 }); | |
| 811 } | |
| 747 } | 812 } |
| 748 | 813 |
| 749 /// Collects the libraries that needs to be imported, and gives each library | 814 /// Collects the libraries that needs to be imported, and gives each library |
| 750 /// a unique prefix. | 815 /// a unique prefix. |
| 751 class _ImportCollector { | 816 class _ImportCollector { |
| 752 Map<LibraryElement, String> _mapping = new Map<LibraryElement, String>(); | 817 Map<LibraryElement, String> _mapping = new Map<LibraryElement, String>(); |
| 753 int _count = 0; | 818 int _count = 0; |
| 754 | 819 |
| 755 /// Returns the prefix associated with [library]. | 820 /// Returns the prefix associated with [library]. |
| 756 String _getPrefix(LibraryElement library) { | 821 String _getPrefix(LibraryElement library) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 } | 1047 } |
| 983 ClassElement reflector = | 1048 ClassElement reflector = |
| 984 value.fields["(super)"].fields["reflector"].type.element; | 1049 value.fields["(super)"].fields["reflector"].type.element; |
| 985 if (reflector == null || | 1050 if (reflector == null || |
| 986 reflector.type.element.supertype.element != | 1051 reflector.type.element.supertype.element != |
| 987 reflectableClass) { | 1052 reflectableClass) { |
| 988 String found = | 1053 String found = |
| 989 reflector == null ? "" : " Found ${reflector.name}"; | 1054 reflector == null ? "" : " Found ${reflector.name}"; |
| 990 _warn( | 1055 _warn( |
| 991 "The reflector must be a direct subclass of Reflectable." + | 1056 "The reflector must be a direct subclass of Reflectable." + |
| 992 found, import); | 1057 found, |
| 1058 import); | |
| 993 continue; | 1059 continue; |
| 994 } | 1060 } |
| 995 globalPatterns | 1061 globalPatterns |
| 996 .putIfAbsent( | 1062 .putIfAbsent( |
| 997 new RegExp(pattern), () => new List<ClassElement>()) | 1063 new RegExp(pattern), () => new List<ClassElement>()) |
| 998 .add(reflector); | 1064 .add(reflector); |
| 999 } | 1065 } |
| 1000 } else if (metadatum.element == | 1066 } else if (metadatum.element == |
| 1001 globalQuantifyMetaCapabilityConstructor) { | 1067 globalQuantifyMetaCapabilityConstructor) { |
| 1002 EvaluationResultImpl evaluation = metadatum.evaluationResult; | 1068 EvaluationResultImpl evaluation = metadatum.evaluationResult; |
| 1003 if (evaluation != null && evaluation.value != null) { | 1069 if (evaluation != null && evaluation.value != null) { |
| 1004 DartObjectImpl value = evaluation.value; | 1070 DartObjectImpl value = evaluation.value; |
| 1005 Object metadataFieldValue = value.fields["metadataType"].value; | 1071 Object metadataFieldValue = value.fields["metadataType"].value; |
| 1006 if (metadataFieldValue == null || | 1072 if (metadataFieldValue == null || |
| 1007 value.fields["metadataType"].type.element != typeClass) { | 1073 value.fields["metadataType"].type.element != typeClass) { |
| 1008 // TODO(sigurdm) implement: Create a span for the annotation. | 1074 // TODO(sigurdm) implement: Create a span for the annotation. |
| 1009 _warn("The metadata must be a Type. " | 1075 _warn( |
| 1076 "The metadata must be a Type. " | |
| 1010 "Found ${value.fields["metadataType"].type.element.name}", | 1077 "Found ${value.fields["metadataType"].type.element.name}", |
| 1011 import); | 1078 import); |
| 1012 continue; | 1079 continue; |
| 1013 } | 1080 } |
| 1014 ClassElement reflector = | 1081 ClassElement reflector = |
| 1015 value.fields["(super)"].fields["reflector"].type.element; | 1082 value.fields["(super)"].fields["reflector"].type.element; |
| 1016 if (reflector == null || | 1083 if (reflector == null || |
| 1017 reflector.type.element.supertype.element != | 1084 reflector.type.element.supertype.element != |
| 1018 reflectableClass) { | 1085 reflectableClass) { |
| 1019 String found = | 1086 String found = |
| 1020 reflector == null ? "" : " Found ${reflector.name}"; | 1087 reflector == null ? "" : " Found ${reflector.name}"; |
| 1021 _warn( | 1088 _warn( |
| 1022 "The reflector must be a direct subclass of Reflectable." + | 1089 "The reflector must be a direct subclass of Reflectable." + |
| 1023 found, import); | 1090 found, |
| 1091 import); | |
| 1024 continue; | 1092 continue; |
| 1025 } | 1093 } |
| 1026 globalMetadata | 1094 globalMetadata |
| 1027 .putIfAbsent( | 1095 .putIfAbsent( |
| 1028 metadataFieldValue, () => new List<ClassElement>()) | 1096 metadataFieldValue, () => new List<ClassElement>()) |
| 1029 .add(reflector); | 1097 .add(reflector); |
| 1030 } | 1098 } |
| 1031 } | 1099 } |
| 1032 } | 1100 } |
| 1033 } | 1101 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1094 // Add the class if it is annotated by a reflector. | 1162 // Add the class if it is annotated by a reflector. |
| 1095 ClassElement reflector = | 1163 ClassElement reflector = |
| 1096 _getReflectableAnnotation(metadatum, focusClass); | 1164 _getReflectableAnnotation(metadatum, focusClass); |
| 1097 if (reflector != null) { | 1165 if (reflector != null) { |
| 1098 addClassDomain(type, reflector); | 1166 addClassDomain(type, reflector); |
| 1099 } | 1167 } |
| 1100 } | 1168 } |
| 1101 // Add the class to the domain of all reflectors associated with a | 1169 // Add the class to the domain of all reflectors associated with a |
| 1102 // pattern, via GlobalQuantifyCapability, that matches the qualified | 1170 // pattern, via GlobalQuantifyCapability, that matches the qualified |
| 1103 // name of the class. | 1171 // name of the class. |
| 1104 globalPatterns | 1172 globalPatterns.forEach( |
| 1105 .forEach((RegExp pattern, List<ClassElement> reflectors) { | 1173 (RegExp pattern, List<ClassElement> reflectors) { |
| 1106 String qualifiedName = "${type.library.name}.${type.name}"; | 1174 String qualifiedName = "${type.library.name}.${type.name}"; |
| 1107 if (pattern.hasMatch(qualifiedName)) { | 1175 if (pattern.hasMatch(qualifiedName)) { |
| 1108 for (ClassElement reflector in reflectors) { | 1176 for (ClassElement reflector in reflectors) { |
| 1109 addClassDomain(type, reflector); | 1177 addClassDomain(type, reflector); |
| 1110 } | 1178 } |
| 1111 } | 1179 } |
| 1112 }); | 1180 }); |
| 1113 } | 1181 } |
| 1114 } | 1182 } |
| 1115 } | 1183 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1129 LibraryElement annotatedLibrary = classData._classElement.library; | 1197 LibraryElement annotatedLibrary = classData._classElement.library; |
| 1130 if (metadataLibrary != annotatedLibrary) { | 1198 if (metadataLibrary != annotatedLibrary) { |
| 1131 domain._missingImports.add(annotatedLibrary); | 1199 domain._missingImports.add(annotatedLibrary); |
| 1132 } | 1200 } |
| 1133 } | 1201 } |
| 1134 } | 1202 } |
| 1135 | 1203 |
| 1136 ImportElement _findLastImport(LibraryElement library) { | 1204 ImportElement _findLastImport(LibraryElement library) { |
| 1137 if (library.imports.isNotEmpty) { | 1205 if (library.imports.isNotEmpty) { |
| 1138 ImportElement importElement = library.imports.lastWhere( | 1206 ImportElement importElement = library.imports.lastWhere( |
| 1139 (importElement) => importElement.node != null, orElse: () => null); | 1207 (importElement) => importElement.node != null, |
| 1208 orElse: () => null); | |
| 1140 if (importElement != null) { | 1209 if (importElement != null) { |
| 1141 // Found an import element with a node (i.e., a non-synthetic one). | 1210 // Found an import element with a node (i.e., a non-synthetic one). |
| 1142 return importElement; | 1211 return importElement; |
| 1143 } else { | 1212 } else { |
| 1144 // No non-synthetic imports. | 1213 // No non-synthetic imports. |
| 1145 return null; | 1214 return null; |
| 1146 } | 1215 } |
| 1147 } | 1216 } |
| 1148 // library.imports.isEmpty | 1217 // library.imports.isEmpty |
| 1149 return null; | 1218 return null; |
| 1150 } | 1219 } |
| 1151 | 1220 |
| 1152 ExportElement _findFirstExport(LibraryElement library) { | 1221 ExportElement _findFirstExport(LibraryElement library) { |
| 1153 if (library.exports.isNotEmpty) { | 1222 if (library.exports.isNotEmpty) { |
| 1154 ExportElement exportElement = library.exports.firstWhere( | 1223 ExportElement exportElement = library.exports.firstWhere( |
| 1155 (exportElement) => exportElement.node != null, orElse: () => null); | 1224 (exportElement) => exportElement.node != null, |
| 1225 orElse: () => null); | |
| 1156 if (exportElement != null) { | 1226 if (exportElement != null) { |
| 1157 // Found an export element with a node (i.e., a non-synthetic one) | 1227 // Found an export element with a node (i.e., a non-synthetic one) |
| 1158 return exportElement; | 1228 return exportElement; |
| 1159 } else { | 1229 } else { |
| 1160 // No non-synthetic exports. | 1230 // No non-synthetic exports. |
| 1161 return null; | 1231 return null; |
| 1162 } | 1232 } |
| 1163 } | 1233 } |
| 1164 // library.exports.isEmpty | 1234 // library.exports.isEmpty |
| 1165 return null; | 1235 return null; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 | 1281 |
| 1212 DartObjectImpl constant = evaluated.value; | 1282 DartObjectImpl constant = evaluated.value; |
| 1213 | 1283 |
| 1214 ParameterizedType dartType = constant.type; | 1284 ParameterizedType dartType = constant.type; |
| 1215 // We insist that the type must be a class, and we insist that it must | 1285 // We insist that the type must be a class, and we insist that it must |
| 1216 // be in the given `capabilityLibrary` (because we could never know | 1286 // be in the given `capabilityLibrary` (because we could never know |
| 1217 // how to interpret the meaning of a user-written capability class, so | 1287 // how to interpret the meaning of a user-written capability class, so |
| 1218 // users cannot write their own capability classes). | 1288 // users cannot write their own capability classes). |
| 1219 if (dartType.element is! ClassElement) { | 1289 if (dartType.element is! ClassElement) { |
| 1220 if (dartType.element.source != null) { | 1290 if (dartType.element.source != null) { |
| 1221 _logger.error(errors.applyTemplate(errors.SUPER_ARGUMENT_NON_CLASS, { | 1291 _logger.error( |
| 1222 "type": dartType.displayName | 1292 errors.applyTemplate(errors.SUPER_ARGUMENT_NON_CLASS, |
| 1223 }), span: _resolver.getSourceSpan(dartType.element)); | 1293 {"type": dartType.displayName}), |
| 1294 span: _resolver.getSourceSpan(dartType.element)); | |
| 1224 } else { | 1295 } else { |
| 1225 _logger.error(errors.applyTemplate( | 1296 _logger.error(errors.applyTemplate( |
| 1226 errors.SUPER_ARGUMENT_NON_CLASS, {"type": dartType.displayName})); | 1297 errors.SUPER_ARGUMENT_NON_CLASS, {"type": dartType.displayName})); |
| 1227 } | 1298 } |
| 1228 } | 1299 } |
| 1229 ClassElement classElement = dartType.element; | 1300 ClassElement classElement = dartType.element; |
| 1230 if (classElement.library != capabilityLibrary) { | 1301 if (classElement.library != capabilityLibrary) { |
| 1231 _logger.error(errors.applyTemplate(errors.SUPER_ARGUMENT_WRONG_LIBRARY, { | 1302 _logger.error( |
| 1232 "library": capabilityLibrary, | 1303 errors.applyTemplate(errors.SUPER_ARGUMENT_WRONG_LIBRARY, |
| 1233 "element": classElement | 1304 {"library": capabilityLibrary, "element": classElement}), |
| 1234 }), span: _resolver.getSourceSpan(classElement)); | 1305 span: _resolver.getSourceSpan(classElement)); |
| 1235 } | 1306 } |
| 1236 | 1307 |
| 1237 /// Extracts the namePattern String from an instance of a subclass of | 1308 /// Extracts the namePattern String from an instance of a subclass of |
| 1238 /// NamePatternCapability. | 1309 /// NamePatternCapability. |
| 1239 String extractNamePattern(DartObjectImpl constant) { | 1310 String extractNamePattern(DartObjectImpl constant) { |
| 1240 if (constant.fields == null || | 1311 if (constant.fields == null || |
| 1241 constant.fields["(super)"] == null || | 1312 constant.fields["(super)"] == null || |
| 1242 constant.fields["(super)"].fields["namePattern"] == null || | 1313 constant.fields["(super)"].fields["namePattern"] == null || |
| 1243 constant.fields["(super)"].fields["namePattern"].stringValue == | 1314 constant.fields["(super)"].fields["namePattern"].stringValue == |
| 1244 null) { | 1315 null) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1427 '\nimport "$reflectWorldUri" show initializeReflectable;'); | 1498 '\nimport "$reflectWorldUri" show initializeReflectable;'); |
| 1428 | 1499 |
| 1429 // TODO(eernst) implement: This won't work if main is not declared | 1500 // TODO(eernst) implement: This won't work if main is not declared |
| 1430 // in `mainLibrary`. | 1501 // in `mainLibrary`. |
| 1431 if (mainLibrary.entryPoint == null) { | 1502 if (mainLibrary.entryPoint == null) { |
| 1432 _logger.warning("Could not find a main method in $entryPoint. Skipping."); | 1503 _logger.warning("Could not find a main method in $entryPoint. Skipping."); |
| 1433 return source; | 1504 return source; |
| 1434 } | 1505 } |
| 1435 sourceManager.insert(mainLibrary.entryPoint.nameOffset, "_"); | 1506 sourceManager.insert(mainLibrary.entryPoint.nameOffset, "_"); |
| 1436 String args = (mainLibrary.entryPoint.parameters.length == 0) ? "" : "args"; | 1507 String args = (mainLibrary.entryPoint.parameters.length == 0) ? "" : "args"; |
| 1437 sourceManager.insert(source.length, """ | 1508 sourceManager.insert( |
| 1509 source.length, | |
| 1510 """ | |
| 1438 main($args) { | 1511 main($args) { |
| 1439 initializeReflectable(); | 1512 initializeReflectable(); |
| 1440 return _main($args); | 1513 return _main($args); |
| 1441 }"""); | 1514 }"""); |
| 1442 return sourceManager.source; | 1515 return sourceManager.source; |
| 1443 } | 1516 } |
| 1444 | 1517 |
| 1445 /// Performs the transformation which eliminates all imports of | 1518 /// Performs the transformation which eliminates all imports of |
| 1446 /// `package:reflectable/reflectable.dart` and instead provides a set of | 1519 /// `package:reflectable/reflectable.dart` and instead provides a set of |
| 1447 /// statically generated mirror classes. | 1520 /// statically generated mirror classes. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1514 /// which case we can drop this class and use that method. | 1587 /// which case we can drop this class and use that method. |
| 1515 class _AggregateTransformWrapper implements Transform { | 1588 class _AggregateTransformWrapper implements Transform { |
| 1516 final AggregateTransform _aggregateTransform; | 1589 final AggregateTransform _aggregateTransform; |
| 1517 final Asset primaryInput; | 1590 final Asset primaryInput; |
| 1518 _AggregateTransformWrapper(this._aggregateTransform, this.primaryInput); | 1591 _AggregateTransformWrapper(this._aggregateTransform, this.primaryInput); |
| 1519 TransformLogger get logger => _aggregateTransform.logger; | 1592 TransformLogger get logger => _aggregateTransform.logger; |
| 1520 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1593 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
| 1521 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1594 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
| 1522 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1595 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
| 1523 } | 1596 } |
| 1597 | |
| 1524 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1598 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
| 1525 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1599 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
| 1526 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1600 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
| 1527 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1601 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
| 1528 } | 1602 } |
| 1529 | 1603 |
| 1530 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { | 1604 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { |
| 1531 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); | 1605 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); |
| 1532 } | 1606 } |
| 1533 | 1607 |
| 1534 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { | 1608 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { |
| 1535 return executable is! PropertyAccessorElement || | 1609 return executable is! PropertyAccessorElement || |
| 1536 _accessorIsntImplicitGetterOrSetter(executable); | 1610 _accessorIsntImplicitGetterOrSetter(executable); |
| 1537 } | 1611 } |
| 1538 | 1612 |
| 1539 /// Returns an integer encoding of the kind and attributes of the given | 1613 /// Returns an integer encoding of the kind and attributes of the given |
| 1540 /// field. | 1614 /// field. |
| 1541 int _fieldDescriptor(FieldElement element) { | 1615 int _fieldDescriptor(FieldElement element) { |
| 1542 int result = constants.field; | 1616 int result = constants.field; |
| 1543 if (element.isPrivate) result |= constants.privateAttribute; | 1617 if (element.isPrivate) result |= constants.privateAttribute; |
| 1544 if (element.isSynthetic) result |= constants.syntheticAttribute; | 1618 if (element.isSynthetic) result |= constants.syntheticAttribute; |
| 1545 if (element.isConst) result |= constants.constAttribute; | 1619 if (element.isConst) result |= constants.constAttribute; |
| 1546 if (element.isFinal) result |= constants.finalAttribute; | 1620 if (element.isFinal) result |= constants.finalAttribute; |
| 1547 if (element.isStatic) result |= constants.staticAttribute; | 1621 if (element.isStatic) result |= constants.staticAttribute; |
| 1548 return result; | 1622 return result; |
| 1549 } | 1623 } |
| 1550 | 1624 |
| 1551 /// Returns an integer encoding of the kind and attributes of the given | 1625 /// Returns an integer encoding of the kind and attributes of the given |
| 1626 /// parameter. | |
| 1627 int _parameterDescriptor(ParameterElement element) { | |
| 1628 int result = constants.parameter; | |
| 1629 if (element.isPrivate) result |= constants.privateAttribute; | |
| 1630 if (element.isSynthetic) result |= constants.syntheticAttribute; | |
| 1631 if (element.isConst) result |= constants.constAttribute; | |
| 1632 if (element.isFinal) result |= constants.finalAttribute; | |
| 1633 if (element.defaultValueCode != null) { | |
| 1634 result |= constants.hasDefaultValueAttribute; | |
| 1635 } | |
| 1636 if (element.parameterKind.isOptional) { | |
| 1637 result |= constants.optionalAttribute; | |
| 1638 } | |
| 1639 if (element.parameterKind == ParameterKind.NAMED) { | |
| 1640 result |= constants.namedAttribute; | |
| 1641 } | |
| 1642 if (element.type.isDynamic) { | |
| 1643 result |= constants.dynamicAttribute; | |
| 1644 } | |
| 1645 Element elementType = element.type.element; | |
| 1646 if (elementType is ClassElement) { | |
| 1647 result |= constants.classTypeAttribute; | |
| 1648 } | |
| 1649 return result; | |
| 1650 } | |
| 1651 | |
| 1652 /// Returns an integer encoding of the kind and attributes of the given | |
| 1552 /// method/constructor/getter/setter. | 1653 /// method/constructor/getter/setter. |
| 1553 int _declarationDescriptor(ExecutableElement element) { | 1654 int _declarationDescriptor(ExecutableElement element) { |
| 1554 int result; | 1655 int result; |
| 1555 if (element is PropertyAccessorElement) { | 1656 if (element is PropertyAccessorElement) { |
| 1556 result = element.isGetter ? constants.getter : constants.setter; | 1657 result = element.isGetter ? constants.getter : constants.setter; |
| 1557 } else if (element is ConstructorElement) { | 1658 } else if (element is ConstructorElement) { |
| 1558 if (element.isFactory) { | 1659 if (element.isFactory) { |
| 1559 result = constants.factoryConstructor; | 1660 result = constants.factoryConstructor; |
| 1560 } else { | 1661 } else { |
| 1561 result = constants.generativeConstructor; | 1662 result = constants.generativeConstructor; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1581 : "${element.enclosingElement.name}.${element.name}"; | 1682 : "${element.enclosingElement.name}.${element.name}"; |
| 1582 } | 1683 } |
| 1583 return element.name; | 1684 return element.name; |
| 1584 } | 1685 } |
| 1585 | 1686 |
| 1586 String _formatAsList(Iterable parts) => "[${parts.join(", ")}]"; | 1687 String _formatAsList(Iterable parts) => "[${parts.join(", ")}]"; |
| 1587 | 1688 |
| 1588 String _formatAsMap(Iterable parts) => "{${parts.join(", ")}}"; | 1689 String _formatAsMap(Iterable parts) => "{${parts.join(", ")}}"; |
| 1589 | 1690 |
| 1590 /// Returns code that will reproduce the given constant expression. | 1691 /// Returns code that will reproduce the given constant expression. |
| 1591 String _extractConstantCode(Expression expression, | 1692 String _extractConstantCode( |
| 1592 LibraryElement originatingLibrary, Resolver resolver, | 1693 Expression expression, |
| 1694 LibraryElement originatingLibrary, | |
| 1695 Resolver resolver, | |
| 1593 _ImportCollector importCollector) { | 1696 _ImportCollector importCollector) { |
| 1594 if (expression is ListLiteral) { | 1697 if (expression is ListLiteral) { |
| 1595 List<String> elements = expression.elements.map((Expression subExpression) { | 1698 List<String> elements = expression.elements.map((Expression subExpression) { |
| 1596 return _extractConstantCode( | 1699 return _extractConstantCode( |
| 1597 subExpression, originatingLibrary, resolver, importCollector); | 1700 subExpression, originatingLibrary, resolver, importCollector); |
| 1598 }); | 1701 }); |
| 1599 // TODO(sigurdm) feature: Type arguments. | 1702 // TODO(sigurdm) feature: Type arguments. |
| 1600 return "const ${_formatAsList(elements)}"; | 1703 return "const ${_formatAsList(elements)}"; |
| 1601 } else if (expression is MapLiteral) { | 1704 } else if (expression is MapLiteral) { |
| 1602 List<String> elements = expression.entries.map((MapLiteralEntry entry) { | 1705 List<String> elements = expression.entries.map((MapLiteralEntry entry) { |
| 1603 String key = _extractConstantCode( | 1706 String key = _extractConstantCode( |
| 1604 entry.key, originatingLibrary, resolver, importCollector); | 1707 entry.key, originatingLibrary, resolver, importCollector); |
| 1605 String value = _extractConstantCode( | 1708 String value = _extractConstantCode( |
| 1606 entry.value, originatingLibrary, resolver, importCollector); | 1709 entry.value, originatingLibrary, resolver, importCollector); |
| 1607 return "$key: $value"; | 1710 return "$key: $value"; |
| 1608 }); | 1711 }); |
| 1609 // TODO(sigurdm) feature: Type arguments. | 1712 // TODO(sigurdm) feature: Type arguments. |
| 1610 return "const ${_formatAsMap(elements)}"; | 1713 return "const ${_formatAsMap(elements)}"; |
| 1611 } else if (expression is InstanceCreationExpression) { | 1714 } else if (expression is InstanceCreationExpression) { |
| 1612 String constructor = expression.constructorName.toSource(); | 1715 String constructor = expression.constructorName.toSource(); |
| 1613 LibraryElement libraryOfConstructor = expression.staticElement.library; | 1716 LibraryElement libraryOfConstructor = expression.staticElement.library; |
| 1614 importCollector._addLibrary(libraryOfConstructor); | 1717 importCollector._addLibrary(libraryOfConstructor); |
| 1615 String prefix = | 1718 String prefix = |
| 1616 importCollector._getPrefix(expression.staticElement.library); | 1719 importCollector._getPrefix(expression.staticElement.library); |
| 1617 // TODO(sigurdm) implement: Named arguments. | 1720 // TODO(sigurdm) implement: Named arguments. |
| 1618 String arguments = expression.argumentList.arguments | 1721 String arguments = |
| 1619 .map((Expression argument) { | 1722 expression.argumentList.arguments.map((Expression argument) { |
| 1620 return _extractConstantCode( | 1723 return _extractConstantCode( |
| 1621 argument, originatingLibrary, resolver, importCollector); | 1724 argument, originatingLibrary, resolver, importCollector); |
| 1622 }).join(", "); | 1725 }).join(", "); |
| 1623 // TODO(sigurdm) feature: Type arguments. | 1726 // TODO(sigurdm) feature: Type arguments. |
| 1624 return "const $prefix.$constructor($arguments)"; | 1727 return "const $prefix.$constructor($arguments)"; |
| 1625 } else if (expression is Identifier) { | 1728 } else if (expression is Identifier) { |
| 1626 Element element = expression.staticElement; | 1729 Element element = expression.staticElement; |
| 1627 importCollector._addLibrary(element.library); | 1730 importCollector._addLibrary(element.library); |
| 1628 String prefix = importCollector._getPrefix(element.library); | 1731 String prefix = importCollector._getPrefix(element.library); |
| 1629 Element enclosingElement = element.enclosingElement; | 1732 Element enclosingElement = element.enclosingElement; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1753 span: resolver.getSourceSpan(element)); | 1856 span: resolver.getSourceSpan(element)); |
| 1754 continue; | 1857 continue; |
| 1755 } | 1858 } |
| 1756 importCollector._addLibrary(library); | 1859 importCollector._addLibrary(library); |
| 1757 String prefix = importCollector._getPrefix(library); | 1860 String prefix = importCollector._getPrefix(library); |
| 1758 if (annotationNode.arguments != null) { | 1861 if (annotationNode.arguments != null) { |
| 1759 // A const constructor. | 1862 // A const constructor. |
| 1760 String constructor = (annotationNode.constructorName == null) | 1863 String constructor = (annotationNode.constructorName == null) |
| 1761 ? annotationNode.name | 1864 ? annotationNode.name |
| 1762 : "${annotationNode.name}.${annotationNode.constructorName}"; | 1865 : "${annotationNode.name}.${annotationNode.constructorName}"; |
| 1763 String arguments = annotationNode.arguments.arguments | 1866 String arguments = |
| 1764 .map((Expression argument) { | 1867 annotationNode.arguments.arguments.map((Expression argument) { |
| 1765 return _extractConstantCode( | 1868 return _extractConstantCode( |
| 1766 argument, element.library, resolver, importCollector); | 1869 argument, element.library, resolver, importCollector); |
| 1767 }).join(", "); | 1870 }).join(", "); |
| 1768 metadataParts.add("const $prefix.$constructor($arguments)"); | 1871 metadataParts.add("const $prefix.$constructor($arguments)"); |
| 1769 } else { | 1872 } else { |
| 1770 // A field reference. | 1873 // A field reference. |
| 1771 metadataParts.add("$prefix.${annotationNode.name}"); | 1874 metadataParts.add("$prefix.${annotationNode.name}"); |
| 1772 } | 1875 } |
| 1773 } | 1876 } |
| 1774 | 1877 |
| 1775 return _formatAsList(metadataParts); | 1878 return _formatAsList(metadataParts); |
| 1776 } | 1879 } |
| 1777 | 1880 |
| 1778 Iterable<FieldElement> _declaredFields( | 1881 Iterable<FieldElement> _extractDeclaredFields( |
| 1779 ClassElement classElement, _Capabilities capabilities) { | 1882 ClassElement classElement, _Capabilities capabilities) { |
| 1780 return classElement.fields.where((FieldElement field) { | 1883 return classElement.fields.where((FieldElement field) { |
| 1781 Function capabilityChecker = field.isStatic | 1884 Function capabilityChecker = field.isStatic |
| 1782 ? capabilities.supportsStaticInvoke | 1885 ? capabilities.supportsStaticInvoke |
| 1783 : capabilities.supportsInstanceInvoke; | 1886 : capabilities.supportsInstanceInvoke; |
| 1784 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); | 1887 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); |
| 1785 }); | 1888 }); |
| 1786 } | 1889 } |
| 1787 | 1890 |
| 1788 Iterable<MethodElement> _declaredMethods( | 1891 Iterable<MethodElement> _extractDeclaredMethods( |
| 1789 ClassElement classElement, _Capabilities capabilities) { | 1892 ClassElement classElement, _Capabilities capabilities) { |
| 1790 return classElement.methods.where((MethodElement method) { | 1893 return classElement.methods.where((MethodElement method) { |
| 1791 Function capabilityChecker = method.isStatic | 1894 Function capabilityChecker = method.isStatic |
| 1792 ? capabilities.supportsStaticInvoke | 1895 ? capabilities.supportsStaticInvoke |
| 1793 : capabilities.supportsInstanceInvoke; | 1896 : capabilities.supportsInstanceInvoke; |
| 1794 return capabilityChecker(method.name, method.metadata); | 1897 return capabilityChecker(method.name, method.metadata); |
| 1795 }); | 1898 }); |
| 1796 } | 1899 } |
| 1797 | 1900 |
| 1901 Iterable<ParameterElement> _extractDeclaredParameters( | |
| 1902 Iterable<MethodElement> declaredMethods) { | |
| 1903 List<ParameterElement> result = <ParameterElement>[]; | |
| 1904 for (MethodElement declaredMethod in declaredMethods) { | |
| 1905 result.addAll(declaredMethod.parameters); | |
| 1906 } | |
| 1907 return result; | |
| 1908 } | |
| 1909 | |
| 1798 /// Returns the [PropertyAccessorElement]s which are the accessors | 1910 /// Returns the [PropertyAccessorElement]s which are the accessors |
| 1799 /// of the given [classElement], including both the declared ones | 1911 /// of the given [classElement], including both the declared ones |
| 1800 /// and the implicitly generated ones corresponding to fields. This | 1912 /// and the implicitly generated ones corresponding to fields. This |
| 1801 /// is the set of accessors that corresponds to the behavioral interface | 1913 /// is the set of accessors that corresponds to the behavioral interface |
| 1802 /// of the corresponding instances, as opposed to the source code oriented | 1914 /// of the corresponding instances, as opposed to the source code oriented |
| 1803 /// interface, e.g., `declarations`. But the latter can be computed from | 1915 /// interface, e.g., `declarations`. But the latter can be computed from |
| 1804 /// here, by filtering out the accessors whose `isSynthetic` is true | 1916 /// here, by filtering out the accessors whose `isSynthetic` is true |
| 1805 /// and adding the fields. | 1917 /// and adding the fields. |
| 1806 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( | 1918 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( |
| 1807 ClassElement classElement, _Capabilities capabilities) { | 1919 ClassElement classElement, _Capabilities capabilities) { |
| 1808 return classElement.accessors.where((PropertyAccessorElement accessor) { | 1920 return classElement.accessors.where((PropertyAccessorElement accessor) { |
| 1809 Function capabilityChecker = accessor.isStatic | 1921 Function capabilityChecker = accessor.isStatic |
| 1810 ? capabilities.supportsStaticInvoke | 1922 ? capabilities.supportsStaticInvoke |
| 1811 : capabilities.supportsInstanceInvoke; | 1923 : capabilities.supportsInstanceInvoke; |
| 1812 return capabilityChecker(accessor.name, accessor.metadata); | 1924 return capabilityChecker(accessor.name, accessor.metadata); |
| 1813 }); | 1925 }); |
| 1814 } | 1926 } |
| 1815 | 1927 |
| 1816 Iterable<ConstructorElement> _declaredConstructors( | 1928 Iterable<ConstructorElement> _declaredConstructors( |
| 1817 ClassElement classElement, _Capabilities capabilities) { | 1929 ClassElement classElement, _Capabilities capabilities) { |
| 1818 return classElement.constructors.where((ConstructorElement constructor) { | 1930 return classElement.constructors.where((ConstructorElement constructor) { |
| 1819 return capabilities.supportsNewInstance( | 1931 return capabilities.supportsNewInstance( |
| 1820 constructor.name, constructor.metadata); | 1932 constructor.name, constructor.metadata); |
| 1821 }); | 1933 }); |
| 1822 } | 1934 } |
| 1823 | 1935 |
| 1824 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { | 1936 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { |
| 1825 List<FieldElement> declaredFieldsOfClass = | 1937 List<FieldElement> declaredFieldsOfClass = |
| 1826 _declaredFields(type, domain._capabilities).toList(); | 1938 _extractDeclaredFields(type, domain._capabilities).toList(); |
| 1827 List<MethodElement> declaredMethodsOfClass = | 1939 List<MethodElement> declaredMethodsOfClass = |
| 1828 _declaredMethods(type, domain._capabilities).toList(); | 1940 _extractDeclaredMethods(type, domain._capabilities).toList(); |
| 1941 List<ParameterElement> declaredParametersOfClass = | |
| 1942 _extractDeclaredParameters(declaredMethodsOfClass); | |
| 1829 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass = | 1943 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass = |
| 1830 _declaredAndImplicitAccessors(type, domain._capabilities).toList(); | 1944 _declaredAndImplicitAccessors(type, domain._capabilities).toList(); |
| 1831 List<ConstructorElement> declaredConstructorsOfClass = | 1945 List<ConstructorElement> declaredConstructorsOfClass = |
| 1832 _declaredConstructors(type, domain._capabilities).toList(); | 1946 _declaredConstructors(type, domain._capabilities).toList(); |
| 1833 return new _ClassDomain(type, declaredFieldsOfClass, declaredMethodsOfClass, | 1947 return new _ClassDomain( |
| 1834 declaredAndImplicitAccessorsOfClass, declaredConstructorsOfClass, domain); | 1948 type, |
| 1835 } | 1949 declaredFieldsOfClass, |
| 1950 declaredMethodsOfClass, | |
| 1951 declaredParametersOfClass, | |
| 1952 declaredAndImplicitAccessorsOfClass, | |
| 1953 declaredConstructorsOfClass, | |
| 1954 domain); | |
| 1955 } | |
| OLD | NEW |