// 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, are only used when throwing // NoSuchMethodError for compile-time resolution failures. static const int _DYNAMIC = 0; static const int _STATIC = 1; static const int _CONSTRUCTOR = 2; static const int _TOP_LEVEL = 3; static const int _CALL_SHIFT = _TYPE_BITS; static const int _CALL_BITS = 2; static const int _CALL_MASK = (1 << _CALL_BITS) - 1; // Internal representation of the invocation mirror. final String _functionName; final List _argumentsDescriptor; final List _arguments; // External representation of the invocation mirror; populated on demand. Symbol _memberName; int _type; List _positionalArguments; Map _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 = _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 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 {}; } _namedArguments = new Map(); 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 == _METHOD; } bool get isAccessor { if (_type == null) { _setMemberNameAndType(); } return _type != _METHOD; } bool get isGetter { if (_type == null) { _setMemberNameAndType(); } return _type == _GETTER; } bool get isSetter { if (_type == null) { _setMemberNameAndType(); } return _type == _SETTER; } _InvocationMirror(this._functionName, this._argumentsDescriptor, this._arguments); static _allocateInvocationMirror(String functionName, List argumentsDescriptor, List arguments) { return new _InvocationMirror(functionName, argumentsDescriptor, arguments); } 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); }