| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart2js.kernel.element_map; | 5 part of dart2js.kernel.element_map; |
| 6 | 6 |
| 7 class KernelNoSuchMethodResolver implements NoSuchMethodResolver { | 7 class KernelNoSuchMethodResolver implements NoSuchMethodResolver { |
| 8 final KernelToElementMap elementMap; | 8 final KernelToElementMap elementMap; |
| 9 | 9 |
| 10 KernelNoSuchMethodResolver(this.elementMap); | 10 KernelNoSuchMethodResolver(this.elementMap); |
| 11 | 11 |
| 12 ElementEnvironment get _elementEnvironment => elementMap.elementEnvironment; |
| 13 |
| 14 CommonElements get _commonElements => elementMap.commonElements; |
| 15 |
| 12 @override | 16 @override |
| 13 bool hasForwardingSyntax(KFunction method) { | 17 bool hasForwardingSyntax(KFunction method) { |
| 14 throw new UnimplementedError( | 18 ir.Procedure node = elementMap._lookupProcedure(method); |
| 15 "KernelNoSuchMethodResolver.hasForwardingSyntax"); | 19 if (node.function.positionalParameters.isEmpty) return false; |
| 20 ir.VariableDeclaration firstParameter = |
| 21 node.function.positionalParameters.first; |
| 22 ir.Statement body = node.function.body; |
| 23 ir.Expression expr; |
| 24 if (body is ir.Block && body.statements.isNotEmpty) { |
| 25 ir.Block block = body; |
| 26 body = block.statements.first; |
| 27 } |
| 28 if (body is ir.ReturnStatement) { |
| 29 expr = body.expression; |
| 30 } |
| 31 if (expr is ir.AsExpression && |
| 32 elementMap.getDartType(expr.type) == _commonElements.dynamicType) { |
| 33 ir.AsExpression asExpression = expr; |
| 34 expr = asExpression.operand; |
| 35 } |
| 36 if (expr is ir.SuperMethodInvocation && |
| 37 expr.name.name == Identifiers.noSuchMethod_) { |
| 38 ir.Arguments arguments = expr.arguments; |
| 39 if (arguments.positional.length == 1 && |
| 40 arguments.named.isEmpty && |
| 41 arguments.positional.first is ir.VariableGet) { |
| 42 ir.VariableGet get = arguments.positional.first; |
| 43 return get.variable == firstParameter; |
| 44 } |
| 45 } |
| 46 return false; |
| 16 } | 47 } |
| 17 | 48 |
| 18 @override | 49 @override |
| 19 bool hasThrowingSyntax(KFunction method) { | 50 bool hasThrowingSyntax(KFunction method) { |
| 20 throw new UnimplementedError( | 51 ir.Procedure node = elementMap._lookupProcedure(method); |
| 21 "KernelNoSuchMethodResolver.hasThrowingSyntax"); | 52 ir.Statement body = node.function.body; |
| 53 if (body is ir.Block && body.statements.isNotEmpty) { |
| 54 ir.Block block = body; |
| 55 body = block.statements.first; |
| 56 } |
| 57 ir.Expression expr; |
| 58 if (body is ir.ReturnStatement) { |
| 59 expr = body.expression; |
| 60 } else if (body is ir.ExpressionStatement) { |
| 61 expr = body.expression; |
| 62 } |
| 63 return expr is ir.Throw; |
| 22 } | 64 } |
| 23 | 65 |
| 24 @override | 66 @override |
| 25 FunctionEntity getSuperNoSuchMethod(FunctionEntity method) { | 67 FunctionEntity getSuperNoSuchMethod(FunctionEntity method) { |
| 26 throw new UnimplementedError( | 68 ClassEntity cls = method.enclosingClass; |
| 27 "KernelNoSuchMethodResolver.getSuperNoSuchMethod"); | 69 while (cls != null) { |
| 70 cls = _elementEnvironment.getSuperClass(cls); |
| 71 MemberEntity member = |
| 72 _elementEnvironment.lookupClassMember(cls, Identifiers.noSuchMethod_); |
| 73 if (member != null) { |
| 74 if (member.isFunction) { |
| 75 FunctionEntity function = member; |
| 76 if (function.parameterStructure.positionalParameters >= 1) { |
| 77 return function; |
| 78 } |
| 79 } |
| 80 // If [member] is not a valid `noSuchMethod` the target is |
| 81 // `Object.superNoSuchMethod`. |
| 82 break; |
| 83 } |
| 84 } |
| 85 FunctionEntity function = _elementEnvironment.lookupClassMember( |
| 86 _commonElements.objectClass, Identifiers.noSuchMethod_); |
| 87 assert(invariant(method, function != null, |
| 88 message: "No super noSuchMethod found for $method.")); |
| 89 return function; |
| 28 } | 90 } |
| 29 } | 91 } |
| OLD | NEW |