| 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 'dart:math' show max; | 10 import 'dart:math' show max; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 annotatedClasses | 61 annotatedClasses |
| 62 .forEach((ClassDomain classDomain) => classDomain.computeNames(namer)); | 62 .forEach((ClassDomain classDomain) => classDomain.computeNames(namer)); |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 | 65 |
| 66 /// Information about reflectability for a given class. | 66 /// Information about reflectability for a given class. |
| 67 class ClassDomain { | 67 class ClassDomain { |
| 68 final ClassElement classElement; | 68 final ClassElement classElement; |
| 69 final Iterable<MethodElement> invokableMethods; | 69 final Iterable<MethodElement> invokableMethods; |
| 70 final Iterable<MethodElement> declaredMethods; | 70 final Iterable<MethodElement> declaredMethods; |
| 71 final Iterable<PropertyAccessorElement> declaredAccessors; |
| 72 final Iterable<ConstructorElement> constructors; |
| 71 | 73 |
| 72 ReflectorDomain reflectorDomain; | 74 ReflectorDomain reflectorDomain; |
| 73 String staticClassMirrorName; | 75 String staticClassMirrorName; |
| 74 String staticInstanceMirrorName; | 76 String staticInstanceMirrorName; |
| 75 String get baseName => classElement.name; | 77 String get baseName => classElement.name; |
| 76 | 78 |
| 77 ClassDomain(this.classElement, this.invokableMethods, this.declaredMethods, | 79 ClassDomain(this.classElement, this.invokableMethods, this.declaredMethods, |
| 78 this.reflectorDomain); | 80 this.declaredAccessors, this.constructors, this.reflectorDomain); |
| 79 | 81 |
| 80 Iterable<ExecutableElement> get declarations { | 82 Iterable<ExecutableElement> get declarations { |
| 81 // TODO(sigurdm): Include constructors. | |
| 82 // TODO(sigurdm): Include fields. | 83 // TODO(sigurdm): Include fields. |
| 83 // TODO(sigurdm): Include getters and setters. | |
| 84 // TODO(sigurdm): Include type variables (if we decide to keep them). | 84 // TODO(sigurdm): Include type variables (if we decide to keep them). |
| 85 return [declaredMethods].expand((x) => x); | 85 return [declaredMethods, declaredAccessors, constructors].expand((x) => x); |
| 86 } | 86 } |
| 87 | 87 |
| 88 /// Returns an integer encoding the kind and attributes of the given | 88 /// Returns an integer encoding the kind and attributes of the given |
| 89 /// method/constructor/getter/setter. | 89 /// method/constructor/getter/setter. |
| 90 int _declarationDescriptor(ExecutableElement element) { | 90 int _declarationDescriptor(ExecutableElement element) { |
| 91 int result; | 91 int result; |
| 92 if (element is PropertyAccessorElement) { | 92 if (element is PropertyAccessorElement) { |
| 93 result = element.isGetter ? constants.getter : constants.setter; | 93 result = element.isGetter ? constants.getter : constants.setter; |
| 94 } else if (element is ConstructorElement) { | 94 } else if (element is ConstructorElement) { |
| 95 if (element.isFactory) { | 95 if (element.isFactory) { |
| 96 result = constants.factoryConstructor; | 96 result = constants.factoryConstructor; |
| 97 } else if (element.redirectedConstructor != null) { | |
| 98 result = constants.redirectingConstructor; | |
| 99 } else { | 97 } else { |
| 100 result = constants.generativeConstructor; | 98 result = constants.generativeConstructor; |
| 101 } | 99 } |
| 102 if (element.isConst) { | 100 if (element.isConst) { |
| 103 result += constants.constAttribute; | 101 result += constants.constAttribute; |
| 104 } | 102 } |
| 103 if (element.redirectedConstructor != null) { |
| 104 result += constants.redirectingConstructor; |
| 105 } |
| 105 } else { | 106 } else { |
| 106 result = constants.method; | 107 result = constants.method; |
| 107 } | 108 } |
| 108 if (element.isPrivate) { | 109 if (element.isPrivate) { |
| 109 result += constants.privateAttribute; | 110 result += constants.privateAttribute; |
| 110 } | 111 } |
| 111 if (element.isAbstract) { | 112 if (element.isAbstract) { |
| 112 result += constants.abstractAttribute; | 113 result += constants.abstractAttribute; |
| 113 } | 114 } |
| 114 if (element.isStatic) { | 115 if (element.isStatic) { |
| 115 result += constants.staticAttribute; | 116 result += constants.staticAttribute; |
| 116 } | 117 } |
| 117 return result; | 118 return result; |
| 118 } | 119 } |
| 119 | 120 |
| 121 String nameOfDeclaration(ExecutableElement element) { |
| 122 if (element is ConstructorElement) { |
| 123 return element.name == "" |
| 124 ? classElement.name |
| 125 : "${classElement.name}.${element.name}"; |
| 126 } |
| 127 return element.name; |
| 128 } |
| 129 |
| 120 /// Returns a String with the textual representation of the declarations-map. | 130 /// Returns a String with the textual representation of the declarations-map. |
| 121 String get declarationsString { | 131 String get declarationsString { |
| 122 Iterable<String> declarationParts = declarations.map( | 132 Iterable<String> declarationParts = declarations.map( |
| 123 (ExecutableElement instanceMember) { | 133 (ExecutableElement declaration) { |
| 124 return '"${instanceMember.name}": ' | 134 return '"${nameOfDeclaration(declaration)}": ' |
| 125 'new MethodMirrorImpl("${instanceMember.name}", ' | 135 'new MethodMirrorImpl("${declaration.name}", ' |
| 126 '${_declarationDescriptor(instanceMember)}, this)'; | 136 '${_declarationDescriptor(declaration)}, this)'; |
| 127 }); | 137 }); |
| 128 return "{${declarationParts.join(", ")}}"; | 138 return "{${declarationParts.join(", ")}}"; |
| 129 } | 139 } |
| 130 | 140 |
| 131 void computeNames(Namer namer) { | 141 void computeNames(Namer namer) { |
| 132 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); | 142 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); |
| 133 staticInstanceMirrorName = | 143 staticInstanceMirrorName = |
| 134 namer.freshName("Static_${baseName}_InstanceMirror"); | 144 namer.freshName("Static_${baseName}_InstanceMirror"); |
| 135 } | 145 } |
| 136 } | 146 } |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 result.addAll(classElement.methods); | 392 result.addAll(classElement.methods); |
| 383 classElement.allSupertypes.forEach((InterfaceType superType) { | 393 classElement.allSupertypes.forEach((InterfaceType superType) { |
| 384 result.addAll(superType.methods); | 394 result.addAll(superType.methods); |
| 385 }); | 395 }); |
| 386 return result; | 396 return result; |
| 387 } | 397 } |
| 388 | 398 |
| 389 Iterable<MethodElement> declaredMethods( | 399 Iterable<MethodElement> declaredMethods( |
| 390 ClassElement classElement, Capabilities capabilities) { | 400 ClassElement classElement, Capabilities capabilities) { |
| 391 return classElement.methods.where((MethodElement method) { | 401 return classElement.methods.where((MethodElement method) { |
| 402 if (method.isAbstract) return false; |
| 392 if (method.isStatic) { | 403 if (method.isStatic) { |
| 393 // TODO(sigurdm): Ask capability about support. | 404 // TODO(sigurdm): Ask capabilities about support. |
| 394 return true; | 405 return true; |
| 395 } else { | 406 } else { |
| 396 return capabilities.supportsInstanceInvoke(method.name); | 407 return capabilities.supportsInstanceInvoke(method.name); |
| 397 } | 408 } |
| 398 }); | 409 }); |
| 399 } | 410 } |
| 400 | 411 |
| 412 Iterable<PropertyAccessorElement> declaredAccessors( |
| 413 ClassElement classElement, Capabilities capabilities) { |
| 414 return classElement.accessors.where((PropertyAccessorElement accessor) { |
| 415 if (accessor.isStatic) { |
| 416 // TODO(sigurdm): Ask capabilities about support. |
| 417 return true; |
| 418 } else { |
| 419 return capabilities.supportsInstanceInvoke(accessor.name); |
| 420 } |
| 421 }); |
| 422 } |
| 423 |
| 424 Iterable<ConstructorElement> declaredConstructors( |
| 425 ClassElement classElement, Capabilities capabilities) { |
| 426 return classElement.constructors.where((ConstructorElement constructor) { |
| 427 // TODO(sigurdm): Ask capabilities about support. |
| 428 return true; |
| 429 }); |
| 430 } |
| 431 |
| 401 Iterable<MethodElement> invocableInstanceMethods( | 432 Iterable<MethodElement> invocableInstanceMethods( |
| 402 ClassElement classElement, Capabilities capabilities) { | 433 ClassElement classElement, Capabilities capabilities) { |
| 403 return allMethods(classElement).where((MethodElement method) { | 434 return allMethods(classElement).where((MethodElement method) { |
| 404 MethodDeclaration methodDeclaration = method.node; | 435 MethodDeclaration methodDeclaration = method.node; |
| 405 // TODO(eernst): We currently ignore method declarations when | 436 // TODO(eernst): We currently ignore method declarations when |
| 406 // they are operators. One issue is generation of code (which | 437 // they are operators. One issue is generation of code (which |
| 407 // does not work if we go ahead naively). | 438 // does not work if we go ahead naively). |
| 408 if (methodDeclaration.isOperator) return false; | 439 if (methodDeclaration.isOperator) return false; |
| 409 String methodName = methodDeclaration.name.name; | 440 String methodName = methodDeclaration.name.name; |
| 410 return capabilities.supportsInstanceInvoke(methodName); | 441 return capabilities.supportsInstanceInvoke(methodName); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 ReflectorDomain domain = domains.putIfAbsent(reflector, () { | 488 ReflectorDomain domain = domains.putIfAbsent(reflector, () { |
| 458 Capabilities capabilities = | 489 Capabilities capabilities = |
| 459 _capabilitiesOf(capabilityLibrary, reflector); | 490 _capabilitiesOf(capabilityLibrary, reflector); |
| 460 return new ReflectorDomain( | 491 return new ReflectorDomain( |
| 461 reflector, new List<ClassDomain>(), capabilities); | 492 reflector, new List<ClassDomain>(), capabilities); |
| 462 }); | 493 }); |
| 463 List<MethodElement> instanceMethods = | 494 List<MethodElement> instanceMethods = |
| 464 invocableInstanceMethods(type, domain.capabilities).toList(); | 495 invocableInstanceMethods(type, domain.capabilities).toList(); |
| 465 List<MethodElement> declaredMethodsOfClass = | 496 List<MethodElement> declaredMethodsOfClass = |
| 466 declaredMethods(type, domain.capabilities).toList(); | 497 declaredMethods(type, domain.capabilities).toList(); |
| 467 domain.annotatedClasses.add(new ClassDomain( | 498 List<PropertyAccessorElement> declaredAccessorsOfClass = |
| 468 type, instanceMethods, declaredMethodsOfClass, domain)); | 499 declaredAccessors(type, domain.capabilities).toList(); |
| 500 List<ConstructorElement> declaredConstructorsOfClass = |
| 501 declaredConstructors(type, domain.capabilities).toList(); |
| 502 domain.annotatedClasses.add(new ClassDomain(type, instanceMethods, |
| 503 declaredMethodsOfClass, declaredAccessorsOfClass, |
| 504 declaredConstructorsOfClass, domain)); |
| 469 } | 505 } |
| 470 } | 506 } |
| 471 } | 507 } |
| 472 } | 508 } |
| 473 domains.values.forEach(_collectMissingImports); | 509 domains.values.forEach(_collectMissingImports); |
| 474 | 510 |
| 475 world.reflectors.addAll(domains.values.toList()); | 511 world.reflectors.addAll(domains.values.toList()); |
| 476 world.computeNames(namer); | 512 world.computeNames(namer); |
| 477 return world; | 513 return world; |
| 478 } | 514 } |
| (...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1344 TransformLogger get logger => _aggregateTransform.logger; | 1380 TransformLogger get logger => _aggregateTransform.logger; |
| 1345 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1381 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
| 1346 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1382 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
| 1347 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1383 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
| 1348 } | 1384 } |
| 1349 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1385 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
| 1350 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1386 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
| 1351 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1387 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
| 1352 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1388 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
| 1353 } | 1389 } |
| OLD | NEW |