Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1050)

Unified Diff: reflectable/lib/src/transformer_implementation.dart

Issue 1181413005: Implement newInstance in the transformer. (Closed) Base URL: https://github.com/dart-lang/reflectable.git@master
Patch Set: Address review Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « reflectable/lib/src/mirrors_unimpl.dart ('k') | test_reflectable/.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: reflectable/lib/src/transformer_implementation.dart
diff --git a/reflectable/lib/src/transformer_implementation.dart b/reflectable/lib/src/transformer_implementation.dart
index 744a395b10e8661ad6303ec789ea187ef1653b6f..c7f9223a70870c3189ed9c289e92150c12435564 100644
--- a/reflectable/lib/src/transformer_implementation.dart
+++ b/reflectable/lib/src/transformer_implementation.dart
@@ -239,6 +239,78 @@ class ClassDomain {
return "new UnmodifiableListView([${metadataParts.join(", ")}])";
}
+ String get newInstanceString {
+ // TODO(eernst, sigurdm, #8): Recreate the default values faithfully.
+ List<String> constructorLines = new List<String>();
+
+ String name(int i) {
+ String alphabet = "abcdefghijklmnopqrstuvwxyz";
+ int alphabetLength = alphabet.length;
+ if (i < alphabetLength) {
+ return "_${alphabet[i]}";
+ }
+ return "_${alphabet[i % alphabetLength]}${i ~/ alphabetLength}";
+ }
+ for (ConstructorElement constructor in constructors) {
+ FunctionType type = constructor.type;
+ int positionalCount = type.normalParameterTypes.length;
eernst 2015/06/19 09:22:21 I suspect that `normalParameterTypes` delivers inf
sigurdm 2015/06/19 10:52:00 Done.
+ int optionalCount = type.optionalParameterTypes.length;
eernst 2015/06/19 09:22:21 Similarly, since both named parameters and (some)
sigurdm 2015/06/19 10:52:00 Done.
+ List<String> argumentNames = type.namedParameterTypes.keys.toList();
+ String positionals =
+ new Iterable.generate(positionalCount, (int i) => name(i)).join(", ");
+ String optionalsWithDefaults = new Iterable.generate(optionalCount,
+ (int i) {
+ String defaultValueCode =
+ constructor.parameters[positionalCount + i].defaultValueCode;
+ String defaultValueString =
+ defaultValueCode == null ? "" : " = $defaultValueCode";
eernst 2015/06/19 09:22:21 Wouldn't it be better to have the '.. faithfully'
sigurdm 2015/06/19 10:52:00 Done
+ return "${name(i + positionalCount)}$defaultValueString";
+ }).join(", ");
+ String namedWithDefaults = new Iterable.generate(argumentNames.length,
+ (int i) {
+ String defaultValueCode =
+ constructor.parameters[positionalCount + i].defaultValueCode;
+ String defaultValueString =
+ defaultValueCode == null ? "" : ": $defaultValueCode";
+ return "${argumentNames[i]}$defaultValueString";
+ }).join(", ");
+
+ String optionalArguments = new Iterable.generate(
+ optionalCount, (int i) => name(i + positionalCount)).join(", ");
+ String namedArguments =
+ argumentNames.map((String name) => "$name: $name").join(", ");
+ List<String> parameterParts = new List<String>();
+ List<String> argumentParts = new List<String>();
+ if (positionalCount != 0) {
+ parameterParts.add(positionals);
+ argumentParts.add(positionals);
+ }
+ if (optionalCount != 0) {
+ parameterParts.add("[$optionalsWithDefaults]");
+ argumentParts.add(optionalArguments);
+ }
+ if (argumentNames.isNotEmpty) {
+ parameterParts.add("{${namedWithDefaults}}");
+ argumentParts.add(namedArguments);
+ }
+ constructorLines.add('case "${constructor.name}": '
+ 'c = (${parameterParts.join(', ')}) => '
+ 'new ${nameOfDeclaration(constructor)}'
+ '(${argumentParts.join(", ")});');
+ constructorLines.add(' break;');
+ }
+ return """newInstance(String constructorName, List positionalArguments,
+ [Map<Symbol, dynamic> namedArguments]) {
+ Function c;
+ switch (constructorName) {
+ ${constructorLines.join("\n ")}
+ default: throw new NoSuchInvokeCapabilityError(${classElement.name},
+ constructorName, positionalArguments, namedArguments);
+ }
+ return Function.apply(c, positionalArguments, namedArguments);
+ }""";
+ }
+
void computeNames(Namer namer) {
staticClassMirrorName = namer.freshName("Static_${baseName}_ClassMirror");
staticInstanceMirrorName =
@@ -495,6 +567,7 @@ class TransformerImplementation {
Iterable<MethodElement> declaredMethods(
ClassElement classElement, Capabilities capabilities) {
return classElement.methods.where((MethodElement method) {
+ if (method.isAbstract) return false;
eernst 2015/06/19 09:22:21 Maybe this one was reintroduced spuriously by git?
sigurdm 2015/06/19 10:52:00 Done.
if (method.isStatic) {
// TODO(sigurdm): Ask capabilities about support.
return true;
@@ -910,6 +983,9 @@ class TransformerImplementation {
implementedMembers
.add("List<Object> metadata = ${classDomain.metadataString};");
}
+ if (!classDomain.classElement.isAbstract) {
+ implementedMembers.add(classDomain.newInstanceString);
+ }
eernst 2015/06/19 09:22:21 Maybe this one was reintroduced spuriously by git?
sigurdm 2015/06/19 10:52:00 No this one is good. We do not want to be able to
return """
class ${classDomain.staticClassMirrorName} extends ClassMirrorUnimpl {
« no previous file with comments | « reflectable/lib/src/mirrors_unimpl.dart ('k') | test_reflectable/.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698