Index: pkg/analyzer/lib/src/summary/summarize_elements.dart |
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart |
index 3d9896b09496050ee0033d0c38f8b90057ea1d14..a3b8c030b6d27ce782d48561a4f11099a9c73f87 100644 |
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart |
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart |
@@ -246,6 +246,11 @@ class _CompilationUnitSerializer { |
final List<_SerializeTypeRef> deferredLinkedTypes = <_SerializeTypeRef>[]; |
/** |
+ * List which should be stored in [LinkedUnit.constCycles]. |
+ */ |
+ final List<int> constCycles = <int>[]; |
+ |
+ /** |
* Index into the "references table" representing an unresolved reference, if |
* such an index exists. `null` if no such entry has been made in the |
* references table yet. |
@@ -394,13 +399,15 @@ class _CompilationUnitSerializer { |
/** |
* Create the [LinkedUnit.types] table based on deferred types that were |
- * found during [addCompilationUnitElements]. |
+ * found during [addCompilationUnitElements]. Also populate |
+ * [LinkedUnit.constCycles]. |
*/ |
- void createLinkedTypes() { |
+ void createLinkedInfo() { |
buildingLinkedReferences = true; |
linkedUnit.types = deferredLinkedTypes |
.map((_SerializeTypeRef closure) => closure()) |
.toList(); |
+ linkedUnit.constCycles = constCycles; |
buildingLinkedReferences = false; |
} |
@@ -706,17 +713,19 @@ class _CompilationUnitSerializer { |
b.redirectedConstructorName = redirectedConstructor.name; |
} |
} |
- if (executableElement.isConst && |
- executableElement.constantInitializers != null) { |
- Set<String> constructorParameterNames = |
- executableElement.parameters.map((p) => p.name).toSet(); |
- b.constantInitializers = executableElement.constantInitializers |
- .map((ConstructorInitializer initializer) => |
- serializeConstructorInitializer( |
- initializer, |
- (expr) => |
- serializeConstExpr(expr, constructorParameterNames))) |
- .toList(); |
+ if (executableElement.isConst) { |
+ b.constCycleSlot = storeConstCycle(!executableElement.isCycleFree); |
+ if (executableElement.constantInitializers != null) { |
+ Set<String> constructorParameterNames = |
+ executableElement.parameters.map((p) => p.name).toSet(); |
+ b.constantInitializers = executableElement.constantInitializers |
+ .map((ConstructorInitializer initializer) => |
+ serializeConstructorInitializer( |
+ initializer, |
+ (expr) => |
+ serializeConstExpr(expr, constructorParameterNames))) |
+ .toList(); |
+ } |
} |
} else { |
b.kind = UnlinkedExecutableKind.functionOrMethod; |
@@ -1104,6 +1113,18 @@ class _CompilationUnitSerializer { |
} |
/** |
+ * Create a new slot id and return it. If [hasCycle] is `true`, arrange for |
+ * the slot id to be included in [LinkedUnit.constCycles]. |
+ */ |
+ int storeConstCycle(bool hasCycle) { |
+ int slot = ++numSlots; |
+ if (hasCycle) { |
+ constCycles.add(slot); |
+ } |
+ return slot; |
+ } |
+ |
+ /** |
* Create a slot id for the given [type] (which may be either a propagated |
* type or an inferred type). If [type] is not `null`, it is stored in |
* [linkedTypes] so that once the compilation unit has been fully visited, |
@@ -1522,7 +1543,7 @@ class _LibrarySerializer { |
pb.numPrelinkedDependencies = dependencies.length; |
for (_CompilationUnitSerializer compilationUnitSerializer |
in compilationUnitSerializers) { |
- compilationUnitSerializer.createLinkedTypes(); |
+ compilationUnitSerializer.createLinkedInfo(); |
} |
pb.importDependencies = linkedImports; |
List<String> exportedNames = |