|  | // Copyright (c) 2018, 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. | 
|  |  | 
|  | // Test that `length` access in JSArray.indexOf is encoding using `.length` and | 
|  | // not `.get$length()`. | 
|  |  | 
|  | import 'package:compiler/src/compiler.dart'; | 
|  | import 'package:compiler/src/commandline_options.dart'; | 
|  | import 'package:compiler/src/elements/entities.dart'; | 
|  | import 'package:compiler/src/elements/names.dart'; | 
|  | import 'package:compiler/src/js_model/js_world.dart'; | 
|  | import 'package:compiler/src/js_emitter/model.dart'; | 
|  | import 'package:compiler/src/js_model/js_strategy.dart'; | 
|  | import 'package:compiler/src/js/js.dart' as js; | 
|  | import 'package:compiler/src/universe/selector.dart'; | 
|  | import 'package:expect/async_helper.dart'; | 
|  | import 'package:expect/expect.dart'; | 
|  | import 'package:compiler/src/util/memory_compiler.dart'; | 
|  | import '../helpers/element_lookup.dart'; | 
|  | import '../helpers/program_lookup.dart'; | 
|  |  | 
|  | const String source = ''' | 
|  | import 'package:expect/expect.dart'; | 
|  |  | 
|  | @pragma('dart2js:noInline') | 
|  | test(o, a) => o.indexOf(a); | 
|  | main() { | 
|  | test([1, 2, 3], 2); | 
|  | test(['1', '2', '3'], '2'); | 
|  | } | 
|  | '''; | 
|  |  | 
|  | main() { | 
|  | asyncTest(() async { | 
|  | print('--test from kernel (strong mode)----------------------------------'); | 
|  | await runTest([]); | 
|  | print('--test from kernel (strong mode, omit-implicit-checks)------------'); | 
|  | await runTest([Flags.omitImplicitChecks]); | 
|  | }); | 
|  | } | 
|  |  | 
|  | runTest(List<String> options) async { | 
|  | CompilationResult result = await runCompiler( | 
|  | memorySourceFiles: {'main.dart': source}, | 
|  | options: options, | 
|  | ); | 
|  | Expect.isTrue(result.isSuccess); | 
|  | Compiler compiler = result.compiler!; | 
|  | JsBackendStrategy backendStrategy = compiler.backendStrategy; | 
|  | JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!; | 
|  | final jsArrayIndexOf = | 
|  | findClassMember(closedWorld, 'JSArray', 'indexOf') as FunctionEntity; | 
|  | ProgramLookup programLookup = ProgramLookup(backendStrategy); | 
|  |  | 
|  | Selector getLengthSelector = Selector.getter(const PublicName('length')); | 
|  | js.Name getLengthName = backendStrategy.namerForTesting.invocationName( | 
|  | getLengthSelector, | 
|  | ); | 
|  |  | 
|  | Method method = programLookup.getMethod(jsArrayIndexOf)!; | 
|  | int lengthCount = 0; | 
|  | forEachNode( | 
|  | method.code, | 
|  | onCall: (js.Call node) { | 
|  | js.Node target = node.target; | 
|  | Expect.isFalse( | 
|  | target is js.PropertyAccess && target.selector == getLengthName, | 
|  | "Unexpected .get\$length access ${js.nodeToString(node)} in\n" | 
|  | "${js.nodeToString(method.code, pretty: true)}", | 
|  | ); | 
|  | }, | 
|  | onPropertyAccess: (js.PropertyAccess node) { | 
|  | js.Node selector = node.selector; | 
|  | if (selector is js.LiteralString && selector.value == 'length') { | 
|  | lengthCount++; | 
|  | } | 
|  | }, | 
|  | ); | 
|  | Expect.equals( | 
|  | 2, | 
|  | lengthCount, | 
|  | "Unexpected .length access in\n" | 
|  | "${js.nodeToString(method.code, pretty: true)}", | 
|  | ); | 
|  | } |