[dart2js] Preserve "signatures" when lowering late variables.

When we lower an uninitialized static field to a cell, we gives the cell
a mangled name and create a getter/setter pair with the original field
name. The getter/setter simply call the appropriate members on the cell.

This means that other libraries, even ones that haven't been transformed
(e.g. during modular compilation) will still interoperate correctly,
since the transformed library still has the same external signature.

Change-Id: I88edcb71fa5cb910869b4266628a029ad358b77e
Fixes: https://github.com/dart-lang/sdk/issues/45854
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/214064
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Mayank Patke <fishythefish@google.com>
This commit is contained in:
Mayank Patke 2021-09-22 16:55:26 +00:00 committed by commit-bot@chromium.org
parent 31a04e775d
commit d992af7e9c
12 changed files with 318 additions and 285 deletions

View file

@ -71,22 +71,15 @@ class LateLowering {
bool _shouldLowerInstanceField(Field field) =>
field.isLate && !field.isStatic;
String _mangleFieldName(Field field) {
assert(_shouldLowerInstanceField(field));
Class cls = field.enclosingClass!;
return '_#${cls.name}#${field.name.text}';
Name _mangleFieldCellName(Field field) {
assert(_shouldLowerStaticField(field));
return Name('_#${field.name.text}', field.enclosingLibrary);
}
void transformAdditionalExports(Library library) {
List<Reference> additionalExports = library.additionalExports;
Set<Reference> newExports = {};
additionalExports.removeWhere((Reference reference) {
Field? cell = _fieldCells[reference.node];
if (cell == null) return false;
newExports.add(cell.getterReference);
return true;
});
additionalExports.addAll(newExports);
Name _mangleFieldName(Field field) {
assert(_shouldLowerInstanceField(field));
Class cls = field.enclosingClass!;
return Name('_#${cls.name}#${field.name.text}', field.enclosingLibrary);
}
ConstructorInvocation _callCellConstructor(Expression name, int fileOffset) =>
@ -154,6 +147,13 @@ class LateLowering {
Arguments([value])..fileOffset = fileOffset)
..fileOffset = fileOffset;
void exitLibrary() {
assert(_variableCells.isEmpty);
_fieldCells.clear();
_backingInstanceFields.clear();
_getterToField.clear();
}
void enterFunction() {
_variableCells.add(null);
}
@ -198,6 +198,7 @@ class LateLowering {
type: InterfaceType(_coreTypes.cellClass, nonNullable),
isFinal: true)
..fileOffset = fileOffset;
return _addToCurrentScope(variable, cell);
}
@ -282,17 +283,71 @@ class LateLowering {
return _fieldCells.putIfAbsent(field, () {
int fileOffset = field.fileOffset;
Name name = field.name;
field.getterReference.canonicalName?.unbind();
field.setterReference?.canonicalName?.unbind();
return Field.immutable(name,
Uri fileUri = field.fileUri;
DartType type = field.type;
Field fieldCell = Field.immutable(_mangleFieldCellName(field),
type: InterfaceType(_coreTypes.cellClass, nonNullable),
initializer: _callCellConstructor(
_nameLiteral(name.text, fileOffset), fileOffset),
isFinal: true,
isStatic: true,
fileUri: field.fileUri)
fileUri: fileUri)
..fileOffset = fileOffset
..isNonNullableByDefault = true;
StaticGet fieldCellAccess() =>
StaticGet(fieldCell)..fileOffset = fileOffset;
Procedure getter = Procedure(
name,
ProcedureKind.Getter,
FunctionNode(
ReturnStatement(
_callReader(_readField, fieldCellAccess(), type, fileOffset))
..fileOffset = fileOffset,
returnType: type)
..fileOffset = fileOffset,
isStatic: true,
fileUri: fileUri,
reference: field.getterReference)
..fileOffset = fileOffset
..isNonNullableByDefault = true;
VariableDeclaration setterValue = VariableDeclaration('value', type: type)
..fileOffset = fileOffset;
VariableGet setterValueRead() =>
VariableGet(setterValue)..fileOffset = fileOffset;
Procedure setter = Procedure(
name,
ProcedureKind.Setter,
FunctionNode(
ReturnStatement(_callSetter(
field.isFinal
? _coreTypes.cellFinalFieldValueSetter
: _coreTypes.cellValueSetter,
fieldCellAccess(),
setterValueRead(),
fileOffset))
..fileOffset = fileOffset,
positionalParameters: [setterValue],
returnType: VoidType())
..fileOffset = fileOffset,
isStatic: true,
fileUri: fileUri,
reference: field.setterReference)
..fileOffset = fileOffset
..isNonNullableByDefault = true;
TreeNode parent = field.parent!;
if (parent is Class) {
parent.addProcedure(getter);
parent.addProcedure(setter);
} else if (parent is Library) {
parent.addProcedure(getter);
parent.addProcedure(setter);
}
return fieldCell;
});
}
@ -313,7 +368,7 @@ class LateLowering {
Expression? initializer = field.initializer;
Class enclosingClass = field.enclosingClass!;
Name mangledName = Name(_mangleFieldName(field), field.enclosingLibrary);
Name mangledName = _mangleFieldName(field);
Field backingField = Field.mutable(mangledName,
type: type,
initializer: StaticInvocation(_coreTypes.createSentinelMethod,
@ -518,36 +573,4 @@ class LateLowering {
return FieldInitializer(backingField, initializer.value)
..fileOffset = initializer.fileOffset;
}
StaticGet _fieldCellAccess(Field field, int fileOffset) =>
StaticGet(_fieldCell(field))..fileOffset = fileOffset;
TreeNode transformStaticGet(StaticGet node, Member contextMember) {
_contextMember = contextMember;
Member target = node.target;
if (target is Field && _shouldLowerStaticField(target)) {
int fileOffset = node.fileOffset;
StaticGet cell = _fieldCellAccess(target, fileOffset);
return _callReader(_readField, cell, target.type, fileOffset);
}
return node;
}
TreeNode transformStaticSet(StaticSet node, Member contextMember) {
_contextMember = contextMember;
Member target = node.target;
if (target is Field && _shouldLowerStaticField(target)) {
int fileOffset = node.fileOffset;
StaticGet cell = _fieldCellAccess(target, fileOffset);
Procedure setter = target.isFinal
? _coreTypes.cellFinalFieldValueSetter
: _coreTypes.cellValueSetter;
return _callSetter(setter, cell, node.value, fileOffset);
}
return node;
}
}

View file

@ -21,12 +21,6 @@ void transformLibraries(List<Library> libraries, CoreTypes coreTypes,
ClassHierarchy hierarchy, CompilerOptions? options) {
final transformer = _Lowering(coreTypes, hierarchy, options);
libraries.forEach(transformer.visitLibrary);
// Do a second pass to remove/replace now-unused nodes.
// Since the transformer API doesn't visit `Library.additionalExports`, we
// have to manually replace references to transformed nodes.
libraries.forEach(transformer.transformAdditionalExports);
}
class _Lowering extends Transformer {
@ -40,16 +34,19 @@ class _Lowering extends Transformer {
: factorySpecializer = FactorySpecializer(coreTypes, hierarchy),
_lateLowering = LateLowering(coreTypes, _options);
void transformAdditionalExports(Library node) {
_lateLowering.transformAdditionalExports(node);
}
@override
TreeNode defaultMember(Member node) {
_currentMember = node;
return super.defaultMember(node);
}
@override
TreeNode visitLibrary(Library node) {
node.transformChildren(this);
_lateLowering.exitLibrary();
return node;
}
@override
TreeNode visitStaticInvocation(StaticInvocation node) {
node.transformChildren(this);
@ -94,16 +91,4 @@ class _Lowering extends Transformer {
node.transformChildren(this);
return _lateLowering.transformFieldInitializer(node, _currentMember!);
}
@override
TreeNode visitStaticGet(StaticGet node) {
node.transformChildren(this);
return _lateLowering.transformStaticGet(node, _currentMember!);
}
@override
TreeNode visitStaticSet(StaticSet node) {
node.transformChildren(this);
return _lateLowering.transformStaticSet(node, _currentMember!);
}
}

View file

@ -1,23 +1,4 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
// Statics.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
// Statics.b = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
// lib.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
// lib.b = 42;
// ^
//
import self as self;
import "main_lib1.dart" as mai;
import "dart:core" as core;
@ -69,16 +50,12 @@ static method testInitializedFinalInstanceField() → void {
}
static method testUninitializedNonFinalStaticField() → void {
core::print(mai::Statics::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
Statics.a = 42;
^";
mai::Statics::a = 42;
core::print(mai::Statics::a);
}
static method testUninitializedFinalStaticField() → void {
core::print(mai::Statics::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
Statics.b = 42;
^";
mai::Statics::b = 42;
core::print(mai::Statics::b);
}
static method testInitializedNonFinalStaticField() → void {
@ -91,16 +68,12 @@ static method testInitializedFinalStaticField() → void {
}
static method testUninitializedNonFinalTopLevelField() → void {
core::print(mai2::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
lib.a = 42;
^";
mai2::a = 42;
core::print(mai2::a);
}
static method testUninitializedFinalTopLevelField() → void {
core::print(mai2::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
lib.b = 42;
^";
mai2::b = 42;
core::print(mai2::b);
}
static method testInitializedNonFinalTopLevelField() → void {
@ -157,8 +130,8 @@ class C extends core::Object {
}
}
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
synthetic constructor •() → mai::Statics
@ -166,6 +139,14 @@ class Statics extends core::Object {
;
static method _#new#tearOff() → mai::Statics
return new mai::Statics::•();
static get a() → core::int
return mai::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
}
static method testNullableUninitializedNonFinalLocal() → void {
final _la::_Cell x = new _la::_Cell::named("x");
@ -216,10 +197,18 @@ static method testNonNullableInitializedFinalLocal() → void {
library /*isNonNullableByDefault*/;
import self as mai2;
import "dart:_late_helper" as _la;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
static get a() → core::int
return mai2::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai2::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai2::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai2::_#b.{_la::_Cell::finalFieldValue} = value;

View file

@ -1,23 +1,4 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
// Statics.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
// Statics.b = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
// lib.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
// lib.b = 42;
// ^
//
import self as self;
import "main_lib1.dart" as mai;
import "dart:core" as core;
@ -69,16 +50,12 @@ static method testInitializedFinalInstanceField() → void {
}
static method testUninitializedNonFinalStaticField() → void {
core::print(mai::Statics::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
Statics.a = 42;
^";
mai::Statics::a = 42;
core::print(mai::Statics::a);
}
static method testUninitializedFinalStaticField() → void {
core::print(mai::Statics::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
Statics.b = 42;
^";
mai::Statics::b = 42;
core::print(mai::Statics::b);
}
static method testInitializedNonFinalStaticField() → void {
@ -91,16 +68,12 @@ static method testInitializedFinalStaticField() → void {
}
static method testUninitializedNonFinalTopLevelField() → void {
core::print(mai2::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
lib.a = 42;
^";
mai2::a = 42;
core::print(mai2::a);
}
static method testUninitializedFinalTopLevelField() → void {
core::print(mai2::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
lib.b = 42;
^";
mai2::b = 42;
core::print(mai2::b);
}
static method testInitializedNonFinalTopLevelField() → void {
@ -157,8 +130,8 @@ class C extends core::Object {
}
}
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
synthetic constructor •() → mai::Statics
@ -166,6 +139,14 @@ class Statics extends core::Object {
;
static method _#new#tearOff() → mai::Statics
return new mai::Statics::•();
static get a() → core::int
return mai::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
}
static method testNullableUninitializedNonFinalLocal() → void {
final _la::_Cell x = new _la::_Cell::named("x");
@ -216,13 +197,21 @@ static method testNonNullableInitializedFinalLocal() → void {
library /*isNonNullableByDefault*/;
import self as mai2;
import "dart:_late_helper" as _la;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
static get a() → core::int
return mai2::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai2::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai2::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai2::_#b.{_la::_Cell::finalFieldValue} = value;
Extra constant evaluation status:
@ -236,4 +225,4 @@ Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:63:23 ->
Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:71:22 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:7:14 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:8:20 -> DoubleConstant(-1.0)
Extra constant evaluation: evaluated: 205, effectively constant: 10
Extra constant evaluation: evaluated: 229, effectively constant: 10

View file

@ -1,23 +1,4 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
// Statics.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
// Statics.b = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
// lib.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
// lib.b = 42;
// ^
//
import self as self;
import "main_lib1.dart" as mai;
import "dart:core" as core;
@ -69,16 +50,12 @@ static method testInitializedFinalInstanceField() → void {
}
static method testUninitializedNonFinalStaticField() → void {
core::print(mai::Statics::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
Statics.a = 42;
^";
mai::Statics::a = 42;
core::print(mai::Statics::a);
}
static method testUninitializedFinalStaticField() → void {
core::print(mai::Statics::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
Statics.b = 42;
^";
mai::Statics::b = 42;
core::print(mai::Statics::b);
}
static method testInitializedNonFinalStaticField() → void {
@ -91,16 +68,12 @@ static method testInitializedFinalStaticField() → void {
}
static method testUninitializedNonFinalTopLevelField() → void {
core::print(mai2::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
lib.a = 42;
^";
mai2::a = 42;
core::print(mai2::a);
}
static method testUninitializedFinalTopLevelField() → void {
core::print(mai2::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
lib.b = 42;
^";
mai2::b = 42;
core::print(mai2::b);
}
static method testInitializedNonFinalTopLevelField() → void {
@ -157,8 +130,8 @@ class C extends core::Object {
}
}
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
synthetic constructor •() → mai::Statics
@ -166,6 +139,14 @@ class Statics extends core::Object {
;
static method _#new#tearOff() → mai::Statics
return new mai::Statics::•();
static get a() → core::int
return mai::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
}
static method testNullableUninitializedNonFinalLocal() → void {
final _la::_Cell x = new _la::_Cell::named("x");
@ -216,10 +197,18 @@ static method testNonNullableInitializedFinalLocal() → void {
library /*isNonNullableByDefault*/;
import self as mai2;
import "dart:_late_helper" as _la;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
static get a() → core::int
return mai2::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai2::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai2::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai2::_#b.{_la::_Cell::finalFieldValue} = value;

View file

@ -70,14 +70,30 @@ class C extends core::Object {
}
}
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell c = new _la::_Cell::named("c");
static final field _la::_Cell d = new _la::_Cell::named("d");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
static final field _la::_Cell _#c = new _la::_Cell::named("c");
static final field _la::_Cell _#d = new _la::_Cell::named("d");
synthetic constructor •() → mai::Statics
;
static method _#new#tearOff() → mai::Statics
return new mai::Statics::•();
static get a() → core::int
return mai::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
static get c() → core::int
return mai::Statics::_#c.{_la::_Cell::readField}<core::int>(){() → core::int};
static set c(core::int value) → void
return mai::Statics::_#c.{_la::_Cell::value} = value;
static get d() → core::int
return mai::Statics::_#d.{_la::_Cell::readField}<core::int>(){() → core::int};
static set d(core::int value) → void
return mai::Statics::_#d.{_la::_Cell::finalFieldValue} = value;
}
static method testNullableUninitializedNonFinalLocal() → void
;
@ -98,9 +114,26 @@ static method testNonNullableInitializedFinalLocal() → void
library /*isNonNullableByDefault*/;
import self as self2;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell c = new _la::_Cell::named("c");
static final field _la::_Cell d = new _la::_Cell::named("d");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
static final field _la::_Cell _#c = new _la::_Cell::named("c");
static final field _la::_Cell _#d = new _la::_Cell::named("d");
static get a() → core::int
return self2::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return self2::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return self2::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return self2::_#b.{_la::_Cell::finalFieldValue} = value;
static get c() → core::int
return self2::_#c.{_la::_Cell::readField}<core::int>(){() → core::int};
static set c(core::int value) → void
return self2::_#c.{_la::_Cell::value} = value;
static get d() → core::int
return self2::_#d.{_la::_Cell::readField}<core::int>(){() → core::int};
static set d(core::int value) → void
return self2::_#d.{_la::_Cell::finalFieldValue} = value;

View file

@ -1,23 +1,4 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
// Statics.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
// Statics.b = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
// lib.a = 42;
// ^
//
// pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
// lib.b = 42;
// ^
//
import self as self;
import "main_lib1.dart" as mai;
import "dart:core" as core;
@ -69,16 +50,12 @@ static method testInitializedFinalInstanceField() → void {
}
static method testUninitializedNonFinalStaticField() → void {
core::print(mai::Statics::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:59:11: Error: Setter not found: 'a'.
Statics.a = 42;
^";
mai::Statics::a = 42;
core::print(mai::Statics::a);
}
static method testUninitializedFinalStaticField() → void {
core::print(mai::Statics::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:65:11: Error: Setter not found: 'b'.
Statics.b = 42;
^";
mai::Statics::b = 42;
core::print(mai::Statics::b);
}
static method testInitializedNonFinalStaticField() → void {
@ -91,16 +68,12 @@ static method testInitializedFinalStaticField() → void {
}
static method testUninitializedNonFinalTopLevelField() → void {
core::print(mai2::a);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:81:7: Error: Setter not found: 'a'.
lib.a = 42;
^";
mai2::a = 42;
core::print(mai2::a);
}
static method testUninitializedFinalTopLevelField() → void {
core::print(mai2::b);
invalid-expression "pkg/front_end/testcases/dart2js/late_from_dill/main.dart:87:7: Error: Setter not found: 'b'.
lib.b = 42;
^";
mai2::b = 42;
core::print(mai2::b);
}
static method testInitializedNonFinalTopLevelField() → void {
@ -157,8 +130,8 @@ class C extends core::Object {
}
}
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
synthetic constructor •() → mai::Statics
@ -166,6 +139,14 @@ class Statics extends core::Object {
;
static method _#new#tearOff() → mai::Statics
return new mai::Statics::•();
static get a() → core::int
return mai::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
}
static method testNullableUninitializedNonFinalLocal() → void {
final _la::_Cell x = new _la::_Cell::named("x");
@ -216,13 +197,21 @@ static method testNonNullableInitializedFinalLocal() → void {
library /*isNonNullableByDefault*/;
import self as mai2;
import "dart:_late_helper" as _la;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
static get a() → core::int
return mai2::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return mai2::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return mai2::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return mai2::_#b.{_la::_Cell::finalFieldValue} = value;
Extra constant evaluation status:
@ -236,4 +225,4 @@ Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:63:23 ->
Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib1.dart:71:22 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:7:14 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///main_lib2.dart:8:20 -> DoubleConstant(-1.0)
Extra constant evaluation: evaluated: 205, effectively constant: 10
Extra constant evaluation: evaluated: 229, effectively constant: 10

View file

@ -3,18 +3,20 @@ import self as self;
import "dart:core" as core;
import "dart:_late_helper" as _la;
import "late_statics_lib.dart" as lat;
additionalExports = (lat::c,
lat::c,
lat::d,
additionalExports = (lat::a,
lat::a,
lat::b)
lat::b,
lat::b,
lat::c,
lat::c,
lat::d)
import "org-dartlang-testcase:///late_statics_lib.dart" as lib;
export "org-dartlang-testcase:///late_statics_lib.dart";
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
synthetic constructor •() → self::Statics
@ -22,6 +24,14 @@ class Statics extends core::Object {
;
static method _#new#tearOff() → self::Statics
return new self::Statics::•();
static get a() → core::int
return self::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return self::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return self::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return self::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
}
static method main() → void {
self::testUninitializedNonFinalStaticField();
@ -34,14 +44,14 @@ static method main() → void {
self::testInitializedFinalTopLevelField();
}
static method testUninitializedNonFinalStaticField() → void {
core::print(self::Statics::a.{_la::_Cell::readField}<core::int>(){() → core::int});
self::Statics::a.{_la::_Cell::value} = 42;
core::print(self::Statics::a.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(self::Statics::a);
self::Statics::a = 42;
core::print(self::Statics::a);
}
static method testUninitializedFinalStaticField() → void {
core::print(self::Statics::b.{_la::_Cell::readField}<core::int>(){() → core::int});
self::Statics::b.{_la::_Cell::finalFieldValue} = 42;
core::print(self::Statics::b.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(self::Statics::b);
self::Statics::b = 42;
core::print(self::Statics::b);
}
static method testInitializedNonFinalStaticField() → void {
core::print(self::Statics::c);
@ -52,14 +62,14 @@ static method testInitializedFinalStaticField() → void {
core::print(self::Statics::d);
}
static method testUninitializedNonFinalTopLevelField() → void {
core::print(lat::a.{_la::_Cell::readField}<core::int>(){() → core::int});
lat::a.{_la::_Cell::value} = 42;
core::print(lat::a.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(lat::a);
lat::a = 42;
core::print(lat::a);
}
static method testUninitializedFinalTopLevelField() → void {
core::print(lat::b.{_la::_Cell::readField}<core::int>(){() → core::int});
lat::b.{_la::_Cell::finalFieldValue} = 42;
core::print(lat::b.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(lat::b);
lat::b = 42;
core::print(lat::b);
}
static method testInitializedNonFinalTopLevelField() → void {
core::print(lat::c);
@ -72,13 +82,21 @@ static method testInitializedFinalTopLevelField() → void {
library /*isNonNullableByDefault*/;
import self as lat;
import "dart:_late_helper" as _la;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
static get a() → core::int
return lat::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return lat::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return lat::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return lat::_#b.{_la::_Cell::finalFieldValue} = value;
Extra constant evaluation status:
@ -86,4 +104,4 @@ Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:22:23
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:23:29 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics_lib.dart:7:14 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics_lib.dart:8:20 -> DoubleConstant(-1.0)
Extra constant evaluation: evaluated: 63, effectively constant: 4
Extra constant evaluation: evaluated: 71, effectively constant: 4

View file

@ -3,18 +3,20 @@ import self as self;
import "dart:core" as core;
import "dart:_late_helper" as _la;
import "late_statics_lib.dart" as lat;
additionalExports = (lat::c,
lat::c,
lat::d,
additionalExports = (lat::a,
lat::a,
lat::b)
lat::b,
lat::b,
lat::c,
lat::c,
lat::d)
import "org-dartlang-testcase:///late_statics_lib.dart" as lib;
export "org-dartlang-testcase:///late_statics_lib.dart";
class Statics extends core::Object {
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
synthetic constructor •() → self::Statics
@ -22,6 +24,14 @@ class Statics extends core::Object {
;
static method _#new#tearOff() → self::Statics
return new self::Statics::•();
static get a() → core::int
return self::Statics::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return self::Statics::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return self::Statics::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return self::Statics::_#b.{_la::_Cell::finalFieldValue} = value;
}
static method main() → void {
self::testUninitializedNonFinalStaticField();
@ -34,14 +44,14 @@ static method main() → void {
self::testInitializedFinalTopLevelField();
}
static method testUninitializedNonFinalStaticField() → void {
core::print(self::Statics::a.{_la::_Cell::readField}<core::int>(){() → core::int});
self::Statics::a.{_la::_Cell::value} = 42;
core::print(self::Statics::a.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(self::Statics::a);
self::Statics::a = 42;
core::print(self::Statics::a);
}
static method testUninitializedFinalStaticField() → void {
core::print(self::Statics::b.{_la::_Cell::readField}<core::int>(){() → core::int});
self::Statics::b.{_la::_Cell::finalFieldValue} = 42;
core::print(self::Statics::b.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(self::Statics::b);
self::Statics::b = 42;
core::print(self::Statics::b);
}
static method testInitializedNonFinalStaticField() → void {
core::print(self::Statics::c);
@ -52,14 +62,14 @@ static method testInitializedFinalStaticField() → void {
core::print(self::Statics::d);
}
static method testUninitializedNonFinalTopLevelField() → void {
core::print(lat::a.{_la::_Cell::readField}<core::int>(){() → core::int});
lat::a.{_la::_Cell::value} = 42;
core::print(lat::a.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(lat::a);
lat::a = 42;
core::print(lat::a);
}
static method testUninitializedFinalTopLevelField() → void {
core::print(lat::b.{_la::_Cell::readField}<core::int>(){() → core::int});
lat::b.{_la::_Cell::finalFieldValue} = 42;
core::print(lat::b.{_la::_Cell::readField}<core::int>(){() → core::int});
core::print(lat::b);
lat::b = 42;
core::print(lat::b);
}
static method testInitializedNonFinalTopLevelField() → void {
core::print(lat::c);
@ -72,13 +82,21 @@ static method testInitializedFinalTopLevelField() → void {
library /*isNonNullableByDefault*/;
import self as lat;
import "dart:_late_helper" as _la;
import "dart:core" as core;
import "dart:_late_helper" as _la;
static final field _la::_Cell a = new _la::_Cell::named("a");
static final field _la::_Cell b = new _la::_Cell::named("b");
static final field _la::_Cell _#a = new _la::_Cell::named("a");
static final field _la::_Cell _#b = new _la::_Cell::named("b");
late static field core::int c = 1.{core::int::unary-}(){() → core::int};
late static final field core::int d = 1.{core::int::unary-}(){() → core::int};
static get a() → core::int
return lat::_#a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set a(core::int value) → void
return lat::_#a.{_la::_Cell::value} = value;
static get b() → core::int
return lat::_#b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set b(core::int value) → void
return lat::_#b.{_la::_Cell::finalFieldValue} = value;
Extra constant evaluation status:
@ -86,4 +104,4 @@ Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:22:23
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics.dart:23:29 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics_lib.dart:7:14 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_statics_lib.dart:8:20 -> DoubleConstant(-1.0)
Extra constant evaluation: evaluated: 63, effectively constant: 4
Extra constant evaluation: evaluated: 71, effectively constant: 4

View file

@ -23,7 +23,6 @@ worlds:
- entry: late_statics.dart
worldType: updated
errors: true # (currently?) dart2js changes the interface and doesn't have the setter anymore. dartbug.com/45854
expectInitializeFromDill: false
invalidate:
- late_statics.dart

View file

@ -4,12 +4,16 @@ library from "org-dartlang-test:///late_statics.dart" as lat {
import "org-dartlang-test:///late_statics_lib.dart" as lib;
static method testUninitializedNonFinalTopLevelField() → void {
dart.core::print(lat2::a.{_late_helper::_Cell::readField}<dart.core::int>(){() → dart.core::int});
lat2::a.{_late_helper::_Cell::value} = 42;
dart.core::print(lat2::a.{_late_helper::_Cell::readField}<dart.core::int>(){() → dart.core::int});
dart.core::print(lat2::a);
lat2::a = 42;
dart.core::print(lat2::a);
}
}
library from "org-dartlang-test:///late_statics_lib.dart" as lat2 {
static final field _late_helper::_Cell a = new _late_helper::_Cell::named("a");
static final field _late_helper::_Cell _#a = new _late_helper::_Cell::named("a");
static get a() → dart.core::int
return lat2::_#a.{_late_helper::_Cell::readField}<dart.core::int>(){() → dart.core::int};
static set a(dart.core::int value) → void
return lat2::_#a.{_late_helper::_Cell::value} = value;
}

View file

@ -1,22 +1,19 @@
main = <No Member>;
library from "org-dartlang-test:///late_statics.dart" as lat {
//
// Problems in library:
//
// org-dartlang-test:///late_statics.dart:4:7: Error: Setter not found: 'a'.
// lib.a = 42;
// ^
//
import "org-dartlang-test:///late_statics_lib.dart" as lib;
static method testUninitializedNonFinalTopLevelField() → void {
dart.core::print(lat2::a);
invalid-expression "org-dartlang-test:///late_statics.dart:4:7: Error: Setter not found: 'a'.\n lib.a = 42;\n ^";
lat2::a = 42;
dart.core::print(lat2::a);
}
}
library from "org-dartlang-test:///late_statics_lib.dart" as lat2 {
static final field _late_helper::_Cell a = new _late_helper::_Cell::named("a");
static final field _late_helper::_Cell _#a = new _late_helper::_Cell::named("a");
static get a() → dart.core::int
return lat2::_#a.{_late_helper::_Cell::readField}<dart.core::int>(){() → dart.core::int};
static set a(dart.core::int value) → void
return lat2::_#a.{_late_helper::_Cell::value} = value;
}