[kernel] Add Field.fieldReference

This adds a third reference to Field declaration, so that we know have
three references, one for each use case:

1) fieldReference used for initialization; in FieldInitializer and as
   the key in the InstanceConstant.fieldValues map.
2) getterReference used for reading; in InstanceGet, StaticGet and
   SuperPropertyGet
3) setterReference used for writing; in InstanceSet, StaticSet and
   SuperPropertySet

TEST=existing

Change-Id: I223f130e808e7f19a831c1fe5e3a4725d1bcdc3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203770
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Johnni Winther 2021-09-24 12:01:08 +00:00 committed by commit-bot@chromium.org
parent 4389cf7bba
commit 5b7968346d
37 changed files with 322 additions and 106 deletions

View file

@ -61,7 +61,7 @@ class _CloneMixinMethodsWithSuper {
Procedure? existingGetter = existingNonSetters[field.name];
Procedure? existingSetter = existingSetters[field.name];
cls.addField(cloneVisitor.cloneField(
field, existingGetter?.reference, existingSetter?.reference));
field, null, existingGetter?.reference, existingSetter?.reference));
if (existingGetter != null) {
cls.procedures.remove(existingGetter);
}

View file

@ -200,6 +200,7 @@ class EnumBuilder extends SourceClassBuilder {
Constructor? constructorReference;
Reference? toStringReference;
Reference? valuesFieldReference;
Reference? valuesGetterReference;
Reference? valuesSetterReference;
if (referencesFromIndexed != null) {
@ -208,6 +209,8 @@ class EnumBuilder extends SourceClassBuilder {
toStringReference =
referencesFromIndexed.lookupGetterReference(new Name("toString"));
Name valuesName = new Name("values");
valuesFieldReference =
referencesFromIndexed.lookupFieldReference(valuesName);
valuesGetterReference =
referencesFromIndexed.lookupGetterReference(valuesName);
valuesSetterReference =
@ -244,6 +247,7 @@ class EnumBuilder extends SourceClassBuilder {
charOffset,
charOffset,
staticFieldNameScheme,
fieldReference: valuesFieldReference,
fieldGetterReference: valuesGetterReference,
fieldSetterReference: valuesSetterReference);
members["values"] = valuesBuilder;
@ -303,10 +307,12 @@ class EnumBuilder extends SourceClassBuilder {
name.length,
parent.fileUri);
}
Reference? fieldReference;
Reference? getterReference;
Reference? setterReference;
if (referencesFromIndexed != null) {
Name nameName = new Name(name, referencesFromIndexed.library);
fieldReference = referencesFromIndexed.lookupFieldReference(nameName);
getterReference =
referencesFromIndexed.lookupGetterReference(nameName);
setterReference =
@ -322,6 +328,7 @@ class EnumBuilder extends SourceClassBuilder {
enumConstantInfo.charOffset,
enumConstantInfo.charOffset,
staticFieldNameScheme,
fieldReference: fieldReference,
fieldGetterReference: getterReference,
fieldSetterReference: setterReference);
members[name] = fieldBuilder..next = existing;

View file

@ -120,8 +120,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
int charOffset,
int charEndOffset,
NameScheme fieldNameScheme,
{Reference? fieldGetterReference,
{Reference? fieldReference,
Reference? fieldGetterReference,
Reference? fieldSetterReference,
Reference? lateIsSetFieldReference,
Reference? lateIsSetGetterReference,
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
@ -138,6 +140,8 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
late_lowering.computeIsSetStrategy(libraryBuilder);
if (isAbstract || isExternal) {
assert(fieldReference == null);
assert(lateIsSetFieldReference == null);
assert(lateIsSetGetterReference == null);
assert(lateIsSetSetterReference == null);
assert(lateGetterReference == null);
@ -169,8 +173,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -184,8 +190,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -201,8 +209,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -216,8 +226,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -238,8 +250,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -253,8 +267,10 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -263,6 +279,7 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
isSetStrategy);
}
} else {
assert(lateIsSetFieldReference == null);
assert(lateIsSetGetterReference == null);
assert(lateIsSetSetterReference == null);
assert(lateGetterReference == null);
@ -274,6 +291,7 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
isLate: isLate,
hasInitializer: hasInitializer,
isNonNullableByDefault: library.isNonNullableByDefault,
fieldReference: fieldReference,
getterReference: fieldGetterReference,
setterReference: fieldSetterReference);
}
@ -599,6 +617,7 @@ class RegularFieldEncoding implements FieldEncoding {
required bool isLate,
required bool hasInitializer,
required bool isNonNullableByDefault,
required Reference? fieldReference,
required Reference? getterReference,
required Reference? setterReference}) {
// ignore: unnecessary_null_comparison
@ -619,6 +638,7 @@ class RegularFieldEncoding implements FieldEncoding {
isConst: isConst,
isLate: isLate,
fileUri: fileUri,
fieldReference: fieldReference,
getterReference: getterReference)
: new Field.mutable(
nameScheme.getFieldName(FieldNameType.Field, name,
@ -626,6 +646,7 @@ class RegularFieldEncoding implements FieldEncoding {
isFinal: isFinal,
isLate: isLate,
fileUri: fileUri,
fieldReference: fieldReference,
getterReference: getterReference,
setterReference: setterReference);
_field
@ -808,8 +829,10 @@ abstract class AbstractLateFieldEncoding implements FieldEncoding {
Uri fileUri,
int charOffset,
int charEndOffset,
Reference? fieldReference,
Reference? fieldGetterReference,
Reference? fieldSetterReference,
Reference? lateIsSetFieldReference,
Reference? lateIsSetGetterReference,
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
@ -824,6 +847,7 @@ abstract class AbstractLateFieldEncoding implements FieldEncoding {
_field = new Field.mutable(
nameScheme.getFieldName(FieldNameType.Field, name, isSynthesized: true),
fileUri: fileUri,
fieldReference: fieldReference,
getterReference: fieldGetterReference,
setterReference: fieldSetterReference)
..fileOffset = charOffset
@ -841,6 +865,7 @@ abstract class AbstractLateFieldEncoding implements FieldEncoding {
nameScheme.getFieldName(FieldNameType.IsSetField, name,
isSynthesized: true),
fileUri: fileUri,
fieldReference: lateIsSetFieldReference,
getterReference: lateIsSetGetterReference,
setterReference: lateIsSetSetterReference)
..fileOffset = charOffset
@ -1191,8 +1216,10 @@ class LateFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
Uri fileUri,
int charOffset,
int charEndOffset,
Reference? fieldReference,
Reference? fieldGetterReference,
Reference? fieldSetterReference,
Reference? lateIsSetFieldReference,
Reference? lateIsSetGetterReference,
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
@ -1205,8 +1232,10 @@ class LateFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -1223,8 +1252,10 @@ class LateFieldWithInitializerEncoding extends AbstractLateFieldEncoding
Uri fileUri,
int charOffset,
int charEndOffset,
Reference? fieldReference,
Reference? fieldGetterReference,
Reference? fieldSetterReference,
Reference? lateIsSetFieldReference,
Reference? lateIsSetGetterReference,
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
@ -1237,8 +1268,10 @@ class LateFieldWithInitializerEncoding extends AbstractLateFieldEncoding
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -1270,8 +1303,10 @@ class LateFinalFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
Uri fileUri,
int charOffset,
int charEndOffset,
Reference? fieldReference,
Reference? fieldGetterReference,
Reference? fieldSetterReference,
Reference? lateIsSetFieldReference,
Reference? lateIsSetGetterReference,
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
@ -1284,8 +1319,10 @@ class LateFinalFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,
@ -1318,8 +1355,10 @@ class LateFinalFieldWithInitializerEncoding extends AbstractLateFieldEncoding {
Uri fileUri,
int charOffset,
int charEndOffset,
Reference? fieldReference,
Reference? fieldGetterReference,
Reference? fieldSetterReference,
Reference? lateIsSetFieldReference,
Reference? lateIsSetGetterReference,
Reference? lateIsSetSetterReference,
Reference? lateGetterReference,
@ -1332,8 +1371,10 @@ class LateFinalFieldWithInitializerEncoding extends AbstractLateFieldEncoding {
fileUri,
charOffset,
charEndOffset,
fieldReference,
fieldGetterReference,
fieldSetterReference,
lateIsSetFieldReference,
lateIsSetGetterReference,
lateIsSetSetterReference,
lateGetterReference,

View file

@ -4083,7 +4083,7 @@ class InstanceBuilder {
final Map<Reference, Constant> fieldValues = <Reference, Constant>{};
fields.forEach((Field field, Constant value) {
assert(value is! UnevaluatedConstant);
fieldValues[field.getterReference] = value;
fieldValues[field.fieldReference] = value;
});
assert(unusedArguments.isEmpty);
return new InstanceConstant(klass.reference, typeArguments, fieldValues);
@ -4092,7 +4092,7 @@ class InstanceBuilder {
InstanceCreation buildUnevaluatedInstance() {
final Map<Reference, Expression> fieldValues = <Reference, Expression>{};
fields.forEach((Field field, Constant value) {
fieldValues[field.getterReference] = evaluator.extract(value);
fieldValues[field.fieldReference] = evaluator.extract(value);
});
return new InstanceCreation(
klass.reference, typeArguments, fieldValues, asserts, unusedArguments);

View file

@ -331,7 +331,7 @@ class TypeLabeler implements DartTypeVisitor<void>, ConstantVisitor<void> {
if (field.isStatic) continue;
if (!first) result.add(", ");
result.add("${field.name}: ");
node.fieldValues[field.getterReference]!.accept(this);
node.fieldValues[field.fieldReference]!.accept(this);
first = false;
}
result.add("}");

View file

@ -864,8 +864,11 @@ class SourceClassBuilder extends ClassBuilderImpl
procedure.stubTarget = null;
}
void _addRedirectingConstructor(SourceFactoryBuilder constructorBuilder,
SourceLibraryBuilder library, Reference? getterReference) {
void _addRedirectingConstructor(
SourceFactoryBuilder constructorBuilder,
SourceLibraryBuilder library,
Reference? fieldReference,
Reference? getterReference) {
// Add a new synthetic field to this class for representing factory
// constructors. This is used to support resolving such constructors in
// source code.
@ -888,6 +891,7 @@ class SourceClassBuilder extends ClassBuilderImpl
isFinal: true,
initializer: literal,
fileUri: cls.fileUri,
fieldReference: fieldReference,
getterReference: getterReference)
..fileOffset = cls.fileOffset;
cls.addField(field);
@ -930,11 +934,18 @@ class SourceClassBuilder extends ClassBuilderImpl
// is actually in the kernel tree. This call creates a StaticGet
// to [declaration.target] in a field `_redirecting#` which is
// only legal to do to things in the kernel tree.
Reference? getterReference =
referencesFromIndexed?.lookupGetterReference(new Name(
"_redirecting#", referencesFromIndexed!.library));
Reference? fieldReference;
Reference? getterReference;
if (referencesFromIndexed != null) {
Name name =
new Name(redirectingName, referencesFromIndexed!.library);
fieldReference =
referencesFromIndexed!.lookupFieldReference(name);
getterReference =
referencesFromIndexed!.lookupGetterReference(name);
}
_addRedirectingConstructor(
declaration, library, getterReference);
declaration, library, fieldReference, getterReference);
}
Member? targetNode;
if (targetBuilder is FunctionBuilder) {

View file

@ -175,7 +175,7 @@ class SourceExtensionBuilder extends ExtensionBuilderImpl {
Reference memberReference;
if (member is Field) {
libraryBuilder.library.addField(member);
memberReference = member.getterReference;
memberReference = member.fieldReference;
} else if (member is Procedure) {
libraryBuilder.library.addProcedure(member);
memberReference = member.reference;

View file

@ -1023,12 +1023,15 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
if (unserializableExports != null) {
Name fieldName = new Name("_exports#", library);
Reference? fieldReference =
referencesFromIndexed?.lookupFieldReference(fieldName);
Reference? getterReference =
referencesFromIndexed?.lookupGetterReference(fieldName);
library.addField(new Field.immutable(fieldName,
initializer: new StringLiteral(jsonEncode(unserializableExports)),
isStatic: true,
isConst: true,
fieldReference: fieldReference,
getterReference: getterReference,
fileUri: library.fileUri));
}
@ -2246,8 +2249,10 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
extensionName = currentTypeParameterScopeBuilder.name;
}
Reference? fieldReference;
Reference? fieldGetterReference;
Reference? fieldSetterReference;
Reference? lateIsSetFieldReference;
Reference? lateIsSetGetterReference;
Reference? lateIsSetSetterReference;
Reference? lateGetterReference;
@ -2264,18 +2269,21 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
(_currentClassReferencesFromIndexed ?? referencesFromIndexed)!;
Name nameToLookupName = nameScheme.getFieldName(FieldNameType.Field, name,
isSynthesized: fieldIsLateWithLowering);
fieldReference = indexedContainer.lookupFieldReference(nameToLookupName);
fieldGetterReference =
indexedContainer.lookupGetterReference(nameToLookupName);
fieldSetterReference =
indexedContainer.lookupSetterReference(nameToLookupName);
if (fieldIsLateWithLowering) {
Name lateIsSetNameName = nameScheme.getFieldName(
Name lateIsSetName = nameScheme.getFieldName(
FieldNameType.IsSetField, name,
isSynthesized: fieldIsLateWithLowering);
lateIsSetFieldReference =
indexedContainer.lookupFieldReference(lateIsSetName);
lateIsSetGetterReference =
indexedContainer.lookupGetterReference(lateIsSetNameName);
indexedContainer.lookupGetterReference(lateIsSetName);
lateIsSetSetterReference =
indexedContainer.lookupSetterReference(lateIsSetNameName);
indexedContainer.lookupSetterReference(lateIsSetName);
lateGetterReference = indexedContainer.lookupGetterReference(
nameScheme.getFieldName(FieldNameType.Getter, name,
isSynthesized: fieldIsLateWithLowering));
@ -2295,8 +2303,10 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
charOffset,
charEndOffset,
nameScheme,
fieldReference: fieldReference,
fieldGetterReference: fieldGetterReference,
fieldSetterReference: fieldSetterReference,
lateIsSetFieldReference: lateIsSetFieldReference,
lateIsSetGetterReference: lateIsSetGetterReference,
lateIsSetSetterReference: lateIsSetSetterReference,
lateGetterReference: lateGetterReference,

View file

@ -1970,9 +1970,12 @@ void doSimulateTransformer(Component c) {
Name fieldName = new Name("unique_SimulateTransformer");
Field field = new Field.immutable(fieldName,
isFinal: true,
getterReference: lib.reference.canonicalName
fieldReference: lib.reference.canonicalName
?.getChildFromFieldWithName(fieldName)
.reference,
getterReference: lib.reference.canonicalName
?.getChildFromFieldGetterWithName(fieldName)
.reference,
fileUri: lib.fileUri);
lib.addField(field);
for (Class c in lib.classes) {
@ -1983,9 +1986,12 @@ void doSimulateTransformer(Component c) {
fieldName = new Name("unique_SimulateTransformer");
field = new Field.immutable(fieldName,
isFinal: true,
getterReference: c.reference.canonicalName
fieldReference: lib.reference.canonicalName
?.getChildFromFieldWithName(fieldName)
.reference,
getterReference: c.reference.canonicalName
?.getChildFromFieldGetterWithName(fieldName)
.reference,
fileUri: c.fileUri);
c.addField(field);
}

View file

@ -240,20 +240,20 @@ void main() {
check({symConst: "#foo", symLibConst: "#dart:core::bar"}, 0);
Constant fooConst = new InstanceConstant(
fooClass.reference, [], {booField.getterReference: trueConst});
fooClass.reference, [], {booField.fieldReference: trueConst});
check({fooConst: "Foo {boo: true}"}, 1);
Constant foo2Const = new InstanceConstant(foo2Class.reference, [], {
nextField.getterReference: nullConst,
valueField.getterReference: intConst
nextField.fieldReference: nullConst,
valueField.fieldReference: intConst
});
check({foo2Const: "Foo {value: 2, next: null}"}, 1);
Constant foo2nConst = new InstanceConstant(foo2Class.reference, [], {
valueField.getterReference: intConst,
nextField.getterReference: new InstanceConstant(foo2Class.reference, [], {
valueField.getterReference: intConst,
nextField.getterReference: nullConst
valueField.fieldReference: intConst,
nextField.fieldReference: new InstanceConstant(foo2Class.reference, [], {
valueField.fieldReference: intConst,
nextField.fieldReference: nullConst
}),
});
check({foo2nConst: "Foo {value: 2, next: Foo {value: 2, next: null}}"}, 1);
@ -261,7 +261,7 @@ void main() {
Constant bazFooFoo2Const = new InstanceConstant(
bazClass.reference,
[foo, foo2],
{xField.getterReference: fooConst, yField.getterReference: foo2Const});
{xField.fieldReference: fooConst, yField.fieldReference: foo2Const});
check({
bazFooFoo2Const: "Baz<Foo/*1*/, Foo/*2*/> "
"{x: Foo/*1*/ {boo: true}, y: Foo/*2*/ {value: 2, next: null}}"

View file

@ -115,7 +115,7 @@ const Map<String?, Map<String, FieldRule?>> _fieldRuleMap = {
'typeParameters': FieldRule(isDeclaration: true),
},
'Field': {
'reference': FieldRule(name: 'getterReference'),
'reference': FieldRule(name: 'fieldReference'),
},
'TypeParameter': {
'_variance': FieldRule(name: 'variance'),

View file

@ -147,7 +147,7 @@ type CanonicalName {
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 72;
UInt32 formatVersion = 73;
Byte[10] shortSdkHash;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
@ -376,6 +376,7 @@ abstract type Member extends Node {}
type Field extends Member {
Byte tag = 4;
CanonicalNameReference canonicalNameField;
CanonicalNameReference canonicalNameGetter;
CanonicalNameReference canonicalNameSetter;
// An absolute path URI to the .dart file from which the field was created.

View file

@ -216,11 +216,7 @@ abstract class NamedNode extends TreeNode {
NamedNode(Reference? reference)
: this.reference = reference ?? new Reference() {
if (this is Field) {
(this as Field).getterReference.node = this;
} else {
this.reference.node = this;
}
this.reference.node = this;
}
/// This is an advanced feature.
@ -493,7 +489,10 @@ class Library extends NamedNode
}
for (int i = 0; i < fields.length; ++i) {
Field field = fields[i];
canonicalName.getChildFromField(field).bindTo(field.getterReference);
canonicalName.getChildFromField(field).bindTo(field.fieldReference);
canonicalName
.getChildFromFieldGetter(field)
.bindTo(field.getterReference);
if (field.hasSetter) {
canonicalName
.getChildFromFieldSetter(field)
@ -1262,7 +1261,10 @@ class Class extends NamedNode implements Annotatable, FileUriNode {
if (!dirty) return;
for (int i = 0; i < fields.length; ++i) {
Field member = fields[i];
canonicalName.getChildFromField(member).bindTo(member.getterReference);
canonicalName.getChildFromField(member).bindTo(member.fieldReference);
canonicalName
.getChildFromFieldGetter(member)
.bindTo(member.getterReference);
if (member.hasSetter) {
canonicalName
.getChildFromFieldSetter(member)
@ -2049,13 +2051,28 @@ class Field extends Member {
DartType type; // Not null. Defaults to DynamicType.
int flags = 0;
Expression? initializer; // May be null.
/// Reference used for reading from this field.
///
/// This should be used as the target in [StaticGet], [InstanceGet], and
/// [SuperPropertyGet].
final Reference getterReference;
/// Reference used for writing to this field.
///
/// This should be used as the target in [StaticSet], [InstanceSet], and
/// [SuperPropertySet].
final Reference? setterReference;
@override
@Deprecated("Use the specific getterReference/setterReference instead")
Reference get reference => super.reference;
Reference get getterReference => super.reference;
/// Reference used for initializing this field.
///
/// This should be used as the target in [FieldInitializer] and as the key
/// in the field values of [InstanceConstant].
Reference get fieldReference => super.reference;
Field.mutable(Name name,
{this.type: const DynamicType(),
@ -2066,10 +2083,13 @@ class Field extends Member {
bool isLate: false,
int transformerFlags: 0,
required Uri fileUri,
Reference? fieldReference,
Reference? getterReference,
Reference? setterReference})
: this.setterReference = setterReference ?? new Reference(),
super(name, fileUri, getterReference) {
: this.getterReference = getterReference ?? new Reference(),
this.setterReference = setterReference ?? new Reference(),
super(name, fileUri, fieldReference) {
this.getterReference.node = this;
this.setterReference!.node = this;
// ignore: unnecessary_null_comparison
assert(type != null);
@ -2091,9 +2111,12 @@ class Field extends Member {
bool isLate: false,
int transformerFlags: 0,
required Uri fileUri,
Reference? fieldReference,
Reference? getterReference})
: this.setterReference = null,
super(name, fileUri, getterReference) {
: this.getterReference = getterReference ?? new Reference(),
this.setterReference = null,
super(name, fileUri, fieldReference) {
this.getterReference.node = this;
// ignore: unnecessary_null_comparison
assert(type != null);
initializer?.parent = this;
@ -2107,7 +2130,8 @@ class Field extends Member {
@override
void _relinkNode() {
super._relinkNode();
this.fieldReference.node = this;
this.getterReference.node = this;
if (hasSetter) {
this.setterReference!.node = this;
}
@ -2268,7 +2292,7 @@ class Field extends Member {
@override
void toTextInternal(AstPrinter printer) {
printer.writeMemberName(getterReference);
printer.writeMemberName(fieldReference);
}
}
@ -3162,10 +3186,7 @@ class FieldInitializer extends Initializer {
Expression value;
FieldInitializer(Field field, Expression value)
: this.byReference(
// getterReference is used since this refers to the field itself
field.getterReference,
value);
: this.byReference(field.fieldReference, value);
FieldInitializer.byReference(this.fieldReference, this.value) {
value.parent = this;
@ -3174,7 +3195,7 @@ class FieldInitializer extends Initializer {
Field get field => fieldReference.asField;
void set field(Field field) {
fieldReference = field.getterReference;
fieldReference = field.fieldReference;
}
@override

View file

@ -1578,11 +1578,13 @@ class BinaryBuilder {
Field readField() {
int tag = readByte();
assert(tag == Tag.Field);
CanonicalName fieldCanonicalName = readNonNullCanonicalNameReference();
Reference fieldReference = fieldCanonicalName.reference;
CanonicalName getterCanonicalName = readNonNullCanonicalNameReference();
Reference getterReference = getterCanonicalName.reference;
CanonicalName? setterCanonicalName = readNullableCanonicalNameReference();
Reference? setterReference = setterCanonicalName?.reference;
Field? node = getterReference.node as Field?;
Field? node = fieldReference.node as Field?;
if (alwaysCreateNewNamedNodes) {
node = null;
}
@ -1594,12 +1596,15 @@ class BinaryBuilder {
if (node == null) {
if (setterReference != null) {
node = new Field.mutable(name,
fieldReference: fieldReference,
getterReference: getterReference,
setterReference: setterReference,
fileUri: fileUri);
} else {
node = new Field.immutable(name,
getterReference: getterReference, fileUri: fileUri);
fieldReference: fieldReference,
getterReference: getterReference,
fileUri: fileUri);
}
}
List<Expression> annotations = readAnnotationList(node);

View file

@ -1326,6 +1326,24 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitField(Field node) {
CanonicalName? fieldCanonicalName = node.fieldReference.canonicalName;
if (fieldCanonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
}
String? fieldOrphancy = node.fieldReference.getOrphancyDescription(node);
if (fieldOrphancy != null) {
throw new ArgumentError('Trying to serialize orphaned field reference.\n'
'${fieldOrphancy}');
}
fieldOrphancy =
fieldCanonicalName.getOrphancyDescription(node, node.fieldReference);
if (fieldOrphancy != null) {
throw new ArgumentError(
'Trying to serialize orphaned field canonical name.\n'
'(${node.runtimeType}:${node.hashCode})\n'
'${fieldOrphancy}');
}
CanonicalName? getterCanonicalName = node.getterReference.canonicalName;
if (getterCanonicalName == null) {
throw new ArgumentError('Missing canonical name for $node');
@ -1367,6 +1385,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
}
enterScope(memberScope: true);
writeByte(Tag.Field);
writeNonNullCanonicalNameReference(fieldCanonicalName);
writeNonNullCanonicalNameReference(getterCanonicalName);
writeNullAllowedCanonicalNameReference(setterCanonicalName);
writeUriReference(node.fileUri);

View file

@ -176,7 +176,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 = 72;
static const int BinaryFormatVersion = 73;
}
abstract class ConstantTag {

View file

@ -30,7 +30,12 @@ import 'ast.dart';
/// "@constructors"
/// Qualified name
///
/// Field or the implicit getter of a field:
/// Field:
/// Canonical name of enclosing class or library
/// "@fields"
/// Qualified name
///
/// Implicit getter of a field:
/// Canonical name of enclosing class or library
/// "@getters"
/// Qualified name
@ -137,6 +142,10 @@ class CanonicalName {
}
CanonicalName getChildFromField(Field field) {
return getChild(fieldsName).getChildFromQualifiedName(field.name);
}
CanonicalName getChildFromFieldGetter(Field field) {
return getChild(gettersName).getChildFromQualifiedName(field.name);
}
@ -156,6 +165,10 @@ class CanonicalName {
}
CanonicalName getChildFromFieldWithName(Name name) {
return getChild(fieldsName).getChildFromQualifiedName(name);
}
CanonicalName getChildFromFieldGetterWithName(Name name) {
return getChild(gettersName).getChildFromQualifiedName(name);
}
@ -339,6 +352,10 @@ class CanonicalName {
/// within a library or a class.
static const String methodsName = '@methods';
/// Symbolic name used for the [CanonicalName] node that holds all fields
/// within a library or class.
static const String fieldsName = '@fields';
/// Symbolic name used for the [CanonicalName] node that holds all getters and
/// readable fields within a library or class.
static const String gettersName = '@getters';
@ -355,6 +372,7 @@ class CanonicalName {
constructorsName,
factoriesName,
methodsName,
fieldsName,
gettersName,
settersName,
typedefsName,
@ -513,12 +531,15 @@ class Reference {
bool get isConsistent {
NamedNode? node = _node;
if (node != null) {
if (node.reference != this &&
(node is! Field || node.setterReference != this)) {
// The reference of a [NamedNode] must point to this reference, or
// if the node is a [Field] the setter reference must point to this
// reference.
return false;
if (node is Field) {
// The field, getter or setter reference of the [Field] must point to
// this reference.
return node.fieldReference == this ||
node.getterReference == this ||
node.setterReference == this;
} else {
// The reference of the [NamedNode] must point to this reference.
return node.reference == this;
}
}
if (canonicalName != null && canonicalName!._reference != this) {
@ -529,12 +550,16 @@ class Reference {
String getInconsistency() {
StringBuffer sb = new StringBuffer();
sb.write('Reference ${this} (${hashCode}):');
sb.write('Reference ${toStringInternal()} (${hashCode}):');
NamedNode? node = _node;
if (node != null) {
if (node is Field) {
if (node.getterReference != this && node.setterReference != this) {
if (node.fieldReference != this &&
node.getterReference != this &&
node.setterReference != this) {
sb.write(' _node=${node} (${node.runtimeType}:${node.hashCode})');
sb.write(' _node.fieldReference='
'${node.fieldReference} (${node.fieldReference.hashCode})');
sb.write(' _node.getterReference='
'${node.getterReference} (${node.getterReference.hashCode})');
sb.write(' _node.setterReference='

View file

@ -903,8 +903,8 @@ class CloneVisitorWithMembers extends CloneVisitorNotMembers {
return result;
}
Field cloneField(
Field node, Reference? getterReference, Reference? setterReference) {
Field cloneField(Field node, Reference? fieldReference,
Reference? getterReference, Reference? setterReference) {
final Uri? activeFileUriSaved = _activeFileUri;
_activeFileUri = node.fileUri;
@ -915,6 +915,7 @@ class CloneVisitorWithMembers extends CloneVisitorNotMembers {
initializer: cloneOptional(node.initializer),
transformerFlags: node.transformerFlags,
fileUri: node.fileUri,
fieldReference: fieldReference,
getterReference: getterReference,
setterReference: setterReference);
} else {
@ -927,6 +928,7 @@ class CloneVisitorWithMembers extends CloneVisitorNotMembers {
initializer: cloneOptional(node.initializer),
transformerFlags: node.transformerFlags,
fileUri: node.fileUri,
fieldReference: fieldReference,
getterReference: getterReference);
}
result

View file

@ -44,11 +44,11 @@ String? _getExternalNameValue(CoreTypes coreTypes, Expression annotation) {
return (constant.fieldValues.values.single as StringConstant).value;
} else if (_isPragma(constant.classNode)) {
final String pragmaName =
(constant.fieldValues[coreTypes.pragmaName.getterReference]
(constant.fieldValues[coreTypes.pragmaName.fieldReference]
as StringConstant)
.value;
final Constant? pragmaOptionsValue =
constant.fieldValues[coreTypes.pragmaOptions.getterReference];
constant.fieldValues[coreTypes.pragmaOptions.fieldReference];
final String? pragmaOptions = pragmaOptionsValue is StringConstant
? pragmaOptionsValue.value
: null;

View file

@ -31,9 +31,11 @@ class ReferenceFromIndex {
}
abstract class IndexedContainer {
final Map<Name, Reference> _fieldReferences = new Map<Name, Reference>();
final Map<Name, Reference> _getterReferences = new Map<Name, Reference>();
final Map<Name, Reference> _setterReferences = new Map<Name, Reference>();
Reference? lookupFieldReference(Name name) => _fieldReferences[name];
Reference? lookupGetterReference(Name name) => _getterReferences[name];
Reference? lookupSetterReference(Name name) => _setterReferences[name];
@ -63,6 +65,8 @@ abstract class IndexedContainer {
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Name name = field.name;
assert(_fieldReferences[name] == null);
_fieldReferences[name] = field.fieldReference;
assert(_getterReferences[name] == null);
_getterReferences[name] = field.getterReference;
if (field.hasSetter) {

View file

@ -1642,6 +1642,9 @@ class EquivalenceStrategy {
if (!checkField_initializer(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkField_getterReference(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkField_setterReference(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
@ -1660,7 +1663,7 @@ class EquivalenceStrategy {
if (!checkField_transformerFlags(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkField_getterReference(visitor, node, other)) {
if (!checkField_fieldReference(visitor, node, other)) {
result = visitor.resultOnInequivalence;
}
if (!checkField_fileOffset(visitor, node, other)) {
@ -4915,6 +4918,12 @@ class EquivalenceStrategy {
node.initializer, other.initializer, 'initializer');
}
bool checkField_getterReference(
EquivalenceVisitor visitor, Field node, Field other) {
return visitor.checkReferences(
node.getterReference, other.getterReference, 'getterReference');
}
bool checkField_setterReference(
EquivalenceVisitor visitor, Field node, Field other) {
return visitor.checkReferences(
@ -4971,10 +4980,10 @@ class EquivalenceStrategy {
return checkMember_transformerFlags(visitor, node, other);
}
bool checkField_getterReference(
bool checkField_fieldReference(
EquivalenceVisitor visitor, Field node, Field other) {
return visitor.checkReferences(
node.getterReference, other.getterReference, 'getterReference');
node.fieldReference, other.fieldReference, 'fieldReference');
}
bool checkMember_fileOffset(

View file

@ -120,6 +120,8 @@ class MixinFullResolution {
}
for (var field in class_.mixin.fields) {
Reference? fieldReference =
indexedClass?.lookupFieldReference(field.name);
Reference? getterReference =
indexedClass?.lookupGetterReference(field.name);
Reference? setterReference =
@ -132,8 +134,8 @@ class MixinFullResolution {
setterReference = setters[field.name]?.reference;
setterReference?.canonicalName?.unbind();
}
Field clone =
cloner.cloneField(field, getterReference, setterReference);
Field clone = cloner.cloneField(
field, fieldReference, getterReference, setterReference);
Procedure? setter = setters[field.name];
if (setter != null) {
setters.remove(field.name);

View file

@ -352,9 +352,12 @@ class WidgetCreatorTracker {
type:
new InterfaceType(_locationClass, clazz.enclosingLibrary.nullable),
isFinal: true,
getterReference: clazz.reference.canonicalName
fieldReference: clazz.reference.canonicalName
?.getChildFromFieldWithName(fieldName)
.reference,
getterReference: clazz.reference.canonicalName
?.getChildFromFieldGetterWithName(fieldName)
.reference,
fileUri: clazz.fileUri);
clazz.addField(locationField);

View file

@ -96,7 +96,7 @@ void testMemberCloning() {
void testFields(Iterable<Field> fields) {
testMembers<Field>(
fields,
(cloner, field) => cloner.cloneField(field, null, null),
(cloner, field) => cloner.cloneField(field, null, null, null),
(field) => "${field.runtimeType}(${field.name}):"
"${field.initializer}");
}
@ -197,6 +197,8 @@ class MemberEquivalenceStrategy extends EquivalenceStrategy {
@override
bool checkField(EquivalenceVisitor visitor, Field? node, Object? other) {
if (node is Field && other is Field) {
assumeClonedReferences(
visitor, node, node.fieldReference, other, other.fieldReference);
assumeClonedReferences(
visitor, node, node.getterReference, other, other.getterReference);
assumeClonedReferences(

View file

@ -696,9 +696,9 @@ class _FfiDefinitionTransformer extends FfiTransformer {
final constant = annotation.constant;
if (constant is InstanceConstant &&
constant.classNode == pragmaClass &&
constant.fieldValues[pragmaName.getterReference] ==
constant.fieldValues[pragmaName.fieldReference] ==
StringConstant(vmFfiStructFields)) {
return constant.fieldValues[pragmaOptions.getterReference]
return constant.fieldValues[pragmaOptions.fieldReference]
as InstanceConstant?;
}
}
@ -708,7 +708,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
Set<Class> _compoundAnnotatedDependencies(InstanceConstant layoutConstant) {
final fieldTypes = layoutConstant
.fieldValues[ffiStructLayoutTypesField.getterReference] as ListConstant;
.fieldValues[ffiStructLayoutTypesField.fieldReference] as ListConstant;
final result = <Class>{};
for (final fieldType in fieldTypes.entries) {
if (fieldType is TypeLiteralConstant) {
@ -726,7 +726,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
CompoundNativeTypeCfe _compoundAnnotatedNativeTypeCfe(Class compoundClass) {
final layoutConstant = _compoundAnnotatedFields(compoundClass)!;
final fieldTypes = layoutConstant
.fieldValues[ffiStructLayoutTypesField.getterReference] as ListConstant;
.fieldValues[ffiStructLayoutTypesField.fieldReference] as ListConstant;
final members = <NativeTypeCfe>[];
for (final fieldType in fieldTypes.entries) {
if (fieldType is TypeLiteralConstant) {
@ -734,14 +734,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
members
.add(NativeTypeCfe(this, dartType, compoundCache: compoundCache));
} else if (fieldType is InstanceConstant) {
final singleElementConstant = fieldType
.fieldValues[ffiInlineArrayElementTypeField.getterReference]
as TypeLiteralConstant;
final singleElementConstant =
fieldType.fieldValues[ffiInlineArrayElementTypeField.fieldReference]
as TypeLiteralConstant;
final singleElementType = NativeTypeCfe(
this, singleElementConstant.type,
compoundCache: compoundCache);
final arrayLengthConstant =
fieldType.fieldValues[ffiInlineArrayLengthField.getterReference]
fieldType.fieldValues[ffiInlineArrayLengthField.fieldReference]
as IntConstant;
final arrayLength = arrayLengthConstant.value;
members.add(ArrayNativeTypeCfe(singleElementType, arrayLength));
@ -749,7 +749,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
}
if (compoundClass.superclass == structClass) {
final packingConstant = layoutConstant
.fieldValues[ffiStructLayoutPackingField.getterReference];
.fieldValues[ffiStructLayoutPackingField.fieldReference];
if (packingConstant is IntConstant) {
return StructNativeTypeCfe(compoundClass, members,
packing: packingConstant.value);
@ -767,12 +767,12 @@ class _FfiDefinitionTransformer extends FfiTransformer {
node.addAnnotation(ConstantExpression(
InstanceConstant(pragmaClass.reference, [], {
pragmaName.getterReference: StringConstant(vmFfiStructFields),
pragmaOptions.getterReference:
pragmaName.fieldReference: StringConstant(vmFfiStructFields),
pragmaOptions.fieldReference:
InstanceConstant(ffiStructLayoutClass.reference, [], {
ffiStructLayoutTypesField.getterReference: ListConstant(
ffiStructLayoutTypesField.fieldReference: ListConstant(
InterfaceType(typeClass, Nullability.nonNullable), constants),
ffiStructLayoutPackingField.getterReference:
ffiStructLayoutPackingField.fieldReference:
packing == null ? NullConstant() : IntConstant(packing)
})
}),
@ -850,8 +850,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
..isNonNullableByDefault = true
..addAnnotation(ConstantExpression(
InstanceConstant(pragmaClass.reference, /*type_arguments=*/ [], {
pragmaName.getterReference: StringConstant("vm:prefer-inline"),
pragmaOptions.getterReference: NullConstant(),
pragmaName.fieldReference: StringConstant("vm:prefer-inline"),
pragmaOptions.fieldReference: NullConstant(),
})));
compound.addProcedure(getter);
@ -887,7 +887,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
List<int> _arraySize(InstanceConstant constant) {
final dimensions =
constant.fieldValues[arraySizeDimensionsField.getterReference];
constant.fieldValues[arraySizeDimensionsField.fieldReference];
if (dimensions != null) {
if (dimensions is ListConstant) {
final result = dimensions.entries
@ -905,7 +905,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
arraySizeDimension5Field
];
final result = dimensionFields
.map((f) => constant.fieldValues[f.getterReference])
.map((f) => constant.fieldValues[f.fieldReference])
.whereType<IntConstant>()
.map((c) => c.value)
.toList();
@ -1414,9 +1414,9 @@ class ArrayNativeTypeCfe implements NativeTypeCfe {
@override
Constant generateConstant(FfiTransformer transformer) =>
InstanceConstant(transformer.ffiInlineArrayClass.reference, [], {
transformer.ffiInlineArrayElementTypeField.getterReference:
transformer.ffiInlineArrayElementTypeField.fieldReference:
singleElementType.generateConstant(transformer),
transformer.ffiInlineArrayLengthField.getterReference:
transformer.ffiInlineArrayLengthField.fieldReference:
IntConstant(dimensionsFlattened)
});

View file

@ -94,9 +94,9 @@ class FfiNativeTransformer extends Transformer {
assert(currentLibrary != null);
final params = node.function.positionalParameters;
final functionName = annotationConst
.fieldValues[ffiNativeNameField.getterReference] as StringConstant;
.fieldValues[ffiNativeNameField.fieldReference] as StringConstant;
final isLeaf = annotationConst
.fieldValues[ffiNativeIsLeafField.getterReference] as BoolConstant;
.fieldValues[ffiNativeIsLeafField.fieldReference] as BoolConstant;
// double Function(double)
final DartType dartType =

View file

@ -78,7 +78,7 @@ class ConstantPragmaAnnotationParser extends PragmaAnnotationParser {
String pragmaName;
Constant? name =
pragmaConstant.fieldValues[coreTypes.pragmaName.getterReference];
pragmaConstant.fieldValues[coreTypes.pragmaName.fieldReference];
if (name is StringConstant) {
pragmaName = name.value;
} else {
@ -86,7 +86,7 @@ class ConstantPragmaAnnotationParser extends PragmaAnnotationParser {
}
Constant options =
pragmaConstant.fieldValues[coreTypes.pragmaOptions.getterReference]!;
pragmaConstant.fieldValues[coreTypes.pragmaOptions.fieldReference]!;
switch (pragmaName) {
case kEntryPointPragmaName:

View file

@ -116,7 +116,7 @@ class ProtobufHandler {
if (constant is InstanceConstant &&
constant.classReference == _tagNumberClass.reference) {
if (messageClass._usedTags.add((constant
.fieldValues[_tagNumberField.getterReference] as IntConstant)
.fieldValues[_tagNumberField.fieldReference] as IntConstant)
.value)) {
_invalidatedClasses.add(messageClass);
}

View file

@ -1756,6 +1756,11 @@ class _TreeShakerPass2 extends RemovingTransformer {
// Ensure that kernel file writer will not be able to
// write a dangling reference to the deleted member.
if (node is Field) {
assert(
node.fieldReference.node == node,
"Trying to remove canonical name from field reference on $node "
"which has been repurposed for ${node.fieldReference.node}.");
node.fieldReference.canonicalName?.unbind();
assert(
node.getterReference.node == node,
"Trying to remove canonical name from getter reference on $node "

View file

@ -1045,9 +1045,9 @@ main() {
}
});
/// This test basicaly verifies that components `relink` method is correctly
/// called when rejecting (i.e. logically going back in time to before a
/// rejected compilation).
/// This test basically verifies that components `relink` method is
/// correctly called when rejecting (i.e. logically going back in time to
/// before a rejected compilation).
test('check links after reject', () async {
final Uri fooUri = Uri.file('${mytest.path}/foo.dart');
new File.fromUri(fooUri).writeAsStringSync("""

View file

@ -403,8 +403,7 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_index) {
Field& field = Field::Handle(Z);
Instance& constant = Instance::Handle(Z);
for (intptr_t j = 0; j < number_of_fields; ++j) {
field = H.LookupFieldByKernelGetterOrSetter(
reader.ReadCanonicalNameReference());
field = H.LookupFieldByKernelField(reader.ReadCanonicalNameReference());
// Recurse into lazily evaluating all "sub" constants
// needed to evaluate the current constant.
const intptr_t entry_index = reader.ReadUInt();

View file

@ -238,7 +238,7 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers(
ReadBool();
const NameIndex field_name = ReadCanonicalNameReference();
const Field& field =
Field::Handle(Z, H.LookupFieldByKernelGetterOrSetter(field_name));
Field::Handle(Z, H.LookupFieldByKernelField(field_name));
initializer_fields[i] = &field;
SkipExpression();
continue;

View file

@ -316,8 +316,22 @@ bool TranslationHelper::IsFactory(NameIndex name) {
return StringEquals(CanonicalNameString(kind), "@factories");
}
bool TranslationHelper::IsField(NameIndex name) {
// Fields with private names have the import URI of the library where they
// are visible as the parent and the string "@fields" as the parent's parent.
// Fields with non-private names have the string "@fields" as the parent.
if (IsRoot(name)) {
return false;
}
NameIndex kind = CanonicalNameParent(name);
if (IsPrivate(name)) {
kind = CanonicalNameParent(kind);
}
return StringEquals(CanonicalNameString(kind), "@fields");
}
NameIndex TranslationHelper::EnclosingName(NameIndex name) {
ASSERT(IsConstructor(name) || IsProcedure(name));
ASSERT(IsConstructor(name) || IsProcedure(name) || IsField(name));
NameIndex enclosing = CanonicalNameParent(CanonicalNameParent(name));
if (IsPrivate(name)) {
enclosing = CanonicalNameParent(enclosing);
@ -574,6 +588,27 @@ ClassPtr TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) {
return info_.InsertClass(thread_, name_index_handle_, klass);
}
FieldPtr TranslationHelper::LookupFieldByKernelField(NameIndex kernel_field) {
ASSERT(IsField(kernel_field));
NameIndex enclosing = EnclosingName(kernel_field);
Class& klass = Class::Handle(Z);
if (IsLibrary(enclosing)) {
Library& library =
Library::Handle(Z, LookupLibraryByKernelLibrary(enclosing));
klass = library.toplevel_class();
CheckStaticLookup(klass);
} else {
ASSERT(IsClass(enclosing));
klass = LookupClassByKernelClass(enclosing);
}
Field& field = Field::Handle(
Z, klass.LookupFieldAllowPrivate(
DartSymbolObfuscate(CanonicalNameString(kernel_field))));
CheckStaticLookup(field);
return field.ptr();
}
FieldPtr TranslationHelper::LookupFieldByKernelGetterOrSetter(
NameIndex kernel_field,
bool required) {
@ -1006,6 +1041,11 @@ void FieldHelper::ReadUntilExcluding(Field field) {
if (++next_read_ == field) return;
}
FALL_THROUGH;
case kCanonicalNameField:
canonical_name_field_ =
helper_->ReadCanonicalNameReference(); // read canonical_name_field.
if (++next_read_ == field) return;
FALL_THROUGH;
case kCanonicalNameGetter:
canonical_name_getter_ =
helper_->ReadCanonicalNameReference(); // read canonical_name_getter.

View file

@ -109,6 +109,7 @@ class TranslationHelper {
bool IsGetter(NameIndex name);
bool IsSetter(NameIndex name);
bool IsFactory(NameIndex name);
bool IsField(NameIndex name);
// For a member (field, constructor, or procedure) return the canonical name
// of the enclosing class or library.
@ -165,6 +166,7 @@ class TranslationHelper {
virtual LibraryPtr LookupLibraryByKernelLibrary(NameIndex library);
virtual ClassPtr LookupClassByKernelClass(NameIndex klass);
FieldPtr LookupFieldByKernelField(NameIndex field);
FieldPtr LookupFieldByKernelGetterOrSetter(NameIndex field,
bool required = true);
FunctionPtr LookupStaticMethodByKernelProcedure(NameIndex procedure,
@ -444,6 +446,7 @@ class FieldHelper {
public:
enum Field {
kStart, // tag.
kCanonicalNameField,
kCanonicalNameGetter,
kCanonicalNameSetter,
kSourceUriIndex,
@ -491,6 +494,7 @@ class FieldHelper {
bool IsLate() const { return (flags_ & kIsLate) != 0; }
bool IsExtensionMember() const { return (flags_ & kExtensionMember) != 0; }
NameIndex canonical_name_field_;
NameIndex canonical_name_getter_;
NameIndex canonical_name_setter_;
TokenPosition position_ = TokenPosition::kNoSource;

View file

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

View file

@ -33,8 +33,8 @@ main() {
Expect.isTrue(File(powTest).existsSync(),
"Can't locate dart$_execSuffix on this platform");
final d = Directory.systemTemp.createTempSync('aot_tmp');
final kernelOutput = d.uri.resolve('pow_test.dill').path;
final aotOutput = d.uri.resolve('pow_test.aot').path;
final kernelOutput = File.fromUri(d.uri.resolve('pow_test.dill')).path;
final aotOutput = File.fromUri(d.uri.resolve('pow_test.aot')).path;
final genKernelResult = runAndPrintOutput(
genKernel,

View file

@ -33,8 +33,8 @@ main() {
Expect.isTrue(File(powTest).existsSync(),
"Can't locate dart$_execSuffix on this platform");
final d = Directory.systemTemp.createTempSync('aot_tmp');
final kernelOutput = d.uri.resolve('pow_test.dill').path;
final aotOutput = d.uri.resolve('pow_test.aot').path;
final kernelOutput = File.fromUri(d.uri.resolve('pow_test.dill')).path;
final aotOutput = File.fromUri(d.uri.resolve('pow_test.aot')).path;
final genKernelResult = runAndPrintOutput(
genKernel,