[cfe,dart2js] Reuse field reference for static late lowering

In response to https://github.com/flutter/flutter/issues/89740 and
https://github.com/flutter/flutter/issues/94561

Change-Id: I22c100a575b91e70a2c5835b8db6dd450f319ce7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/221947
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2021-12-07 21:12:17 +00:00 committed by Commit Bot
parent 8f249569ad
commit 2b4934a54d
20 changed files with 357 additions and 1 deletions

View file

@ -280,13 +280,17 @@ class LateLowering {
Name name = field.name;
Uri fileUri = field.fileUri;
DartType type = field.type;
// We need to unbind the canonical name since we reuse the reference but
// change the name.
field.fieldReference.canonicalName?.unbind();
Field fieldCell = Field.immutable(_mangleFieldCellName(field),
type: InterfaceType(_coreTypes.cellClass, nonNullable),
initializer: _callCellConstructor(
_nameLiteral(name.text, fileOffset), fileOffset),
isFinal: true,
isStatic: true,
fileUri: fileUri)
fileUri: fileUri,
fieldReference: field.fieldReference)
..fileOffset = fileOffset
..isNonNullableByDefault = true;
StaticGet fieldCellAccess() =>
@ -364,6 +368,8 @@ class LateLowering {
Expression? initializer = field.initializer;
Class enclosingClass = field.enclosingClass!;
// We need to unbind the canonical name since we reuse the reference but
// change the name.
field.fieldReference.canonicalName?.unbind();
Field backingField = Field.mutable(mangledName,
type: type,

View file

@ -0,0 +1,12 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'main_lib.dart';
main() {
MyInt.a = 42;
print(MyInt.a);
MyInt.b = 87;
print(MyInt.b);
}

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
// MyInt.a = 42;
// ^
//
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
invalid-expression "pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
MyInt.a = 42;
^";
core::print(mai::_#MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = mai::_#MyInt|a;
static field b = mai::MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
late static field core::int MyInt|b = 42;
static get MyInt|a() → core::int
return mai::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return mai::_#MyInt|a.{_la::_Cell::value} = value;

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
// MyInt.a = 42;
// ^
//
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
invalid-expression "pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
MyInt.a = 42;
^";
core::print(mai::_#MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = mai::_#MyInt|a;
static field b = mai::MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
late static field core::int MyInt|b = 42;
static get MyInt|a() → core::int
return mai::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return mai::_#MyInt|a.{_la::_Cell::value} = value;

View file

@ -0,0 +1,3 @@
import 'main_lib.dart';
main() {}

View file

@ -0,0 +1,3 @@
import 'main_lib.dart';
main() {}

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
// MyInt.a = 42;
// ^
//
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
invalid-expression "pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
MyInt.a = 42;
^";
core::print(mai::_#MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = mai::_#MyInt|a;
static field b = mai::MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
late static field core::int MyInt|b = 42;
static get MyInt|a() → core::int
return mai::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return mai::_#MyInt|a.{_la::_Cell::value} = value;

View file

@ -0,0 +1,27 @@
library /*isNonNullableByDefault*/;
import self as self;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic
;
library /*isNonNullableByDefault*/;
import self as self2;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = self2::_#MyInt|a;
static field b = self2::_#MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
static final field _la::_Cell _#MyInt|b = new _la::_Cell::named("MyInt|b");
static get MyInt|a() → core::int
return self2::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return self2::_#MyInt|a.{_la::_Cell::value} = value;
static get MyInt|b() → core::int
return self2::_#MyInt|b.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|b(core::int value) → void
return self2::_#MyInt|b.{_la::_Cell::value} = value;

View file

@ -0,0 +1,38 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
// MyInt.a = 42;
// ^
//
import self as self;
import "dart:core" as core;
import "main_lib.dart" as mai;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
invalid-expression "pkg/front_end/testcases/dart2js/flutter_issue94561/main.dart:8:9: Error: Setter not found: 'a'.
MyInt.a = 42;
^";
core::print(mai::_#MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = mai::_#MyInt|a;
static field b = mai::MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
late static field core::int MyInt|b = 42;
static get MyInt|a() → core::int
return mai::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return mai::_#MyInt|a.{_la::_Cell::value} = value;

View file

@ -0,0 +1,12 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'main_lib.dart';
main() {
MyInt.a = 42;
print(MyInt.a);
MyInt.b = 87;
print(MyInt.b);
}

View file

@ -0,0 +1,24 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
mai::MyInt|a = 42;
core::print(mai::MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
extension MyInt on core::int {
static field a = mai::MyInt|a;
static field b = mai::MyInt|b;
}
late static field core::int MyInt|a;
late static field core::int MyInt|b = 42;

View file

@ -0,0 +1,29 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
mai::MyInt|a = 42;
core::print(mai::MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = mai::_#MyInt|a;
static field b = mai::MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
late static field core::int MyInt|b = 42;
static get MyInt|a() → core::int
return mai::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return mai::_#MyInt|a.{_la::_Cell::value} = value;

View file

@ -0,0 +1,3 @@
import 'main_lib.dart';
main() {}

View file

@ -0,0 +1,3 @@
import 'main_lib.dart';
main() {}

View file

@ -0,0 +1,24 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
mai::MyInt|a = 42;
core::print(mai::MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
extension MyInt on core::int {
static field a = mai::MyInt|a;
static field b = mai::MyInt|b;
}
late static field core::int MyInt|a;
late static field core::int MyInt|b = 42;

View file

@ -0,0 +1,18 @@
library /*isNonNullableByDefault*/;
import self as self;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic
;
library /*isNonNullableByDefault*/;
import self as self2;
import "dart:core" as core;
extension MyInt on core::int {
static field a = self2::MyInt|a;
static field b = self2::MyInt|b;
}
late static field core::int MyInt|a;
late static field core::int MyInt|b;

View file

@ -0,0 +1,29 @@
library /*isNonNullableByDefault*/;
import self as self;
import "main_lib.dart" as mai;
import "dart:core" as core;
import "org-dartlang-testcase:///main_lib.dart";
static method main() → dynamic {
mai::MyInt|a = 42;
core::print(mai::MyInt|a);
mai::MyInt|b = 87;
core::print(mai::MyInt|b);
}
library /*isNonNullableByDefault*/;
import self as mai;
import "dart:core" as core;
import "dart:_late_helper" as _la;
extension MyInt on core::int {
static field a = mai::_#MyInt|a;
static field b = mai::MyInt|b;
}
static final field _la::_Cell _#MyInt|a = new _la::_Cell::named("MyInt|a");
late static field core::int MyInt|b = 42;
static get MyInt|a() → core::int
return mai::_#MyInt|a.{_la::_Cell::readField}<core::int>(){() → core::int};
static set MyInt|a(core::int value) → void
return mai::_#MyInt|a.{_la::_Cell::value} = value;

View file

@ -0,0 +1,8 @@
// Copyright (c) 2021, 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.
extension MyInt on int {
static late int a;
static late int b = 42;
}

View file

@ -0,0 +1 @@
main_lib.dart

View file

@ -2498,6 +2498,8 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeName(descriptor.name);
writeByte(descriptor.kind.index);
writeByte(descriptor.flags);
assert(descriptor.member.canonicalName != null,
"No canonical name for ${descriptor}.");
writeNonNullCanonicalNameReference(descriptor.member.canonicalName!);
}
}