[cfe] Implement lowering for constructor initialization of late fields

Change-Id: Ia6187c3eac630a2bd4351868aadfaa8771648830
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/125821
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Johnni Winther 2019-11-21 09:36:35 +00:00 committed by commit-bot@chromium.org
parent f692a2fbb8
commit 4c8c44ec78
33 changed files with 2219 additions and 54 deletions

View file

@ -72,6 +72,12 @@ abstract class FieldBuilder implements MemberBuilder {
/// expression.
void buildBody(Expression initializer);
/// Builds the field initializers for each field used to encode this field
/// using the [fileOffset] for the created nodes and [value] as the initial
/// field value.
List<Initializer> buildInitializer(int fileOffset, Expression value,
{bool isSynthetic});
bool get isEligibleForInference;
DartType get builtType;
@ -147,6 +153,7 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
@override
bool get hasInitializer => (modifiers & hasInitializerMask) != 0;
@override
void buildBody(Expression initializer) {
assert(!hasBodyBeenBuilt);
hasBodyBeenBuilt = true;
@ -161,6 +168,13 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
_fieldEncoding.createBodies(initializer);
}
@override
List<Initializer> buildInitializer(int fileOffset, Expression value,
{bool isSynthetic}) {
return _fieldEncoding.createInitializer(fileOffset, value,
isSynthetic: isSynthetic);
}
bool get isEligibleForInference {
return type == null && (hasInitializer || isClassInstanceMember);
}
@ -362,6 +376,9 @@ abstract class FieldEncoding {
/// or part of a const constructor.
void createBodies(Expression initializer);
List<Initializer> createInitializer(int fileOffset, Expression value,
{bool isSynthetic});
/// Registers that the (implicit) setter associated with this field needs to
/// contain a runtime type check to deal with generic covariance.
void setGenericCovariantImpl();
@ -418,6 +435,16 @@ class RegularFieldEncoding implements FieldEncoding {
}
}
@override
List<Initializer> createInitializer(int fileOffset, Expression value,
{bool isSynthetic}) {
return <Initializer>[
new FieldInitializer(_field, value)
..fileOffset = fileOffset
..isSynthetic = isSynthetic
];
}
@override
void build(
SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
@ -527,6 +554,22 @@ abstract class AbstractLateFieldEncoding implements FieldEncoding {
}
}
@override
List<Initializer> createInitializer(int fileOffset, Expression value,
{bool isSynthetic}) {
List<Initializer> initializers = <Initializer>[];
if (_lateIsSetField != null) {
initializers.add(new FieldInitializer(
_lateIsSetField, new BoolLiteral(true)..fileOffset = fileOffset)
..fileOffset = fileOffset
..isSynthetic = isSynthetic);
}
initializers.add(new FieldInitializer(_field, value)
..fileOffset = fileOffset
..isSynthetic = isSynthetic);
return initializers;
}
Expression _createFieldGet(Field field) {
if (field.isStatic) {
return new StaticGet(field)..fileOffset = fileOffset;

View file

@ -746,16 +746,18 @@ class BodyBuilder extends ScopeListener<JumpTarget>
if (member.formals != null) {
for (FormalParameterBuilder formal in member.formals) {
if (formal.isInitializingFormal) {
Initializer initializer;
List<Initializer> initializers;
if (member.isExternal) {
initializer = buildInvalidInitializer(
buildProblem(
fasta.messageExternalConstructorWithFieldInitializers,
formal.charOffset,
formal.name.length),
formal.charOffset);
initializers = <Initializer>[
buildInvalidInitializer(
buildProblem(
fasta.messageExternalConstructorWithFieldInitializers,
formal.charOffset,
formal.name.length),
formal.charOffset)
];
} else {
initializer = buildFieldInitializer(
initializers = buildFieldInitializer(
true,
formal.name,
formal.charOffset,
@ -763,7 +765,9 @@ class BodyBuilder extends ScopeListener<JumpTarget>
new VariableGet(formal.variable),
formalType: formal.variable.type);
}
member.addInitializer(initializer, this);
for (Initializer initializer in initializers) {
member.addInitializer(initializer, this);
}
}
}
}
@ -809,25 +813,33 @@ class BodyBuilder extends ScopeListener<JumpTarget>
assert(!inInitializer);
final ModifierBuilder member = this.member;
Object node = pop();
Initializer initializer;
List<Initializer> initializers;
if (node is Initializer) {
initializer = node;
initializers = <Initializer>[node];
} else if (node is Generator) {
initializer = node.buildFieldInitializer(initializedFields);
initializers = node.buildFieldInitializer(initializedFields);
} else if (node is ConstructorInvocation) {
initializer = buildSuperInitializer(
false, node.target, node.arguments, token.charOffset);
initializers = <Initializer>[
buildSuperInitializer(
false, node.target, node.arguments, token.charOffset)
];
} else {
Expression value = toValue(node);
if (!forest.isThrow(node)) {
value =
wrapInProblem(value, fasta.messageExpectedAnInitializer, noLength);
}
initializer = buildInvalidInitializer(node, token.charOffset);
initializers = <Initializer>[
buildInvalidInitializer(node, token.charOffset)
];
}
for (Initializer initializer in initializers) {
typeInferrer?.inferInitializer(this, initializer);
}
typeInferrer?.inferInitializer(this, initializer);
if (member is ConstructorBuilder && !member.isExternal) {
member.addInitializer(initializer, this);
for (Initializer initializer in initializers) {
member.addInitializer(initializer, this);
}
} else {
addProblem(
fasta.templateInitializerOutsideConstructor
@ -5275,22 +5287,26 @@ class BodyBuilder extends ScopeListener<JumpTarget>
/// immediately enclosing class. It is a static warning if the static type of
/// _id_ is not a subtype of _Tid_."
@override
Initializer buildFieldInitializer(bool isSynthetic, String name,
List<Initializer> buildFieldInitializer(bool isSynthetic, String name,
int fieldNameOffset, int assignmentOffset, Expression expression,
{DartType formalType}) {
Builder builder = declarationBuilder.lookupLocalMember(name);
if (builder?.next != null) {
// Duplicated name, already reported.
return new LocalInitializer(new VariableDeclaration.forValue(buildProblem(
fasta.templateDuplicatedDeclarationUse.withArguments(name),
fieldNameOffset,
name.length)))
..fileOffset = fieldNameOffset;
return <Initializer>[
new LocalInitializer(new VariableDeclaration.forValue(buildProblem(
fasta.templateDuplicatedDeclarationUse.withArguments(name),
fieldNameOffset,
name.length)))
..fileOffset = fieldNameOffset
];
} else if (builder is FieldBuilder && builder.isDeclarationInstanceMember) {
initializedFields ??= <String, int>{};
if (initializedFields.containsKey(name)) {
return buildDuplicatedInitializer(builder.field, expression, name,
assignmentOffset, initializedFields[name]);
return <Initializer>[
buildDuplicatedInitializer(builder.field, expression, name,
assignmentOffset, initializedFields[name])
];
}
initializedFields[name] = assignmentOffset;
if (builder.isFinal && builder.hasInitializer) {
@ -5313,12 +5329,14 @@ class BodyBuilder extends ScopeListener<JumpTarget>
]),
constness: Constness.explicitNew,
charOffset: assignmentOffset);
return new ShadowInvalidFieldInitializer(
builder.field,
expression,
new VariableDeclaration.forValue(
forest.createThrow(assignmentOffset, invocation)))
..fileOffset = assignmentOffset;
return <Initializer>[
new ShadowInvalidFieldInitializer(
builder.field,
expression,
new VariableDeclaration.forValue(
forest.createThrow(assignmentOffset, invocation)))
..fileOffset = assignmentOffset
];
} else {
if (formalType != null &&
!typeEnvironment.isSubtypeOf(formalType, builder.field.type,
@ -5334,17 +5352,18 @@ class BodyBuilder extends ScopeListener<JumpTarget>
.withLocation(builder.fileUri, builder.charOffset, noLength)
]);
}
return new FieldInitializer(builder.field, expression)
..fileOffset = assignmentOffset
..isSynthetic = isSynthetic;
return builder.buildInitializer(assignmentOffset, expression,
isSynthetic: isSynthetic);
}
} else {
return buildInvalidInitializer(
buildProblem(
fasta.templateInitializerForStaticField.withArguments(name),
fieldNameOffset,
name.length),
fieldNameOffset);
return <Initializer>[
buildInvalidInitializer(
buildProblem(
fasta.templateInitializerForStaticField.withArguments(name),
fieldNameOffset,
name.length),
fieldNameOffset)
];
}
}

View file

@ -200,11 +200,13 @@ abstract class Generator {
Expression buildForEffect() => buildSimpleRead();
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
return _helper.buildInvalidInitializer(
_helper.buildProblem(
messageInvalidInitializer, fileOffset, lengthForToken(token)),
fileOffset);
List<Initializer> buildFieldInitializer(Map<String, int> initializedFields) {
return <Initializer>[
_helper.buildInvalidInitializer(
_helper.buildProblem(
messageInvalidInitializer, fileOffset, lengthForToken(token)),
fileOffset)
];
}
/// Returns an expression, generator or initializer for an invocation of this
@ -3000,9 +3002,11 @@ abstract class ErroneousExpressionGenerator extends Generator {
withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
@override
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
return _helper.buildInvalidInitializer(
buildError(_forest.createArgumentsEmpty(fileOffset), isSetter: true));
List<Initializer> buildFieldInitializer(Map<String, int> initializedFields) {
return <Initializer>[
_helper.buildInvalidInitializer(
buildError(_forest.createArgumentsEmpty(fileOffset), isSetter: true))
];
}
@override
@ -3316,7 +3320,7 @@ class DelayedAssignment extends ContextAwareGenerator {
}
@override
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
List<Initializer> buildFieldInitializer(Map<String, int> initializedFields) {
if (!identical("=", assignmentOperator) ||
generator is! ThisPropertyAccessGenerator) {
return generator.buildFieldInitializer(initializedFields);
@ -3620,8 +3624,8 @@ class ParserErrorGenerator extends Generator {
Expression _makeInvalidWrite(Expression value) => buildProblem();
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
return _helper.buildInvalidInitializer(buildProblem());
List<Initializer> buildFieldInitializer(Map<String, int> initializedFields) {
return <Initializer>[_helper.buildInvalidInitializer(buildProblem())];
}
Expression doInvocation(int offset, Arguments arguments) {
@ -3757,9 +3761,11 @@ class ThisAccessGenerator extends Generator {
}
@override
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
List<Initializer> buildFieldInitializer(Map<String, int> initializedFields) {
Expression error = buildFieldInitializerError(initializedFields);
return _helper.buildInvalidInitializer(error, error.fileOffset);
return <Initializer>[
_helper.buildInvalidInitializer(error, error.fileOffset)
];
}
buildPropertyAccess(

View file

@ -63,7 +63,7 @@ abstract class ExpressionGeneratorHelper implements InferenceHelper {
Initializer buildInvalidInitializer(Expression expression, [int offset]);
Initializer buildFieldInitializer(bool isSynthetic, String name,
List<Initializer> buildFieldInitializer(bool isSynthetic, String name,
int fieldNameOffset, int assignmentOffset, Expression expression,
{DartType formalType});

View file

@ -0,0 +1,82 @@
// 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 Class {
late int field = 10;
Class.constructor1();
Class.constructor2(int this.field);
Class.constructor3(int value) : this.field = value + 1;
Class.constructor4([int this.field = 42]);
}
class Subclass extends Class {
Subclass.constructor1() : super.constructor1();
Subclass.constructor2(int value) : super.constructor2(value);
Subclass.constructor3(int value) : super.constructor3(value);
Subclass.constructor4([int value = 87]) : super.constructor4(value);
}
test1() {
var c1 = new Class.constructor1();
expect(10, c1.field);
c1.field = 16;
expect(16, c1.field);
var c2 = new Class.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Class.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Class.constructor4();
expect(42, c4.field);
c4.field = 43;
expect(43, c4.field);
var c5 = new Class.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
test2() {
var c1 = new Subclass.constructor1();
expect(10, c1.field);
c1.field = 16;
expect(16, c1.field);
var c2 = new Subclass.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Subclass.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Subclass.constructor4();
expect(87, c4.field);
c4.field = 88;
expect(88, c4.field);
var c5 = new Subclass.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
main() {
test1();
test2();
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}

View file

@ -0,0 +1,35 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field;
constructor constructor1() → self::Class*
;
constructor constructor2(core::int field) → self::Class*
;
constructor constructor3(core::int value) → self::Class*
;
constructor constructor4([core::int field]) → self::Class*
;
get field() → core::int;
set field(core::int #t1) → void;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
;
constructor constructor2(core::int value) → self::Subclass*
;
constructor constructor3(core::int value) → self::Subclass*
;
constructor constructor4([core::int value]) → self::Subclass*
;
}
static method test1() → dynamic
;
static method test2() → dynamic
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;

View file

@ -0,0 +1,94 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
get field() → core::int
return let final core::int? #t1 = this.{self::Class::_#field} in #t1.==(null) ?{core::int} this.{self::Class::_#field} = 10 : #t1{core::int};
set field(core::int #t2) → void
this.{self::Class::_#field} = #t2;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,94 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
get field() → core::int
return let final core::int? #t1 = this.{self::Class::_#field} in #t1.==(null) ?{core::int} this.{self::Class::_#field} = 10 : #t1{core::int};
set field(core::int #t2) → void
this.{self::Class::_#field} = #t2;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,93 @@
// 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 Class {
late int field;
Class.constructor1();
Class.constructor2(int this.field);
Class.constructor3(int value) : this.field = value + 1;
Class.constructor4([int this.field = 42]);
}
class Subclass extends Class {
Subclass.constructor1() : super.constructor1();
Subclass.constructor2(int value) : super.constructor2(value);
Subclass.constructor3(int value) : super.constructor3(value);
Subclass.constructor4([int value = 87]) : super.constructor4(value);
}
test1() {
var c1 = new Class.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class.field');
c1.field = 16;
expect(16, c1.field);
var c2 = new Class.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Class.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Class.constructor4();
expect(42, c4.field);
c4.field = 43;
expect(43, c4.field);
var c5 = new Class.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
test2() {
var c1 = new Subclass.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class.field');
c1.field = 16;
expect(16, c1.field);
var c2 = new Subclass.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Subclass.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Subclass.constructor4();
expect(87, c4.field);
c4.field = 88;
expect(88, c4.field);
var c5 = new Subclass.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
main() {
test1();
test2();
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}
throws(f(), String message) {
dynamic value;
try {
value = f();
} catch (e) {
print(e);
return;
}
throw '$message: $value';
}

View file

@ -0,0 +1,37 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field;
constructor constructor1() → self::Class*
;
constructor constructor2(core::int field) → self::Class*
;
constructor constructor3(core::int value) → self::Class*
;
constructor constructor4([core::int field]) → self::Class*
;
get field() → core::int;
set field(core::int #t1) → void;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
;
constructor constructor2(core::int value) → self::Subclass*
;
constructor constructor3(core::int value) → self::Subclass*
;
constructor constructor4([core::int value]) → self::Subclass*
;
}
static method test1() → dynamic
;
static method test2() → dynamic
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
static method throws(() → dynamic f, core::String message) → dynamic
;

View file

@ -0,0 +1,105 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
get field() → core::int
return let final core::int? #t1 = this.{self::Class::_#field} in #t1.==(null) ?{core::int} throw "Field 'field' has not been initialized." : #t1{core::int};
set field(core::int #t2) → void
this.{self::Class::_#field} = #t2;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,105 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
get field() → core::int
return let final core::int? #t1 = this.{self::Class::_#field} in #t1.==(null) ?{core::int} throw "Field 'field' has not been initialized." : #t1{core::int};
set field(core::int #t2) → void
this.{self::Class::_#field} = #t2;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,97 @@
// 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 Class {
late final int field;
Class.constructor1();
Class.constructor2(int this.field);
Class.constructor3(int value) : this.field = value + 1;
Class.constructor4([int this.field = 42]);
}
class Subclass extends Class {
Subclass.constructor1() : super.constructor1();
Subclass.constructor2(int value) : super.constructor2(value);
Subclass.constructor3(int value) : super.constructor3(value);
Subclass.constructor4([int value = 87]) : super.constructor4(value);
}
test1() {
var c1 = new Class.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class.field');
c1.field = 16;
expect(16, c1.field);
throws(() => c1.field = 17, 'Write value to initialized Class.field');
var c2 = new Class.constructor2(42);
expect(42, c2.field);
throws(() => c2.field = 43, 'Write value to initialized Class.field');
var c3 = new Class.constructor3(87);
expect(88, c3.field);
throws(() => c3.field = 89, 'Write value to initialized Class.field');
var c4 = new Class.constructor4();
expect(42, c4.field);
throws(() => c4.field = 43, 'Write value to initialized Class.field');
var c5 = new Class.constructor4(123);
expect(123, c5.field);
throws(() => c5.field = 124, 'Write value to initialized Class.field');
var c6 = new Class.constructor1();
c6.field = 32;
expect(32, c6.field);
throws(() => c6.field = 32, 'Write value to initialized Class.field');
}
test2() {
var c1 = new Subclass.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class1.field');
c1.field = 16;
expect(16, c1.field);
throws(() => c1.field = 17, 'Write value to initialized Class.field');
var c2 = new Subclass.constructor2(42);
expect(42, c2.field);
throws(() => c2.field = 43, 'Write value to initialized Class.field');
var c3 = new Subclass.constructor3(87);
expect(88, c3.field);
throws(() => c3.field = 89, 'Write value to initialized Class.field');
var c4 = new Subclass.constructor4();
expect(87, c4.field);
throws(() => c4.field = 88, 'Write value to initialized Class.field');
var c5 = new Subclass.constructor4(123);
expect(123, c5.field);
throws(() => c5.field = 124, 'Write value to initialized Class.field');
var c6 = new Subclass.constructor1();
c6.field = 32;
expect(32, c6.field);
throws(() => c6.field = 32, 'Write value to initialized Class.field');
}
main() {
test1();
test2();
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}
throws(f(), String message) {
dynamic value;
try {
value = f();
} catch (e) {
print(e);
return;
}
throw '$message: $value';
}

View file

@ -0,0 +1,37 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field;
constructor constructor1() → self::Class*
;
constructor constructor2(core::int field) → self::Class*
;
constructor constructor3(core::int value) → self::Class*
;
constructor constructor4([core::int field]) → self::Class*
;
get field() → core::int;
set field(core::int #t1) → void;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
;
constructor constructor2(core::int value) → self::Subclass*
;
constructor constructor3(core::int value) → self::Subclass*
;
constructor constructor4([core::int value]) → self::Subclass*
;
}
static method test1() → dynamic
;
static method test2() → dynamic
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
static method throws(() → dynamic f, core::String message) → dynamic
;

View file

@ -0,0 +1,110 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
get field() → core::int
return let final core::int? #t1 = this.{self::Class::_#field} in #t1.==(null) ?{core::int} throw "Field 'field' has not been initialized." : #t1{core::int};
set field(core::int #t2) → void
if(this.{self::Class::_#field}.==(null))
this.{self::Class::_#field} = #t2;
else
throw "Field 'field' has already been initialized.";
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Class c6 = new self::Class::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class1.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 88, "Write value to initialized Class.field");
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Subclass c6 = new self::Subclass::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,110 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field = field, super core::Object::•()
;
get field() → core::int
return let final core::int? #t1 = this.{self::Class::_#field} in #t1.==(null) ?{core::int} throw "Field 'field' has not been initialized." : #t1{core::int};
set field(core::int #t2) → void
if(this.{self::Class::_#field}.==(null))
this.{self::Class::_#field} = #t2;
else
throw "Field 'field' has already been initialized.";
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Class c6 = new self::Class::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int => c1.{self::Class::field}, "Read value from uninitialized Class1.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 88, "Write value to initialized Class.field");
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Subclass c6 = new self::Subclass::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,84 @@
// 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.
int? initField() => 10;
class Class {
late int? field = initField();
Class.constructor1();
Class.constructor2(int this.field);
Class.constructor3(int value) : this.field = value + 1;
Class.constructor4([int this.field = 42]);
}
class Subclass extends Class {
Subclass.constructor1() : super.constructor1();
Subclass.constructor2(int value) : super.constructor2(value);
Subclass.constructor3(int value) : super.constructor3(value);
Subclass.constructor4([int value = 87]) : super.constructor4(value);
}
test1() {
var c1 = new Class.constructor1();
expect(10, c1.field);
c1.field = 16;
expect(16, c1.field);
var c2 = new Class.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Class.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Class.constructor4();
expect(42, c4.field);
c4.field = 43;
expect(43, c4.field);
var c5 = new Class.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
test2() {
var c1 = new Subclass.constructor1();
expect(10, c1.field);
c1.field = 16;
expect(16, c1.field);
var c2 = new Subclass.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Subclass.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Subclass.constructor4();
expect(87, c4.field);
c4.field = 88;
expect(88, c4.field);
var c5 = new Subclass.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
main() {
test1();
test2();
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}

View file

@ -0,0 +1,38 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field;
field dynamic _#field#isSet;
constructor constructor1() → self::Class*
;
constructor constructor2(core::int field) → self::Class*
;
constructor constructor3(core::int value) → self::Class*
;
constructor constructor4([core::int field]) → self::Class*
;
get field() → core::int?;
set field(core::int? #t1) → void;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
;
constructor constructor2(core::int value) → self::Subclass*
;
constructor constructor3(core::int value) → self::Subclass*
;
constructor constructor4([core::int value]) → self::Subclass*
;
}
static method initField() → core::int?
;
static method test1() → dynamic
;
static method test2() → dynamic
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;

View file

@ -0,0 +1,104 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
field dynamic _#field#isSet = false;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
get field() → core::int? {
if(!this.{self::Class::_#field#isSet}) {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = self::initField();
}
return this.{self::Class::_#field};
}
set field(core::int? #t1) → void {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = #t1;
}
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method initField() → core::int?
return 10;
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,104 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
field dynamic _#field#isSet = false;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
get field() → core::int? {
if(!this.{self::Class::_#field#isSet}) {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = self::initField();
}
return this.{self::Class::_#field};
}
set field(core::int? #t1) → void {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = #t1;
}
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method initField() → core::int?
return 10;
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::expect(10, c1.{self::Class::field});
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,93 @@
// 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 Class {
late int? field;
Class.constructor1();
Class.constructor2(int this.field);
Class.constructor3(int value) : this.field = value + 1;
Class.constructor4([int this.field = 42]);
}
class Subclass extends Class {
Subclass.constructor1() : super.constructor1();
Subclass.constructor2(int value) : super.constructor2(value);
Subclass.constructor3(int value) : super.constructor3(value);
Subclass.constructor4([int value = 87]) : super.constructor4(value);
}
test1() {
var c1 = new Class.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class.field');
c1.field = 16;
expect(16, c1.field);
var c2 = new Class.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Class.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Class.constructor4();
expect(42, c4.field);
c4.field = 43;
expect(43, c4.field);
var c5 = new Class.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
test2() {
var c1 = new Subclass.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class.field');
c1.field = 16;
expect(16, c1.field);
var c2 = new Subclass.constructor2(42);
expect(42, c2.field);
c2.field = 43;
expect(43, c2.field);
var c3 = new Subclass.constructor3(87);
expect(88, c3.field);
c3.field = 89;
expect(89, c3.field);
var c4 = new Subclass.constructor4();
expect(87, c4.field);
c4.field = 88;
expect(88, c4.field);
var c5 = new Subclass.constructor4(123);
expect(123, c5.field);
c5.field = 124;
expect(124, c5.field);
}
main() {
test1();
test2();
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}
throws(f(), String message) {
dynamic value;
try {
value = f();
} catch (e) {
print(e);
return;
}
throw '$message: $value';
}

View file

@ -0,0 +1,38 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field;
field dynamic _#field#isSet;
constructor constructor1() → self::Class*
;
constructor constructor2(core::int field) → self::Class*
;
constructor constructor3(core::int value) → self::Class*
;
constructor constructor4([core::int field]) → self::Class*
;
get field() → core::int?;
set field(core::int? #t1) → void;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
;
constructor constructor2(core::int value) → self::Subclass*
;
constructor constructor3(core::int value) → self::Subclass*
;
constructor constructor4([core::int value]) → self::Subclass*
;
}
static method test1() → dynamic
;
static method test2() → dynamic
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
static method throws(() → dynamic f, core::String message) → dynamic
;

View file

@ -0,0 +1,108 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
field dynamic _#field#isSet = false;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
get field() → core::int?
return this.{self::Class::_#field#isSet} ?{core::int?} this.{self::Class::_#field} : throw "Field 'field' has not been initialized.";
set field(core::int? #t1) → void {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = #t1;
}
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,108 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
field dynamic _#field#isSet = false;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
get field() → core::int?
return this.{self::Class::_#field#isSet} ?{core::int?} this.{self::Class::_#field} : throw "Field 'field' has not been initialized.";
set field(core::int? #t1) → void {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = #t1;
}
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
c4.{self::Class::field} = 43;
self::expect(43, c4.{self::Class::field});
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
c2.{self::Class::field} = 43;
self::expect(43, c2.{self::Class::field});
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
c3.{self::Class::field} = 89;
self::expect(89, c3.{self::Class::field});
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
c4.{self::Class::field} = 88;
self::expect(88, c4.{self::Class::field});
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
c5.{self::Class::field} = 124;
self::expect(124, c5.{self::Class::field});
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,97 @@
// 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 Class {
late final int? field;
Class.constructor1();
Class.constructor2(int this.field);
Class.constructor3(int value) : this.field = value + 1;
Class.constructor4([int this.field = 42]);
}
class Subclass extends Class {
Subclass.constructor1() : super.constructor1();
Subclass.constructor2(int value) : super.constructor2(value);
Subclass.constructor3(int value) : super.constructor3(value);
Subclass.constructor4([int value = 87]) : super.constructor4(value);
}
test1() {
var c1 = new Class.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class.field');
c1.field = 16;
expect(16, c1.field);
throws(() => c1.field = 17, 'Write value to initialized Class.field');
var c2 = new Class.constructor2(42);
expect(42, c2.field);
throws(() => c2.field = 43, 'Write value to initialized Class.field');
var c3 = new Class.constructor3(87);
expect(88, c3.field);
throws(() => c3.field = 89, 'Write value to initialized Class.field');
var c4 = new Class.constructor4();
expect(42, c4.field);
throws(() => c4.field = 43, 'Write value to initialized Class.field');
var c5 = new Class.constructor4(123);
expect(123, c5.field);
throws(() => c5.field = 124, 'Write value to initialized Class.field');
var c6 = new Class.constructor1();
c6.field = 32;
expect(32, c6.field);
throws(() => c6.field = 32, 'Write value to initialized Class.field');
}
test2() {
var c1 = new Subclass.constructor1();
throws(() => c1.field, 'Read value from uninitialized Class1.field');
c1.field = 16;
expect(16, c1.field);
throws(() => c1.field = 17, 'Write value to initialized Class.field');
var c2 = new Subclass.constructor2(42);
expect(42, c2.field);
throws(() => c2.field = 43, 'Write value to initialized Class.field');
var c3 = new Subclass.constructor3(87);
expect(88, c3.field);
throws(() => c3.field = 89, 'Write value to initialized Class.field');
var c4 = new Subclass.constructor4();
expect(87, c4.field);
throws(() => c4.field = 88, 'Write value to initialized Class.field');
var c5 = new Subclass.constructor4(123);
expect(123, c5.field);
throws(() => c5.field = 124, 'Write value to initialized Class.field');
var c6 = new Subclass.constructor1();
c6.field = 32;
expect(32, c6.field);
throws(() => c6.field = 32, 'Write value to initialized Class.field');
}
main() {
test1();
test2();
}
expect(expected, actual) {
if (expected != actual) throw 'Expected $expected, actual $actual';
}
throws(f(), String message) {
dynamic value;
try {
value = f();
} catch (e) {
print(e);
return;
}
throw '$message: $value';
}

View file

@ -0,0 +1,38 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field;
field dynamic _#field#isSet;
constructor constructor1() → self::Class*
;
constructor constructor2(core::int field) → self::Class*
;
constructor constructor3(core::int value) → self::Class*
;
constructor constructor4([core::int field]) → self::Class*
;
get field() → core::int?;
set field(core::int? #t1) → void;
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
;
constructor constructor2(core::int value) → self::Subclass*
;
constructor constructor3(core::int value) → self::Subclass*
;
constructor constructor4([core::int value]) → self::Subclass*
;
}
static method test1() → dynamic
;
static method test2() → dynamic
;
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
;
static method throws(() → dynamic f, core::String message) → dynamic
;

View file

@ -0,0 +1,113 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
field dynamic _#field#isSet = false;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
get field() → core::int?
return this.{self::Class::_#field#isSet} ?{core::int?} this.{self::Class::_#field} : throw "Field 'field' has not been initialized.";
set field(core::int? #t1) → void
if(this.{self::Class::_#field#isSet})
throw "Field 'field' has already been initialized.";
else {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = #t1;
}
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Class c6 = new self::Class::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class1.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 88, "Write value to initialized Class.field");
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Subclass c6 = new self::Subclass::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -0,0 +1,113 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
field core::int? _#field = null;
field dynamic _#field#isSet = false;
constructor constructor1() → self::Class*
: super core::Object::•()
;
constructor constructor2(core::int field) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
constructor constructor3(core::int value) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = value.{core::num::+}(1), super core::Object::•()
;
constructor constructor4([core::int field = #C1]) → self::Class*
: self::Class::_#field#isSet = true, self::Class::_#field = field, super core::Object::•()
;
get field() → core::int?
return this.{self::Class::_#field#isSet} ?{core::int?} this.{self::Class::_#field} : throw "Field 'field' has not been initialized.";
set field(core::int? #t1) → void
if(this.{self::Class::_#field#isSet})
throw "Field 'field' has already been initialized.";
else {
this.{self::Class::_#field#isSet} = true;
this.{self::Class::_#field} = #t1;
}
}
class Subclass extends self::Class {
constructor constructor1() → self::Subclass*
: super self::Class::constructor1()
;
constructor constructor2(core::int value) → self::Subclass*
: super self::Class::constructor2(value)
;
constructor constructor3(core::int value) → self::Subclass*
: super self::Class::constructor3(value)
;
constructor constructor4([core::int value = #C2]) → self::Subclass*
: super self::Class::constructor4(value)
;
}
static method test1() → dynamic {
self::Class c1 = new self::Class::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Class c2 = new self::Class::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c3 = new self::Class::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Class c4 = new self::Class::constructor4();
self::expect(42, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Class c5 = new self::Class::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Class c6 = new self::Class::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method test2() → dynamic {
self::Subclass c1 = new self::Subclass::constructor1();
self::throws(() → core::int? => c1.{self::Class::field}, "Read value from uninitialized Class1.field");
c1.{self::Class::field} = 16;
self::expect(16, c1.{self::Class::field});
self::throws(() → core::int => c1.{self::Class::field} = 17, "Write value to initialized Class.field");
self::Subclass c2 = new self::Subclass::constructor2(42);
self::expect(42, c2.{self::Class::field});
self::throws(() → core::int => c2.{self::Class::field} = 43, "Write value to initialized Class.field");
self::Subclass c3 = new self::Subclass::constructor3(87);
self::expect(88, c3.{self::Class::field});
self::throws(() → core::int => c3.{self::Class::field} = 89, "Write value to initialized Class.field");
self::Subclass c4 = new self::Subclass::constructor4();
self::expect(87, c4.{self::Class::field});
self::throws(() → core::int => c4.{self::Class::field} = 88, "Write value to initialized Class.field");
self::Subclass c5 = new self::Subclass::constructor4(123);
self::expect(123, c5.{self::Class::field});
self::throws(() → core::int => c5.{self::Class::field} = 124, "Write value to initialized Class.field");
self::Subclass c6 = new self::Subclass::constructor1();
c6.{self::Class::field} = 32;
self::expect(32, c6.{self::Class::field});
self::throws(() → core::int => c6.{self::Class::field} = 32, "Write value to initialized Class.field");
}
static method main() → dynamic {
self::test1();
self::test2();
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))
throw "Expected ${expected}, actual ${actual}";
}
static method throws(() → dynamic f, core::String message) → dynamic {
dynamic value;
try {
value = f.call();
}
on dynamic catch(final dynamic e) {
core::print(e);
return;
}
throw "${message}: ${value}";
}
constants {
#C1 = 42
#C2 = 87
}

View file

@ -38,6 +38,12 @@ main() {
Class.staticMethod();
new Class().instanceMethod();
var c = new Class();
throws(() => c.lateInstanceField,
'Read value from uninitialized Class.lateInstanceField');
c.lateInstanceField = 16;
expect(16, c.lateInstanceField);
}
expect(expected, actual) {

View file

@ -46,6 +46,10 @@ static method main() → dynamic {
self::expect(87, self::Class::lateStaticField1);
self::Class::staticMethod();
new self::Class::•().{self::Class::instanceMethod}();
self::Class c = new self::Class::•();
self::throws(() → core::int => c.{self::Class::lateInstanceField}, "Read value from uninitialized Class.lateInstanceField");
c.{self::Class::lateInstanceField} = 16;
self::expect(16, c.{self::Class::lateInstanceField});
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))

View file

@ -46,6 +46,10 @@ static method main() → dynamic {
self::expect(87, self::Class::lateStaticField1);
self::Class::staticMethod();
new self::Class::•().{self::Class::instanceMethod}();
self::Class c = new self::Class::•();
self::throws(() → core::int => c.{self::Class::lateInstanceField}, "Read value from uninitialized Class.lateInstanceField");
c.{self::Class::lateInstanceField} = 16;
self::expect(16, c.{self::Class::lateInstanceField});
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual))

View file

@ -892,6 +892,12 @@ instantiate_to_bound/typedef_literal_map: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_omitted_bound: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_raw_in_bound: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_super_bounded_type: TextSerializationFailure # Was: Pass
late_lowering/instance_field_with_initializer: TextSerializationFailure
late_lowering/instance_field_without_initializer: TextSerializationFailure
late_lowering/instance_final_field_without_initializer: TextSerializationFailure
late_lowering/instance_nullable_field_with_initializer: TextSerializationFailure
late_lowering/instance_nullable_field_without_initializer: TextSerializationFailure
late_lowering/instance_nullable_final_field_without_initializer: TextSerializationFailure
late_lowering/late_field_with_initializer: TextSerializationFailure
late_lowering/late_field_without_initializer: TextSerializationFailure
late_lowering/late_final_field_with_initializer: TextSerializationFailure

View file

@ -441,6 +441,46 @@ method() {
}
```
##### Instance field initialization
A field initialization of late _nullable_ instance field
```
class Class {
late T? x;
Class.a();
Class.b(this.x);
Class.c() : x = <exp>;
}
```
is encoded as
```
class Class {
bool _#x#isSet = false;
T? _#x;
Class.a();
Class.b(T x) : _#x#isSet true, _#x = x;
Class.c() : _#x#isSet = true, _#x = <exp>;
}
```
A field initialization of late _non-nullable_ instance field
```
class Class {
late T x;
Class.a();
Class.b(this.x);
Class.c() : x = <exp>;
}
```
is encoded as
```
class Class {
T? _#x;
Class.a();
Class.b(T x) : _#x = x;
Class.b() : _#x = <exp>;
}
```
### The Null Check Operator