mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:37:43 +00:00
Make extension methods more readable on dart2js stacktraces
Change-Id: I776b78c5a8742aad5ccc9aa4ffbc86827aacba96 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118205 Commit-Queue: Sigmund Cherem <sigmund@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
3f8c7e5fa2
commit
ff0e8f8035
|
@ -42,6 +42,11 @@ String computeKernelElementNameForSourceMaps(
|
|||
[CallStructure callStructure]) {
|
||||
MemberDefinition definition = elementMap.getMemberDefinition(member);
|
||||
switch (definition.kind) {
|
||||
case MemberKind.regular:
|
||||
ir.Member node = definition.node;
|
||||
if (node.isExtensionMember) return _findExtensionMemberName(node);
|
||||
return computeElementNameForSourceMaps(member, callStructure);
|
||||
|
||||
case MemberKind.closureCall:
|
||||
ir.TreeNode node = definition.node;
|
||||
String name;
|
||||
|
@ -70,6 +75,32 @@ String computeKernelElementNameForSourceMaps(
|
|||
}
|
||||
}
|
||||
|
||||
/// Extract a simple readable name for an extension member.
|
||||
String _findExtensionMemberName(ir.Member member) {
|
||||
assert(member.isExtensionMember);
|
||||
for (ir.Extension extension in member.enclosingLibrary.extensions) {
|
||||
for (ir.ExtensionMemberDescriptor descriptor in extension.members) {
|
||||
if (descriptor.member == member.reference) {
|
||||
String extensionName;
|
||||
// Anonymous extensions contain a # on their synthetic name.
|
||||
if (extension.name.contains('#')) {
|
||||
ir.DartType type = extension.onType;
|
||||
if (type is ir.InterfaceType) {
|
||||
extensionName = "${type.classNode.name}.<anonymous extension>";
|
||||
} else {
|
||||
extensionName = "<anonymous extension>";
|
||||
}
|
||||
} else {
|
||||
extensionName = extension.name;
|
||||
}
|
||||
String memberName = descriptor.name.name;
|
||||
return '$extensionName.$memberName';
|
||||
}
|
||||
}
|
||||
}
|
||||
throw StateError('No original name found for extension member $member.');
|
||||
}
|
||||
|
||||
/// [SourceInformationBuilder] that generates [PositionSourceInformation] from
|
||||
/// Kernel nodes.
|
||||
class KernelSourceInformationBuilder implements SourceInformationBuilder {
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
"exclude": [
|
||||
"^tests/compiler/dart2js/.*/data/.*",
|
||||
"^tests/compiler/dart2js/.*/model_data/.*",
|
||||
"^tests/compiler/dart2js/deferred_loading/libs/.*"
|
||||
"^tests/compiler/dart2js/deferred_loading/libs/.*",
|
||||
"^tests/compiler/dart2js/sourcemaps/stacktrace/extension_method.dart"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
class MyClass {
|
||||
MyClass();
|
||||
|
||||
@pragma('dart2js:noInline')
|
||||
set internalSetter(int v) {
|
||||
/*7:MyClass.internalSetter*/ throw "error";
|
||||
}
|
||||
}
|
||||
|
||||
int q = 3;
|
||||
|
||||
extension Ext on MyClass {
|
||||
@pragma('dart2js:noInline')
|
||||
int method() {
|
||||
this./*6:Ext.method*/ internalSetter = 1;
|
||||
// TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
|
||||
if (q > 29) return 3;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@pragma('dart2js:noInline')
|
||||
int get propertyB {
|
||||
/*5:Ext.propertyB*/ method();
|
||||
// TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
|
||||
if (q > 29) return 3;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@pragma('dart2js:noInline')
|
||||
set propertyA(int v) {
|
||||
/*4:Ext.propertyA*/ propertyB;
|
||||
// TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
|
||||
if (q > 29) return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
@pragma('dart2js:noInline')
|
||||
int operator+(int v) {
|
||||
this./*3:Ext.+*/ propertyA = 2;
|
||||
// TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
|
||||
if (q > 30) return 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
@pragma('dart2js:noInline')
|
||||
int operator[](int v) {
|
||||
this /*2:Ext.[]*/ + 2;
|
||||
// TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
|
||||
if (q > 30) return 1;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
extension on MyClass {
|
||||
@pragma('dart2js:noInline')
|
||||
int method2() {
|
||||
this/*1:MyClass.<anonymous extension>.method2*/[0];
|
||||
// TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
|
||||
if (q > 29) return 3;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
@pragma('dart2js:noInline')
|
||||
confuse(x) => x;
|
||||
|
||||
main() {
|
||||
q++;
|
||||
confuse(null);
|
||||
MyClass x = confuse(new MyClass());
|
||||
x. /*0:main*/method2();
|
||||
}
|
|
@ -85,6 +85,7 @@ Future runTest(Test test, String config,
|
|||
'--libraries-spec=sdk/lib/libraries.json',
|
||||
'--packages=${Platform.packageConfig}',
|
||||
Flags.testMode,
|
||||
'--enable-experiment=extension-methods',
|
||||
input,
|
||||
]..addAll(options);
|
||||
print("Compiling dart2js ${arguments.join(' ')}");
|
||||
|
|
Loading…
Reference in a new issue