[ddc] Add constructor symbol information
- Adds tests for various types of constructors.
- Recognize when a constructor is const and mark the class symbol
accordingly.
Change-Id: I9ae7fc2837a6821b196f06a267603fd18c3e5075
Issue: https://github.com/dart-lang/sdk/issues/40273
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/208362
Reviewed-by: Anna Gringauze <annagrin@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 0297cf8..f55ce1a 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1046,8 +1046,9 @@
if (name != '' || hasUnnamedSuper)
_emitSuperConstructorCall(className, name, jsParams),
];
- body.add(_addConstructorToClass(
- c, className, name, js_ast.Fun(jsParams, js_ast.Block(ctorBody))));
+ // TODO(nshahan) Record the name for this constructor in memberNames.
+ body.add(_addConstructorToClass(c, className, _constructorName(name),
+ js_ast.Fun(jsParams, js_ast.Block(ctorBody))));
}
}
@@ -1197,14 +1198,17 @@
return body;
}
- void addConstructor(String name, js_ast.Expression jsCtor) {
+ void addConstructor(js_ast.LiteralString name, js_ast.Expression jsCtor) {
body.add(_addConstructorToClass(c, className, name, jsCtor));
}
var fields = c.fields;
for (var ctor in c.constructors) {
if (ctor.isExternal) continue;
- addConstructor(ctor.name.text, _emitConstructor(ctor, fields, className));
+ var constructorName = _constructorName(ctor.name.text);
+ memberNames[ctor] = constructorName.valueWithoutQuotes;
+ addConstructor(
+ constructorName, _emitConstructor(ctor, fields, className));
}
// If classElement has only factory constructors, and it can be mixed in,
@@ -1617,7 +1621,7 @@
return body;
}
- js_ast.Expression _constructorName(String name) {
+ js_ast.LiteralString _constructorName(String name) {
if (name == '') {
// Default constructors (factory or not) use `new` as their name.
return propertyName('new');
@@ -1773,8 +1777,8 @@
}
js_ast.Statement _addConstructorToClass(Class c, js_ast.Expression className,
- String name, js_ast.Expression jsCtor) {
- jsCtor = defineValueOnClass(c, className, _constructorName(name), jsCtor);
+ js_ast.LiteralString name, js_ast.Expression jsCtor) {
+ jsCtor = defineValueOnClass(c, className, name, jsCtor);
return js.statement('#.prototype = #.prototype;', [jsCtor, className]);
}
@@ -2084,9 +2088,10 @@
/// [_emitFunction] instead.
var name = node.name.text;
var jsBody = _emitSyncFunctionBody(function, name);
+ var jsName = _constructorName(name);
+ memberNames[node] = jsName.valueWithoutQuotes;
- return js_ast.Method(
- _constructorName(name), js_ast.Fun(_emitParameters(function), jsBody),
+ return js_ast.Method(jsName, js_ast.Fun(_emitParameters(function), jsBody),
isStatic: true)
..sourceInformation = _nodeEnd(node.fileEndOffset);
}
diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
index e99dc07..2b458bb 100644
--- a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
+++ b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
@@ -49,12 +49,38 @@
// TODO(nshahan) How to handle function types or types from other modules?
type is InterfaceType ? _classJsNames[type.classNode] : null;
+ /// Returns the symbol for the function defined by [node].
+ void _createFunctionSymbol(Member node) {
+ var functionSymbol = FunctionSymbol(
+ name: node.name.text,
+ // TODO(nshahan) typeId - probably should canonicalize but keep original
+ // type argument names.
+ // TODO(nshahan) Should we mark all constructors static?
+ isStatic: node is Procedure ? node.isStatic : false,
+ isConst: node.isConst,
+ localId: _memberJsNames[node] ?? _procedureJsNames[node],
+ scopeId: _scopes.last.id,
+ variableIds: <String>[],
+ scopeIds: <String>[],
+ location: SourceLocation(
+ scriptId: _scriptId(node.location.file),
+ tokenPos: node.fileOffset,
+ endTokenPos: node.fileEndOffset));
+
+ _scopes.add(functionSymbol);
+ node.visitChildren(this);
+ _scopes
+ ..removeLast()
+ ..last.scopeIds.add(functionSymbol.id);
+ _moduleSymbols.functions.add(functionSymbol);
+ }
+
@override
void visitClass(Class node) {
var classSymbol = ClassSymbol(
name: node.name,
isAbstract: node.isAbstract,
- // TODO(nshahan) isConst - Does this mean has a const constructor?
+ isConst: node.constructors.any((constructor) => constructor.isConst),
superClassId: _classJsNames[node.superclass],
interfaceIds: [
for (var type in node.implementedTypes) _classJsNames[type.classNode]
@@ -83,6 +109,9 @@
}
@override
+ void visitConstructor(Constructor node) => _createFunctionSymbol(node);
+
+ @override
void visitField(Field node) {
var fieldSymbol = VariableSymbol(
name: node.name.text,
@@ -149,27 +178,7 @@
// Also avoid adding information for the static methods introduced by the
// CFE lowering for constructor tearoffs.
if (node.function.body == null || isTearOffLowering(node)) return;
- var functionSymbol = FunctionSymbol(
- name: node.name.text,
- // TODO(nshahan) typeId - probably should canonicalize but keep original
- // type argument names.
- isStatic: node.isStatic,
- isConst: node.isConst,
- localId: _memberJsNames[node] ?? _procedureJsNames[node],
- scopeId: _scopes.last.id,
- variableIds: <String>[],
- scopeIds: <String>[],
- location: SourceLocation(
- scriptId: _scriptId(node.location.file),
- tokenPos: node.fileOffset,
- endTokenPos: node.fileEndOffset));
-
- _scopes.add(functionSymbol);
- node.visitChildren(this);
- _scopes
- ..removeLast()
- ..last.scopeIds.add(functionSymbol.id);
- _moduleSymbols.functions.add(functionSymbol);
+ _createFunctionSymbol(node);
}
@override
diff --git a/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
index c08995f..7d89f6d0 100644
--- a/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
+++ b/pkg/dev_compiler/test/module_symbols/class_symbols_test.dart
@@ -10,6 +10,13 @@
import '../shared_test_options.dart';
import 'module_symbols_test_shared.dart';
+/// Returns the [FunctionSymbol] from [ModuleSymbols] with the [name] in the
+/// original Dart source code or throws an error if there isn't exactly one.
+FunctionSymbol _symbolForDartFunction(ModuleSymbols symbols, String name) =>
+ symbols.functions
+ .where((functionSymbol) => functionSymbol.name == name)
+ .single;
+
void main() async {
for (var mode in [
NullSafetyTestOption('Sound Mode:', true),
@@ -20,6 +27,7 @@
group('simple class debug symbols', () {
TestDriver driver;
ClassSymbol classSymbol;
+ FunctionSymbol functionSymbol;
final source = '''
${options.dartLangComment}
@@ -29,6 +37,7 @@
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
+ functionSymbol = result.symbols.functions.single;
});
tearDownAll(() {
driver.cleanUp();
@@ -39,7 +48,9 @@
test('is not abstract', () async {
expect(classSymbol.isAbstract, isFalse);
});
- // TODO test isConst
+ test('is not const', () async {
+ expect(classSymbol.isConst, isFalse);
+ });
test('has no superclassId', () async {
expect(classSymbol.superClassId, isNull);
});
@@ -71,7 +82,14 @@
test('no fields', () async {
expect(classSymbol.variableIds, isEmpty);
});
- // TODO only has the implicit constructor in scopeIds.
+ test('only default constructor in functionIds', () {
+ var constructorId = classSymbol.functionIds.single;
+ expect(constructorId, functionSymbol.id);
+ // Default constructor has no name in Dart Kernel AST.
+ expect(functionSymbol.name, isEmpty);
+ // Default constructor is named 'new' in JavaScript.
+ expect(functionSymbol.id, endsWith('A|new'));
+ });
});
group('abstract class debug symbols', () {
TestDriver driver;
@@ -308,14 +326,15 @@
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicInstanceMethod');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
expect(methodSymbol.id, endsWith('A|publicInstanceMethod'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -340,14 +359,15 @@
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateInstanceMethod');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
expect(methodSymbol.id, endsWith('A|Symbol(_privateInstanceMethod)'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -372,14 +392,15 @@
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicStaticMethod');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
expect(methodSymbol.id, endsWith('A|publicStaticMethod'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -404,14 +425,15 @@
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateStaticMethod');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
expect(methodSymbol.id, endsWith('A|_privateStaticMethod'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -429,21 +451,22 @@
${options.dartLangComment}
class A {
- String get publicGetter() => 'Fosse';
+ String get publicInstanceGetter() => 'Fosse';
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicInstanceGetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|publicGetter'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|publicInstanceGetter'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -461,21 +484,22 @@
${options.dartLangComment}
class A {
- String get _privateGetter() => 'Fosse';
+ String get _privateInstanceGetter() => 'Fosse';
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateInstanceGetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|Symbol(_privateGetter)'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|Symbol(_privateInstanceGetter)'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -494,21 +518,22 @@
class A {
var _value
- set publicSetter(String v) => _value = v;
+ set publicInstanceSetter(String v) => _value = v;
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicInstanceSetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|publicSetter'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|publicInstanceSetter'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -527,21 +552,22 @@
class A {
var _value
- set _privateSetter(String v) => _value = v;
+ set _privateInstanceSetter(String v) => _value = v;
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateInstanceSetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|Symbol(_privateSetter)'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|Symbol(_privateInstanceSetter)'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -559,21 +585,22 @@
${options.dartLangComment}
class A {
- static String get publicGetter() => 'Fosse';
+ static String get publicStaticGetter() => 'Fosse';
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicStaticGetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|publicGetter'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|publicStaticGetter'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -591,21 +618,22 @@
${options.dartLangComment}
class A {
- static String get _privateGetter() => 'Fosse';
+ static String get _privateStaticGetter() => 'Fosse';
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateStaticGetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|_privateGetter'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|_privateStaticGetter'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -624,21 +652,22 @@
class A {
var _value;
- static set publicSetter(String v) => _value = v;
+ static set publicStaticSetter(String v) => _value = v;
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicStaticSetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|publicSetter'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|publicStaticSetter'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -657,21 +686,22 @@
class A {
var _value;
- static set _privateSetter(String v) => _value = v;
+ static set _privateStaticSetter(String v) => _value = v;
}
''';
setUpAll(() async {
driver = TestDriver(options, source);
var result = await driver.compile();
classSymbol = result.symbols.classes.single;
- methodSymbol = result.symbols.functions.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateStaticSetter');
});
tearDownAll(() {
driver.cleanUp();
});
test('functionId in classSymbol', () async {
- expect(methodSymbol.id, endsWith('A|_privateSetter'));
- expect(methodSymbol.id, classSymbol.functionIds.single);
+ expect(methodSymbol.id, endsWith('A|_privateStaticSetter'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
});
test('has class scopeId', () async {
expect(methodSymbol.scopeId, endsWith('|A'));
@@ -681,6 +711,257 @@
expect(methodSymbol.isStatic, isTrue);
});
});
+ group('class public const constructor debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ const A();
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = _symbolForDartFunction(result.symbols, '');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|new'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ test('is const', () async {
+ expect(methodSymbol.isConst, isTrue);
+ expect(classSymbol.isConst, isTrue);
+ });
+ });
+ group('class public named constructor debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ A.named();
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = _symbolForDartFunction(result.symbols, 'named');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|named'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
+ group('class private named constructor debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ A._(this._value);
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = _symbolForDartFunction(result.symbols, '_');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|__'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
+ group('class unnamed factory debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ A._(this._value);
+ factory A() => A._(10);
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol = _symbolForDartFunction(result.symbols, '');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|new'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
+ group('class public named factory debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ A._(this._value);
+ factory A.publicFactory() => A._(10);
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicFactory');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicFactory'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
+ group('class private named factory debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ A._(this._value);
+ factory A._privateFactory() => A._(10);
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateFactory');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|_privateFactory'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
+ group('class public redirecting constructor debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ A(this._value);
+ A.publicRedirecting() : this(10);
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, 'publicRedirecting');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|publicRedirecting'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
+ group('class private redirecting constructor debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ FunctionSymbol methodSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {
+ var _value;
+ A(this._value);
+ A._privateRedirecting() : this(10);
+ }
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ methodSymbol =
+ _symbolForDartFunction(result.symbols, '_privateRedirecting');
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('functionId in classSymbol', () async {
+ expect(methodSymbol.id, endsWith('A|_privateRedirecting'));
+ expect(classSymbol.functionIds, contains(methodSymbol.id));
+ });
+ test('has class scopeId', () async {
+ expect(methodSymbol.scopeId, endsWith('|A'));
+ expect(methodSymbol.scopeId, classSymbol.id);
+ });
+ });
});
}
}