Skip to content

Commit c8aab9f

Browse files
alexmarkovCommit Queue
authored andcommitted
[dyn_modules] Do not trim field initializers in mixins
When applying a mixin during dynamic module compilation, fields and methods are copied from kernel AST of the mixin. So field initializers within mixins should be preserved while trimming host app kernel file, in order to be available for the dynamic module compilation. TEST=pkg/dynamic_modules/test/data/mixin_field Fixes b/418729276 Change-Id: I00c4392989d552e24dc8c4b4b60c1667de234f98 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429680 Reviewed-by: Sigmund Cherem <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent f810790 commit c8aab9f

File tree

5 files changed

+68
-6
lines changed

5 files changed

+68
-6
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2025, 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+
extendable:
5+
- library: 'shared/shared.dart'
6+
class: 'Foo'
7+
8+
callable:
9+
- library: 'shared/shared.dart'
10+
class: 'Foo'
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2025, 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+
import '../../common/testing.dart' as helper;
6+
7+
import 'shared/shared.dart'; // ignore: unused_import
8+
9+
/// A dynamic module can use mixin with a field.
10+
void main() async {
11+
final func = (await helper.load('entry1.dart')) as void Function();
12+
func();
13+
helper.done();
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2025, 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+
import '../shared/shared.dart';
6+
7+
class Bar with Foo {
8+
void doIt() {
9+
add(1, 'hello');
10+
printAll();
11+
}
12+
}
13+
14+
@pragma('dyn-module:entry-point')
15+
void Function() main() {
16+
return () {
17+
Bar().doIt();
18+
};
19+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) 2025, 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+
mixin Foo {
6+
final Map<int, String> _foo = {};
7+
8+
void add(int i, String s) {
9+
_foo[i] = s;
10+
}
11+
12+
void printAll() {
13+
print(_foo);
14+
}
15+
}

pkg/front_end/lib/src/util/trim.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ class Trimmer extends RecursiveVisitor {
148148
final bool Function(Library) isExtendable;
149149

150150
/// Whether we are within a mixin declaration in an extendable library, and
151-
/// hence method bodies need to be preserved.
152-
bool preserveMethodBodies = false;
151+
/// hence member bodies need to be preserved.
152+
bool preserveMemberBodies = false;
153153

154154
Trimmer(this.librariesToClear, this.isExtendable);
155155

@@ -181,10 +181,10 @@ class Trimmer extends RecursiveVisitor {
181181

182182
@override
183183
void visitClass(Class node) {
184-
preserveMethodBodies = isExtendable(node.enclosingLibrary) &&
184+
preserveMemberBodies = isExtendable(node.enclosingLibrary) &&
185185
(node.isMixinClass || node.isMixinDeclaration);
186186
super.visitClass(node);
187-
preserveMethodBodies = false;
187+
preserveMemberBodies = false;
188188
}
189189

190190
@override
@@ -204,7 +204,7 @@ class Trimmer extends RecursiveVisitor {
204204
void visitProcedure(Procedure node) {
205205
// Preserve method bodies of mixin declarations, these are copied when
206206
// mixins are applied in subtypes.
207-
if (!preserveMethodBodies) {
207+
if (!preserveMemberBodies) {
208208
node.function.body = null;
209209
}
210210
}
@@ -224,7 +224,11 @@ class Trimmer extends RecursiveVisitor {
224224
if (node.isLate && node.isFinal) return;
225225
if (node.isStatic) return;
226226

227-
node.initializer = null;
227+
// Preserve field initializers in mixin declarations, these are copied when
228+
// mixins are applied in subtypes.
229+
if (!preserveMemberBodies) {
230+
node.initializer = null;
231+
}
228232
}
229233
}
230234

0 commit comments

Comments
 (0)