Index: pkg/analyzer/tool/summary/generate.dart |
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart |
index 869b38de43abbfc5f4b37d5460a53deffc194010..39d0b99b91e5253c715d607e687afcf48668a5a7 100644 |
--- a/pkg/analyzer/tool/summary/generate.dart |
+++ b/pkg/analyzer/tool/summary/generate.dart |
@@ -618,6 +618,44 @@ class _CodeGenerator { |
}); |
out('}'); |
} |
+ // Generate collectApiSignature(). |
+ { |
+ out(); |
+ out('/**'); |
+ out(' * Accumulate non-[informative] data into [signature].'); |
+ out(' */'); |
+ out('void collectApiSignature(fb.ApiSignature signature) {'); |
+ indent(() { |
+ List<idlModel.FieldDeclaration> sortedFields = cls.fields.toList() |
+ ..sort((idlModel.FieldDeclaration a, idlModel.FieldDeclaration b) => |
+ a.id.compareTo(b.id)); |
+ for (idlModel.FieldDeclaration field in sortedFields) { |
+ if (field.isInformative) { |
+ continue; |
+ } |
+ String ref = 'this._${field.name}'; |
+ if (field.type.isList) { |
+ out('if ($ref == null) {'); |
+ indent(() { |
+ out('signature.addInt(0);'); |
+ }); |
+ out('} else {'); |
+ indent(() { |
+ out('signature.addInt($ref.length);'); |
+ out('for (var x in $ref) {'); |
+ indent(() { |
+ _generateSignatureCall(field.type.typeName, 'x', false); |
+ }); |
+ out('}'); |
+ }); |
+ out('}'); |
+ } else { |
+ _generateSignatureCall(field.type.typeName, ref, true); |
+ } |
+ } |
+ }); |
+ out('}'); |
+ } |
// Generate finish. |
if (cls.isTopLevel) { |
out(); |
@@ -820,7 +858,8 @@ class _CodeGenerator { |
} else { |
out('$returnType get $fieldName {'); |
indent(() { |
- String readExpr = '$readCode.vTableGet(_bc, _bcOffset, $index, $def)'; |
+ String readExpr = |
+ '$readCode.vTableGet(_bc, _bcOffset, $index, $def)'; |
out('_$fieldName ??= $readExpr;'); |
out('return _$fieldName;'); |
}); |
@@ -918,6 +957,56 @@ class _CodeGenerator { |
} |
/** |
+ * Generate a call to the appropriate method of [ApiSignature] for the type |
+ * [typeName], using the data named by [ref]. If [couldBeNull] is `true`, |
+ * generate code to handle the possibility that [ref] is `null` (substituting |
+ * in the appropriate default value). |
+ */ |
+ void _generateSignatureCall(String typeName, String ref, bool couldBeNull) { |
+ if (_idl.enums.containsKey(typeName)) { |
+ if (couldBeNull) { |
+ out('signature.addInt($ref == null ? 0 : $ref.index);'); |
+ } else { |
+ out('signature.addInt($ref.index);'); |
+ } |
+ } else if (_idl.classes.containsKey(typeName)) { |
+ if (couldBeNull) { |
+ out('signature.addBool($ref != null);'); |
+ } |
+ out('$ref?.collectApiSignature(signature);'); |
+ } else { |
+ switch (typeName) { |
+ case 'String': |
+ if (couldBeNull) { |
+ ref += " ?? ''"; |
+ } |
+ out("signature.addString($ref);"); |
+ break; |
+ case 'int': |
+ if (couldBeNull) { |
+ ref += ' ?? 0'; |
+ } |
+ out('signature.addInt($ref);'); |
+ break; |
+ case 'bool': |
+ if (couldBeNull) { |
+ ref += ' == true'; |
+ } |
+ out('signature.addBool($ref);'); |
+ break; |
+ case 'double': |
+ if (couldBeNull) { |
+ ref += ' ?? 0.0'; |
+ } |
+ out('signature.addDouble($ref);'); |
+ break; |
+ default: |
+ throw "Don't know how to generate signature call for $typeName"; |
+ } |
+ } |
+ } |
+ |
+ /** |
* Return the documentation text of the given [node], or `null` if the [node] |
* does not have a comment. Each line is `\n` separated. |
*/ |