| Index: pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
|
| diff --git a/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart b/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
|
| index 7fc92d4f7d2fbb06282eb6c44f36fb1543d8fa5f..8fd57733831deceb11c73ee912ece8a379dc1f51 100644
|
| --- a/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
|
| +++ b/pkg/compiler/lib/src/kernel/no_such_method_resolver.dart
|
| @@ -9,21 +9,83 @@ class KernelNoSuchMethodResolver implements NoSuchMethodResolver {
|
|
|
| KernelNoSuchMethodResolver(this.elementMap);
|
|
|
| + ElementEnvironment get _elementEnvironment => elementMap.elementEnvironment;
|
| +
|
| + CommonElements get _commonElements => elementMap.commonElements;
|
| +
|
| @override
|
| bool hasForwardingSyntax(KFunction method) {
|
| - throw new UnimplementedError(
|
| - "KernelNoSuchMethodResolver.hasForwardingSyntax");
|
| + ir.Procedure node = elementMap._lookupProcedure(method);
|
| + if (node.function.positionalParameters.isEmpty) return false;
|
| + ir.VariableDeclaration firstParameter =
|
| + node.function.positionalParameters.first;
|
| + ir.Statement body = node.function.body;
|
| + ir.Expression expr;
|
| + if (body is ir.Block && body.statements.isNotEmpty) {
|
| + ir.Block block = body;
|
| + body = block.statements.first;
|
| + }
|
| + if (body is ir.ReturnStatement) {
|
| + expr = body.expression;
|
| + }
|
| + if (expr is ir.AsExpression &&
|
| + elementMap.getDartType(expr.type) == _commonElements.dynamicType) {
|
| + ir.AsExpression asExpression = expr;
|
| + expr = asExpression.operand;
|
| + }
|
| + if (expr is ir.SuperMethodInvocation &&
|
| + expr.name.name == Identifiers.noSuchMethod_) {
|
| + ir.Arguments arguments = expr.arguments;
|
| + if (arguments.positional.length == 1 &&
|
| + arguments.named.isEmpty &&
|
| + arguments.positional.first is ir.VariableGet) {
|
| + ir.VariableGet get = arguments.positional.first;
|
| + return get.variable == firstParameter;
|
| + }
|
| + }
|
| + return false;
|
| }
|
|
|
| @override
|
| bool hasThrowingSyntax(KFunction method) {
|
| - throw new UnimplementedError(
|
| - "KernelNoSuchMethodResolver.hasThrowingSyntax");
|
| + ir.Procedure node = elementMap._lookupProcedure(method);
|
| + ir.Statement body = node.function.body;
|
| + if (body is ir.Block && body.statements.isNotEmpty) {
|
| + ir.Block block = body;
|
| + body = block.statements.first;
|
| + }
|
| + ir.Expression expr;
|
| + if (body is ir.ReturnStatement) {
|
| + expr = body.expression;
|
| + } else if (body is ir.ExpressionStatement) {
|
| + expr = body.expression;
|
| + }
|
| + return expr is ir.Throw;
|
| }
|
|
|
| @override
|
| FunctionEntity getSuperNoSuchMethod(FunctionEntity method) {
|
| - throw new UnimplementedError(
|
| - "KernelNoSuchMethodResolver.getSuperNoSuchMethod");
|
| + ClassEntity cls = method.enclosingClass;
|
| + while (cls != null) {
|
| + cls = _elementEnvironment.getSuperClass(cls);
|
| + MemberEntity member =
|
| + _elementEnvironment.lookupClassMember(cls, Identifiers.noSuchMethod_);
|
| + if (member != null) {
|
| + if (member.isFunction) {
|
| + FunctionEntity function = member;
|
| + if (function.parameterStructure.positionalParameters >= 1) {
|
| + return function;
|
| + }
|
| + }
|
| + // If [member] is not a valid `noSuchMethod` the target is
|
| + // `Object.superNoSuchMethod`.
|
| + break;
|
| + }
|
| + }
|
| + FunctionEntity function = _elementEnvironment.lookupClassMember(
|
| + _commonElements.objectClass, Identifiers.noSuchMethod_);
|
| + assert(invariant(method, function != null,
|
| + message: "No super noSuchMethod found for $method."));
|
| + return function;
|
| }
|
| }
|
|
|