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

Unified Diff: runtime/lib/mirrors_impl.dart

Issue 23604003: Support named and optional positional arguments in reflective invocation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix wrong variable in async unwrap error message Created 7 years, 3 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 | « runtime/lib/mirrors.cc ('k') | runtime/vm/bootstrap_natives.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/lib/mirrors_impl.dart
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index b2bd353f66e6cfdf6a9a8266f62cc71fefc4acfe..acd7f0550e2d41c579ddcc36f9b418beb2811aec 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -81,7 +81,7 @@ List _metadata(reflectee)
// This will verify the argument types, unwrap them, and ensure we have a fixed
// array.
-List _unwarpAsyncPositionals(wrappedArgs){
+List _unwarpAsyncPositionals(wrappedArgs) {
List unwrappedArgs = new List(wrappedArgs.length);
for(int i = 0; i < wrappedArgs.length; i++){
var wrappedArg = wrappedArgs[i];
@@ -89,12 +89,28 @@ List _unwarpAsyncPositionals(wrappedArgs){
unwrappedArgs[i] = wrappedArg;
} else if(wrappedArg is InstanceMirror) {
unwrappedArgs[i] = wrappedArg._reflectee;
- } else {
- throw "positional argument $i ($arg) was not a simple value or InstanceMirror";
+ } else {
+ throw "positional argument $i ($wrappedArg) was "
+ "not a simple value or InstanceMirror";
}
}
return unwrappedArgs;
}
+Map _unwarpAsyncNamed(wrappedArgs) {
+ if (wrappedArgs==null) return null;
+ Map unwrappedArgs = new Map();
+ wrappedArgs.forEach((name, wrappedArg){
+ if(_isSimpleValue(wrappedArg)) {
+ unwrappedArgs[name] = wrappedArg;
+ } else if(wrappedArg is InstanceMirror) {
+ unwrappedArgs[name] = wrappedArg._reflectee;
+ } else {
+ throw "named argument ${_n(name)} ($wrappedArg) was "
+ "not a simple value or InstanceMirror";
+ }
+ });
+ return unwrappedArgs;
+}
class _LocalMirrorSystemImpl extends MirrorSystem {
// Change parameter back to "this.libraries" when native code is changed.
@@ -155,13 +171,26 @@ abstract class _LocalObjectMirrorImpl extends _LocalMirrorImpl
InstanceMirror invoke(Symbol memberName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null) {
- throw new UnimplementedError(
- 'named argument support is not implemented');
+
+ int numPositionalArguments = positionalArguments.length;
+ int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
+ int numArguments = numPositionalArguments + numNamedArguments;
+ List arguments = new List(numArguments);
+ arguments.setRange(0, numPositionalArguments, positionalArguments);
+ List names = new List(numNamedArguments);
+ int argumentIndex = numPositionalArguments;
+ int nameIndex = 0;
+ if (numNamedArguments > 0) {
+ namedArguments.forEach((name, value) {
+ arguments[argumentIndex++] = value;
+ names[nameIndex++] = _n(name);
+ });
}
+
return reflect(this._invoke(_reflectee,
_n(memberName),
- positionalArguments.toList(growable:false)));
+ arguments,
+ names));
}
InstanceMirror getField(Symbol memberName) {
@@ -179,19 +208,11 @@ abstract class _LocalObjectMirrorImpl extends _LocalMirrorImpl
Future<InstanceMirror> invokeAsync(Symbol memberName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null) {
- throw new UnimplementedError(
- 'named argument support is not implemented');
- }
-
- try {
- var result = this._invoke(_reflectee,
- _n(memberName),
- _unwarpAsyncPositionals(positionalArguments));
- return new Future.value(reflect(result));
- } catch(e) {
- return new Future.error(e);
- }
+ return new Future(() {
+ return this.invoke(memberName,
+ _unwarpAsyncPositionals(positionalArguments),
+ _unwarpAsyncNamed(namedArguments));
+ });
}
Future<InstanceMirror> getFieldAsync(Symbol memberName) {
@@ -299,7 +320,34 @@ class _LocalInstanceMirrorImpl extends _LocalObjectMirrorImpl
static _identityHash(reflectee)
native "InstanceMirror_identityHash";
- _invoke(reflectee, functionName, positionalArguments)
+ // Override to include the receiver in the arguments.
+ InstanceMirror invoke(Symbol memberName,
+ List positionalArguments,
+ [Map<Symbol, dynamic> namedArguments]) {
+
+ int numPositionalArguments = positionalArguments.length + 1; // Receiver.
+ int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
+ int numArguments = numPositionalArguments + numNamedArguments;
+ List arguments = new List(numArguments);
+ arguments[0] = _reflectee; // Receiver.
+ arguments.setRange(1, numPositionalArguments, positionalArguments);
+ List names = new List(numNamedArguments);
+ int argumentIndex = numPositionalArguments;
+ int nameIndex = 0;
+ if (numNamedArguments > 0) {
+ namedArguments.forEach((name, value) {
+ arguments[argumentIndex++] = value;
+ names[nameIndex++] = _n(name);
+ });
+ }
+
+ return reflect(this._invoke(_reflectee,
+ _n(memberName),
+ arguments,
+ names));
+ }
+
+ _invoke(reflectee, functionName, arguments, argumentNames)
native 'InstanceMirror_invoke';
_invokeGetter(reflectee, getterName)
@@ -331,30 +379,38 @@ class _LocalClosureMirrorImpl extends _LocalInstanceMirrorImpl
InstanceMirror apply(List<Object> positionalArguments,
[Map<Symbol, Object> namedArguments]) {
- if (namedArguments != null) {
- throw new UnimplementedError(
- 'named argument support is not implemented');
+ // TODO(iposva): When closures get an ordinary call method, this can be
+ // replaced with
+ // return this.invoke(#call, positionalArguments, namedArguments);
+ // and the native ClosureMirror_apply can be removed.
+
+ int numPositionalArguments = positionalArguments.length + 1; // Receiver.
+ int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
+ int numArguments = numPositionalArguments + numNamedArguments;
+ List arguments = new List(numArguments);
+ arguments[0] = _reflectee; // Receiver.
+ arguments.setRange(1, numPositionalArguments, positionalArguments);
+ List names = new List(numNamedArguments);
+ int argumentIndex = numPositionalArguments;
+ int nameIndex = 0;
+ if (numNamedArguments > 0) {
+ namedArguments.forEach((name, value) {
+ arguments[argumentIndex++] = value;
+ names[nameIndex++] = _n(name);
+ });
}
+
// It is tempting to implement this in terms of Function.apply, but then
// lazy compilation errors would be fatal.
- return reflect(_apply(_reflectee,
- positionalArguments.toList(growable:false)));
+ return reflect(_apply(_reflectee, arguments, names));
}
Future<InstanceMirror> applyAsync(List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null) {
- throw new UnimplementedError(
- 'named argument support is not implemented');
- }
-
- try {
- var result = _apply(_reflectee,
- _unwarpAsyncPositionals(positionalArguments));
- return new Future.value(reflect(result));
- } on MirroredError catch(e) {
- return new Future.error(e);
- }
+ return new Future(() {
+ return this.apply(_unwarpAsyncPositionals(positionalArguments),
+ _unwarpAsyncNamed(namedArguments));
+ });
}
Future<InstanceMirror> findInContext(Symbol name) {
@@ -364,7 +420,7 @@ class _LocalClosureMirrorImpl extends _LocalInstanceMirrorImpl
String toString() => "ClosureMirror on '${Error.safeToString(_reflectee)}'";
- static _apply(reflectee, positionalArguments)
+ static _apply(reflectee, arguments, argumentNames)
native 'ClosureMirror_apply';
static _computeFunction(reflectee)
@@ -607,31 +663,37 @@ class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
InstanceMirror newInstance(Symbol constructorName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null) {
- throw new UnimplementedError(
- 'named argument support is not implemented');
+ // Native code will add the 1 or 2 implicit arguments depending on whether
+ // we end up invoking a factory or constructor respectively.
+ int numPositionalArguments = positionalArguments.length;
+ int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
+ int numArguments = numPositionalArguments + numNamedArguments;
+ List arguments = new List(numArguments);
+ arguments.setRange(0, numPositionalArguments, positionalArguments);
+ List names = new List(numNamedArguments);
+ int argumentIndex = numPositionalArguments;
+ int nameIndex = 0;
+ if (numNamedArguments > 0) {
+ namedArguments.forEach((name, value) {
+ arguments[argumentIndex++] = value;
+ names[nameIndex++] = _n(name);
+ });
}
+
return reflect(_invokeConstructor(_reflectee,
_n(constructorName),
- positionalArguments.toList(growable:false)));
+ arguments,
+ names));
}
Future<InstanceMirror> newInstanceAsync(Symbol constructorName,
List positionalArguments,
[Map<Symbol, dynamic> namedArguments]) {
- if (namedArguments != null) {
- throw new UnimplementedError(
- 'named argument support is not implemented');
- }
-
- try {
- var result = _invokeConstructor(_reflectee,
- _n(constructorName),
- _unwarpAsyncPositionals(positionalArguments));
- return new Future.value(reflect(result));
- } catch(e) {
- return new Future.error(e);
- }
+ return new Future(() {
+ return this.newInstance(constructorName,
+ _unwarpAsyncPositionals(positionalArguments),
+ _unwarpAsyncNamed(namedArguments));
+ });
}
List<InstanceMirror> get metadata {
@@ -669,7 +731,7 @@ class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
_computeConstructors(reflectee)
native "ClassMirror_constructors";
- _invoke(reflectee, memberName, positionalArguments)
+ _invoke(reflectee, memberName, arguments, argumentNames)
native 'ClassMirror_invoke';
_invokeGetter(reflectee, getterName)
@@ -678,7 +740,7 @@ class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
_invokeSetter(reflectee, setterName, value)
native 'ClassMirror_invokeSetter';
- static _invokeConstructor(reflectee, constructorName, positionalArguments)
+ static _invokeConstructor(reflectee, constructorName, arguments, argumentNames)
native 'ClassMirror_invokeConstructor';
static _ClassMirror_type_variables(reflectee)
@@ -968,7 +1030,7 @@ class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl
int get hashCode => simpleName.hashCode;
- _invoke(reflectee, memberName, positionalArguments)
+ _invoke(reflectee, memberName, arguments, argumentNames)
native 'LibraryMirror_invoke';
_invokeGetter(reflectee, getterName)
« no previous file with comments | « runtime/lib/mirrors.cc ('k') | runtime/vm/bootstrap_natives.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698