| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * This file contains code to generate serialization/deserialization logic for | 6 * This file contains code to generate serialization/deserialization logic for |
| 7 * summaries based on an "IDL" description of the summary format (written in | 7 * summaries based on an "IDL" description of the summary format (written in |
| 8 * stylized Dart). | 8 * stylized Dart). |
| 9 * | 9 * |
| 10 * For each class in the "IDL" input, two corresponding classes are generated: | 10 * For each class in the "IDL" input, two corresponding classes are generated: |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 * Semantic model of the "IDL" input file. | 79 * Semantic model of the "IDL" input file. |
| 80 */ | 80 */ |
| 81 idlModel.Idl _idl; | 81 idlModel.Idl _idl; |
| 82 | 82 |
| 83 /** | 83 /** |
| 84 * Perform basic sanity checking of the IDL (over and above that done by | 84 * Perform basic sanity checking of the IDL (over and above that done by |
| 85 * [extractIdl]). | 85 * [extractIdl]). |
| 86 */ | 86 */ |
| 87 void checkIdl() { | 87 void checkIdl() { |
| 88 _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { | 88 _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { |
| 89 if (cls.fileIdentifier != null) { |
| 90 if (cls.fileIdentifier.length != 4) { |
| 91 throw new Exception('$name: file identifier must be 4 characters'); |
| 92 } |
| 93 for (int i = 0; i < cls.fileIdentifier.length; i++) { |
| 94 if (cls.fileIdentifier.codeUnitAt(i) >= 256) { |
| 95 throw new Exception( |
| 96 '$name: file identifier must be encodable as Latin-1'); |
| 97 } |
| 98 } |
| 99 } |
| 89 Map<int, String> idsUsed = <int, String>{}; | 100 Map<int, String> idsUsed = <int, String>{}; |
| 90 for (idlModel.FieldDeclaration field in cls.fields) { | 101 for (idlModel.FieldDeclaration field in cls.fields) { |
| 91 String fieldName = field.name; | 102 String fieldName = field.name; |
| 92 idlModel.FieldType type = field.type; | 103 idlModel.FieldType type = field.type; |
| 93 if (type.isList) { | 104 if (type.isList) { |
| 94 if (_idl.classes.containsKey(type.typeName)) { | 105 if (_idl.classes.containsKey(type.typeName)) { |
| 95 // List of classes is ok | 106 // List of classes is ok |
| 96 } else if (_idl.enums.containsKey(type.typeName)) { | 107 } else if (_idl.enums.containsKey(type.typeName)) { |
| 97 // List of enums is ok | 108 // List of enums is ok |
| 98 } else if (type.typeName == 'int') { | 109 } else if (type.typeName == 'int') { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 | 194 |
| 184 /** | 195 /** |
| 185 * Process the AST in [idlParsed] and store the resulting semantic model in | 196 * Process the AST in [idlParsed] and store the resulting semantic model in |
| 186 * [_idl]. Also perform some error checking. | 197 * [_idl]. Also perform some error checking. |
| 187 */ | 198 */ |
| 188 void extractIdl(LineInfo lineInfo, CompilationUnit idlParsed) { | 199 void extractIdl(LineInfo lineInfo, CompilationUnit idlParsed) { |
| 189 _idl = new idlModel.Idl(); | 200 _idl = new idlModel.Idl(); |
| 190 for (CompilationUnitMember decl in idlParsed.declarations) { | 201 for (CompilationUnitMember decl in idlParsed.declarations) { |
| 191 if (decl is ClassDeclaration) { | 202 if (decl is ClassDeclaration) { |
| 192 bool isTopLevel = false; | 203 bool isTopLevel = false; |
| 204 String fileIdentifier; |
| 205 String clsName = decl.name.name; |
| 193 for (Annotation annotation in decl.metadata) { | 206 for (Annotation annotation in decl.metadata) { |
| 194 if (annotation.arguments == null && | 207 if (annotation.arguments != null && |
| 195 annotation.name.name == 'topLevel') { | 208 annotation.name.name == 'TopLevel' && |
| 209 annotation.constructorName == null) { |
| 196 isTopLevel = true; | 210 isTopLevel = true; |
| 211 if (annotation.arguments == null) { |
| 212 throw new Exception( |
| 213 'Class `$clsName`: TopLevel requires parenthesis'); |
| 214 } |
| 215 if (annotation.constructorName != null) { |
| 216 throw new Exception( |
| 217 "Class `$clsName`: TopLevel doesn't have named constructors"); |
| 218 } |
| 219 if (annotation.arguments.arguments.length == 1) { |
| 220 Expression arg = annotation.arguments.arguments[0]; |
| 221 if (arg is StringLiteral) { |
| 222 fileIdentifier = arg.stringValue; |
| 223 } else { |
| 224 throw new Exception( |
| 225 'Class `$clsName`: TopLevel argument must be a string' |
| 226 ' literal'); |
| 227 } |
| 228 } else if (annotation.arguments.arguments.length != 0) { |
| 229 throw new Exception( |
| 230 'Class `$clsName`: TopLevel requires 0 or 1 arguments'); |
| 231 } |
| 197 } | 232 } |
| 198 } | 233 } |
| 199 String doc = _getNodeDoc(lineInfo, decl); | 234 String doc = _getNodeDoc(lineInfo, decl); |
| 200 idlModel.ClassDeclaration cls = | 235 idlModel.ClassDeclaration cls = new idlModel.ClassDeclaration( |
| 201 new idlModel.ClassDeclaration(doc, decl.name.name, isTopLevel); | 236 doc, clsName, isTopLevel, fileIdentifier); |
| 202 _idl.classes[cls.name] = cls; | 237 _idl.classes[clsName] = cls; |
| 203 String expectedBase = 'base.SummaryClass'; | 238 String expectedBase = 'base.SummaryClass'; |
| 204 if (decl.extendsClause == null || | 239 if (decl.extendsClause == null || |
| 205 decl.extendsClause.superclass.name.name != expectedBase) { | 240 decl.extendsClause.superclass.name.name != expectedBase) { |
| 206 throw new Exception( | 241 throw new Exception( |
| 207 'Class `${cls.name}` needs to extend `$expectedBase`'); | 242 'Class `$clsName` needs to extend `$expectedBase`'); |
| 208 } | 243 } |
| 209 for (ClassMember classMember in decl.members) { | 244 for (ClassMember classMember in decl.members) { |
| 210 if (classMember is MethodDeclaration && classMember.isGetter) { | 245 if (classMember is MethodDeclaration && classMember.isGetter) { |
| 211 String desc = '${cls.name}.${classMember.name.name}'; | 246 String desc = '$clsName.${classMember.name.name}'; |
| 212 TypeName type = classMember.returnType; | 247 TypeName type = classMember.returnType; |
| 213 if (type == null) { | 248 if (type == null) { |
| 214 throw new Exception('Class member needs a type: $desc'); | 249 throw new Exception('Class member needs a type: $desc'); |
| 215 } | 250 } |
| 216 bool isList = false; | 251 bool isList = false; |
| 217 if (type.name.name == 'List' && | 252 if (type.name.name == 'List' && |
| 218 type.typeArguments != null && | 253 type.typeArguments != null && |
| 219 type.typeArguments.arguments.length == 1) { | 254 type.typeArguments.arguments.length == 1) { |
| 220 isList = true; | 255 isList = true; |
| 221 type = type.typeArguments.arguments[0]; | 256 type = type.typeArguments.arguments[0]; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 String prefix = i == 0 ? ' : ' : ' '; | 462 String prefix = i == 0 ? ' : ' : ' '; |
| 428 String suffix = i == cls.fields.length - 1 ? ';' : ','; | 463 String suffix = i == cls.fields.length - 1 ? ';' : ','; |
| 429 out('${prefix}_${field.name} = ${field.name}$suffix'); | 464 out('${prefix}_${field.name} = ${field.name}$suffix'); |
| 430 } | 465 } |
| 431 // Generate finish. | 466 // Generate finish. |
| 432 if (cls.isTopLevel) { | 467 if (cls.isTopLevel) { |
| 433 out(); | 468 out(); |
| 434 out('List<int> toBuffer() {'); | 469 out('List<int> toBuffer() {'); |
| 435 indent(() { | 470 indent(() { |
| 436 out('fb.Builder fbBuilder = new fb.Builder();'); | 471 out('fb.Builder fbBuilder = new fb.Builder();'); |
| 437 out('return fbBuilder.finish(finish(fbBuilder));'); | 472 String fileId = cls.fileIdentifier == null |
| 473 ? '' |
| 474 : ', ${quoted(cls.fileIdentifier)}'; |
| 475 out('return fbBuilder.finish(finish(fbBuilder)$fileId);'); |
| 438 }); | 476 }); |
| 439 out('}'); | 477 out('}'); |
| 440 } | 478 } |
| 441 out(); | 479 out(); |
| 442 out('fb.Offset finish(fb.Builder fbBuilder) {'); | 480 out('fb.Offset finish(fb.Builder fbBuilder) {'); |
| 443 indent(() { | 481 indent(() { |
| 444 out('assert(!_finished);'); | 482 out('assert(!_finished);'); |
| 445 out('_finished = true;'); | 483 out('_finished = true;'); |
| 446 // Write objects and remember Offset(s). | 484 // Write objects and remember Offset(s). |
| 447 for (idlModel.FieldDeclaration field in cls.fields) { | 485 for (idlModel.FieldDeclaration field in cls.fields) { |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 return token.lexeme.split('\n').map((String line) { | 769 return token.lexeme.split('\n').map((String line) { |
| 732 if (line.startsWith(indent)) { | 770 if (line.startsWith(indent)) { |
| 733 line = line.substring(indent.length); | 771 line = line.substring(indent.length); |
| 734 } | 772 } |
| 735 return line; | 773 return line; |
| 736 }).join('\n'); | 774 }).join('\n'); |
| 737 } | 775 } |
| 738 return null; | 776 return null; |
| 739 } | 777 } |
| 740 } | 778 } |
| OLD | NEW |