| Index: pkg/kernel/lib/target/vm.dart
|
| diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
|
| index aa943031fe08b16f23934f1cf42efaff724ab890..8ad4a9d86153eaab9fe9c18f0bca3f3e4472e2a1 100644
|
| --- a/pkg/kernel/lib/target/vm.dart
|
| +++ b/pkg/kernel/lib/target/vm.dart
|
| @@ -98,7 +98,7 @@ class VmTarget extends Target {
|
| }
|
|
|
| @override
|
| - Expression instantiateInvocation(Member target, Expression receiver,
|
| + Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
|
| String name, Arguments arguments, int offset, bool isSuper) {
|
| // See [_InvocationMirror]
|
| // (../../../../runtime/lib/invocation_mirror_patch.dart).
|
| @@ -142,19 +142,130 @@ class VmTarget extends Target {
|
| new BoolLiteral(isSuper)..fileOffset = arguments.fileOffset,
|
| ]);
|
|
|
| - return (target is Constructor
|
| - ? new ConstructorInvocation(target, constructorArguments)
|
| - : new StaticInvocation(target, constructorArguments))
|
| + return new ConstructorInvocation(
|
| + coreTypes.invocationMirrorDefaultConstructor, constructorArguments)
|
| ..fileOffset = offset;
|
| }
|
|
|
| - Expression _fixedLengthList(List<Expression> elements, int charOffset) {
|
| + @override
|
| + Expression instantiateNoSuchMethodError(CoreTypes coreTypes,
|
| + Expression receiver, String name, Arguments arguments, int offset,
|
| + {bool isMethod: false,
|
| + bool isGetter: false,
|
| + bool isSetter: false,
|
| + bool isField: false,
|
| + bool isLocalVariable: false,
|
| + bool isDynamic: false,
|
| + bool isSuper: false,
|
| + bool isStatic: false,
|
| + bool isConstructor: false,
|
| + bool isTopLevel: false}) {
|
| + int type = _invocationType(
|
| + isMethod: isMethod,
|
| + isGetter: isGetter,
|
| + isSetter: isSetter,
|
| + isField: isField,
|
| + isLocalVariable: isLocalVariable,
|
| + isDynamic: isDynamic,
|
| + isSuper: isSuper,
|
| + isStatic: isStatic,
|
| + isConstructor: isConstructor,
|
| + isTopLevel: isTopLevel);
|
| + return new ConstructorInvocation(
|
| + coreTypes.noSuchMethodErrorImplementationConstructor,
|
| + new Arguments(<Expression>[
|
| + receiver,
|
| + new SymbolLiteral(name)..fileOffset = offset,
|
| + new IntLiteral(type)..fileOffset = offset,
|
| + _fixedLengthList(arguments.positional, arguments.fileOffset),
|
| + new MapLiteral(new List<MapEntry>.from(
|
| + arguments.named.map((NamedExpression arg) {
|
| + return new MapEntry(
|
| + new SymbolLiteral(arg.name)..fileOffset = arg.fileOffset,
|
| + arg.value)
|
| + ..fileOffset = arg.fileOffset;
|
| + })))
|
| + ..fileOffset = arguments.fileOffset,
|
| + new NullLiteral()
|
| + ]));
|
| + }
|
| +
|
| + int _invocationType(
|
| + {bool isMethod: false,
|
| + bool isGetter: false,
|
| + bool isSetter: false,
|
| + bool isField: false,
|
| + bool isLocalVariable: false,
|
| + bool isDynamic: false,
|
| + bool isSuper: false,
|
| + bool isStatic: false,
|
| + bool isConstructor: false,
|
| + bool isTopLevel: false}) {
|
| + // This is copied from [_InvocationMirror](
|
| + // ../../../../../../runtime/lib/invocation_mirror_patch.dart).
|
| +
|
| + // Constants describing the invocation type.
|
| + // _FIELD cannot be generated by regular invocation mirrors.
|
| + const int _METHOD = 0;
|
| + const int _GETTER = 1;
|
| + const int _SETTER = 2;
|
| + const int _FIELD = 3;
|
| + const int _LOCAL_VAR = 4;
|
| + // ignore: UNUSED_LOCAL_VARIABLE
|
| + const int _TYPE_SHIFT = 0;
|
| + const int _TYPE_BITS = 3;
|
| + // ignore: UNUSED_LOCAL_VARIABLE
|
| + 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.
|
| + const int _DYNAMIC = 0;
|
| + const int _SUPER = 1;
|
| + const int _STATIC = 2;
|
| + const int _CONSTRUCTOR = 3;
|
| + const int _TOP_LEVEL = 4;
|
| + const int _CALL_SHIFT = _TYPE_BITS;
|
| + const int _CALL_BITS = 3;
|
| + // ignore: UNUSED_LOCAL_VARIABLE
|
| + const int _CALL_MASK = (1 << _CALL_BITS) - 1;
|
| +
|
| + int type = -1;
|
| + // For convenience, [isGetter] and [isSetter] takes precedence over
|
| + // [isMethod].
|
| + if (isGetter) {
|
| + type = _GETTER;
|
| + } else if (isSetter) {
|
| + type = _SETTER;
|
| + } else if (isMethod) {
|
| + type = _METHOD;
|
| + } else if (isField) {
|
| + type = _FIELD;
|
| + } else if (isLocalVariable) {
|
| + type = _LOCAL_VAR;
|
| + }
|
| +
|
| + if (isDynamic) {
|
| + type |= (_DYNAMIC << _CALL_SHIFT);
|
| + } else if (isSuper) {
|
| + type |= (_SUPER << _CALL_SHIFT);
|
| + } else if (isStatic) {
|
| + type |= (_STATIC << _CALL_SHIFT);
|
| + } else if (isConstructor) {
|
| + type |= (_CONSTRUCTOR << _CALL_SHIFT);
|
| + } else if (isTopLevel) {
|
| + type |= (_TOP_LEVEL << _CALL_SHIFT);
|
| + }
|
| +
|
| + return type;
|
| + }
|
| +
|
| + Expression _fixedLengthList(List<Expression> elements, int offset) {
|
| // TODO(ahe): It's possible that it would be better to create a fixed-length
|
| // list first, and then populate it. That would create fewer objects. But as
|
| // this is currently only used in (statically resolved) no-such-method
|
| // handling, the current approach seems sufficient.
|
| return new MethodInvocation(
|
| - new ListLiteral(elements)..fileOffset = charOffset,
|
| + new ListLiteral(elements)..fileOffset = offset,
|
| new Name("toList"),
|
| new Arguments(<Expression>[], named: <NamedExpression>[
|
| new NamedExpression("growable", new BoolLiteral(false))
|
|
|