mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 02:35:01 +00:00
9ec07853c5
R=hausner@google.com Review URL: https://codereview.chromium.org//30533004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@29042 260f80e4-7a28-3924-810f-c04153c831b5
151 lines
4.8 KiB
Dart
151 lines
4.8 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
class _InvocationMirror implements Invocation {
|
|
// Constants describing the invocation type.
|
|
// _FIELD cannot be generated by regular invocation mirrors.
|
|
static const int _METHOD = 0;
|
|
static const int _GETTER = 1;
|
|
static const int _SETTER = 2;
|
|
static const int _FIELD = 3;
|
|
static const int _TYPE_SHIFT = 0;
|
|
static const int _TYPE_BITS = 2;
|
|
static const int _TYPE_MASK = (1 << _TYPE_BITS) - 1;
|
|
|
|
// These values, except _DYNAMIC and _SUPER, are only used when throwing
|
|
// NoSuchMethodError for compile-time resolution failures.
|
|
static const int _DYNAMIC = 0;
|
|
static const int _SUPER = 1;
|
|
static const int _STATIC = 2;
|
|
static const int _CONSTRUCTOR = 3;
|
|
static const int _TOP_LEVEL = 4;
|
|
static const int _CALL_SHIFT = _TYPE_BITS;
|
|
static const int _CALL_BITS = 3;
|
|
static const int _CALL_MASK = (1 << _CALL_BITS) - 1;
|
|
|
|
// Internal representation of the invocation mirror.
|
|
final String _functionName;
|
|
final List _argumentsDescriptor;
|
|
final List _arguments;
|
|
final bool _isSuperInvocation;
|
|
|
|
// External representation of the invocation mirror; populated on demand.
|
|
Symbol _memberName;
|
|
int _type;
|
|
List _positionalArguments;
|
|
Map<Symbol, dynamic> _namedArguments;
|
|
|
|
void _setMemberNameAndType() {
|
|
if (_functionName.startsWith("get:")) {
|
|
_type = _GETTER;
|
|
_memberName =
|
|
new _collection_dev.Symbol.unvalidated(_functionName.substring(4));
|
|
} else if (_functionName.startsWith("set:")) {
|
|
_type = _SETTER;
|
|
_memberName =
|
|
new _collection_dev.Symbol.unvalidated(
|
|
_functionName.substring(4) + "=");
|
|
} else {
|
|
_type = _isSuperInvocation ? (_SUPER << _CALL_SHIFT) | _METHOD : _METHOD;
|
|
_memberName = new _collection_dev.Symbol.unvalidated(_functionName);
|
|
}
|
|
}
|
|
|
|
Symbol get memberName {
|
|
if (_memberName == null) {
|
|
_setMemberNameAndType();
|
|
}
|
|
return _memberName;
|
|
}
|
|
|
|
List get positionalArguments {
|
|
if (_positionalArguments == null) {
|
|
int numPositionalArguments = _argumentsDescriptor[1];
|
|
// Don't count receiver.
|
|
if (numPositionalArguments == 1) {
|
|
return _positionalArguments = const [];
|
|
}
|
|
// Exclude receiver.
|
|
_positionalArguments = _arguments.sublist(1, numPositionalArguments);
|
|
}
|
|
return _positionalArguments;
|
|
}
|
|
|
|
Map<Symbol, dynamic> get namedArguments {
|
|
if (_namedArguments == null) {
|
|
int numArguments = _argumentsDescriptor[0] - 1; // Exclude receiver.
|
|
int numPositionalArguments = _argumentsDescriptor[1] - 1;
|
|
int numNamedArguments = numArguments - numPositionalArguments;
|
|
if (numNamedArguments == 0) {
|
|
return _namedArguments = const <Symbol, dynamic>{};
|
|
}
|
|
_namedArguments = new Map<Symbol, dynamic>();
|
|
for (int i = 0; i < numNamedArguments; i++) {
|
|
String arg_name = _argumentsDescriptor[2 + 2*i];
|
|
var arg_value = _arguments[_argumentsDescriptor[3 + 2*i]];
|
|
_namedArguments[new _collection_dev.Symbol.unvalidated(arg_name)] =
|
|
arg_value;
|
|
}
|
|
}
|
|
return _namedArguments;
|
|
}
|
|
|
|
bool get isMethod {
|
|
if (_type == null) {
|
|
_setMemberNameAndType();
|
|
}
|
|
return (_type & _TYPE_MASK) == _METHOD;
|
|
}
|
|
|
|
bool get isAccessor {
|
|
if (_type == null) {
|
|
_setMemberNameAndType();
|
|
}
|
|
return (_type & _TYPE_MASK) != _METHOD;
|
|
}
|
|
|
|
bool get isGetter {
|
|
if (_type == null) {
|
|
_setMemberNameAndType();
|
|
}
|
|
return (_type & _TYPE_MASK) == _GETTER;
|
|
}
|
|
|
|
bool get isSetter {
|
|
if (_type == null) {
|
|
_setMemberNameAndType();
|
|
}
|
|
return (_type & _TYPE_MASK) == _SETTER;
|
|
}
|
|
|
|
_InvocationMirror(this._functionName,
|
|
this._argumentsDescriptor,
|
|
this._arguments,
|
|
this._isSuperInvocation);
|
|
|
|
static _allocateInvocationMirror(String functionName,
|
|
List argumentsDescriptor,
|
|
List arguments,
|
|
bool isSuperInvocation) {
|
|
return new _InvocationMirror(functionName,
|
|
argumentsDescriptor,
|
|
arguments,
|
|
isSuperInvocation);
|
|
}
|
|
|
|
static _invoke(Object receiver,
|
|
String functionName,
|
|
List argumentsDescriptor,
|
|
List arguments)
|
|
native "InvocationMirror_invoke";
|
|
|
|
_invokeOn(Object receiver) {
|
|
return _invoke(receiver, _functionName, _argumentsDescriptor, _arguments);
|
|
}
|
|
|
|
// TODO(ahe): This is a hack. See _LocalInstanceMirrorImpl.delegate
|
|
// in mirrors_impl.dart
|
|
static final _invokeOnClosure = (x, y) => y._invokeOn(x);
|
|
}
|