Use the explicit string 'dynamic' to refer to dynamic in summaries.
Previously we used reference 0 as a special case to mean "dynamic". This saved a tiny amount of space in the summary file, but it's not worth it because it will complicate some error handling scenarios (which will be addressed in future CLs). This CL changes "dynamic" so that it's serialized as though it were defined in the defining compilation unit of each library. R=scheglov@google.com Review URL: https://codereview.chromium.org/1621763002 .
This commit is contained in:
@@ -447,12 +447,6 @@ class EntityRefBuilder extends Object with _EntityRefMixin implements EntityRef
|
||||
/**
|
||||
* Index into [UnlinkedUnit.references] for the entity being referred to, or
|
||||
* zero if this is a reference to a type parameter.
|
||||
*
|
||||
* Note that since zero is also a valid index into
|
||||
* [UnlinkedUnit.references], we cannot distinguish between references to
|
||||
* type parameters and references to other entities by checking [reference]
|
||||
* against zero. To distinguish between references to type parameters and
|
||||
* references to other entities, check whether [paramReference] is zero.
|
||||
*/
|
||||
void set reference(int _value) {
|
||||
assert(!_finished);
|
||||
@@ -549,12 +543,6 @@ abstract class EntityRef extends base.SummaryClass {
|
||||
/**
|
||||
* Index into [UnlinkedUnit.references] for the entity being referred to, or
|
||||
* zero if this is a reference to a type parameter.
|
||||
*
|
||||
* Note that since zero is also a valid index into
|
||||
* [UnlinkedUnit.references], we cannot distinguish between references to
|
||||
* type parameters and references to other entities by checking [reference]
|
||||
* against zero. To distinguish between references to type parameters and
|
||||
* references to other entities, check whether [paramReference] is zero.
|
||||
*/
|
||||
int get reference;
|
||||
|
||||
@@ -1252,8 +1240,8 @@ class LinkedReferenceBuilder extends Object with _LinkedReferenceMixin implement
|
||||
|
||||
/**
|
||||
* If this [LinkedReference] doesn't have an associated [UnlinkedReference],
|
||||
* name of the entity being referred to. The empty string refers to the
|
||||
* pseudo-type `dynamic`.
|
||||
* name of the entity being referred to. For the pseudo-type `dynamic`, the
|
||||
* string is "dynamic".
|
||||
*/
|
||||
void set name(String _value) {
|
||||
assert(!_finished);
|
||||
@@ -1327,8 +1315,8 @@ abstract class LinkedReference extends base.SummaryClass {
|
||||
|
||||
/**
|
||||
* If this [LinkedReference] doesn't have an associated [UnlinkedReference],
|
||||
* name of the entity being referred to. The empty string refers to the
|
||||
* pseudo-type `dynamic`.
|
||||
* name of the entity being referred to. For the pseudo-type `dynamic`, the
|
||||
* string is "dynamic".
|
||||
*/
|
||||
String get name;
|
||||
}
|
||||
@@ -4661,8 +4649,8 @@ class UnlinkedReferenceBuilder extends Object with _UnlinkedReferenceMixin imple
|
||||
String get name => _name ??= '';
|
||||
|
||||
/**
|
||||
* Name of the entity being referred to. The empty string refers to the
|
||||
* pseudo-type `dynamic`.
|
||||
* Name of the entity being referred to. For the pseudo-type `dynamic`, the
|
||||
* string is "dynamic".
|
||||
*/
|
||||
void set name(String _value) {
|
||||
assert(!_finished);
|
||||
@@ -4715,8 +4703,8 @@ class UnlinkedReferenceBuilder extends Object with _UnlinkedReferenceMixin imple
|
||||
abstract class UnlinkedReference extends base.SummaryClass {
|
||||
|
||||
/**
|
||||
* Name of the entity being referred to. The empty string refers to the
|
||||
* pseudo-type `dynamic`.
|
||||
* Name of the entity being referred to. For the pseudo-type `dynamic`, the
|
||||
* string is "dynamic".
|
||||
*/
|
||||
String get name;
|
||||
|
||||
@@ -5225,8 +5213,10 @@ class UnlinkedUnitBuilder extends Object with _UnlinkedUnitMixin implements Unli
|
||||
|
||||
/**
|
||||
* Top level and prefixed names referred to by this compilation unit. The
|
||||
* zeroth element of this array is always populated and always represents a
|
||||
* reference to the pseudo-type "dynamic".
|
||||
* zeroth element of this array is always populated and is used to represent
|
||||
* the absence of a reference in places where a reference is optional (for
|
||||
* example [UnlinkedReference.prefixReference or
|
||||
* UnlinkedImport.prefixReference]).
|
||||
*/
|
||||
void set references(List<UnlinkedReferenceBuilder> _value) {
|
||||
assert(!_finished);
|
||||
@@ -5480,8 +5470,10 @@ abstract class UnlinkedUnit extends base.SummaryClass {
|
||||
|
||||
/**
|
||||
* Top level and prefixed names referred to by this compilation unit. The
|
||||
* zeroth element of this array is always populated and always represents a
|
||||
* reference to the pseudo-type "dynamic".
|
||||
* zeroth element of this array is always populated and is used to represent
|
||||
* the absence of a reference in places where a reference is optional (for
|
||||
* example [UnlinkedReference.prefixReference or
|
||||
* UnlinkedImport.prefixReference]).
|
||||
*/
|
||||
List<UnlinkedReference> get references;
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ class _Prelinker {
|
||||
* Names defined inside the library being prelinked.
|
||||
*/
|
||||
final Map<String, _Meaning> privateNamespace = <String, _Meaning>{
|
||||
'': new _Meaning(0, ReferenceKind.classOrEnum, 0, 0)
|
||||
'dynamic': new _Meaning(0, ReferenceKind.classOrEnum, 0, 0)
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -987,7 +987,7 @@ class _LibraryResynthesizer {
|
||||
name);
|
||||
} else if (referenceResolution.kind == ReferenceKind.unresolved) {
|
||||
return summaryResynthesizer.typeProvider.undefinedType;
|
||||
} else if (name.isEmpty) {
|
||||
} else if (name == 'dynamic') {
|
||||
return summaryResynthesizer.typeProvider.dynamicType;
|
||||
} else {
|
||||
String referencedLibraryUri = librarySource.uri.toString();
|
||||
|
||||
@@ -508,7 +508,6 @@ class _SummarizeAstVisitor extends SimpleAstVisitor {
|
||||
int serializeReference(int prefixIndex, String name) => nameToReference
|
||||
.putIfAbsent(prefixIndex, () => <String, int>{})
|
||||
.putIfAbsent(name, () {
|
||||
assert(name != 'dynamic');
|
||||
int index = unlinkedReferences.length;
|
||||
unlinkedReferences.add(new UnlinkedReferenceBuilder(
|
||||
prefixReference: prefixIndex, name: name));
|
||||
@@ -523,7 +522,9 @@ class _SummarizeAstVisitor extends SimpleAstVisitor {
|
||||
*/
|
||||
EntityRefBuilder serializeTypeName(TypeName node, {bool allowVoid: false}) {
|
||||
EntityRefBuilder b = new EntityRefBuilder();
|
||||
if (node != null) {
|
||||
if (node == null) {
|
||||
b.reference = serializeReference(null, 'dynamic');
|
||||
} else {
|
||||
Identifier identifier = node.name;
|
||||
if (identifier is SimpleIdentifier) {
|
||||
String name = identifier.name;
|
||||
@@ -539,6 +540,7 @@ class _SummarizeAstVisitor extends SimpleAstVisitor {
|
||||
// None of the other things that can be declared in local scopes
|
||||
// are types, so this is an error and should be treated as a
|
||||
// reference to `dynamic`.
|
||||
b.reference = serializeReference(null, 'dynamic');
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -549,9 +551,7 @@ class _SummarizeAstVisitor extends SimpleAstVisitor {
|
||||
if (allowVoid && name == 'void') {
|
||||
return null;
|
||||
}
|
||||
if (name != 'dynamic') {
|
||||
b.reference = serializeReference(null, name);
|
||||
}
|
||||
b.reference = serializeReference(null, name);
|
||||
} else if (identifier is PrefixedIdentifier) {
|
||||
int prefixIndex = prefixIndices.putIfAbsent(identifier.prefix.name,
|
||||
() => serializeReference(null, identifier.prefix.name));
|
||||
|
||||
@@ -33,7 +33,7 @@ ReferenceKind _getReferenceKind(Element element) {
|
||||
kind = ReferenceKind.topLevelPropertyAccessor;
|
||||
} else if (element is FunctionTypeAliasElement) {
|
||||
kind = ReferenceKind.typedef;
|
||||
} else if (element is ClassElement) {
|
||||
} else if (element is ClassElement || element is DynamicElementImpl) {
|
||||
kind = ReferenceKind.classOrEnum;
|
||||
} else if (element is FunctionElement) {
|
||||
kind = ReferenceKind.topLevelFunction;
|
||||
@@ -409,13 +409,6 @@ class _CompilationUnitSerializer {
|
||||
length: element.docRange.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index of the entry in the references table
|
||||
* ([UnlinkedLibrary.references] and [LinkedLibrary.references])
|
||||
* representing the pseudo-type `dynamic`.
|
||||
*/
|
||||
int serializeDynamicReference() => 0;
|
||||
|
||||
/**
|
||||
* Serialize the given [enumElement], creating an [UnlinkedEnum].
|
||||
*/
|
||||
@@ -600,12 +593,11 @@ class _CompilationUnitSerializer {
|
||||
assert(type.isDynamic);
|
||||
if (type is UndefinedTypeImpl) {
|
||||
return serializeUnresolvedReference();
|
||||
} else {
|
||||
return serializeDynamicReference();
|
||||
}
|
||||
} else {
|
||||
return _getElementReferenceId(element, linked: linked);
|
||||
// Note: for a type which is truly `dynamic`, fall through to use
|
||||
// [_getElementReferenceId].
|
||||
}
|
||||
return _getElementReferenceId(element, linked: linked);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -757,12 +749,19 @@ class _CompilationUnitSerializer {
|
||||
}
|
||||
|
||||
int _getElementReferenceId(Element element, {bool linked: false}) {
|
||||
LibraryElement dependentLibrary = element.library;
|
||||
return referenceMap.putIfAbsent(element, () {
|
||||
CompilationUnitElement unitElement =
|
||||
element.getAncestor((Element e) => e is CompilationUnitElement);
|
||||
int unit = dependentLibrary.units.indexOf(unitElement);
|
||||
assert(unit != -1);
|
||||
LibraryElement dependentLibrary = element.library;
|
||||
int unit;
|
||||
if (element.library == null) {
|
||||
assert(element == librarySerializer.typeProvider.dynamicType.element);
|
||||
unit = 0;
|
||||
dependentLibrary = librarySerializer.libraryElement;
|
||||
} else {
|
||||
CompilationUnitElement unitElement =
|
||||
element.getAncestor((Element e) => e is CompilationUnitElement);
|
||||
unit = dependentLibrary.units.indexOf(unitElement);
|
||||
assert(unit != -1);
|
||||
}
|
||||
int numTypeParameters = 0;
|
||||
if (element is TypeParameterizedElement) {
|
||||
numTypeParameters = element.typeParameters.length;
|
||||
|
||||
@@ -236,7 +236,7 @@ abstract class SummaryTest {
|
||||
* Verify that the given [typeRef] represents the type `dynamic`.
|
||||
*/
|
||||
void checkDynamicTypeRef(EntityRef typeRef) {
|
||||
checkTypeRef(typeRef, null, null, null);
|
||||
checkTypeRef(typeRef, null, null, 'dynamic');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -506,10 +506,8 @@ abstract class SummaryTest {
|
||||
// [LinkedUnit.references].
|
||||
name = referenceResolution.name;
|
||||
}
|
||||
if (referenceIndex == 0) {
|
||||
// Index 0 is reserved for "dynamic".
|
||||
expect(name, isEmpty);
|
||||
}
|
||||
// Index 0 is reserved.
|
||||
expect(referenceIndex, isNot(0));
|
||||
if (absoluteUri == null) {
|
||||
expect(referenceResolution.dependency, 0);
|
||||
} else {
|
||||
@@ -1594,8 +1592,7 @@ const v = const C(11, 22, 3.3, '444', e: 55, g: '777', f: 66);
|
||||
33,
|
||||
3
|
||||
], referenceValidators: [
|
||||
(EntityRef r) => checkTypeRef(r, null, null, '',
|
||||
expectedKind: ReferenceKind.classOrEnum)
|
||||
(EntityRef r) => checkDynamicTypeRef(r)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1648,10 +1645,8 @@ const v = const C(11, 22, 3.3, '444', e: 55, g: '777', f: 66);
|
||||
'bbb',
|
||||
'ccc'
|
||||
], referenceValidators: [
|
||||
(EntityRef r) => checkTypeRef(r, null, null, '',
|
||||
expectedKind: ReferenceKind.classOrEnum),
|
||||
(EntityRef r) => checkTypeRef(r, null, null, '',
|
||||
expectedKind: ReferenceKind.classOrEnum)
|
||||
(EntityRef r) => checkDynamicTypeRef(r),
|
||||
(EntityRef r) => checkDynamicTypeRef(r)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,12 +83,6 @@ class EntityRef {
|
||||
/**
|
||||
* Index into [UnlinkedUnit.references] for the entity being referred to, or
|
||||
* zero if this is a reference to a type parameter.
|
||||
*
|
||||
* Note that since zero is also a valid index into
|
||||
* [UnlinkedUnit.references], we cannot distinguish between references to
|
||||
* type parameters and references to other entities by checking [reference]
|
||||
* against zero. To distinguish between references to type parameters and
|
||||
* references to other entities, check whether [paramReference] is zero.
|
||||
*/
|
||||
int reference;
|
||||
|
||||
@@ -258,8 +252,8 @@ class LinkedReference {
|
||||
|
||||
/**
|
||||
* If this [LinkedReference] doesn't have an associated [UnlinkedReference],
|
||||
* name of the entity being referred to. The empty string refers to the
|
||||
* pseudo-type `dynamic`.
|
||||
* name of the entity being referred to. For the pseudo-type `dynamic`, the
|
||||
* string is "dynamic".
|
||||
*/
|
||||
String name;
|
||||
}
|
||||
@@ -1201,8 +1195,8 @@ class UnlinkedPublicNamespace {
|
||||
*/
|
||||
class UnlinkedReference {
|
||||
/**
|
||||
* Name of the entity being referred to. The empty string refers to the
|
||||
* pseudo-type `dynamic`.
|
||||
* Name of the entity being referred to. For the pseudo-type `dynamic`, the
|
||||
* string is "dynamic".
|
||||
*/
|
||||
String name;
|
||||
|
||||
@@ -1315,8 +1309,10 @@ class UnlinkedUnit {
|
||||
|
||||
/**
|
||||
* Top level and prefixed names referred to by this compilation unit. The
|
||||
* zeroth element of this array is always populated and always represents a
|
||||
* reference to the pseudo-type "dynamic".
|
||||
* zeroth element of this array is always populated and is used to represent
|
||||
* the absence of a reference in places where a reference is optional (for
|
||||
* example [UnlinkedReference.prefixReference or
|
||||
* UnlinkedImport.prefixReference]).
|
||||
*/
|
||||
List<UnlinkedReference> references;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user