Chromium Code Reviews| 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 { |