| Index: pkg/analyzer/tool/summary/generate.dart
|
| diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
|
| index afd790d530273f885f4e01113aa5cde274c7e18a..5c2d2bfaabd181ce7997221188144e9c87027ce8 100644
|
| --- a/pkg/analyzer/tool/summary/generate.dart
|
| +++ b/pkg/analyzer/tool/summary/generate.dart
|
| @@ -44,7 +44,7 @@ final GeneratedFile target =
|
| // Parse the input "IDL" file and pass it to the [_CodeGenerator].
|
| PhysicalResourceProvider provider = new PhysicalResourceProvider(
|
| PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS);
|
| - String idlPath = join(pkgPath, 'tool', 'summary', 'idl.dart');
|
| + String idlPath = join(pkgPath, 'lib', 'src', 'summary', 'idl.dart');
|
| File idlFile = provider.getFile(idlPath);
|
| Source idlSource = provider.getFile(idlPath).createSource();
|
| String idlText = idlFile.readAsStringSync();
|
| @@ -110,10 +110,11 @@ class _CodeGenerator {
|
| * represent [type] when deserialized.
|
| */
|
| String dartType(idlModel.FieldType type) {
|
| + String baseType = idlPrefix(type.typeName);
|
| if (type.isList) {
|
| - return 'List<${type.typeName}>';
|
| + return 'List<$baseType>';
|
| } else {
|
| - return type.typeName;
|
| + return baseType;
|
| }
|
| }
|
|
|
| @@ -131,10 +132,11 @@ class _CodeGenerator {
|
| new idlModel.FieldType(type.typeName, false);
|
| return '<${encodedType(elementType)}>[]';
|
| } else {
|
| - return 'const <${type.typeName}>[]';
|
| + return 'const <${idlPrefix(type.typeName)}>[]';
|
| }
|
| } else if (_idl.enums.containsKey(type.typeName)) {
|
| - return '${type.typeName}.${_idl.enums[type.typeName].values[0].name}';
|
| + return '${idlPrefix(type.typeName)}.'
|
| + '${_idl.enums[type.typeName].values[0].name}';
|
| } else if (type.typeName == 'int') {
|
| return '0';
|
| } else if (type.typeName == 'String') {
|
| @@ -155,7 +157,7 @@ class _CodeGenerator {
|
| if (_idl.classes.containsKey(type.typeName)) {
|
| typeStr = '${type.typeName}Builder';
|
| } else {
|
| - typeStr = type.typeName;
|
| + typeStr = idlPrefix(type.typeName);
|
| }
|
| if (type.isList) {
|
| return 'List<$typeStr>';
|
| @@ -183,9 +185,18 @@ class _CodeGenerator {
|
| idlModel.ClassDeclaration cls =
|
| new idlModel.ClassDeclaration(doc, decl.name.name, isTopLevel);
|
| _idl.classes[cls.name] = cls;
|
| + String expectedBase = 'base.SummaryClass';
|
| + if (decl.extendsClause == null ||
|
| + decl.extendsClause.superclass.name.name != expectedBase) {
|
| + throw new Exception(
|
| + 'Class `${cls.name}` needs to extend `$expectedBase`');
|
| + }
|
| for (ClassMember classMember in decl.members) {
|
| - if (classMember is FieldDeclaration) {
|
| - TypeName type = classMember.fields.type;
|
| + if (classMember is MethodDeclaration && classMember.isGetter) {
|
| + TypeName type = classMember.returnType;
|
| + if (type == null) {
|
| + throw new Exception('Class member needs a type: $classMember');
|
| + }
|
| bool isList = false;
|
| if (type.name.name == 'List' &&
|
| type.typeArguments != null &&
|
| @@ -199,10 +210,12 @@ class _CodeGenerator {
|
| String doc = _getNodeDoc(lineInfo, classMember);
|
| idlModel.FieldType fieldType =
|
| new idlModel.FieldType(type.name.name, isList);
|
| - for (VariableDeclaration field in classMember.fields.variables) {
|
| - cls.fields.add(new idlModel.FieldDeclaration(
|
| - doc, field.name.name, fieldType));
|
| - }
|
| + cls.fields.add(new idlModel.FieldDeclaration(
|
| + doc, classMember.name.name, fieldType));
|
| + } else if (classMember is ConstructorDeclaration &&
|
| + classMember.name.name == 'fromBuffer') {
|
| + // Ignore `fromBuffer` declarations; they simply forward to the
|
| + // read functions generated by [_generateReadFunction].
|
| } else {
|
| throw new Exception('Unexpected class member `$classMember`');
|
| }
|
| @@ -227,6 +240,22 @@ class _CodeGenerator {
|
| }
|
|
|
| /**
|
| + * Add the prefix `idl.` to a type name, unless that type name is the name of
|
| + * a built-in type.
|
| + */
|
| + String idlPrefix(String s) {
|
| + switch (s) {
|
| + case 'bool':
|
| + case 'double':
|
| + case 'int':
|
| + case 'String':
|
| + return s;
|
| + default:
|
| + return 'idl.$s';
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Execute [callback] with two spaces added to [_indentation].
|
| */
|
| void indent(void callback()) {
|
| @@ -273,20 +302,20 @@ class _CodeGenerator {
|
| out();
|
| out('library analyzer.src.summary.format;');
|
| out();
|
| - out("import 'base.dart' as base;");
|
| out("import 'flat_buffers.dart' as fb;");
|
| + out("import 'idl.dart' as idl;");
|
| out();
|
| for (idlModel.EnumDeclaration enm in _idl.enums.values) {
|
| - _generateEnum(enm);
|
| - out();
|
| _generateEnumReader(enm);
|
| out();
|
| }
|
| for (idlModel.ClassDeclaration cls in _idl.classes.values) {
|
| _generateBuilder(cls);
|
| out();
|
| - _generateInterface(cls);
|
| - out();
|
| + if (cls.isTopLevel) {
|
| + _generateReadFunction(cls);
|
| + out();
|
| + }
|
| _generateReader(cls);
|
| out();
|
| _generateImpl(cls);
|
| @@ -309,7 +338,7 @@ class _CodeGenerator {
|
| String mixinName = '_${name}Mixin';
|
| List<String> constructorParams = <String>[];
|
| out('class $builderName extends Object with $mixinName '
|
| - 'implements $name {');
|
| + 'implements ${idlPrefix(name)} {');
|
| indent(() {
|
| out('bool _finished = false;');
|
| // Generate fields.
|
| @@ -468,28 +497,10 @@ class _CodeGenerator {
|
| out('}');
|
| }
|
|
|
| - void _generateEnum(idlModel.EnumDeclaration enm) {
|
| - String name = enm.name;
|
| - outDoc(enm.documentation);
|
| - out('enum $name {');
|
| - indent(() {
|
| - for (idlModel.EnumValueDeclaration value in enm.values) {
|
| - outDoc(value.documentation);
|
| - if (enm.values.last == value) {
|
| - out('${value.name}');
|
| - } else {
|
| - out('${value.name},');
|
| - out();
|
| - }
|
| - }
|
| - });
|
| - out('}');
|
| - }
|
| -
|
| void _generateEnumReader(idlModel.EnumDeclaration enm) {
|
| String name = enm.name;
|
| String readerName = '_${name}Reader';
|
| - out('class $readerName extends fb.Reader<$name> {');
|
| + out('class $readerName extends fb.Reader<${idlPrefix(name)}> {');
|
| indent(() {
|
| out('const $readerName() : super();');
|
| out();
|
| @@ -497,10 +508,10 @@ class _CodeGenerator {
|
| out('int get size => 4;');
|
| out();
|
| out('@override');
|
| - out('$name read(fb.BufferPointer bp) {');
|
| + out('${idlPrefix(name)} read(fb.BufferPointer bp) {');
|
| indent(() {
|
| out('int index = const fb.Uint32Reader().read(bp);');
|
| - out('return $name.values[index];');
|
| + out('return ${idlPrefix(name)}.values[index];');
|
| });
|
| out('}');
|
| });
|
| @@ -511,7 +522,8 @@ class _CodeGenerator {
|
| String name = cls.name;
|
| String implName = '_${name}Impl';
|
| String mixinName = '_${name}Mixin';
|
| - out('class $implName extends Object with $mixinName implements $name {');
|
| + out('class $implName extends Object with $mixinName'
|
| + ' implements ${idlPrefix(name)} {');
|
| indent(() {
|
| out('final fb.BufferPointer _bp;');
|
| out();
|
| @@ -541,12 +553,12 @@ class _CodeGenerator {
|
| String itemCode = 'const fb.StringReader()';
|
| readCode = 'const fb.ListReader<String>($itemCode)';
|
| } else if (_idl.classes.containsKey(typeName)) {
|
| - String itemCode = '$typeName>(const _${typeName}Reader()';
|
| - readCode = 'const fb.ListReader<$itemCode)';
|
| + String itemCode = 'const _${typeName}Reader()';
|
| + readCode = 'const fb.ListReader<${idlPrefix(typeName)}>($itemCode)';
|
| } else {
|
| assert(_idl.enums.containsKey(typeName));
|
| String itemCode = 'const _${typeName}Reader()';
|
| - readCode = 'const fb.ListReader<$typeName>($itemCode)';
|
| + readCode = 'const fb.ListReader<${idlPrefix(typeName)}>($itemCode)';
|
| }
|
| } else if (typeName == 'bool') {
|
| readCode = 'const fb.BoolReader()';
|
| @@ -576,34 +588,10 @@ class _CodeGenerator {
|
| out('}');
|
| }
|
|
|
| - void _generateInterface(idlModel.ClassDeclaration cls) {
|
| - String name = cls.name;
|
| - outDoc(cls.documentation);
|
| - out('abstract class $name extends base.SummaryClass {');
|
| - indent(() {
|
| - if (cls.isTopLevel) {
|
| - out('factory $name.fromBuffer(List<int> buffer) {');
|
| - indent(() {
|
| - out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);');
|
| - out('return const _${name}Reader().read(rootRef);');
|
| - });
|
| - out('}');
|
| - }
|
| - cls.fields.asMap().forEach((index, field) {
|
| - String fieldName = field.name;
|
| - idlModel.FieldType type = field.type;
|
| - out();
|
| - outDoc(field.documentation);
|
| - out('${dartType(type)} get $fieldName;');
|
| - });
|
| - });
|
| - out('}');
|
| - }
|
| -
|
| void _generateMixin(idlModel.ClassDeclaration cls) {
|
| String name = cls.name;
|
| String mixinName = '_${name}Mixin';
|
| - out('abstract class $mixinName implements $name {');
|
| + out('abstract class $mixinName implements ${idlPrefix(name)} {');
|
| indent(() {
|
| // Write toMap().
|
| out('@override');
|
| @@ -633,6 +621,16 @@ class _CodeGenerator {
|
| out('}');
|
| }
|
|
|
| + void _generateReadFunction(idlModel.ClassDeclaration cls) {
|
| + String name = cls.name;
|
| + out('${idlPrefix(name)} read$name(List<int> buffer) {');
|
| + indent(() {
|
| + out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);');
|
| + out('return const _${name}Reader().read(rootRef);');
|
| + });
|
| + out('}');
|
| + }
|
| +
|
| /**
|
| * Return the documentation text of the given [node], or `null` if the [node]
|
| * does not have a comment. Each line is `\n` separated.
|
|
|