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 '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 assert(!element.isAbstract); |
|
eernst
2015/06/18 10:07:18
Seems to be enough to revert this one.
sigurdm
2015/06/18 11:04:03
Done.
| |
| 112 result += constants.abstractAttribute; | |
| 113 } | |
| 114 if (element.isStatic) { | 113 if (element.isStatic) { |
| 115 result += constants.staticAttribute; | 114 result += constants.staticAttribute; |
| 116 } | 115 } |
| 117 return result; | 116 return result; |
| 118 } | 117 } |
| 119 | 118 |
| 119 String nameOfDeclaration(ExecutableElement element) { | |
| 120 if (element is ConstructorElement) { | |
| 121 return element.name == "" | |
| 122 ? classElement.name | |
| 123 : "${classElement.name}.${element.name}"; | |
| 124 } | |
| 125 return element.name; | |
| 126 } | |
| 127 | |
| 120 /// Returns a String with the textual representation of the declarations-map. | 128 /// Returns a String with the textual representation of the declarations-map. |
| 121 String get declarationsString { | 129 String get declarationsString { |
| 122 Iterable<String> declarationParts = declarations.map( | 130 Iterable<String> declarationParts = declarations.map( |
| 123 (ExecutableElement instanceMember) { | 131 (ExecutableElement declaration) { |
| 124 return '"${instanceMember.name}": ' | 132 return '"${nameOfDeclaration(declaration)}": ' |
| 125 'new MethodMirrorImpl("${instanceMember.name}", ' | 133 'new MethodMirrorImpl("${declaration.name}", ' |
| 126 '${_declarationDescriptor(instanceMember)}, this)'; | 134 '${_declarationDescriptor(declaration)}, this)'; |
| 127 }); | 135 }); |
| 128 return "{${declarationParts.join(", ")}}"; | 136 return "{${declarationParts.join(", ")}}"; |
| 129 } | 137 } |
| 130 | 138 |
| 131 void computeNames(Namer namer) { | 139 void computeNames(Namer namer) { |
| 132 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); | 140 staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror"); |
| 133 staticInstanceMirrorName = | 141 staticInstanceMirrorName = |
| 134 namer.freshName("Static_${baseName}_InstanceMirror"); | 142 namer.freshName("Static_${baseName}_InstanceMirror"); |
| 135 } | 143 } |
| 136 } | 144 } |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 result.addAll(classElement.methods); | 397 result.addAll(classElement.methods); |
| 390 classElement.allSupertypes.forEach((InterfaceType superType) { | 398 classElement.allSupertypes.forEach((InterfaceType superType) { |
| 391 result.addAll(superType.methods); | 399 result.addAll(superType.methods); |
| 392 }); | 400 }); |
| 393 return result; | 401 return result; |
| 394 } | 402 } |
| 395 | 403 |
| 396 Iterable<MethodElement> declaredMethods( | 404 Iterable<MethodElement> declaredMethods( |
| 397 ClassElement classElement, Capabilities capabilities) { | 405 ClassElement classElement, Capabilities capabilities) { |
| 398 return classElement.methods.where((MethodElement method) { | 406 return classElement.methods.where((MethodElement method) { |
| 407 if (method.isAbstract) return false; | |
| 399 if (method.isStatic) { | 408 if (method.isStatic) { |
| 400 // TODO(sigurdm): Ask capability about support. | 409 // TODO(sigurdm): Ask capabilities about support. |
| 401 return true; | 410 return true; |
| 402 } else { | 411 } else { |
| 403 return capabilities.supportsInstanceInvoke(method.name); | 412 return capabilities.supportsInstanceInvoke(method.name); |
| 404 } | 413 } |
| 405 }); | 414 }); |
| 406 } | 415 } |
| 407 | 416 |
| 417 Iterable<PropertyAccessorElement> declaredAccessors( | |
| 418 ClassElement classElement, Capabilities capabilities) { | |
| 419 return classElement.accessors.where((PropertyAccessorElement accessor) { | |
| 420 if (accessor.isAbstract) return false; | |
|
eernst
2015/06/18 10:07:19
With abstract members included, should this line b
sigurdm
2015/06/18 11:04:03
Done.
| |
| 421 if (accessor.isStatic) { | |
| 422 // TODO(sigurdm): Ask capabilities about support. | |
| 423 return true; | |
| 424 } else { | |
| 425 return capabilities.supportsInstanceInvoke(accessor.name); | |
| 426 } | |
| 427 }); | |
| 428 } | |
| 429 | |
| 430 Iterable<ConstructorElement> declaredConstructors( | |
| 431 ClassElement classElement, Capabilities capabilities) { | |
| 432 return classElement.constructors.where((ConstructorElement constructor) { | |
| 433 // TODO(sigurdm): Ask capabilities about support. | |
| 434 return true; | |
| 435 }); | |
| 436 } | |
| 437 | |
| 408 Iterable<MethodElement> invocableInstanceMethods( | 438 Iterable<MethodElement> invocableInstanceMethods( |
| 409 ClassElement classElement, Capabilities capabilities) { | 439 ClassElement classElement, Capabilities capabilities) { |
| 410 return allMethods(classElement).where((MethodElement method) { | 440 return allMethods(classElement).where((MethodElement method) { |
| 411 MethodDeclaration methodDeclaration = method.node; | 441 MethodDeclaration methodDeclaration = method.node; |
| 412 // TODO(eernst): We currently ignore method declarations when | 442 // TODO(eernst): We currently ignore method declarations when |
| 413 // they are operators. One issue is generation of code (which | 443 // they are operators. One issue is generation of code (which |
| 414 // does not work if we go ahead naively). | 444 // does not work if we go ahead naively). |
| 415 if (methodDeclaration.isOperator) return false; | 445 if (methodDeclaration.isOperator) return false; |
| 416 String methodName = methodDeclaration.name.name; | 446 String methodName = methodDeclaration.name.name; |
| 417 return capabilities.supportsInstanceInvoke(methodName); | 447 return capabilities.supportsInstanceInvoke(methodName); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 ReflectorDomain domain = domains.putIfAbsent(reflector, () { | 494 ReflectorDomain domain = domains.putIfAbsent(reflector, () { |
| 465 Capabilities capabilities = | 495 Capabilities capabilities = |
| 466 _capabilitiesOf(capabilityLibrary, reflector); | 496 _capabilitiesOf(capabilityLibrary, reflector); |
| 467 return new ReflectorDomain( | 497 return new ReflectorDomain( |
| 468 reflector, new List<ClassDomain>(), capabilities); | 498 reflector, new List<ClassDomain>(), capabilities); |
| 469 }); | 499 }); |
| 470 List<MethodElement> instanceMethods = | 500 List<MethodElement> instanceMethods = |
| 471 invocableInstanceMethods(type, domain.capabilities).toList(); | 501 invocableInstanceMethods(type, domain.capabilities).toList(); |
| 472 List<MethodElement> declaredMethodsOfClass = | 502 List<MethodElement> declaredMethodsOfClass = |
| 473 declaredMethods(type, domain.capabilities).toList(); | 503 declaredMethods(type, domain.capabilities).toList(); |
| 474 domain.annotatedClasses.add(new ClassDomain( | 504 List<PropertyAccessorElement> declaredAccessorsOfClass = |
| 475 type, instanceMethods, declaredMethodsOfClass, domain)); | 505 declaredAccessors(type, domain.capabilities).toList(); |
| 506 List<ConstructorElement> declaredConstructorsOfClass = | |
| 507 declaredConstructors(type, domain.capabilities).toList(); | |
| 508 domain.annotatedClasses.add(new ClassDomain(type, instanceMethods, | |
| 509 declaredMethodsOfClass, declaredAccessorsOfClass, | |
| 510 declaredConstructorsOfClass, domain)); | |
| 476 } | 511 } |
| 477 } | 512 } |
| 478 } | 513 } |
| 479 } | 514 } |
| 480 domains.values.forEach(_collectMissingImports); | 515 domains.values.forEach(_collectMissingImports); |
| 481 | 516 |
| 482 world.reflectors.addAll(domains.values.toList()); | 517 world.reflectors.addAll(domains.values.toList()); |
| 483 world.computeNames(namer); | 518 world.computeNames(namer); |
| 484 return world; | 519 return world; |
| 485 } | 520 } |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 TransformLogger get logger => _aggregateTransform.logger; | 1253 TransformLogger get logger => _aggregateTransform.logger; |
| 1219 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); | 1254 Future<Asset> getInput(AssetId id) => _aggregateTransform.getInput(id); |
| 1220 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 1255 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
| 1221 return _aggregateTransform.readInputAsString(id, encoding: encoding); | 1256 return _aggregateTransform.readInputAsString(id, encoding: encoding); |
| 1222 } | 1257 } |
| 1223 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); | 1258 Stream<List<int>> readInput(AssetId id) => _aggregateTransform.readInput(id); |
| 1224 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); | 1259 Future<bool> hasInput(AssetId id) => _aggregateTransform.hasInput(id); |
| 1225 void addOutput(Asset output) => _aggregateTransform.addOutput(output); | 1260 void addOutput(Asset output) => _aggregateTransform.addOutput(output); |
| 1226 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); | 1261 void consumePrimary() => _aggregateTransform.consumePrimary(primaryInput.id); |
| 1227 } | 1262 } |
| OLD | NEW |