Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(758)

Unified Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 1832393002: Add more features to the summary linker. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_common.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/summary/link.dart
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index ec6049e86cec9235923363a52c50a5be802d041e..342db57695c77c0be3b1d3110681d57205abfeac 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -123,9 +123,23 @@ typedef UnlinkedUnit GetUnitCallback(String absoluteUri);
*/
abstract class ClassElementForLink
implements ClassElement, ReferenceableElementForLink {
+ Map<String, ReferenceableElementForLink> _containedNames;
+
@override
ConstructorElementForLink get asConstructor => unnamedConstructor;
+ @override
+ ConstVariableNode get asConstVariable {
+ // TODO(paulberry): implement.
+ throw new UnimplementedError();
+ }
+
+ @override
+ List<ConstructorElementForLink> get constructors;
+
+ @override
+ List<FieldElementForLink> get fields;
+
/**
* Indicates whether this is the core class `Object`.
*/
@@ -137,6 +151,27 @@ abstract class ClassElementForLink
@override
ConstructorElementForLink get unnamedConstructor;
+ @override
+ ReferenceableElementForLink getContainedName(name) {
+ if (_containedNames == null) {
+ _containedNames = <String, ReferenceableElementForLink>{};
+ // TODO(paulberry): what's the correct way to handle name conflicts?
+ for (ConstructorElementForLink constructor in constructors) {
+ _containedNames[constructor.name] = constructor;
+ }
+ for (FieldElementForLink field in fields) {
+ // TODO(paulberry): do we need to handle nonstatic fields for
+ // consistent behavior with erroneous code?
+ if (field.isStatic) {
+ _containedNames[field.name] = field;
+ }
+ }
+ // TODO(paulberry): add methods.
+ }
+ return _containedNames.putIfAbsent(
+ name, () => UndefinedElementForLink.instance);
+ }
+
/**
* Perform type inference and cycle detection on this class and
* store the resulting information in the enclosing elements.
@@ -163,7 +198,7 @@ class ClassElementForLink_Class extends ClassElementForLink {
List<ConstructorElementForLink> _constructors;
ConstructorElementForLink _unnamedConstructor;
bool _unnamedConstructorComputed = false;
- List<FieldElementForLink> _fields;
+ List<FieldElementForLink_ClassField> _fields;
InterfaceTypeForLink _supertype;
InterfaceTypeForLink _type;
@@ -185,11 +220,11 @@ class ClassElementForLink_Class extends ClassElementForLink {
}
@override
- List<FieldElementForLink> get fields {
+ List<FieldElementForLink_ClassField> get fields {
if (_fields == null) {
- _fields = <FieldElementForLink>[];
+ _fields = <FieldElementForLink_ClassField>[];
for (UnlinkedVariable field in _unlinkedClass.fields) {
- _fields.add(new FieldElementForLink(this, field));
+ _fields.add(new FieldElementForLink_ClassField(this, field));
}
}
return _fields;
@@ -229,20 +264,13 @@ class ClassElementForLink_Class extends ClassElementForLink {
DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i),
List<int> implicitFunctionTypeIndices) {
if (_unlinkedClass.typeParameters.length != 0) {
- // TODO(paulberry): implement.
- throw new UnimplementedError();
+ return new InterfaceTypeForLink(this);
} else {
return _type ??= new InterfaceTypeForLink(this);
}
}
@override
- ReferenceableElementForLink getContainedName(name) {
- // TODO(paulberry): implement.
- throw new UnimplementedError();
- }
-
- @override
void link(LinkedUnitBuilder linkedUnit) {
for (ConstructorElementForLink constructorElement in constructors) {
constructorElement.link(linkedUnit);
@@ -260,9 +288,27 @@ class ClassElementForLink_Enum extends ClassElementForLink {
*/
final UnlinkedEnum _unlinkedEnum;
+ InterfaceTypeForLink _type;
+ List<FieldElementForLink_EnumField> _fields;
+
ClassElementForLink_Enum(this._unlinkedEnum);
@override
+ List<ConstructorElementForLink> get constructors => const [];
+
+ @override
+ List<FieldElementForLink_EnumField> get fields {
+ if (_fields == null) {
+ _fields = <FieldElementForLink_EnumField>[];
+ _fields.add(new FieldElementForLink_EnumField(null));
+ for (UnlinkedEnumValue value in _unlinkedEnum.values) {
+ _fields.add(new FieldElementForLink_EnumField(value));
+ }
+ }
+ return _fields;
+ }
+
+ @override
bool get isObject => false;
@override
@@ -273,16 +319,8 @@ class ClassElementForLink_Enum extends ClassElementForLink {
@override
DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i),
- List<int> implicitFunctionTypeIndices) {
- // TODO(paulberry): implement.
- throw new UnimplementedError();
- }
-
- @override
- ReferenceableElementForLink getContainedName(name) {
- // TODO(paulberry): implement.
- throw new UnimplementedError();
- }
+ List<int> implicitFunctionTypeIndices) =>
+ _type ??= new InterfaceTypeForLink(this);
@override
void link(LinkedUnitBuilder linkedUnit) {}
@@ -307,6 +345,7 @@ abstract class CompilationUnitElementForLink implements CompilationUnitElement {
List<ClassElementForLink> _types;
Map<String, ReferenceableElementForLink> _containedNames;
+ List<TopLevelVariableElementForLink> _topLevelVariables;
@override
final LibraryElementForLink enclosingElement;
@@ -321,6 +360,18 @@ abstract class CompilationUnitElementForLink implements CompilationUnitElement {
bool get isInBuildUnit;
@override
+ List<TopLevelVariableElementForLink> get topLevelVariables {
+ if (_topLevelVariables == null) {
+ _topLevelVariables = <TopLevelVariableElementForLink>[];
+ for (UnlinkedVariable unlinkedVariable in _unlinkedUnit.variables) {
+ _topLevelVariables
+ .add(new TopLevelVariableElementForLink(this, unlinkedVariable));
+ }
+ }
+ return _topLevelVariables;
+ }
+
+ @override
List<ClassElementForLink> get types {
if (_types == null) {
_types = <ClassElementForLink>[];
@@ -347,11 +398,15 @@ abstract class CompilationUnitElementForLink implements CompilationUnitElement {
ReferenceableElementForLink getContainedName(name) {
if (_containedNames == null) {
_containedNames = <String, ReferenceableElementForLink>{};
+ // TODO(paulberry): what's the correct way to handle name conflicts?
for (ClassElementForLink type in types) {
- // TODO(paulberry): what's the correct way to handle name conflicts?
_containedNames[type.name] = type;
}
- // TODO(paulberry): fill in other top level entities.
+ for (TopLevelVariableElementForLink variable in topLevelVariables) {
+ _containedNames[variable.name] = variable;
+ }
+ // TODO(paulberry): fill in other top level entities (typedefs
+ // and executables).
}
return _containedNames.putIfAbsent(
name, () => UndefinedElementForLink.instance);
@@ -544,7 +599,7 @@ class ConstConstructorNode extends ConstNode {
// Note: non-static const isn't allowed but we handle it anyway so
// that we won't be confused by incorrect code.
if ((field.isFinal || field.isConst) && !field.isStatic) {
- safeAddDependency(field._constNode);
+ safeAddDependency(field.asConstVariable);
}
}
for (ParameterElementForLink parameterElement
@@ -613,8 +668,13 @@ abstract class ConstNode extends Node<ConstNode> {
for (UnlinkedConstOperation operation in unlinkedConst.operations) {
switch (operation) {
case UnlinkedConstOperation.pushReference:
- // TODO(paulberry): implement.
- throw new UnimplementedError();
+ EntityRef ref = unlinkedConst.references[refPtr++];
+ ConstVariableNode variable =
+ compilationUnit._resolveRef(ref.reference).asConstVariable;
+ if (variable != null) {
+ dependencies.add(variable);
+ }
+ break;
case UnlinkedConstOperation.makeTypedList:
refPtr++;
break;
@@ -664,7 +724,8 @@ class ConstParameterNode extends ConstNode {
* Element representing a constructor resynthesized from a summary
* during linking.
*/
-class ConstructorElementForLink implements ConstructorElement {
+class ConstructorElementForLink
+ implements ConstructorElement, ReferenceableElementForLink {
/**
* The unlinked representation of the constructor in the summary.
*/
@@ -690,6 +751,12 @@ class ConstructorElementForLink implements ConstructorElement {
}
@override
+ ConstructorElementForLink get asConstructor => this;
+
+ @override
+ ConstVariableNode get asConstVariable => null;
+
+ @override
bool get isCycleFree {
if (!_constNode.isEvaluated) {
new ConstDependencyWalker().walk(_constNode);
@@ -712,6 +779,15 @@ class ConstructorElementForLink implements ConstructorElement {
return _parameters;
}
+ @override
+ DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeForLink.instance;
+
+ @override
+ ReferenceableElementForLink getContainedName(name) =>
+ UndefinedElementForLink.instance;
+
/**
* Perform const cycle detection on this constructor.
*/
@@ -910,28 +986,68 @@ class DynamicTypeForLink extends DartTypeForLink {
}
/**
- * Element representing a field resynthesized from a summary during linking.
+ * Element representing a field resynthesized from a summary during
+ * linking.
+ */
+abstract class FieldElementForLink
+ implements FieldElement, ReferenceableElementForLink {}
+
+/**
+ * Specialization of [FieldElementForLink] for class fields.
*/
-class FieldElementForLink extends VariableElementForLink
- implements FieldElement {
- /**
- * The unlinked representation of the field in the summary.
- */
+class FieldElementForLink_ClassField extends VariableElementForLink
+ implements FieldElementForLink {
+ @override
final ClassElementForLink_Class enclosingElement;
- FieldElementForLink(ClassElementForLink_Class enclosingElement,
+ FieldElementForLink_ClassField(ClassElementForLink_Class enclosingElement,
UnlinkedVariable unlinkedVariable)
: enclosingElement = enclosingElement,
super(unlinkedVariable, enclosingElement.enclosingElement);
@override
- bool get isConst => unlinkedVariable.isConst;
+ bool get isStatic => unlinkedVariable.isStatic;
+}
+
+/**
+ * Specialization of [FieldElementForLink] for enum fields.
+ */
+class FieldElementForLink_EnumField extends FieldElementForLink
+ implements FieldElement {
+ /**
+ * The unlinked representation of the field in the summary, or `null` if this
+ * is an enum's `values` field.
+ */
+ final UnlinkedEnumValue unlinkedEnumValue;
+
+ FieldElementForLink_EnumField(this.unlinkedEnumValue);
@override
- bool get isFinal => unlinkedVariable.isFinal;
+ ConstructorElementForLink get asConstructor => null;
@override
- bool get isStatic => unlinkedVariable.isStatic;
+ ConstVariableNode get asConstVariable {
+ // Even though enum fields are constants, there is no need to include them
+ // in the const dependency graph because they can't participate in a
+ // circularity.
+ return null;
+ }
+
+ @override
+ bool get isStatic => true;
+
+ @override
+ String get name =>
+ unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name;
+
+ @override
+ DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeForLink.instance;
+
+ @override
+ ReferenceableElementForLink getContainedName(name) =>
+ UndefinedElementForLink.instance;
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -939,6 +1055,8 @@ class FieldElementForLink extends VariableElementForLink
/**
* Representation of an interface type during linking.
+ *
+ * TODO(paulberry): add the ability to represent type arguments.
*/
class InterfaceTypeForLink extends DartTypeForLink implements InterfaceType {
@override
@@ -1166,6 +1284,13 @@ abstract class ReferenceableElementForLink {
ConstructorElementForLink get asConstructor;
/**
+ * If this element can be used in a getter context to refer to a
+ * constant variable, return the [ConstVariableNode] for the
+ * constant value. Otherwise return `null`.
+ */
+ ConstVariableNode get asConstVariable;
+
+ /**
* Return the type indicated by this element when it is used in a
* type instantiation context. If this element can't legally be
* instantiated as a type, return the dynamic type.
@@ -1184,6 +1309,20 @@ abstract class ReferenceableElementForLink {
}
/**
+ * Element representing a top level variable resynthesized from a
+ * summary during linking.
+ */
+class TopLevelVariableElementForLink extends VariableElementForLink
+ implements TopLevelVariableElement {
+ TopLevelVariableElementForLink(CompilationUnitElement enclosingElement,
+ UnlinkedVariable unlinkedVariable)
+ : super(unlinkedVariable, enclosingElement);
+
+ @override
+ bool get isStatic => true;
+}
+
+/**
* Singleton element used for unresolved references.
*/
class UndefinedElementForLink implements ReferenceableElementForLink {
@@ -1196,6 +1335,9 @@ class UndefinedElementForLink implements ReferenceableElementForLink {
ConstructorElementForLink get asConstructor => null;
@override
+ ConstVariableNode get asConstVariable => null;
+
+ @override
DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i),
List<int> implicitFunctionTypeIndices) =>
DynamicTypeForLink.instance;
@@ -1208,7 +1350,8 @@ class UndefinedElementForLink implements ReferenceableElementForLink {
* Element representing a top level variable resynthesized from a
* summary during linking.
*/
-class VariableElementForLink {
+class VariableElementForLink
+ implements VariableElement, ReferenceableElementForLink {
/**
* The unlinked representation of the variable in the summary.
*/
@@ -1231,6 +1374,39 @@ class VariableElementForLink {
_constNode = new ConstVariableNode(this);
}
}
+
+ @override
+ ConstructorElementForLink get asConstructor => null;
+
+ @override
+ ConstVariableNode get asConstVariable => _constNode;
+
+ @override
+ bool get isConst => unlinkedVariable.isConst;
+
+ @override
+ bool get isFinal => unlinkedVariable.isFinal;
+
+ @override
+ bool get isStatic;
+
+ @override
+ String get name => unlinkedVariable.name;
+
+ @override
+ DartTypeForLink buildType(DartTypeForLink getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeForLink.instance;
+
+ ReferenceableElementForLink getContainedName(name) {
+ // TODO(paulberry): implement.
+ // TODO(paulberry): make sure that circularities involving
+ // ".length" are handled correctly.
+ return UndefinedElementForLink.instance;
+ }
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
/**
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/summary_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698