| 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 'package:path/path.dart' as path; | 16 import 'package:path/path.dart' as path; |
| 16 import 'element_capability.dart' as ec; | 17 import 'element_capability.dart' as ec; |
| 17 import 'encoding_constants.dart' as constants; | 18 import 'encoding_constants.dart' as constants; |
| 18 import "reflectable_class_constants.dart" as reflectable_class_constants; | 19 import "reflectable_class_constants.dart" as reflectable_class_constants; |
| 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); |
| 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 metadataCode = _capabilities._supportsMetadata ? "<Object>[]" : "null"; |
| 489 // TODO(eernst) implement: Detect and, if possible, handle the case |
| 490 // where it is incorrect to move element.defaultValueCode out of its |
| 491 // original scope. If we cannot solve the problem we should issue |
| 492 // a warning (it's worse than `new UndefinedClass()`, because it |
| 493 // might "work" with a different semantics at runtime, rather than just |
| 494 // failing if ever executed). |
| 495 return 'new r.ParameterMirrorImpl(r"${element.name}", $descriptor, ' |
| 496 '$ownerIndex, ${_constConstructionCode(importCollector)}, ' |
| 497 '$metadataCode, ${element.defaultValueCode}, $classMirrorIndex)'; |
| 498 }); |
| 499 String parameterMirrorsCode = _formatAsList(parametersList); |
| 500 |
| 501 return "new r.ReflectorData($classMirrorsCode, $membersCode, " |
| 502 "$parameterMirrorsCode, $typesCode, $gettersCode, $settersCode)"; |
| 460 } | 503 } |
| 461 } | 504 } |
| 462 | 505 |
| 463 /// Information about reflectability for a given class. | 506 /// Information about reflectability for a given class. |
| 464 class _ClassDomain { | 507 class _ClassDomain { |
| 465 /// Element describing the target class. | 508 /// Element describing the target class. |
| 466 final ClassElement _classElement; | 509 final ClassElement _classElement; |
| 467 | 510 |
| 468 /// Fields declared by [classElement] and included for reflection support, | 511 /// Fields declared by [classElement] and included for reflection support, |
| 469 /// according to the reflector described by the [reflectorDomain]; | 512 /// according to the reflector described by the [reflectorDomain]; |
| 470 /// obtained by filtering `classElement.fields`. | 513 /// obtained by filtering `classElement.fields`. |
| 471 final Iterable<FieldElement> _declaredFields; | 514 final Iterable<FieldElement> _declaredFields; |
| 472 | 515 |
| 473 /// Methods which are declared by [classElement] and included for | 516 /// Methods which are declared by [classElement] and included for |
| 474 /// reflection support, according to the reflector described by | 517 /// reflection support, according to the reflector described by |
| 475 /// [reflectorDomain]; obtained by filtering `classElement.methods`. | 518 /// [reflectorDomain]; obtained by filtering `classElement.methods`. |
| 476 final Iterable<MethodElement> _declaredMethods; | 519 final Iterable<MethodElement> _declaredMethods; |
| 477 | 520 |
| 521 /// Formal parameters declared by one of the [_declaredMethods]. |
| 522 final Iterable<ParameterElement> _declaredParameters; |
| 523 |
| 478 /// Getters and setters possessed by [classElement] and included for | 524 /// Getters and setters possessed by [classElement] and included for |
| 479 /// reflection support, according to the reflector described by | 525 /// reflection support, according to the reflector described by |
| 480 /// [reflectorDomain]; obtained by filtering `classElement.accessors`. | 526 /// [reflectorDomain]; obtained by filtering `classElement.accessors`. |
| 481 /// Note that it includes declared as well as synthetic accessors, | 527 /// Note that it includes declared as well as synthetic accessors, |
| 482 /// implicitly created as getters/setters for fields. | 528 /// implicitly created as getters/setters for fields. |
| 483 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; | 529 final Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors; |
| 484 | 530 |
| 485 /// Constructors declared by [classElement] and included for reflection | 531 /// Constructors declared by [classElement] and included for reflection |
| 486 /// support, according to the reflector described by [reflectorDomain]; | 532 /// support, according to the reflector described by [reflectorDomain]; |
| 487 /// obtained by filtering `classElement.constructors`. | 533 /// obtained by filtering `classElement.constructors`. |
| 488 final Iterable<ConstructorElement> _constructors; | 534 final Iterable<ConstructorElement> _constructors; |
| 489 | 535 |
| 490 /// The reflector domain that holds [this] object as one of its | 536 /// The reflector domain that holds [this] object as one of its |
| 491 /// class domains. | 537 /// class domains. |
| 492 final _ReflectorDomain _reflectorDomain; | 538 final _ReflectorDomain _reflectorDomain; |
| 493 | 539 |
| 494 _ClassDomain(this._classElement, this._declaredFields, this._declaredMethods, | 540 _ClassDomain( |
| 495 this._declaredAndImplicitAccessors, this._constructors, | 541 this._classElement, |
| 542 this._declaredFields, |
| 543 this._declaredMethods, |
| 544 this._declaredParameters, |
| 545 this._declaredAndImplicitAccessors, |
| 546 this._constructors, |
| 496 this._reflectorDomain); | 547 this._reflectorDomain); |
| 497 | 548 |
| 498 String get _simpleName => _classElement.name; | 549 String get _simpleName => _classElement.name; |
| 499 String get _qualifiedName { | 550 String get _qualifiedName { |
| 500 return "${_classElement.library.name}.${_classElement.name}"; | 551 return "${_classElement.library.name}.${_classElement.name}"; |
| 501 } | 552 } |
| 502 | 553 |
| 503 /// Returns the declared methods, accessors and constructors in | 554 /// Returns the declared methods, accessors and constructors in |
| 504 /// [classElement]. Note that this includes synthetic getters and | 555 /// [classElement]. Note that this includes synthetic getters and |
| 505 /// setters, and omits fields; in other words, it provides the | 556 /// setters, and omits fields; in other words, it provides the |
| 506 /// behavioral point of view on the class. Also note that this is not | 557 /// behavioral point of view on the class. Also note that this is not |
| 507 /// the same semantics as that of `declarations` in [ClassMirror]. | 558 /// the same semantics as that of `declarations` in [ClassMirror]. |
| 508 Iterable<ExecutableElement> get _declarations { | 559 Iterable<ExecutableElement> get _declarations { |
| 509 // TODO(sigurdm) feature: Include type variables (if we keep them). | 560 // TODO(sigurdm) feature: Include type variables (if we keep them). |
| 510 return [ | 561 return [_declaredMethods, _declaredAndImplicitAccessors, _constructors] |
| 511 _declaredMethods, | 562 .expand((x) => x); |
| 512 _declaredAndImplicitAccessors, | |
| 513 _constructors | |
| 514 ].expand((x) => x); | |
| 515 } | 563 } |
| 516 | 564 |
| 517 /// Finds all instance members by going through the class hierarchy. | 565 /// Finds all instance members by going through the class hierarchy. |
| 518 Iterable<ExecutableElement> get _instanceMembers { | 566 Iterable<ExecutableElement> get _instanceMembers { |
| 519 Map<String, ExecutableElement> helper(ClassElement classElement) { | 567 Map<String, ExecutableElement> helper(ClassElement classElement) { |
| 520 if (_reflectorDomain._instanceMemberCache[classElement] != null) { | 568 if (_reflectorDomain._instanceMemberCache[classElement] != null) { |
| 521 return _reflectorDomain._instanceMemberCache[classElement]; | 569 return _reflectorDomain._instanceMemberCache[classElement]; |
| 522 } | 570 } |
| 523 Map<String, ExecutableElement> result = | 571 Map<String, ExecutableElement> result = |
| 524 new Map<String, ExecutableElement>(); | 572 new Map<String, ExecutableElement>(); |
| 525 | 573 |
| 526 void addIfCapable(ExecutableElement member) { | 574 void addIfCapable(ExecutableElement member) { |
| 575 if (member.isPrivate) return; |
| 527 // If [member] is a synthetic accessor created from a field, search for | 576 // If [member] is a synthetic accessor created from a field, search for |
| 528 // the metadata on the original field. | 577 // the metadata on the original field. |
| 529 List<ElementAnnotation> metadata = (member is PropertyAccessorElement && | 578 List<ElementAnnotation> metadata = (member is PropertyAccessorElement && |
| 530 member.isSynthetic) ? member.variable.metadata : member.metadata; | 579 member.isSynthetic) ? member.variable.metadata : member.metadata; |
| 531 if (_reflectorDomain._capabilities.supportsInstanceInvoke( | 580 if (_reflectorDomain._capabilities |
| 532 member.name, metadata)) { | 581 .supportsInstanceInvoke(member.name, metadata)) { |
| 533 result[member.name] = member; | 582 result[member.name] = member; |
| 534 } | 583 } |
| 535 } | 584 } |
| 536 if (classElement.supertype != null) { | 585 if (classElement.supertype != null) { |
| 537 helper(classElement.supertype.element) | 586 helper(classElement.supertype.element) |
| 538 .forEach((String name, ExecutableElement member) { | 587 .forEach((String name, ExecutableElement member) { |
| 539 addIfCapable(member); | 588 addIfCapable(member); |
| 540 }); | 589 }); |
| 541 } | 590 } |
| 542 for (InterfaceType mixin in classElement.mixins) { | 591 for (InterfaceType mixin in classElement.mixins) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 } | 786 } |
| 738 | 787 |
| 739 // Returns [true] iff these [Capabilities] specify reflection support where | 788 // Returns [true] iff these [Capabilities] specify reflection support where |
| 740 // the set of included classes must be upwards closed, i.e., extra classes | 789 // 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 | 790 // must be added beyond the ones that are directly included as reflectable |
| 742 // because we must support operations like `superclass`. | 791 // because we must support operations like `superclass`. |
| 743 bool get _impliesUpwardsClosure { | 792 bool get _impliesUpwardsClosure { |
| 744 return _capabilities.any((ec.ReflectCapability capability) => | 793 return _capabilities.any((ec.ReflectCapability capability) => |
| 745 capability == ec.typeRelationsCapability); | 794 capability == ec.typeRelationsCapability); |
| 746 } | 795 } |
| 796 |
| 797 bool get _impliesParameterTypes { |
| 798 bool haveDeclarations = |
| 799 _capabilities.any((ec.ReflectCapability capability) { |
| 800 return capability == ec.declarationsCapability; |
| 801 }); |
| 802 if (!haveDeclarations) return false; |
| 803 return _capabilities.any((ec.ReflectCapability capability) { |
| 804 return capability is ec.TypeCapability || |
| 805 capability is ec.TypingCapability; |
| 806 }); |
| 807 } |
| 747 } | 808 } |
| 748 | 809 |
| 749 /// Collects the libraries that needs to be imported, and gives each library | 810 /// Collects the libraries that needs to be imported, and gives each library |
| 750 /// a unique prefix. | 811 /// a unique prefix. |
| 751 class _ImportCollector { | 812 class _ImportCollector { |
| 752 Map<LibraryElement, String> _mapping = new Map<LibraryElement, String>(); | 813 Map<LibraryElement, String> _mapping = new Map<LibraryElement, String>(); |
| 753 int _count = 0; | 814 int _count = 0; |
| 754 | 815 |
| 755 /// Returns the prefix associated with [library]. | 816 /// Returns the prefix associated with [library]. |
| 756 String _getPrefix(LibraryElement library) { | 817 String _getPrefix(LibraryElement library) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } | 1043 } |
| 983 ClassElement reflector = | 1044 ClassElement reflector = |
| 984 value.fields["(super)"].fields["reflector"].type.element; | 1045 value.fields["(super)"].fields["reflector"].type.element; |
| 985 if (reflector == null || | 1046 if (reflector == null || |
| 986 reflector.type.element.supertype.element != | 1047 reflector.type.element.supertype.element != |
| 987 reflectableClass) { | 1048 reflectableClass) { |
| 988 String found = | 1049 String found = |
| 989 reflector == null ? "" : " Found ${reflector.name}"; | 1050 reflector == null ? "" : " Found ${reflector.name}"; |
| 990 _warn( | 1051 _warn( |
| 991 "The reflector must be a direct subclass of Reflectable." + | 1052 "The reflector must be a direct subclass of Reflectable." + |
| 992 found, import); | 1053 found, |
| 1054 import); |
| 993 continue; | 1055 continue; |
| 994 } | 1056 } |
| 995 globalPatterns | 1057 globalPatterns |
| 996 .putIfAbsent( | 1058 .putIfAbsent( |
| 997 new RegExp(pattern), () => new List<ClassElement>()) | 1059 new RegExp(pattern), () => new List<ClassElement>()) |
| 998 .add(reflector); | 1060 .add(reflector); |
| 999 } | 1061 } |
| 1000 } else if (metadatum.element == | 1062 } else if (metadatum.element == |
| 1001 globalQuantifyMetaCapabilityConstructor) { | 1063 globalQuantifyMetaCapabilityConstructor) { |
| 1002 EvaluationResultImpl evaluation = metadatum.evaluationResult; | 1064 EvaluationResultImpl evaluation = metadatum.evaluationResult; |
| 1003 if (evaluation != null && evaluation.value != null) { | 1065 if (evaluation != null && evaluation.value != null) { |
| 1004 DartObjectImpl value = evaluation.value; | 1066 DartObjectImpl value = evaluation.value; |
| 1005 Object metadataFieldValue = value.fields["metadataType"].value; | 1067 Object metadataFieldValue = value.fields["metadataType"].value; |
| 1006 if (metadataFieldValue == null || | 1068 if (metadataFieldValue == null || |
| 1007 value.fields["metadataType"].type.element != typeClass) { | 1069 value.fields["metadataType"].type.element != typeClass) { |
| 1008 // TODO(sigurdm) implement: Create a span for the annotation. | 1070 // TODO(sigurdm) implement: Create a span for the annotation. |
| 1009 _warn("The metadata must be a Type. " | 1071 _warn( |
| 1072 "The metadata must be a Type. " |
| 1010 "Found ${value.fields["metadataType"].type.element.name}", | 1073 "Found ${value.fields["metadataType"].type.element.name}", |
| 1011 import); | 1074 import); |
| 1012 continue; | 1075 continue; |
| 1013 } | 1076 } |
| 1014 ClassElement reflector = | 1077 ClassElement reflector = |
| 1015 value.fields["(super)"].fields["reflector"].type.element; | 1078 value.fields["(super)"].fields["reflector"].type.element; |
| 1016 if (reflector == null || | 1079 if (reflector == null || |
| 1017 reflector.type.element.supertype.element != | 1080 reflector.type.element.supertype.element != |
| 1018 reflectableClass) { | 1081 reflectableClass) { |
| 1019 String found = | 1082 String found = |
| 1020 reflector == null ? "" : " Found ${reflector.name}"; | 1083 reflector == null ? "" : " Found ${reflector.name}"; |
| 1021 _warn( | 1084 _warn( |
| 1022 "The reflector must be a direct subclass of Reflectable." + | 1085 "The reflector must be a direct subclass of Reflectable." + |
| 1023 found, import); | 1086 found, |
| 1087 import); |
| 1024 continue; | 1088 continue; |
| 1025 } | 1089 } |
| 1026 globalMetadata | 1090 globalMetadata |
| 1027 .putIfAbsent( | 1091 .putIfAbsent( |
| 1028 metadataFieldValue, () => new List<ClassElement>()) | 1092 metadataFieldValue, () => new List<ClassElement>()) |
| 1029 .add(reflector); | 1093 .add(reflector); |
| 1030 } | 1094 } |
| 1031 } | 1095 } |
| 1032 } | 1096 } |
| 1033 } | 1097 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 // Add the class if it is annotated by a reflector. | 1158 // Add the class if it is annotated by a reflector. |
| 1095 ClassElement reflector = | 1159 ClassElement reflector = |
| 1096 _getReflectableAnnotation(metadatum, focusClass); | 1160 _getReflectableAnnotation(metadatum, focusClass); |
| 1097 if (reflector != null) { | 1161 if (reflector != null) { |
| 1098 addClassDomain(type, reflector); | 1162 addClassDomain(type, reflector); |
| 1099 } | 1163 } |
| 1100 } | 1164 } |
| 1101 // Add the class to the domain of all reflectors associated with a | 1165 // Add the class to the domain of all reflectors associated with a |
| 1102 // pattern, via GlobalQuantifyCapability, that matches the qualified | 1166 // pattern, via GlobalQuantifyCapability, that matches the qualified |
| 1103 // name of the class. | 1167 // name of the class. |
| 1104 globalPatterns | 1168 globalPatterns.forEach( |
| 1105 .forEach((RegExp pattern, List<ClassElement> reflectors) { | 1169 (RegExp pattern, List<ClassElement> reflectors) { |
| 1106 String qualifiedName = "${type.library.name}.${type.name}"; | 1170 String qualifiedName = "${type.library.name}.${type.name}"; |
| 1107 if (pattern.hasMatch(qualifiedName)) { | 1171 if (pattern.hasMatch(qualifiedName)) { |
| 1108 for (ClassElement reflector in reflectors) { | 1172 for (ClassElement reflector in reflectors) { |
| 1109 addClassDomain(type, reflector); | 1173 addClassDomain(type, reflector); |
| 1110 } | 1174 } |
| 1111 } | 1175 } |
| 1112 }); | 1176 }); |
| 1113 } | 1177 } |
| 1114 } | 1178 } |
| 1115 } | 1179 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1126 void _collectMissingImports(_ReflectorDomain domain) { | 1190 void _collectMissingImports(_ReflectorDomain domain) { |
| 1127 LibraryElement metadataLibrary = domain._reflector.library; | 1191 LibraryElement metadataLibrary = domain._reflector.library; |
| 1128 for (_ClassDomain classData in domain._annotatedClasses) { | 1192 for (_ClassDomain classData in domain._annotatedClasses) { |
| 1129 LibraryElement annotatedLibrary = classData._classElement.library; | 1193 LibraryElement annotatedLibrary = classData._classElement.library; |
| 1130 if (metadataLibrary != annotatedLibrary) { | 1194 if (metadataLibrary != annotatedLibrary) { |
| 1131 domain._missingImports.add(annotatedLibrary); | 1195 domain._missingImports.add(annotatedLibrary); |
| 1132 } | 1196 } |
| 1133 } | 1197 } |
| 1134 } | 1198 } |
| 1135 | 1199 |
| 1136 ImportElement _findLastImport(LibraryElement library) { | |
| 1137 if (library.imports.isNotEmpty) { | |
| 1138 ImportElement importElement = library.imports.lastWhere( | |
| 1139 (importElement) => importElement.node != null, orElse: () => null); | |
| 1140 if (importElement != null) { | |
| 1141 // Found an import element with a node (i.e., a non-synthetic one). | |
| 1142 return importElement; | |
| 1143 } else { | |
| 1144 // No non-synthetic imports. | |
| 1145 return null; | |
| 1146 } | |
| 1147 } | |
| 1148 // library.imports.isEmpty | |
| 1149 return null; | |
| 1150 } | |
| 1151 | |
| 1152 ExportElement _findFirstExport(LibraryElement library) { | |
| 1153 if (library.exports.isNotEmpty) { | |
| 1154 ExportElement exportElement = library.exports.firstWhere( | |
| 1155 (exportElement) => exportElement.node != null, orElse: () => null); | |
| 1156 if (exportElement != null) { | |
| 1157 // Found an export element with a node (i.e., a non-synthetic one) | |
| 1158 return exportElement; | |
| 1159 } else { | |
| 1160 // No non-synthetic exports. | |
| 1161 return null; | |
| 1162 } | |
| 1163 } | |
| 1164 // library.exports.isEmpty | |
| 1165 return null; | |
| 1166 } | |
| 1167 | |
| 1168 /// Find a suitable index for insertion of additional import directives | |
| 1169 /// into [targetLibrary]. | |
| 1170 int _newImportIndex(LibraryElement targetLibrary) { | |
| 1171 // Index in [source] where the new import directive is inserted, we | |
| 1172 // use 0 as the default placement (at the front of the file), but | |
| 1173 // make a heroic attempt to find a better placement first. | |
| 1174 int index = 0; | |
| 1175 ImportElement importElement = _findLastImport(targetLibrary); | |
| 1176 if (importElement != null) { | |
| 1177 index = importElement.node.end; | |
| 1178 } else { | |
| 1179 // No non-synthetic import directives present. | |
| 1180 ExportElement exportElement = _findFirstExport(targetLibrary); | |
| 1181 if (exportElement != null) { | |
| 1182 // Put the new import before the exports | |
| 1183 index = exportElement.node.offset; | |
| 1184 } else { | |
| 1185 // No non-synthetic import nor export directives present. | |
| 1186 CompilationUnit compilationUnitNode = | |
| 1187 targetLibrary.definingCompilationUnit.node; | |
| 1188 LibraryDirective libraryDirective = compilationUnitNode.directives | |
| 1189 .firstWhere((directive) => directive is LibraryDirective, | |
| 1190 orElse: () => null); | |
| 1191 if (libraryDirective != null) { | |
| 1192 // Put the new import after the library name directive. | |
| 1193 index = libraryDirective.end; | |
| 1194 } else { | |
| 1195 // No library directive either, keep index == 0. | |
| 1196 } | |
| 1197 } | |
| 1198 } | |
| 1199 return index; | |
| 1200 } | |
| 1201 | |
| 1202 /// Returns the [ReflectCapability] denoted by the given [initializer]. | 1200 /// Returns the [ReflectCapability] denoted by the given [initializer]. |
| 1203 ec.ReflectCapability _capabilityOfExpression(LibraryElement capabilityLibrary, | 1201 ec.ReflectCapability _capabilityOfExpression(LibraryElement capabilityLibrary, |
| 1204 Expression expression, LibraryElement containingLibrary) { | 1202 Expression expression, LibraryElement containingLibrary) { |
| 1205 EvaluationResult evaluated = | 1203 EvaluationResult evaluated = |
| 1206 _resolver.evaluateConstant(containingLibrary, expression); | 1204 _resolver.evaluateConstant(containingLibrary, expression); |
| 1207 | 1205 |
| 1208 if (!evaluated.isValid) { | 1206 if (!evaluated.isValid) { |
| 1209 _logger.error("Invalid constant $expression in capability-list."); | 1207 _logger.error("Invalid constant $expression in capability-list."); |
| 1210 } | 1208 } |
| 1211 | 1209 |
| 1212 DartObjectImpl constant = evaluated.value; | 1210 DartObjectImpl constant = evaluated.value; |
| 1213 | 1211 |
| 1214 ParameterizedType dartType = constant.type; | 1212 ParameterizedType dartType = constant.type; |
| 1215 // We insist that the type must be a class, and we insist that it must | 1213 // 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 | 1214 // be in the given `capabilityLibrary` (because we could never know |
| 1217 // how to interpret the meaning of a user-written capability class, so | 1215 // how to interpret the meaning of a user-written capability class, so |
| 1218 // users cannot write their own capability classes). | 1216 // users cannot write their own capability classes). |
| 1219 if (dartType.element is! ClassElement) { | 1217 if (dartType.element is! ClassElement) { |
| 1220 if (dartType.element.source != null) { | 1218 if (dartType.element.source != null) { |
| 1221 _logger.error(errors.applyTemplate(errors.SUPER_ARGUMENT_NON_CLASS, { | 1219 _logger.error( |
| 1222 "type": dartType.displayName | 1220 errors.applyTemplate(errors.SUPER_ARGUMENT_NON_CLASS, |
| 1223 }), span: _resolver.getSourceSpan(dartType.element)); | 1221 {"type": dartType.displayName}), |
| 1222 span: _resolver.getSourceSpan(dartType.element)); |
| 1224 } else { | 1223 } else { |
| 1225 _logger.error(errors.applyTemplate( | 1224 _logger.error(errors.applyTemplate( |
| 1226 errors.SUPER_ARGUMENT_NON_CLASS, {"type": dartType.displayName})); | 1225 errors.SUPER_ARGUMENT_NON_CLASS, {"type": dartType.displayName})); |
| 1227 } | 1226 } |
| 1228 } | 1227 } |
| 1229 ClassElement classElement = dartType.element; | 1228 ClassElement classElement = dartType.element; |
| 1230 if (classElement.library != capabilityLibrary) { | 1229 if (classElement.library != capabilityLibrary) { |
| 1231 _logger.error(errors.applyTemplate(errors.SUPER_ARGUMENT_WRONG_LIBRARY, { | 1230 _logger.error( |
| 1232 "library": capabilityLibrary, | 1231 errors.applyTemplate(errors.SUPER_ARGUMENT_WRONG_LIBRARY, |
| 1233 "element": classElement | 1232 {"library": capabilityLibrary, "element": classElement}), |
| 1234 }), span: _resolver.getSourceSpan(classElement)); | 1233 span: _resolver.getSourceSpan(classElement)); |
| 1235 } | 1234 } |
| 1236 | 1235 |
| 1237 /// Extracts the namePattern String from an instance of a subclass of | 1236 /// Extracts the namePattern String from an instance of a subclass of |
| 1238 /// NamePatternCapability. | 1237 /// NamePatternCapability. |
| 1239 String extractNamePattern(DartObjectImpl constant) { | 1238 String extractNamePattern(DartObjectImpl constant) { |
| 1240 if (constant.fields == null || | 1239 if (constant.fields == null || |
| 1241 constant.fields["(super)"] == null || | 1240 constant.fields["(super)"] == null || |
| 1242 constant.fields["(super)"].fields["namePattern"] == null || | 1241 constant.fields["(super)"].fields["namePattern"] == null || |
| 1243 constant.fields["(super)"].fields["namePattern"].stringValue == | 1242 constant.fields["(super)"].fields["namePattern"].stringValue == |
| 1244 null) { | 1243 null) { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 List<String> imports = new List<String>(); | 1392 List<String> imports = new List<String>(); |
| 1394 world.importCollector._libraries.forEach((LibraryElement library) { | 1393 world.importCollector._libraries.forEach((LibraryElement library) { |
| 1395 Uri uri = _resolver.getImportUri(library, from: generatedId); | 1394 Uri uri = _resolver.getImportUri(library, from: generatedId); |
| 1396 String prefix = world.importCollector._getPrefix(library); | 1395 String prefix = world.importCollector._getPrefix(library); |
| 1397 imports.add("import '$uri' as $prefix;"); | 1396 imports.add("import '$uri' as $prefix;"); |
| 1398 }); | 1397 }); |
| 1399 imports.sort(); | 1398 imports.sort(); |
| 1400 | 1399 |
| 1401 String args = | 1400 String args = |
| 1402 (entryPointLibrary.entryPoint.parameters.length == 0) ? "" : "args"; | 1401 (entryPointLibrary.entryPoint.parameters.length == 0) ? "" : "args"; |
| 1403 StringBuffer buffer = new StringBuffer(); | |
| 1404 return """ | 1402 return """ |
| 1405 // This file has been generated by the reflectable package. | 1403 // This file has been generated by the reflectable package. |
| 1406 // https://github.com/dart-lang/reflectable. | 1404 // https://github.com/dart-lang/reflectable. |
| 1407 | 1405 |
| 1408 library reflectable_generated_main_library; | 1406 library reflectable_generated_main_library; |
| 1409 | 1407 |
| 1410 import "dart:core"; | 1408 import "dart:core"; |
| 1411 import "$originalEntryPointFilename" as original show main; | 1409 import "$originalEntryPointFilename" as original show main; |
| 1412 ${imports.join('\n')} | 1410 ${imports.join('\n')} |
| 1413 | 1411 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 /// which case we can drop this class and use that method. | 1512 /// which case we can drop this class and use that method. |
| 1515 class _AggregateTransformWrapper implements Transform { | 1513 class _AggregateTransformWrapper implements Transform { |
| 1516 final AggregateTransform _aggregateTransform; | 1514 final AggregateTransform _aggregateTransform; |
| 1517 final Asset primaryInput; | 1515 final Asset primaryInput; |
| 1518 _AggregateTransformWrapper(this._aggregateTransform, this.primaryInput); | 1516 _AggregateTransformWrapper(this._aggregateTransform, this.primaryInput); |
| 1519 TransformLogger get logger => _aggregateTransform.logger; | 1517 TransformLogger get logger => _aggregateTransform.logger; |
| 1520 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1518 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
| 1521 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1519 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
| 1522 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1520 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
| 1523 } | 1521 } |
| 1522 |
| 1524 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1523 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
| 1525 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1524 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
| 1526 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1525 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
| 1527 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1526 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
| 1528 } | 1527 } |
| 1529 | 1528 |
| 1530 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { | 1529 bool _accessorIsntImplicitGetterOrSetter(PropertyAccessorElement accessor) { |
| 1531 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); | 1530 return !accessor.isSynthetic || (!accessor.isGetter && !accessor.isSetter); |
| 1532 } | 1531 } |
| 1533 | 1532 |
| 1534 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { | 1533 bool _executableIsntImplicitGetterOrSetter(ExecutableElement executable) { |
| 1535 return executable is! PropertyAccessorElement || | 1534 return executable is! PropertyAccessorElement || |
| 1536 _accessorIsntImplicitGetterOrSetter(executable); | 1535 _accessorIsntImplicitGetterOrSetter(executable); |
| 1537 } | 1536 } |
| 1538 | 1537 |
| 1539 /// Returns an integer encoding of the kind and attributes of the given | 1538 /// Returns an integer encoding of the kind and attributes of the given |
| 1540 /// field. | 1539 /// field. |
| 1541 int _fieldDescriptor(FieldElement element) { | 1540 int _fieldDescriptor(FieldElement element) { |
| 1542 int result = constants.field; | 1541 int result = constants.field; |
| 1543 if (element.isPrivate) result |= constants.privateAttribute; | 1542 if (element.isPrivate) result |= constants.privateAttribute; |
| 1544 if (element.isSynthetic) result |= constants.syntheticAttribute; | 1543 if (element.isSynthetic) result |= constants.syntheticAttribute; |
| 1545 if (element.isConst) result |= constants.constAttribute; | 1544 if (element.isConst) result |= constants.constAttribute; |
| 1546 if (element.isFinal) result |= constants.finalAttribute; | 1545 if (element.isFinal) result |= constants.finalAttribute; |
| 1547 if (element.isStatic) result |= constants.staticAttribute; | 1546 if (element.isStatic) result |= constants.staticAttribute; |
| 1548 return result; | 1547 return result; |
| 1549 } | 1548 } |
| 1550 | 1549 |
| 1551 /// Returns an integer encoding of the kind and attributes of the given | 1550 /// Returns an integer encoding of the kind and attributes of the given |
| 1551 /// parameter. |
| 1552 int _parameterDescriptor(ParameterElement element) { |
| 1553 int result = constants.parameter; |
| 1554 if (element.isPrivate) result |= constants.privateAttribute; |
| 1555 if (element.isSynthetic) result |= constants.syntheticAttribute; |
| 1556 if (element.isConst) result |= constants.constAttribute; |
| 1557 if (element.isFinal) result |= constants.finalAttribute; |
| 1558 if (element.defaultValueCode != null) { |
| 1559 result |= constants.hasDefaultValueAttribute; |
| 1560 } |
| 1561 if (element.parameterKind.isOptional) { |
| 1562 result |= constants.optionalAttribute; |
| 1563 } |
| 1564 if (element.parameterKind == ParameterKind.NAMED) { |
| 1565 result |= constants.namedAttribute; |
| 1566 } |
| 1567 if (element.type.isDynamic) { |
| 1568 result |= constants.dynamicAttribute; |
| 1569 } |
| 1570 Element elementType = element.type.element; |
| 1571 if (elementType is ClassElement) { |
| 1572 result |= constants.classTypeAttribute; |
| 1573 } |
| 1574 return result; |
| 1575 } |
| 1576 |
| 1577 /// Returns an integer encoding of the kind and attributes of the given |
| 1552 /// method/constructor/getter/setter. | 1578 /// method/constructor/getter/setter. |
| 1553 int _declarationDescriptor(ExecutableElement element) { | 1579 int _declarationDescriptor(ExecutableElement element) { |
| 1554 int result; | 1580 int result; |
| 1555 if (element is PropertyAccessorElement) { | 1581 if (element is PropertyAccessorElement) { |
| 1556 result = element.isGetter ? constants.getter : constants.setter; | 1582 result = element.isGetter ? constants.getter : constants.setter; |
| 1557 } else if (element is ConstructorElement) { | 1583 } else if (element is ConstructorElement) { |
| 1558 if (element.isFactory) { | 1584 if (element.isFactory) { |
| 1559 result = constants.factoryConstructor; | 1585 result = constants.factoryConstructor; |
| 1560 } else { | 1586 } else { |
| 1561 result = constants.generativeConstructor; | 1587 result = constants.generativeConstructor; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1581 : "${element.enclosingElement.name}.${element.name}"; | 1607 : "${element.enclosingElement.name}.${element.name}"; |
| 1582 } | 1608 } |
| 1583 return element.name; | 1609 return element.name; |
| 1584 } | 1610 } |
| 1585 | 1611 |
| 1586 String _formatAsList(Iterable parts) => "[${parts.join(", ")}]"; | 1612 String _formatAsList(Iterable parts) => "[${parts.join(", ")}]"; |
| 1587 | 1613 |
| 1588 String _formatAsMap(Iterable parts) => "{${parts.join(", ")}}"; | 1614 String _formatAsMap(Iterable parts) => "{${parts.join(", ")}}"; |
| 1589 | 1615 |
| 1590 /// Returns code that will reproduce the given constant expression. | 1616 /// Returns code that will reproduce the given constant expression. |
| 1591 String _extractConstantCode(Expression expression, | 1617 String _extractConstantCode( |
| 1592 LibraryElement originatingLibrary, Resolver resolver, | 1618 Expression expression, |
| 1619 LibraryElement originatingLibrary, |
| 1620 Resolver resolver, |
| 1593 _ImportCollector importCollector) { | 1621 _ImportCollector importCollector) { |
| 1594 if (expression is ListLiteral) { | 1622 if (expression is ListLiteral) { |
| 1595 List<String> elements = expression.elements.map((Expression subExpression) { | 1623 List<String> elements = expression.elements.map((Expression subExpression) { |
| 1596 return _extractConstantCode( | 1624 return _extractConstantCode( |
| 1597 subExpression, originatingLibrary, resolver, importCollector); | 1625 subExpression, originatingLibrary, resolver, importCollector); |
| 1598 }); | 1626 }); |
| 1599 // TODO(sigurdm) feature: Type arguments. | 1627 // TODO(sigurdm) feature: Type arguments. |
| 1600 return "const ${_formatAsList(elements)}"; | 1628 return "const ${_formatAsList(elements)}"; |
| 1601 } else if (expression is MapLiteral) { | 1629 } else if (expression is MapLiteral) { |
| 1602 List<String> elements = expression.entries.map((MapLiteralEntry entry) { | 1630 List<String> elements = expression.entries.map((MapLiteralEntry entry) { |
| 1603 String key = _extractConstantCode( | 1631 String key = _extractConstantCode( |
| 1604 entry.key, originatingLibrary, resolver, importCollector); | 1632 entry.key, originatingLibrary, resolver, importCollector); |
| 1605 String value = _extractConstantCode( | 1633 String value = _extractConstantCode( |
| 1606 entry.value, originatingLibrary, resolver, importCollector); | 1634 entry.value, originatingLibrary, resolver, importCollector); |
| 1607 return "$key: $value"; | 1635 return "$key: $value"; |
| 1608 }); | 1636 }); |
| 1609 // TODO(sigurdm) feature: Type arguments. | 1637 // TODO(sigurdm) feature: Type arguments. |
| 1610 return "const ${_formatAsMap(elements)}"; | 1638 return "const ${_formatAsMap(elements)}"; |
| 1611 } else if (expression is InstanceCreationExpression) { | 1639 } else if (expression is InstanceCreationExpression) { |
| 1612 String constructor = expression.constructorName.toSource(); | 1640 String constructor = expression.constructorName.toSource(); |
| 1613 LibraryElement libraryOfConstructor = expression.staticElement.library; | 1641 LibraryElement libraryOfConstructor = expression.staticElement.library; |
| 1614 importCollector._addLibrary(libraryOfConstructor); | 1642 importCollector._addLibrary(libraryOfConstructor); |
| 1615 String prefix = | 1643 String prefix = |
| 1616 importCollector._getPrefix(expression.staticElement.library); | 1644 importCollector._getPrefix(expression.staticElement.library); |
| 1617 // TODO(sigurdm) implement: Named arguments. | 1645 // TODO(sigurdm) implement: Named arguments. |
| 1618 String arguments = expression.argumentList.arguments | 1646 String arguments = |
| 1619 .map((Expression argument) { | 1647 expression.argumentList.arguments.map((Expression argument) { |
| 1620 return _extractConstantCode( | 1648 return _extractConstantCode( |
| 1621 argument, originatingLibrary, resolver, importCollector); | 1649 argument, originatingLibrary, resolver, importCollector); |
| 1622 }).join(", "); | 1650 }).join(", "); |
| 1623 // TODO(sigurdm) feature: Type arguments. | 1651 // TODO(sigurdm) feature: Type arguments. |
| 1624 return "const $prefix.$constructor($arguments)"; | 1652 return "const $prefix.$constructor($arguments)"; |
| 1625 } else if (expression is Identifier) { | 1653 } else if (expression is Identifier) { |
| 1626 Element element = expression.staticElement; | 1654 Element element = expression.staticElement; |
| 1627 importCollector._addLibrary(element.library); | 1655 importCollector._addLibrary(element.library); |
| 1628 String prefix = importCollector._getPrefix(element.library); | 1656 String prefix = importCollector._getPrefix(element.library); |
| 1629 Element enclosingElement = element.enclosingElement; | 1657 Element enclosingElement = element.enclosingElement; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1753 span: resolver.getSourceSpan(element)); | 1781 span: resolver.getSourceSpan(element)); |
| 1754 continue; | 1782 continue; |
| 1755 } | 1783 } |
| 1756 importCollector._addLibrary(library); | 1784 importCollector._addLibrary(library); |
| 1757 String prefix = importCollector._getPrefix(library); | 1785 String prefix = importCollector._getPrefix(library); |
| 1758 if (annotationNode.arguments != null) { | 1786 if (annotationNode.arguments != null) { |
| 1759 // A const constructor. | 1787 // A const constructor. |
| 1760 String constructor = (annotationNode.constructorName == null) | 1788 String constructor = (annotationNode.constructorName == null) |
| 1761 ? annotationNode.name | 1789 ? annotationNode.name |
| 1762 : "${annotationNode.name}.${annotationNode.constructorName}"; | 1790 : "${annotationNode.name}.${annotationNode.constructorName}"; |
| 1763 String arguments = annotationNode.arguments.arguments | 1791 String arguments = |
| 1764 .map((Expression argument) { | 1792 annotationNode.arguments.arguments.map((Expression argument) { |
| 1765 return _extractConstantCode( | 1793 return _extractConstantCode( |
| 1766 argument, element.library, resolver, importCollector); | 1794 argument, element.library, resolver, importCollector); |
| 1767 }).join(", "); | 1795 }).join(", "); |
| 1768 metadataParts.add("const $prefix.$constructor($arguments)"); | 1796 metadataParts.add("const $prefix.$constructor($arguments)"); |
| 1769 } else { | 1797 } else { |
| 1770 // A field reference. | 1798 // A field reference. |
| 1771 metadataParts.add("$prefix.${annotationNode.name}"); | 1799 metadataParts.add("$prefix.${annotationNode.name}"); |
| 1772 } | 1800 } |
| 1773 } | 1801 } |
| 1774 | 1802 |
| 1775 return _formatAsList(metadataParts); | 1803 return _formatAsList(metadataParts); |
| 1776 } | 1804 } |
| 1777 | 1805 |
| 1778 Iterable<FieldElement> _declaredFields( | 1806 Iterable<FieldElement> _extractDeclaredFields( |
| 1779 ClassElement classElement, _Capabilities capabilities) { | 1807 ClassElement classElement, _Capabilities capabilities) { |
| 1780 return classElement.fields.where((FieldElement field) { | 1808 return classElement.fields.where((FieldElement field) { |
| 1809 if (field.isPrivate) return false; |
| 1781 Function capabilityChecker = field.isStatic | 1810 Function capabilityChecker = field.isStatic |
| 1782 ? capabilities.supportsStaticInvoke | 1811 ? capabilities.supportsStaticInvoke |
| 1783 : capabilities.supportsInstanceInvoke; | 1812 : capabilities.supportsInstanceInvoke; |
| 1784 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); | 1813 return !field.isSynthetic && capabilityChecker(field.name, field.metadata); |
| 1785 }); | 1814 }); |
| 1786 } | 1815 } |
| 1787 | 1816 |
| 1788 Iterable<MethodElement> _declaredMethods( | 1817 Iterable<MethodElement> _extractDeclaredMethods( |
| 1789 ClassElement classElement, _Capabilities capabilities) { | 1818 ClassElement classElement, _Capabilities capabilities) { |
| 1790 return classElement.methods.where((MethodElement method) { | 1819 return classElement.methods.where((MethodElement method) { |
| 1820 if (method.isPrivate) return false; |
| 1791 Function capabilityChecker = method.isStatic | 1821 Function capabilityChecker = method.isStatic |
| 1792 ? capabilities.supportsStaticInvoke | 1822 ? capabilities.supportsStaticInvoke |
| 1793 : capabilities.supportsInstanceInvoke; | 1823 : capabilities.supportsInstanceInvoke; |
| 1794 return capabilityChecker(method.name, method.metadata); | 1824 return capabilityChecker(method.name, method.metadata); |
| 1795 }); | 1825 }); |
| 1796 } | 1826 } |
| 1797 | 1827 |
| 1828 Iterable<ParameterElement> _extractDeclaredParameters( |
| 1829 Iterable<MethodElement> declaredMethods) { |
| 1830 List<ParameterElement> result = <ParameterElement>[]; |
| 1831 for (MethodElement declaredMethod in declaredMethods) { |
| 1832 result.addAll(declaredMethod.parameters); |
| 1833 } |
| 1834 return result; |
| 1835 } |
| 1836 |
| 1798 /// Returns the [PropertyAccessorElement]s which are the accessors | 1837 /// Returns the [PropertyAccessorElement]s which are the accessors |
| 1799 /// of the given [classElement], including both the declared ones | 1838 /// of the given [classElement], including both the declared ones |
| 1800 /// and the implicitly generated ones corresponding to fields. This | 1839 /// and the implicitly generated ones corresponding to fields. This |
| 1801 /// is the set of accessors that corresponds to the behavioral interface | 1840 /// is the set of accessors that corresponds to the behavioral interface |
| 1802 /// of the corresponding instances, as opposed to the source code oriented | 1841 /// of the corresponding instances, as opposed to the source code oriented |
| 1803 /// interface, e.g., `declarations`. But the latter can be computed from | 1842 /// interface, e.g., `declarations`. But the latter can be computed from |
| 1804 /// here, by filtering out the accessors whose `isSynthetic` is true | 1843 /// here, by filtering out the accessors whose `isSynthetic` is true |
| 1805 /// and adding the fields. | 1844 /// and adding the fields. |
| 1806 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( | 1845 Iterable<PropertyAccessorElement> _declaredAndImplicitAccessors( |
| 1807 ClassElement classElement, _Capabilities capabilities) { | 1846 ClassElement classElement, _Capabilities capabilities) { |
| 1808 return classElement.accessors.where((PropertyAccessorElement accessor) { | 1847 return classElement.accessors.where((PropertyAccessorElement accessor) { |
| 1848 if (accessor.isPrivate) return false; |
| 1809 Function capabilityChecker = accessor.isStatic | 1849 Function capabilityChecker = accessor.isStatic |
| 1810 ? capabilities.supportsStaticInvoke | 1850 ? capabilities.supportsStaticInvoke |
| 1811 : capabilities.supportsInstanceInvoke; | 1851 : capabilities.supportsInstanceInvoke; |
| 1812 return capabilityChecker(accessor.name, accessor.metadata); | 1852 return capabilityChecker(accessor.name, accessor.metadata); |
| 1813 }); | 1853 }); |
| 1814 } | 1854 } |
| 1815 | 1855 |
| 1816 Iterable<ConstructorElement> _declaredConstructors( | 1856 Iterable<ConstructorElement> _declaredConstructors( |
| 1817 ClassElement classElement, _Capabilities capabilities) { | 1857 ClassElement classElement, _Capabilities capabilities) { |
| 1818 return classElement.constructors.where((ConstructorElement constructor) { | 1858 return classElement.constructors.where((ConstructorElement constructor) { |
| 1859 if (constructor.isPrivate) return false; |
| 1819 return capabilities.supportsNewInstance( | 1860 return capabilities.supportsNewInstance( |
| 1820 constructor.name, constructor.metadata); | 1861 constructor.name, constructor.metadata); |
| 1821 }); | 1862 }); |
| 1822 } | 1863 } |
| 1823 | 1864 |
| 1824 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { | 1865 _ClassDomain _createClassDomain(ClassElement type, _ReflectorDomain domain) { |
| 1825 List<FieldElement> declaredFieldsOfClass = | 1866 List<FieldElement> declaredFieldsOfClass = |
| 1826 _declaredFields(type, domain._capabilities).toList(); | 1867 _extractDeclaredFields(type, domain._capabilities).toList(); |
| 1827 List<MethodElement> declaredMethodsOfClass = | 1868 List<MethodElement> declaredMethodsOfClass = |
| 1828 _declaredMethods(type, domain._capabilities).toList(); | 1869 _extractDeclaredMethods(type, domain._capabilities).toList(); |
| 1870 List<ParameterElement> declaredParametersOfClass = |
| 1871 _extractDeclaredParameters(declaredMethodsOfClass); |
| 1829 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass = | 1872 List<PropertyAccessorElement> declaredAndImplicitAccessorsOfClass = |
| 1830 _declaredAndImplicitAccessors(type, domain._capabilities).toList(); | 1873 _declaredAndImplicitAccessors(type, domain._capabilities).toList(); |
| 1831 List<ConstructorElement> declaredConstructorsOfClass = | 1874 List<ConstructorElement> declaredConstructorsOfClass = |
| 1832 _declaredConstructors(type, domain._capabilities).toList(); | 1875 _declaredConstructors(type, domain._capabilities).toList(); |
| 1833 return new _ClassDomain(type, declaredFieldsOfClass, declaredMethodsOfClass, | 1876 return new _ClassDomain( |
| 1834 declaredAndImplicitAccessorsOfClass, declaredConstructorsOfClass, domain); | 1877 type, |
| 1835 } | 1878 declaredFieldsOfClass, |
| 1879 declaredMethodsOfClass, |
| 1880 declaredParametersOfClass, |
| 1881 declaredAndImplicitAccessorsOfClass, |
| 1882 declaredConstructorsOfClass, |
| 1883 domain); |
| 1884 } |
| OLD | NEW |