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 { |