Skip to content

Commit d5c9f08

Browse files
chloestefantsovaCommit Bot
authored and
Commit Bot
committed
[cfe] Add DillConstructorBuilder to super parameters inference
Part of #47525 Change-Id: If88bf24dffa79e214e49b5133ee8314bbdb53716 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239426 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent ba4e18b commit d5c9f08

15 files changed

+388
-33
lines changed

pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,20 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
320320

321321
ConstructorBuilder? superTargetBuilder =
322322
_computeSuperTargetBuilder(initializers);
323+
324+
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
325+
superTargetBuilder.inferFormalTypes(typeEnvironment);
326+
} else if (superTargetBuilder is SyntheticSourceConstructorBuilder) {
327+
MemberBuilder? superTargetOriginBuilder =
328+
superTargetBuilder._effectivelyDefiningConstructor;
329+
if (superTargetOriginBuilder is DeclaredSourceConstructorBuilder) {
330+
superTargetOriginBuilder.inferFormalTypes(typeEnvironment);
331+
}
332+
}
333+
323334
Constructor superTarget;
324335
List<FormalParameterBuilder>? superFormals;
336+
FunctionNode? superConstructorFunction;
325337
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
326338
superTarget = superTargetBuilder.constructor;
327339
superFormals = superTargetBuilder.formals!;
@@ -330,30 +342,45 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
330342
if (superTargetBuilder is SyntheticSourceConstructorBuilder) {
331343
superFormals = superTargetBuilder.formals;
332344
} else {
333-
// The error in this case should be reported elsewhere. Here we perform
334-
// a simple recovery.
335-
return performRecoveryForErroneousCase();
345+
superConstructorFunction = superTargetBuilder.function;
336346
}
337347
} else {
338348
// The error in this case should be reported elsewhere. Here we perform a
339349
// simple recovery.
340350
return performRecoveryForErroneousCase();
341351
}
342352

343-
if (superFormals == null) {
344-
// The error in this case should be reported elsewhere. Here we perform a
345-
// simple recovery.
346-
return performRecoveryForErroneousCase();
347-
}
348-
349-
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
350-
superTargetBuilder.inferFormalTypes(typeEnvironment);
351-
} else if (superTargetBuilder is SyntheticSourceConstructorBuilder) {
352-
MemberBuilder? superTargetOriginBuilder =
353-
superTargetBuilder._effectivelyDefiningConstructor;
354-
if (superTargetOriginBuilder is DeclaredSourceConstructorBuilder) {
355-
superTargetOriginBuilder.inferFormalTypes(typeEnvironment);
353+
List<DartType?> positionalSuperFormalType = [];
354+
List<bool> positionalSuperFormalHasInitializer = [];
355+
Map<String, DartType?> namedSuperFormalType = {};
356+
Map<String, bool> namedSuperFormalHasInitializer = {};
357+
if (superFormals != null) {
358+
for (FormalParameterBuilder formal in superFormals) {
359+
if (formal.isPositional) {
360+
positionalSuperFormalType.add(formal.variable?.type);
361+
positionalSuperFormalHasInitializer
362+
.add(formal.hasDeclaredInitializer);
363+
} else {
364+
namedSuperFormalType[formal.name] = formal.variable?.type;
365+
namedSuperFormalHasInitializer[formal.name] =
366+
formal.hasDeclaredInitializer;
367+
}
368+
}
369+
} else if (superConstructorFunction != null) {
370+
for (VariableDeclaration formal
371+
in superConstructorFunction.positionalParameters) {
372+
positionalSuperFormalType.add(formal.type);
373+
positionalSuperFormalHasInitializer.add(formal.initializer != null);
356374
}
375+
for (VariableDeclaration formal
376+
in superConstructorFunction.namedParameters) {
377+
namedSuperFormalType[formal.name!] = formal.type;
378+
namedSuperFormalHasInitializer[formal.name!] =
379+
formal.initializer != null;
380+
}
381+
} else {
382+
// The error is reported elsewhere.
383+
return performRecoveryForErroneousCase();
357384
}
358385

359386
int superInitializingFormalIndex = -1;
@@ -373,33 +400,30 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
373400
superInitializingFormalIndex++;
374401
bool hasImmediatelyDeclaredInitializer = formal.hasDeclaredInitializer;
375402

376-
FormalParameterBuilder? correspondingSuperFormal;
377-
403+
DartType? correspondingSuperFormalType;
378404
if (formal.isPositional) {
379-
if (superInitializingFormalIndex < superFormals.length) {
380-
correspondingSuperFormal =
381-
superFormals[superInitializingFormalIndex];
405+
assert(positionalSuperFormalHasInitializer.length ==
406+
positionalSuperFormalType.length);
407+
if (superInitializingFormalIndex <
408+
positionalSuperFormalHasInitializer.length) {
382409
formal.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer ||
383-
correspondingSuperFormal.hasDeclaredInitializer;
410+
positionalSuperFormalHasInitializer[
411+
superInitializingFormalIndex];
412+
correspondingSuperFormalType =
413+
positionalSuperFormalType[superInitializingFormalIndex];
384414
if (!hasImmediatelyDeclaredInitializer && !formal.isRequired) {
385415
(positionalSuperParameters ??= <int?>[]).add(formalIndex);
386416
} else {
387417
(positionalSuperParameters ??= <int?>[]).add(null);
388418
}
389419
} else {
390-
// TODO(cstefantsova): Report an error.
420+
// The error is reported elsewhere.
391421
}
392422
} else {
393-
for (FormalParameterBuilder superFormal in superFormals) {
394-
if (superFormal.isNamed && superFormal.name == formal.name) {
395-
correspondingSuperFormal = superFormal;
396-
break;
397-
}
398-
}
399-
400-
if (correspondingSuperFormal != null) {
423+
if (namedSuperFormalHasInitializer[formal.name] != null) {
401424
formal.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer ||
402-
correspondingSuperFormal.hasDeclaredInitializer;
425+
namedSuperFormalHasInitializer[formal.name]!;
426+
correspondingSuperFormalType = namedSuperFormalType[formal.name];
403427
if (!hasImmediatelyDeclaredInitializer && !formal.isNamedRequired) {
404428
(namedSuperParameters ??= <String>[]).add(formal.name);
405429
}
@@ -409,7 +433,7 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
409433
}
410434

411435
if (formal.type == null) {
412-
DartType? type = correspondingSuperFormal?.variable?.type;
436+
DartType? type = correspondingSuperFormalType;
413437
if (substitution.isNotEmpty && type != null) {
414438
type = substitute(type, substitution);
415439
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright (c) 2020, 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.md file.
4+
5+
type: newworld
6+
target: DDC
7+
trackWidgetCreation: true
8+
worlds:
9+
- entry: main.dart
10+
sources:
11+
main.dart: |
12+
import 'package:flutter/src/widgets/framework.dart';
13+
flutter/lib/src/widgets/framework.dart: |
14+
abstract class Bar {
15+
const Bar();
16+
}
17+
abstract class Widget extends Bar {
18+
const Widget();
19+
}
20+
class Key {}
21+
class StatefulWidget extends Widget {
22+
final Key? key;
23+
24+
const StatefulWidget({this.key});
25+
}
26+
.dart_tool/package_config.json: |
27+
{
28+
"configVersion": 2,
29+
"packages": [
30+
{
31+
"name": "flutter",
32+
"rootUri": "../flutter",
33+
"packageUri": "lib/"
34+
}
35+
]
36+
}
37+
expectedLibraryCount: 2
38+
- entry: main.dart
39+
worldType: updated
40+
invalidate:
41+
- main.dart
42+
expectInitializeFromDill: false
43+
sources:
44+
main.dart: |
45+
import 'package:flutter/src/widgets/framework.dart';
46+
class GalleryApp extends StatefulWidget {
47+
const GalleryApp({super.key});
48+
}
49+
expectedLibraryCount: 2
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
main = <No Member>;
2+
library from "package:flutter/src/widgets/framework.dart" as fra {
3+
4+
abstract class Bar extends dart.core::Object /*hasConstConstructor*/ {
5+
const constructor •() → fra::Bar
6+
: super dart.core::Object::•()
7+
;
8+
}
9+
abstract class Widget extends fra::Bar /*hasConstConstructor*/ {
10+
const constructor •() → fra::Widget
11+
: super fra::Bar::•()
12+
;
13+
}
14+
class Key extends dart.core::Object {
15+
synthetic constructor •() → fra::Key
16+
: super dart.core::Object::•()
17+
;
18+
static method _#new#tearOff() → fra::Key
19+
return new fra::Key::•();
20+
}
21+
class StatefulWidget extends fra::Widget /*hasConstConstructor*/ {
22+
final field fra::Key? key;
23+
const constructor •({fra::Key? key = #C1}) → fra::StatefulWidget
24+
: fra::StatefulWidget::key = key, super fra::Widget::•()
25+
;
26+
static method _#new#tearOff({fra::Key? key = #C1}) → fra::StatefulWidget
27+
return new fra::StatefulWidget::•(key: key);
28+
}
29+
}
30+
library from "org-dartlang-test:///main.dart" as main {
31+
32+
import "package:flutter/src/widgets/framework.dart";
33+
34+
}
35+
constants {
36+
#C1 = null
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
main = <No Member>;
2+
library from "package:flutter/src/widgets/framework.dart" as fra {
3+
4+
abstract class Bar extends dart.core::Object /*hasConstConstructor*/ {
5+
const constructor •() → fra::Bar
6+
: super dart.core::Object::•()
7+
;
8+
}
9+
abstract class Widget extends fra::Bar /*hasConstConstructor*/ {
10+
const constructor •() → fra::Widget
11+
: super fra::Bar::•()
12+
;
13+
}
14+
class Key extends dart.core::Object {
15+
synthetic constructor •() → fra::Key
16+
: super dart.core::Object::•()
17+
;
18+
static method _#new#tearOff() → fra::Key
19+
return new fra::Key::•();
20+
}
21+
class StatefulWidget extends fra::Widget /*hasConstConstructor*/ {
22+
final field fra::Key? key;
23+
const constructor •({fra::Key? key = #C1}) → fra::StatefulWidget
24+
: fra::StatefulWidget::key = key, super fra::Widget::•()
25+
;
26+
static method _#new#tearOff({fra::Key? key = #C1}) → fra::StatefulWidget
27+
return new fra::StatefulWidget::•(key: key);
28+
}
29+
}
30+
library from "org-dartlang-test:///main.dart" as main {
31+
32+
import "package:flutter/src/widgets/framework.dart";
33+
34+
class GalleryApp extends fra::StatefulWidget /*hasConstConstructor*/ {
35+
const constructor •({fra::Key? key = #C1}) → main::GalleryApp
36+
: super fra::StatefulWidget::•(key: key)
37+
;
38+
static method _#new#tearOff({fra::Key? key}) → main::GalleryApp
39+
return new main::GalleryApp::•(key: key);
40+
}
41+
}
42+
constants {
43+
#C1 = null
44+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'main_lib.dart';
2+
3+
class GalleryApp extends StatefulWidget {
4+
const GalleryApp({super.key});
5+
}
6+
7+
main() {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "main_lib.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib.dart";
6+
7+
class GalleryApp extends mai::StatefulWidget /*hasConstConstructor*/ {
8+
const constructor •({mai::Key? key = #C1}) → self::GalleryApp
9+
: super mai::StatefulWidget::•(key: key)
10+
;
11+
}
12+
static method main() → dynamic {}
13+
14+
library /*isNonNullableByDefault*/;
15+
import self as mai;
16+
import "dart:core" as core;
17+
18+
class Key extends core::Object {
19+
synthetic constructor •() → mai::Key
20+
: super core::Object::•()
21+
;
22+
}
23+
class StatefulWidget extends core::Object /*hasConstConstructor*/ {
24+
final field mai::Key? key;
25+
const constructor •({mai::Key? key = #C1}) → mai::StatefulWidget
26+
: mai::StatefulWidget::key = key, super core::Object::•()
27+
;
28+
}
29+
30+
constants {
31+
#C1 = null
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "main_lib.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib.dart";
6+
7+
class GalleryApp extends mai::StatefulWidget /*hasConstConstructor*/ {
8+
const constructor •({mai::Key? key = #C1}) → self::GalleryApp
9+
: super mai::StatefulWidget::•(key: key)
10+
;
11+
}
12+
static method main() → dynamic {}
13+
14+
library /*isNonNullableByDefault*/;
15+
import self as mai;
16+
import "dart:core" as core;
17+
18+
class Key extends core::Object {
19+
synthetic constructor •() → mai::Key
20+
: super core::Object::•()
21+
;
22+
}
23+
class StatefulWidget extends core::Object /*hasConstConstructor*/ {
24+
final field mai::Key? key;
25+
const constructor •({mai::Key? key = #C1}) → mai::StatefulWidget
26+
: mai::StatefulWidget::key = key, super core::Object::•()
27+
;
28+
}
29+
30+
constants {
31+
#C1 = null
32+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'main_lib.dart';
2+
3+
class GalleryApp extends StatefulWidget {
4+
const GalleryApp({super.key});
5+
}
6+
7+
main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'main_lib.dart';
2+
3+
class GalleryApp extends StatefulWidget {
4+
const GalleryApp({super.key});
5+
}
6+
7+
main() {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
import "main_lib.dart" as mai;
4+
5+
import "org-dartlang-testcase:///main_lib.dart";
6+
7+
class GalleryApp extends mai::StatefulWidget /*hasConstConstructor*/ {
8+
const constructor •({mai::Key? key = #C1}) → self::GalleryApp
9+
: super mai::StatefulWidget::•(key: key)
10+
;
11+
}
12+
static method main() → dynamic {}
13+
14+
library /*isNonNullableByDefault*/;
15+
import self as mai;
16+
import "dart:core" as core;
17+
18+
class Key extends core::Object {
19+
synthetic constructor •() → mai::Key
20+
: super core::Object::•()
21+
;
22+
}
23+
class StatefulWidget extends core::Object /*hasConstConstructor*/ {
24+
final field mai::Key? key;
25+
const constructor •({mai::Key? key = #C1}) → mai::StatefulWidget
26+
: mai::StatefulWidget::key = key, super core::Object::•()
27+
;
28+
}
29+
30+
constants {
31+
#C1 = null
32+
}

0 commit comments

Comments
 (0)