Skip to content

Commit c2c5357

Browse files
nshahanCommit Queue
authored andcommitted
[front_end] Add option for expanded invalidation
In this mode when an edit only touches the body of a mixin (not the public API) libraries that apply the mixin will also be invalidated. Add mixin invalidation test. Issue: #61864 Change-Id: Id4dde67364dcef958ae1e0e0bbf124cec389f5f0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/459343 Commit-Queue: Nicholas Shahan <nshahan@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
1 parent 37574df commit c2c5357

File tree

17 files changed

+463
-0
lines changed

17 files changed

+463
-0
lines changed

pkg/dev_compiler/lib/src/kernel/target.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,15 @@ class DevCompilerTarget extends Target {
328328
@override
329329
DartLibrarySupport get dartLibrarySupport =>
330330
const DevCompilerDartLibrarySupport();
331+
332+
// For correctness the DDC runtime needs to reevaluate libraries that contain
333+
// mixin applications when the mixin was edited. If the edit was only within
334+
// the body of a mixin member the experimental invalidation logic would only
335+
// invalidate that library. This enables a search for applications of the
336+
// mixin in other libraries adds them to the invalidated set.
337+
@override
338+
bool get incrementalCompilerIncludeMixinApplicationInvalidatedLibraries =>
339+
true;
331340
}
332341

333342
class DevCompilerDartLibrarySupport extends CustomizedDartLibrarySupport {

pkg/front_end/lib/src/base/incremental_compiler.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
332332
reusedResult,
333333
c,
334334
uriTranslator,
335+
context
336+
.options
337+
.target
338+
.incrementalCompilerIncludeMixinApplicationInvalidatedLibraries,
335339
);
336340
recorderForTesting?.recordRebuildBodiesCount(
337341
experimentalInvalidation?.missingSources.length ?? 0,
@@ -528,6 +532,14 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
528532
c,
529533
cleanedUpBuilders: cleanedUpBuilders,
530534
);
535+
if (experimentalInvalidation != null &&
536+
experimentalInvalidation.invalidatedMixinApplicationLibraries !=
537+
null) {
538+
outputLibraries = {
539+
...outputLibraries,
540+
...experimentalInvalidation.invalidatedMixinApplicationLibraries!,
541+
}.toList();
542+
}
531543
List<String> problemsAsJson = _componentProblems.reissueProblems(
532544
context,
533545
currentKernelTarget,
@@ -1118,6 +1130,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
11181130
ReusageResult reusedResult,
11191131
CompilerContext c,
11201132
UriTranslator uriTranslator,
1133+
bool collectMixinsToo,
11211134
) async {
11221135
Set<DillLibraryBuilder>? rebuildBodies;
11231136
Set<DillLibraryBuilder> originalNotReusedLibraries;
@@ -1232,6 +1245,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
12321245
// procedures, if the changed file is used as a mixin anywhere else
12331246
// we can't only recompile the changed file.
12341247
// TODO(jensj): Check for mixins in a smarter and faster way.
1248+
Set<Library>? invalidatedMixinApplicationLibraries;
12351249
if (!skipExperimentalInvalidationChecksForTesting) {
12361250
for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
12371251
if (missingSources!.contains(builder.fileUri)) {
@@ -1256,6 +1270,13 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
12561270
return null;
12571271
}
12581272
}
1273+
if (collectMixinsToo &&
1274+
c.mixedInClass != null &&
1275+
missingSources.contains(c.mixedInClass!.fileUri)) {
1276+
(invalidatedMixinApplicationLibraries ??= {}).add(
1277+
c.enclosingLibrary,
1278+
);
1279+
}
12591280
}
12601281
}
12611282

@@ -1324,6 +1345,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
13241345
rebuildBodies,
13251346
originalNotReusedLibraries,
13261347
missingSources,
1348+
invalidatedMixinApplicationLibraries,
13271349
);
13281350
}
13291351

@@ -2727,11 +2749,13 @@ class ExperimentalInvalidation {
27272749
final Set<DillLibraryBuilder> rebuildBodies;
27282750
final Set<DillLibraryBuilder> originalNotReusedLibraries;
27292751
final Set<Uri> missingSources;
2752+
final Set<Library>? invalidatedMixinApplicationLibraries;
27302753

27312754
ExperimentalInvalidation(
27322755
this.rebuildBodies,
27332756
this.originalNotReusedLibraries,
27342757
this.missingSources,
2758+
this.invalidatedMixinApplicationLibraries,
27352759
);
27362760
}
27372761

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'main_lib1.dart';
2+
3+
C c = new C();
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library;
2+
import self as self;
3+
import "main_lib1.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib1.dart";
6+
7+
static field mai::C c = new mai::C::•();
8+
9+
library;
10+
import self as mai;
11+
import "dart:core" as core;
12+
import "main_lib2.dart" as mai2;
13+
14+
import "org-dartlang-testcase:///main_lib2.dart";
15+
16+
class C extends mai::_C&Object&M {
17+
synthetic constructor •() → mai::C
18+
: super mai::_C&Object&M::•()
19+
;
20+
static synthetic method _#new#tearOff() → mai::C
21+
return new mai::C::•();
22+
}
23+
abstract class _C&Object&M = core::Object with mai2::M /*isAnonymousMixin,hasConstConstructor*/ {
24+
const synthetic constructor •() → mai::_C&Object&M
25+
: super core::Object::•()
26+
;
27+
synthetic mixin-super-stub method m1() → core::String
28+
return super.{mai2::M::m1}();
29+
synthetic mixin-super-stub method m2() → core::String
30+
return super.{mai2::M::m2}();
31+
}
32+
33+
library;
34+
import self as mai2;
35+
import "dart:core" as core;
36+
37+
abstract class M extends core::Object /*isMixinDeclaration*/ {
38+
method m1() → core::String {
39+
return "hello";
40+
}
41+
method m2() → core::String {
42+
return "hello";
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library;
2+
import self as self;
3+
import "main_lib1.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib1.dart";
6+
7+
static field mai::C c = new mai::C::•();
8+
9+
library;
10+
import self as mai;
11+
import "dart:core" as core;
12+
import "main_lib2.dart" as mai2;
13+
14+
import "org-dartlang-testcase:///main_lib2.dart";
15+
16+
class C extends mai::_C&Object&M {
17+
synthetic constructor •() → mai::C
18+
: super mai::_C&Object&M::•()
19+
;
20+
static synthetic method _#new#tearOff() → mai::C
21+
return new mai::C::•();
22+
}
23+
abstract class _C&Object&M = core::Object with mai2::M /*isAnonymousMixin,hasConstConstructor*/ {
24+
const synthetic constructor •() → mai::_C&Object&M
25+
: super core::Object::•()
26+
;
27+
synthetic mixin-super-stub method m1() → core::String
28+
return super.{mai2::M::m1}();
29+
synthetic mixin-super-stub method m2() → core::String
30+
return super.{mai2::M::m2}();
31+
}
32+
33+
library;
34+
import self as mai2;
35+
import "dart:core" as core;
36+
37+
abstract class M extends core::Object /*isMixinDeclaration*/ {
38+
method m1() → core::String {
39+
return "hello";
40+
}
41+
method m2() → core::String {
42+
return "hello";
43+
}
44+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
library;
2+
import self as self;
3+
import "main_lib1.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib1.dart";
6+
7+
static field mai::C c;
8+
9+
library;
10+
import self as mai;
11+
import "dart:core" as core;
12+
import "main_lib2.dart" as mai2;
13+
14+
import "org-dartlang-testcase:///main_lib2.dart";
15+
16+
class C extends mai::_C&Object&M {
17+
synthetic constructor •() → mai::C
18+
;
19+
static synthetic method _#new#tearOff() → mai::C
20+
return new mai::C::•();
21+
}
22+
abstract class _C&Object&M = core::Object with mai2::M /*isAnonymousMixin,hasConstConstructor*/ {
23+
const synthetic constructor •() → mai::_C&Object&M
24+
: super core::Object::•()
25+
;
26+
synthetic mixin-super-stub method m1() → core::String
27+
return super.{mai2::M::m1}();
28+
synthetic mixin-super-stub method m2() → core::String
29+
return super.{mai2::M::m2}();
30+
}
31+
32+
library;
33+
import self as mai2;
34+
import "dart:core" as core;
35+
36+
abstract class M extends core::Object /*isMixinDeclaration*/ {
37+
method m1() → core::String
38+
;
39+
method m2() → core::String
40+
;
41+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library;
2+
import self as self;
3+
import "main_lib1.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib1.dart";
6+
7+
static field mai::C c = new mai::C::•();
8+
9+
library;
10+
import self as mai;
11+
import "dart:core" as core;
12+
import "main_lib2.dart" as mai2;
13+
14+
import "org-dartlang-testcase:///main_lib2.dart";
15+
16+
class C extends mai::_C&Object&M {
17+
synthetic constructor •() → mai::C
18+
: super mai::_C&Object&M::•()
19+
;
20+
static synthetic method _#new#tearOff() → mai::C
21+
return new mai::C::•();
22+
}
23+
abstract class _C&Object&M = core::Object with mai2::M /*isAnonymousMixin,hasConstConstructor*/ {
24+
const synthetic constructor •() → mai::_C&Object&M
25+
: super core::Object::•()
26+
;
27+
synthetic mixin-super-stub method m1() → core::String
28+
return super.{mai2::M::m1}();
29+
synthetic mixin-super-stub method m2() → core::String
30+
return super.{mai2::M::m2}();
31+
}
32+
33+
library;
34+
import self as mai2;
35+
import "dart:core" as core;
36+
37+
abstract class M extends core::Object /*isMixinDeclaration*/ {
38+
method m1() → core::String {
39+
return "hello";
40+
}
41+
method m2() → core::String {
42+
return "hello";
43+
}
44+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'main_lib1.dart';
2+
3+
C c = new C();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'main_lib1.dart';
2+
3+
C c = new C();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'main_lib2.dart';
2+
3+
class C with M {}

0 commit comments

Comments
 (0)