[cfe,kernel] Add Field.isInternalImplementation

This bit is required to support synthesized field used for the late
lowering. These fields should not be seen as part of the interface,
that is, classes that implement the class declaring the late field should
not be required to override these fields.

Closes #41436

Change-Id: I9a98322bdd1842b46bde34fff1176a7577672e0f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142998
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2020-04-15 13:46:43 +00:00 committed by commit-bot@chromium.org
parent ce61c5ff7b
commit eb18db2116
17 changed files with 282 additions and 11 deletions

2
DEPS
View file

@ -469,7 +469,7 @@ deps = {
"packages": [
{
"package": "dart/cfe/dart2js_dills",
"version": "binary_version:41_2",
"version": "binary_version:42",
}
],
"dep_type": "cipd",

View file

@ -674,12 +674,14 @@ abstract class AbstractLateFieldEncoding implements FieldEncoding {
new Field(null, fileUri: fileUri, reference: referenceFrom?.reference)
..fileOffset = charOffset
..fileEndOffset = charEndOffset
..isNonNullableByDefault = true;
..isNonNullableByDefault = true
..isInternalImplementation = true;
_lateIsSetField = new Field(null,
fileUri: fileUri, reference: lateIsSetReferenceFrom?.reference)
..fileOffset = charOffset
..fileEndOffset = charEndOffset
..isNonNullableByDefault = true;
..isNonNullableByDefault = true
..isInternalImplementation = true;
_lateGetter = new Procedure(
null, ProcedureKind.Getter, new FunctionNode(null),
fileUri: fileUri, reference: getterReferenceFrom?.reference)

View file

@ -155,11 +155,11 @@ class DillClassMember extends BuilderClassMember {
@override
bool get isSourceDeclaration => false;
// TODO(johnniwinther): This should be `true` for fields added for late
// lowering. Currently not needed because these fields are private and we only
// use this property while checking implementation of abstract members.
@override
bool get isInternalImplementation => false;
bool get isInternalImplementation {
Member member = memberBuilder.member;
return member is Field && member.isInternalImplementation;
}
@override
bool get isProperty =>

View file

@ -275,6 +275,7 @@ ioo
isolate
isolates
issue41210b
issue41436c
iter
joo
jumped

View file

@ -0,0 +1,11 @@
// Copyright (c) 2020, 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 'issue41436c_lib.dart';
class C extends B {}
main() {
new C();
}

View file

@ -0,0 +1,11 @@
// Copyright (c) 2020, 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.
abstract class A {
late int x;
}
class B implements A {
int x = 3;
}

View file

@ -0,0 +1,34 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue41436c_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue41436c_lib.dart";
class C extends iss::B {
synthetic constructor •() → self::C
;
no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#_#A#x=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
}
static method main() → dynamic
;
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
abstract class A extends core::Object {
field core::int? _#A#x;
synthetic constructor •() → iss::A
;
get x() → core::int;
set x(core::int #t1) → void;
}
class B extends core::Object implements iss::A {
field core::int x;
synthetic constructor •() → iss::B
;
}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue41436c_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue41436c_lib.dart";
class C extends iss::B {
synthetic constructor •() → self::C
: super iss::B::•()
;
no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
}
static method main() → dynamic {
new self::C::•();
}
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
import "dart:_internal" as _in;
abstract class A extends core::Object {
field core::int? _#A#x = null;
synthetic constructor •() → iss::A
: super core::Object::•()
;
get x() → core::int
return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
set x(core::int #t2) → void
this.{iss::A::_#A#x} = #t2;
}
class B extends core::Object implements iss::A {
field core::int x = 3;
synthetic constructor •() → iss::B
: super core::Object::•()
;
}
constants {
#C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
#C2 = <core::Type*>[]
#C3 = <dynamic>[]
#C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
#C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue41436c_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue41436c_lib.dart";
class C extends iss::B {
synthetic constructor •() → self::C
: super iss::B::•()
;
no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
}
static method main() → dynamic {
new self::C::•();
}
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
import "dart:_internal" as _in;
abstract class A extends core::Object {
field core::int? _#A#x = null;
synthetic constructor •() → iss::A
: super core::Object::•()
;
get x() → core::int
return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
set x(core::int #t2) → void
this.{iss::A::_#A#x} = #t2;
}
class B extends core::Object implements iss::A {
field core::int x = 3;
synthetic constructor •() → iss::B
: super core::Object::•()
;
}
constants {
#C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
#C2 = <core::Type*>[]
#C3 = <dynamic>[]
#C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
#C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue41436c_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue41436c_lib.dart";
class C extends iss::B {
synthetic constructor •() → self::C
: super iss::B::•()
;
no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
}
static method main() → dynamic {
new self::C::•();
}
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
import "dart:_internal" as _in;
abstract class A extends core::Object {
field core::int? _#A#x = null;
synthetic constructor •() → iss::A
: super core::Object::•()
;
get x() → core::int
return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
set x(core::int #t2) → void
this.{iss::A::_#A#x} = #t2;
}
class B extends core::Object implements iss::A {
field core::int x = 3;
synthetic constructor •() → iss::B
: super core::Object::•()
;
}
constants {
#C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
#C2 = <core::Type*>[]
#C3 = <dynamic>[]
#C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
#C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
}

View file

@ -0,0 +1,49 @@
library /*isNonNullableByDefault*/;
import self as self;
import "issue41436c_lib.dart" as iss;
import "dart:core" as core;
import "org-dartlang-testcase:///issue41436c_lib.dart";
class C extends iss::B {
synthetic constructor •() → self::C
: super iss::B::•()
;
no-such-method-forwarder get /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x() → core::int?
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C1, 1, #C2, #C3, core::Map::unmodifiable<core::Symbol*, dynamic>(#C4))) as{TypeError,ForDynamic,ForNonNullableByDefault} core::int?;
no-such-method-forwarder set /* from org-dartlang-testcase:///issue41436c_lib.dart */ _#A#x(core::int? value) → void
return this.{core::Object::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 2, #C2, core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C4)));
}
static method main() → dynamic {
new self::C::•();
}
library /*isNonNullableByDefault*/;
import self as iss;
import "dart:core" as core;
import "dart:_internal" as _in;
abstract class A extends core::Object {
field core::int? _#A#x = null;
synthetic constructor •() → iss::A
: super core::Object::•()
;
get x() → core::int
return let final core::int? #t1 = this.{iss::A::_#A#x} in #t1.==(null) ?{core::int} throw new _in::LateInitializationErrorImpl::•("Field 'x' has not been initialized.") : #t1{core::int};
set x(core::int #t2) → void
this.{iss::A::_#A#x} = #t2;
}
class B extends core::Object implements iss::A {
field core::int x = 3;
synthetic constructor •() → iss::B
: super core::Object::•()
;
}
constants {
#C1 = #org-dartlang-testcase:///issue41436c.dart::_#A#x
#C2 = <core::Type*>[]
#C3 = <dynamic>[]
#C4 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C3}
#C5 = #org-dartlang-testcase:///issue41436c.dart::_#A#x=
}

View file

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

View file

@ -1264,6 +1264,7 @@ late_lowering/issue40601: TextSerializationFailure
late_lowering/issue40805: TextSerializationFailure
late_lowering/issue41436/issue41436: TextSerializationFailure
late_lowering/issue41436b: TextSerializationFailure
late_lowering/issue41436c/issue41436c: TextSerializationFailure
late_lowering/late_field_inference: TextSerializationFailure
late_lowering/late_field_with_initializer: TextSerializationFailure
late_lowering/late_field_without_initializer: TextSerializationFailure

View file

@ -143,7 +143,7 @@ type CanonicalName {
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 41;
UInt32 formatVersion = 42;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
UriSource sourceMap;
@ -371,7 +371,7 @@ type Field extends Member {
FileOffset fileEndOffset;
UInt flags (isFinal, isConst, isStatic, hasImplicitGetter, hasImplicitSetter,
isCovariant, isGenericCovariantImpl, isLate, isExtensionMember,
isNonNullableByDefault);
isNonNullableByDefault, isInternalImplementation);
Name name;
List<Expression> annotations;
DartType type;

View file

@ -1739,6 +1739,7 @@ class Field extends Member {
static const int FlagLate = 1 << 7;
static const int FlagExtensionMember = 1 << 8;
static const int FlagNonNullableByDefault = 1 << 9;
static const int FlagInternalImplementation = 1 << 10;
/// Whether the field is declared with the `covariant` keyword.
bool get isCovariant => flags & FlagCovariant != 0;
@ -1780,6 +1781,13 @@ class Field extends Member {
/// Whether the field is declared with the `late` keyword.
bool get isLate => flags & FlagLate != 0;
// If `true` this field is not part of the interface but only part of the
// class members.
//
// This is `true` for instance for synthesized fields added for the late
// lowering.
bool get isInternalImplementation => flags & FlagInternalImplementation != 0;
void set isCovariant(bool value) {
flags = value ? (flags | FlagCovariant) : (flags & ~FlagCovariant);
}
@ -1823,6 +1831,12 @@ class Field extends Member {
flags = value ? (flags | FlagLate) : (flags & ~FlagLate);
}
void set isInternalImplementation(bool value) {
flags = value
? (flags | FlagInternalImplementation)
: (flags & ~FlagInternalImplementation);
}
/// True if the field is neither final nor const.
bool get isMutable => flags & (FlagFinal | FlagConst) == 0;
bool get isInstanceMember => !isStatic;

View file

@ -149,7 +149,7 @@ class Tag {
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
static const int BinaryFormatVersion = 41;
static const int BinaryFormatVersion = 42;
}
abstract class ConstantTag {

View file

@ -20,7 +20,7 @@ static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 29;
static const uint32_t kMaxSupportedKernelFormatVersion = 41;
static const uint32_t kMaxSupportedKernelFormatVersion = 42;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \