[cfe] Insert default super initializer when outlining const constructor
This ensures that it is invoked when performing constant evaluation in modular setting. Fixes https://github.com/dart-lang/sdk/issues/37794 Bug: 37794 Change-Id: I26c891044e030ac7702f02b2d4996984f9e898c6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112383 Commit-Queue: Vyacheslav Egorov <vegorov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
78ce916d82
commit
573789f7f1
@@ -96,8 +96,6 @@ import '../problems.dart' show unexpected;
|
||||
|
||||
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
|
||||
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import '../type_inference/type_inference_engine.dart'
|
||||
show IncludesTypeParametersNonCovariantly, Variance;
|
||||
|
||||
@@ -657,11 +655,6 @@ class ConstructorBuilder extends FunctionBuilder {
|
||||
library, classBuilder, this, classBuilder.scope, fileUri);
|
||||
bodyBuilder.constantContext = ConstantContext.inferred;
|
||||
bodyBuilder.parseInitializers(beginInitializers);
|
||||
if (library.loader is SourceLoader) {
|
||||
SourceLoader loader = library.loader;
|
||||
loader.transformPostInference(target, bodyBuilder.transformSetLiterals,
|
||||
bodyBuilder.transformCollections);
|
||||
}
|
||||
bodyBuilder.resolveRedirectingFactoryTargets();
|
||||
}
|
||||
beginInitializers = null;
|
||||
|
||||
@@ -1227,6 +1227,9 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
||||
} else {
|
||||
handleNoInitializers();
|
||||
}
|
||||
// We are passing [AsyncMarker.Sync] because the error will be reported
|
||||
// already.
|
||||
finishConstructor(member, AsyncMarker.Sync);
|
||||
}
|
||||
|
||||
Expression parseFieldInitializer(Token token) {
|
||||
|
||||
@@ -12,7 +12,7 @@ class Strength extends core::Object {
|
||||
final field core::int* value;
|
||||
final field core::String* name;
|
||||
const constructor •(core::int* value, core::String* name) → self::Strength*
|
||||
: self::Strength::value = value, self::Strength::name = name
|
||||
: self::Strength::value = value, self::Strength::name = name, super core::Object::•()
|
||||
;
|
||||
method nextWeaker() → self::Strength*
|
||||
;
|
||||
@@ -28,7 +28,7 @@ class Strength extends core::Object {
|
||||
abstract class Constraint extends core::Object {
|
||||
final field self::Strength* strength;
|
||||
const constructor •(self::Strength* strength) → self::Constraint*
|
||||
: self::Constraint::strength = strength
|
||||
: self::Constraint::strength = strength, super core::Object::•()
|
||||
;
|
||||
abstract method isSatisfied() → core::bool*;
|
||||
abstract method markUnsatisfied() → void;
|
||||
|
||||
@@ -5,7 +5,7 @@ import "dart:core" as core;
|
||||
class Fisk<T extends core::Object* = dynamic> extends core::Object {
|
||||
final field self::Fisk::T* x;
|
||||
const constructor fisk(self::Fisk::T* x) → self::Fisk<self::Fisk::T*>*
|
||||
: self::Fisk::x = x
|
||||
: self::Fisk::x = x, super core::Object::•()
|
||||
;
|
||||
}
|
||||
class Foo extends core::Object {
|
||||
|
||||
@@ -8,6 +8,7 @@ typedef F1 = () →* void;
|
||||
typedef F2 = () →* void;
|
||||
class A extends core::Object {
|
||||
const constructor •(core::int* value) → self::A*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
@self::a
|
||||
|
||||
@@ -5,8 +5,10 @@ import "dart:core" as core;
|
||||
typedef hest_t = ({named: dynamic}) →* dynamic;
|
||||
class Bar extends core::Object {
|
||||
const constructor •() → self::Bar*
|
||||
: super core::Object::•()
|
||||
;
|
||||
const constructor named(dynamic x) → self::Bar*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class Baz extends core::Object {
|
||||
|
||||
@@ -7,6 +7,7 @@ import "dart:mirrors";
|
||||
|
||||
class _FailingTest extends core::Object {
|
||||
const constructor •() → self::_FailingTest*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class MyTest extends core::Object {
|
||||
|
||||
@@ -18,6 +18,7 @@ import "dart:core" as core;
|
||||
|
||||
class A extends core::Object {
|
||||
const constructor •() → self::A*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class B extends core::Object {
|
||||
|
||||
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class _Y<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor •() → self::_Y<self::_Y::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class A<T extends core::Object* = dynamic> extends core::Object {
|
||||
|
||||
@@ -5,6 +5,7 @@ import "dart:core" as core;
|
||||
class C extends core::Object {
|
||||
static const field dynamic constField = 87;
|
||||
const constructor •(dynamic x) → self::C*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static const field dynamic constTopLevelField = 42;
|
||||
|
||||
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Constant extends core::Object {
|
||||
const constructor •() → self::Constant*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class NotConstant extends core::Object {
|
||||
|
||||
@@ -38,7 +38,7 @@ class A extends core::Object {
|
||||
: final dynamic #t1 = throw invalid-expression "pkg/front_end/testcases/general/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const A.named2() : x = new Object();
|
||||
^"
|
||||
^", super core::Object::•()
|
||||
;
|
||||
}
|
||||
class B extends core::Object {
|
||||
@@ -52,6 +52,7 @@ class C extends core::Object {
|
||||
}
|
||||
abstract class AbstractClass extends core::Object {
|
||||
const constructor id() → self::AbstractClass*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
external static method foo(core::String* x) → dynamic;
|
||||
|
||||
+2
-2
@@ -5,13 +5,13 @@ import "dart:core" as core;
|
||||
class A extends core::Object {
|
||||
final field core::int* bar;
|
||||
const constructor •(core::int* bar) → self::A*
|
||||
: self::A::bar = bar
|
||||
: self::A::bar = bar, super core::Object::•()
|
||||
;
|
||||
}
|
||||
class B extends core::Object {
|
||||
final field self::A* baz;
|
||||
const constructor •(self::A* baz) → self::B*
|
||||
: self::B::baz = baz
|
||||
: self::B::baz = baz, super core::Object::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ class _X<T extends core::Object* = dynamic> extends core::Object {
|
||||
}
|
||||
class _Y<T extends core::Object* = dynamic> extends core::Object implements self::_X<self::_Y::T*> {
|
||||
const constructor •() → self::_Y<self::_Y::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class A<T extends core::Object* = dynamic> extends core::Object {
|
||||
|
||||
@@ -7,6 +7,7 @@ import "package:expect/expect.dart";
|
||||
class A extends core::Object {
|
||||
static field dynamic _redirecting# = <dynamic>[self::A::•];
|
||||
const constructor empty() → self::A*
|
||||
: super core::Object::•()
|
||||
;
|
||||
static factory •() → self::A*
|
||||
let dynamic #redirecting_factory = self::B::• in let core::String* #typeArg0 = null in invalid-expression;
|
||||
|
||||
@@ -11,6 +11,7 @@ import "dart:core" as core;
|
||||
|
||||
class C<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor •() → self::C<self::C::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
static method staticMethod() → self::C<dynamic>*
|
||||
;
|
||||
|
||||
@@ -4,8 +4,10 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
const constructor named(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
@self::Foo::•(const <dynamic>[])
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
abstract class Bar extends core::Object {
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method test() → void
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method test() → void
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(dynamic l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method test() → void
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method test() → void
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ import "dart:core" as core;
|
||||
typedef F<T extends core::Object* = dynamic> = () →* void;
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class C<T extends core::Object* = dynamic> extends core::Object {
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method test() → void
|
||||
|
||||
+1
@@ -5,6 +5,7 @@ import "dart:core" as core;
|
||||
typedef F = () →* void;
|
||||
class Foo extends core::Object {
|
||||
const constructor •(core::List<core::String*>* l) → self::Foo*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
||||
@@ -27,6 +27,7 @@ class Foo<T extends core::Object* = dynamic> extends core::Object {
|
||||
}
|
||||
class Bar<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor •() → self::Bar<self::Bar::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
||||
@@ -27,6 +27,7 @@ class Foo<T extends core::Object* = dynamic> extends core::Object {
|
||||
}
|
||||
class Bar<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor •() → self::Bar<self::Bar::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
||||
@@ -4,6 +4,7 @@ import "dart:core" as core;
|
||||
|
||||
class C<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor •() → self::C<self::C::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method f<T extends core::Object* = dynamic>() → self::f::T*
|
||||
|
||||
@@ -5,7 +5,7 @@ import "dart:core" as core;
|
||||
class A extends core::Object {
|
||||
final field core::int* x;
|
||||
const constructor •(core::int* x) → self::A*
|
||||
: self::A::x = x
|
||||
: self::A::x = x, super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
||||
@@ -18,6 +18,7 @@ Try removing the extra positional arguments.
|
||||
^"
|
||||
;
|
||||
const constructor x() → self::C*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
||||
@@ -2,14 +2,14 @@ library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
|
||||
// const B();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
||||
+4
-4
@@ -2,14 +2,14 @@ library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
|
||||
// const B();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
|
||||
// const B();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
@@ -8,6 +15,9 @@ class A extends core::Object {
|
||||
}
|
||||
class B extends self::A {
|
||||
const constructor •() → self::B*
|
||||
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
|
||||
const B();
|
||||
^"
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
||||
@@ -2,14 +2,14 @@ library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
|
||||
// const B();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
||||
+4
-4
@@ -2,14 +2,14 @@ library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
|
||||
// const B();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
|
||||
// A(this.x);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import "dart:core" as core;
|
||||
class C extends core::Object {
|
||||
static field dynamic _redirecting# = <dynamic>[self::C::good];
|
||||
const constructor constant() → self::C*
|
||||
: super core::Object::•()
|
||||
;
|
||||
constructor missingFactoryKeyword() → self::C*
|
||||
;
|
||||
|
||||
@@ -11,7 +11,7 @@ class A<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U
|
||||
constructor empty() → self::A<self::A::N*, self::A::S*, self::A::U*>*
|
||||
;
|
||||
const constructor c(self::A::U* u, self::A::S* s) → self::A<self::A::N*, self::A::S*, self::A::U*>*
|
||||
: self::A::field = const <dynamic>[null]
|
||||
: self::A::field = const <dynamic>[null], super core::Object::•()
|
||||
;
|
||||
static factory f<N extends core::Object* = dynamic, S extends core::Object* = dynamic, U extends core::Object* = dynamic>(self::A::f::S* s) → self::A<self::A::f::N*, self::A::f::S*, self::A::f::U*>*
|
||||
;
|
||||
|
||||
@@ -10,6 +10,7 @@ class C<T extends core::Object* = dynamic> extends core::Object {
|
||||
}
|
||||
class D<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor foo() → self::D<self::D::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
@@ -25,5 +26,6 @@ class E<T extends core::Object* = dynamic> extends core::Object {
|
||||
}
|
||||
class F<T extends core::Object* = dynamic> extends core::Object {
|
||||
const constructor foo() → self2::F<self2::F::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2019, 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.
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
import 'module2.dart';
|
||||
import 'module1.dart';
|
||||
|
||||
main() {
|
||||
const x = B();
|
||||
const y = A();
|
||||
Expect.equals('foo', x.foo);
|
||||
Expect.listEquals(['l', 'i', 's', 't'], x.list);
|
||||
Expect.equals('foo', y.foo);
|
||||
Expect.listEquals(['l', 'i', 's', 't'], y.list);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2019, 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 A {
|
||||
final String foo;
|
||||
final List<String> list;
|
||||
|
||||
const A(
|
||||
[this.foo = 'foo',
|
||||
this.list = const [
|
||||
'l',
|
||||
...['i', 's'],
|
||||
't'
|
||||
]]);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) 2019, 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.
|
||||
|
||||
import 'module1.dart';
|
||||
|
||||
class B extends A {
|
||||
const B();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2019, 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.
|
||||
|
||||
dependencies:
|
||||
main: [module1, module2, expect]
|
||||
module2: [module1]
|
||||
flags:
|
||||
- constant-update-2018
|
||||
Reference in New Issue
Block a user