| // Copyright (c) 2015, 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. |
| |
| library source_map_name_test; |
| |
| import 'package:compiler/src/elements/names.dart'; |
| import 'package:expect/async_helper.dart'; |
| import 'package:expect/expect.dart'; |
| import 'package:compiler/src/commandline_options.dart'; |
| import 'package:compiler/src/common/elements.dart' show JElementEnvironment; |
| import 'package:compiler/src/compiler.dart'; |
| import 'package:compiler/src/elements/entities.dart'; |
| import 'package:compiler/src/io/kernel_source_information.dart'; |
| import 'package:compiler/src/js_model/js_world.dart'; |
| import 'package:compiler/src/util/memory_compiler.dart'; |
| |
| const String SOURCE = ''' |
| |
| var toplevelField; |
| toplevelMethod() {} |
| void toplevelAnonymous() { |
| var foo = () {}; |
| } |
| void toplevelLocal() { |
| void localMethod() {} |
| } |
| |
| class Class { |
| Class() { |
| var foo = () {}; |
| } |
| Class.named() { |
| void localMethod() {} |
| } |
| static var staticField; |
| static staticMethod() {} |
| static void staticAnonymous() { |
| var foo = () {}; |
| } |
| static void staticLocal() { |
| void localMethod() {} |
| } |
| var instanceField; |
| instanceMethod() {} |
| void instanceAnonymous() { |
| var foo = () {}; |
| } |
| void instanceLocal() { |
| void localMethod() {} |
| } |
| void instanceNestedLocal() { |
| void localMethod() { |
| var foo = () {}; |
| void nestedLocalMethod() {} |
| } |
| } |
| } |
| |
| main() { |
| toplevelField = toplevelMethod(); |
| toplevelAnonymous(); |
| toplevelLocal(); |
| |
| Class.staticField = Class.staticMethod; |
| Class.staticAnonymous(); |
| Class.staticLocal(); |
| |
| var c = Class(); |
| c = Class.named(); |
| c.instanceField = c.instanceMethod(); |
| c.instanceAnonymous(); |
| c.instanceLocal(); |
| c.instanceNestedLocal(); |
| } |
| '''; |
| |
| main() { |
| asyncTest(() async { |
| CompilationResult result = await runCompiler( |
| memorySourceFiles: {'main.dart': SOURCE}, |
| options: [Flags.disableInlining], |
| ); |
| Compiler compiler = result.compiler!; |
| JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!; |
| JElementEnvironment env = closedWorld.elementEnvironment; |
| LibraryEntity mainApp = env.mainLibrary!; |
| |
| check(MemberEntity element, String expectedName) { |
| String? name = computeKernelElementNameForSourceMaps( |
| closedWorld.elementMap, |
| element, |
| ); |
| Expect.equals( |
| expectedName, |
| name, |
| "Unexpected name '$name' for $element, expected '$expectedName'.", |
| ); |
| } |
| |
| MemberEntity lookup(String name) { |
| MemberEntity? element; |
| int dotPosition = name.indexOf('.'); |
| if (dotPosition != -1) { |
| String clsName = name.substring(0, dotPosition); |
| ClassEntity? cls = env.lookupClass(mainApp, clsName); |
| Expect.isNotNull(cls, "Class '$clsName' not found."); |
| var subname = name.substring(dotPosition + 1); |
| element = |
| env.lookupLocalClassMember( |
| cls!, |
| Name(subname, cls.library.canonicalUri), |
| ) ?? |
| env.lookupConstructor(cls, subname); |
| } else { |
| element = env.lookupLibraryMember(mainApp, name); |
| } |
| Expect.isNotNull(element, "Element '$name' not found."); |
| return element!; |
| } |
| |
| void checkName( |
| String expectedName, [ |
| List<String>? expectedClosureNames, |
| String? lookupName, |
| ]) { |
| if (lookupName == null) { |
| lookupName = expectedName; |
| } |
| dynamic element = lookup(lookupName); |
| check(element, expectedName); |
| if (element is ConstructorEntity) { |
| env.forEachConstructorBody(element.enclosingClass, (body) { |
| if (body.name != element.name) return; |
| Expect.isNotNull( |
| body, |
| "Constructor body '${element.name}' not found.", |
| ); |
| check(body, expectedName); |
| }); |
| } |
| |
| if (expectedClosureNames != null) { |
| int index = 0; |
| env.forEachNestedClosure(element, (closure) { |
| String expectedName = expectedClosureNames[index]; |
| check(closure, expectedName); |
| index++; |
| }); |
| } |
| } |
| |
| checkName('toplevelField'); |
| checkName('toplevelMethod'); |
| checkName('toplevelAnonymous', ['toplevelAnonymous.<anonymous function>']); |
| checkName('toplevelLocal', ['toplevelLocal.localMethod']); |
| checkName('main'); |
| |
| checkName('Class.staticField'); |
| checkName('Class.staticMethod'); |
| checkName('Class.staticAnonymous', [ |
| 'Class.staticAnonymous.<anonymous function>', |
| ]); |
| checkName('Class.staticLocal', ['Class.staticLocal.localMethod']); |
| |
| checkName('Class', ['Class.<anonymous function>'], 'Class.'); |
| checkName('Class.named', ['Class.named.localMethod']); |
| |
| checkName('Class.instanceField'); |
| checkName('Class.instanceMethod'); |
| checkName('Class.instanceAnonymous', [ |
| 'Class.instanceAnonymous.<anonymous function>', |
| ]); |
| checkName('Class.instanceLocal', ['Class.instanceLocal.localMethod']); |
| checkName('Class.instanceNestedLocal', [ |
| 'Class.instanceNestedLocal.localMethod', |
| 'Class.instanceNestedLocal.localMethod.<anonymous function>', |
| 'Class.instanceNestedLocal.localMethod.nestedLocalMethod', |
| ]); |
| }); |
| } |