Skip to content

Commit a6b0fce

Browse files
alexmarkovCommit Queue
authored andcommitted
[tfa,aot,dart2wasm] Retain libraries which only have extensions and extension types
Previously, TFA-based tree shaker did not retain libraries if they have extensions and extension types which are still used. As a result, kernel files were incomplete and certain tools, such as Flutter const finder failed to read kernel files after tree shaking. This change fixes tree shaker to retain libraries when they have used extensions and extension types. TEST=pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter160137.dart Fixes flutter/flutter#160137 Change-Id: Iac6f3a13323d053dfab2230367dcafa2550484db Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401481 Commit-Queue: Slava Egorov <[email protected]> Auto-Submit: Alexander Markov <[email protected]> Reviewed-by: Slava Egorov <[email protected]>
1 parent 982b9fa commit a6b0fce

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed

pkg/vm/lib/transformations/type_flow/transformer.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,7 @@ class TreeShaker {
998998

999999
void addUsedExtension(Extension node) {
10001000
if (_usedExtensions.add(node)) {
1001+
_usedLibraries.add(node.enclosingLibrary);
10011002
node.annotations = const <Expression>[];
10021003
_pass1.transformTypeParameterList(node.typeParameters, node);
10031004
node.onType.accept(typeVisitor);
@@ -1006,6 +1007,7 @@ class TreeShaker {
10061007

10071008
void addUsedExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
10081009
if (_usedExtensionTypeDeclarations.add(node)) {
1010+
_usedLibraries.add(node.enclosingLibrary);
10091011
node.annotations = const <Expression>[];
10101012
_pass1.transformTypeParameterList(node.typeParameters, node);
10111013
node.declaredRepresentationType.accept(typeVisitor);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Regression test for https://github.com/flutter/flutter/issues/160137.
6+
// Verifies that TFA correctly retains library if it only has an extension
7+
// type declaration.
8+
9+
import 'regress_flutter160137.lib.dart';
10+
11+
class Class {
12+
void procedure() {
13+
Helper helper = new Helper();
14+
if (helper.instance != null) {
15+
print("hello");
16+
}
17+
}
18+
}
19+
20+
class Helper {
21+
Helper();
22+
MyExtensionType? get instance {
23+
return null;
24+
}
25+
}
26+
27+
void main() {
28+
Class c = new Class();
29+
c.procedure();
30+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
library #lib;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
import "file:pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter160137.lib.dart";
6+
7+
class Class extends core::Object {
8+
synthetic constructor •() → self::Class
9+
: super core::Object::•()
10+
;
11+
12+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
13+
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]
14+
method procedure() → void {
15+
self::Helper helper = new self::Helper::•();
16+
{
17+
[@vm.direct-call.metadata=#lib::Helper.instance] [@vm.inferred-type.metadata=dart.core::Null? (value: null)] helper.{self::Helper::instance}{#lib1::MyExtensionType? /* erasure=core::int? */};
18+
}
19+
}
20+
}
21+
class Helper extends core::Object {
22+
constructor •() → self::Helper
23+
: super core::Object::•()
24+
;
25+
26+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
27+
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:3]
28+
get instance() → #lib1::MyExtensionType? /* erasure=core::int? */ {
29+
return null;
30+
}
31+
}
32+
33+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
34+
static method main() → void {
35+
self::Class c = new self::Class::•();
36+
[@vm.direct-call.metadata=#lib::Class.procedure] [@vm.inferred-type.metadata=!? (skip check)] c.{self::Class::procedure}(){() → void};
37+
}
38+
library regress_flutter160137.lib.dart;
39+
import self as self;
40+
import "dart:core" as core;
41+
42+
extension type MyExtensionType(core::int foo) {
43+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension type const MyExtensionType._(int foo) {}

0 commit comments

Comments
 (0)