|  | // Copyright (c) 2017, 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. | 
|  |  | 
|  | // @dart = 2.9 | 
|  |  | 
|  | // VMOptions=--lazy-dispatchers | 
|  | // VMOptions=--no-lazy-dispatchers | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  |  | 
|  | // Test that noSuchMethod calls behave as expected for dynamic object invocations. | 
|  | class BaseClass { | 
|  | final dynamic finalField = "final!"; | 
|  |  | 
|  | baz() => "baz!!"; | 
|  | get bla => (() => "bla!!"); | 
|  | } | 
|  |  | 
|  | class ReturnInvocationName extends BaseClass { | 
|  | var _bar; | 
|  |  | 
|  | ReturnInvocationName(this._bar); | 
|  |  | 
|  | noSuchMethod(Invocation invocation) { | 
|  | var name = invocation.memberName.toString(); | 
|  | var match = new RegExp(r'Symbol\("([^"]+)"\)').matchAsPrefix(name); | 
|  | return match != null ? match.group(1) : name; | 
|  | } | 
|  |  | 
|  | bar() { | 
|  | return _bar; | 
|  | } | 
|  | } | 
|  |  | 
|  | class Foo {} | 
|  |  | 
|  | main() { | 
|  | dynamic x = new ReturnInvocationName(42); | 
|  | Expect.equals('final!', x.finalField); | 
|  | Expect.equals('foo', x.finalField = "foo", 'should call noSuchMethod'); | 
|  | Expect.equals('final!', x.finalField, 'field was not set'); | 
|  |  | 
|  | Expect.equals('_prototype', x._prototype); | 
|  | Expect.equals('_prototype', x._prototype()); | 
|  |  | 
|  | Expect.equals('prototype', x.prototype); | 
|  | Expect.equals('prototype', x.prototype()); | 
|  |  | 
|  | Expect.equals('constructor', x.constructor); | 
|  | Expect.equals('constructor', x.constructor()); | 
|  |  | 
|  | Expect.equals('__proto__', x.__proto__); | 
|  | Expect.equals('__proto__', x.__proto__); | 
|  |  | 
|  | Expect.equals(42, x.bar()); | 
|  | Expect.equals(42, (x.bar)()); | 
|  |  | 
|  | Expect.equals('unary-', -x); | 
|  | Expect.equals('+', x + 42); | 
|  | Expect.equals('[]', x[4]); | 
|  |  | 
|  | dynamic b = new BaseClass(); | 
|  | Expect.equals('final!', b.finalField); | 
|  | Expect.throwsNoSuchMethodError(() => b.finalField = "foo"); | 
|  | Expect.equals('final!', b.finalField, 'field was not set'); | 
|  |  | 
|  | // Verify that noSuchMethod errors are triggered even when the JS object | 
|  | // happens to have a matching member name. | 
|  | dynamic f = new Foo(); | 
|  | Expect.throwsNoSuchMethodError(() => f.prototype); | 
|  | Expect.throwsNoSuchMethodError(() => f.prototype()); | 
|  | Expect.throwsNoSuchMethodError(() => f.prototype = 42); | 
|  |  | 
|  | Expect.throwsNoSuchMethodError(() => f.constructor); | 
|  | Expect.throwsNoSuchMethodError(() => f.constructor()); | 
|  | Expect.throwsNoSuchMethodError(() => f.constructor = 42); | 
|  |  | 
|  | Expect.throwsNoSuchMethodError(() => f.__proto__); | 
|  |  | 
|  | // These are valid JS properties but not Dart methods. | 
|  | Expect.throwsNoSuchMethodError(() => f.toLocaleString); | 
|  |  | 
|  | Expect.throwsNoSuchMethodError(() => f.hasOwnProperty); | 
|  |  | 
|  | f = (int x) {}; | 
|  | // Calls with the wrong number of arguments should be NoSuchMethodErrors. | 
|  | Expect.throwsNoSuchMethodError(() => f()); | 
|  | Expect.throwsNoSuchMethodError(() => f('hi', '!')); | 
|  | Expect.throwsNoSuchMethodError(() => f(x: 42)); | 
|  | } |