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 |