mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[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:
parent
4389cf7bba
commit
5b7968346d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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("}");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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}}"
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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='
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
});
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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("""
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue