Skip to content

Commit

Permalink
[cfe] Pass pre-parsed initializers to resolve super-initizer target
Browse files Browse the repository at this point in the history
Closes dart-lang/sdk#48286

Part of dart-lang/sdk#47525

Change-Id: Ie8816c407b7ab1b6510e5cf139b88c33728f55a8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/231948
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
  • Loading branch information
chloestefantsova authored and Commit Bot committed Feb 10, 2022
1 parent 0c7bf4b commit 6939628
Show file tree
Hide file tree
Showing 17 changed files with 214 additions and 22 deletions.
4 changes: 3 additions & 1 deletion pkg/front_end/lib/src/fasta/kernel/body_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,8 @@ class BodyBuilder extends ScopeListener<JumpTarget>
return fakeReturn.expression!;
}

void parseInitializers(Token token, {bool doFinishConstructor = true}) {
List<Initializer>? parseInitializers(Token token,
{bool doFinishConstructor = true}) {
Parser parser = new Parser(this,
useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
if (!token.isEof) {
Expand All @@ -1635,6 +1636,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
finishConstructor(
member as DeclaredSourceConstructorBuilder, AsyncMarker.Sync, null);
}
return _initializers;
}

Expression parseFieldInitializer(Token token) {
Expand Down
27 changes: 17 additions & 10 deletions pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -238,22 +238,24 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
}

if (_hasSuperInitializingFormals) {
List<Initializer>? initializers;
if (beginInitializers != null) {
BodyBuilder bodyBuilder = library.loader
.createBodyBuilderForOutlineExpression(
library, classBuilder, this, classBuilder.scope, fileUri);
bodyBuilder.constantContext = ConstantContext.required;
bodyBuilder.parseInitializers(beginInitializers!,
initializers = bodyBuilder.parseInitializers(beginInitializers!,
doFinishConstructor: false);
}
finalizeSuperInitializingFormals(
classHierarchy, _superParameterDefaultValueCloners);
classHierarchy, _superParameterDefaultValueCloners, initializers);
}
}
_hasFormalsInferred = true;
}

ConstructorBuilder? _computeSuperTargetBuilder() {
ConstructorBuilder? _computeSuperTargetBuilder(
List<Initializer>? initializers) {
Constructor superTarget;
ClassBuilder superclassBuilder;

Expand All @@ -279,9 +281,10 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
return null;
}

if (constructor.initializers.isNotEmpty &&
constructor.initializers.last is SuperInitializer) {
superTarget = (constructor.initializers.last as SuperInitializer).target;
if (initializers != null &&
initializers.isNotEmpty &&
initializers.last is SuperInitializer) {
superTarget = (initializers.last as SuperInitializer).target;
} else {
MemberBuilder? memberBuilder = superclassBuilder.constructors
.lookup("", charOffset, library.fileUri);
Expand All @@ -299,8 +302,10 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
return constructorBuilder is ConstructorBuilder ? constructorBuilder : null;
}

void finalizeSuperInitializingFormals(ClassHierarchy classHierarchy,
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
void finalizeSuperInitializingFormals(
ClassHierarchy classHierarchy,
List<SynthesizedFunctionNode> synthesizedFunctionNodes,
List<Initializer>? initializers) {
if (formals == null) return;
if (!_hasSuperInitializingFormals) return;

Expand All @@ -312,7 +317,8 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl
}
}

ConstructorBuilder? superTargetBuilder = _computeSuperTargetBuilder();
ConstructorBuilder? superTargetBuilder =
_computeSuperTargetBuilder(initializers);
Constructor superTarget;
List<FormalParameterBuilder>? superFormals;
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
Expand Down Expand Up @@ -468,7 +474,8 @@ class DeclaredSourceConstructorBuilder extends SourceFunctionBuilderImpl

void addSuperParameterDefaultValueCloners(
List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
ConstructorBuilder? superTargetBuilder = _computeSuperTargetBuilder();
ConstructorBuilder? superTargetBuilder =
_computeSuperTargetBuilder(constructor.initializers);
if (superTargetBuilder is DeclaredSourceConstructorBuilder) {
superTargetBuilder
.addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
Expand Down
18 changes: 18 additions & 0 deletions pkg/front_end/testcases/super_parameters/issue48286.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

class S<T> {
num n;
T t;
S(this.n, this.t);
S.named(this.t, this.n);
}

class C<T> extends S<T> {
C.constr1(super.n, String s, super.t);
C.constr2(int i, super.n, String s, super.t) : super();
C.constr3(int i, super.t, String s, super.n) : super.named();
}

main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
: self::S::n = n, self::S::t = t, super core::Object::•()
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
: self::S::t = t, self::S::n = n, super core::Object::•()
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
: super self::S::named(t, n)
;
}
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
: self::S::n = n, self::S::t = t, super core::Object::•()
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
: self::S::t = t, self::S::n = n, super core::Object::•()
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
: super self::S::named(t, n)
;
}
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class S<T> {
num n;
T t;
S(this.n, this.t);
S.named(this.t, this.n);
}
class C<T> extends S<T> {
C.constr1(super.n, String s, super.t);
C.constr2(int i, super.n, String s, super.t) : super();
C.constr3(int i, super.t, String s, super.n) : super.named();
}
main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
: self::S::n = n, self::S::t = t, super core::Object::•()
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
: self::S::t = t, self::S::n = n, super core::Object::•()
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
: super self::S::named(t, n)
;
}
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
: self::S::n = n, self::S::t = t, super core::Object::•()
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
: self::S::t = t, self::S::n = n, super core::Object::•()
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
: super self::S::named(t, n)
;
}
static method main() → dynamic {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
;
}
static method main() → dynamic
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class S<T extends core::Object? = dynamic> extends core::Object {
field core::num n;
covariant-by-class field self::S::T% t;
constructor •(core::num n, self::S::T% t) → self::S<self::S::T%>
: self::S::n = n, self::S::t = t, super core::Object::•()
;
constructor named(self::S::T% t, core::num n) → self::S<self::S::T%>
: self::S::t = t, self::S::n = n, super core::Object::•()
;
}
class C<T extends core::Object? = dynamic> extends self::S<self::C::T%> {
constructor constr1(core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr2(core::int i, core::num n, core::String s, self::C::T% t) → self::C<self::C::T%>
: super self::S::•(n, t)
;
constructor constr3(core::int i, self::C::T% t, core::String s, core::num n) → self::C<self::C::T%>
: super self::S::named(t, n)
;
}
static method main() → dynamic {}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class B1 extends self::A1 {
constructor named2(core::int foo) → self::B1
: super self::A1::named2(foo)
;
constructor named3({required dynamic foo = #C1}) → self::B1
: super self::A1::named3(foo: foo as{TypeError,ForDynamic,ForNonNullableByDefault} core::int)
constructor named3({required core::int foo = #C1}) → self::B1
: super self::A1::named3(foo: foo)
;
}
class A2 extends core::Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class B1 extends self::A1 {
constructor named2(core::int foo) → self::B1
: super self::A1::named2(foo)
;
constructor named3({required dynamic foo = #C1}) → self::B1
: super self::A1::named3(foo: foo as{TypeError,ForDynamic,ForNonNullableByDefault} core::int)
constructor named3({required core::int foo = #C1}) → self::B1
: super self::A1::named3(foo: foo)
;
}
class A2 extends core::Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class B1 extends self::A1 {
constructor named2(core::int foo) → self::B1
: super self::A1::named2(foo)
;
constructor named3({required dynamic foo = #C1}) → self::B1
: super self::A1::named3(foo: foo as{TypeError,ForDynamic,ForNonNullableByDefault} core::int)
constructor named3({required core::int foo = #C1}) → self::B1
: super self::A1::named3(foo: foo)
;
}
class A2 extends core::Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class B1 extends self::A1 {
constructor named2(core::int foo) → self::B1
: super self::A1::named2(foo)
;
constructor named3({required dynamic foo = #C1}) → self::B1
: super self::A1::named3(foo: foo as{TypeError,ForDynamic,ForNonNullableByDefault} core::int)
constructor named3({required core::int foo = #C1}) → self::B1
: super self::A1::named3(foo: foo)
;
}
class A2 extends core::Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class B1 extends self::A1 {
;
constructor named2(core::int foo) → self::B1
;
constructor named3({required dynamic foo}) → self::B1
constructor named3({required core::int foo}) → self::B1
;
}
class A2 extends core::Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class B1 extends self::A1 {
constructor named2(core::int foo) → self::B1
: super self::A1::named2(foo)
;
constructor named3({required dynamic foo = #C1}) → self::B1
: super self::A1::named3(foo: foo as{TypeError,ForDynamic,ForNonNullableByDefault} core::int)
constructor named3({required core::int foo = #C1}) → self::B1
: super self::A1::named3(foo: foo)
;
}
class A2 extends core::Object {
Expand Down
1 change: 1 addition & 0 deletions pkg/front_end/testcases/textual_outline.status
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ regress/issue_41265.crash: FormatterCrash
super_parameters/circular_dependency_inference: FormatterCrash
super_parameters/default_values: FormatterCrash
super_parameters/issue48142: FormatterCrash
super_parameters/issue48286: FormatterCrash
super_parameters/simple: FormatterCrash
super_parameters/simple_inference: FormatterCrash
super_parameters/simple_named_super_parameters: FormatterCrash
Expand Down

0 comments on commit 6939628

Please sign in to comment.