Chromium Code Reviews| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 PhysicalResourceProvider provider = new PhysicalResourceProvider( | 47 PhysicalResourceProvider provider = new PhysicalResourceProvider( |
| 48 PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS); | 48 PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS); |
| 49 String idlPath = join(pkgPath, 'tool', 'summary', 'idl.dart'); | 49 String idlPath = join(pkgPath, 'tool', 'summary', 'idl.dart'); |
| 50 File idlFile = provider.getFile(idlPath); | 50 File idlFile = provider.getFile(idlPath); |
| 51 Source idlSource = provider.getFile(idlPath).createSource(); | 51 Source idlSource = provider.getFile(idlPath).createSource(); |
| 52 String idlText = idlFile.readAsStringSync(); | 52 String idlText = idlFile.readAsStringSync(); |
| 53 BooleanErrorListener errorListener = new BooleanErrorListener(); | 53 BooleanErrorListener errorListener = new BooleanErrorListener(); |
| 54 CharacterReader idlReader = new CharSequenceReader(idlText); | 54 CharacterReader idlReader = new CharSequenceReader(idlText); |
| 55 Scanner scanner = new Scanner(idlSource, idlReader, errorListener); | 55 Scanner scanner = new Scanner(idlSource, idlReader, errorListener); |
| 56 Token tokenStream = scanner.tokenize(); | 56 Token tokenStream = scanner.tokenize(); |
| 57 LineInfo lineInfo = new LineInfo(scanner.lineStarts); | |
| 57 Parser parser = new Parser(idlSource, new BooleanErrorListener()); | 58 Parser parser = new Parser(idlSource, new BooleanErrorListener()); |
| 58 CompilationUnit idlParsed = parser.parseCompilationUnit(tokenStream); | 59 CompilationUnit idlParsed = parser.parseCompilationUnit(tokenStream); |
| 59 _CodeGenerator codeGenerator = new _CodeGenerator(); | 60 _CodeGenerator codeGenerator = new _CodeGenerator(); |
| 60 codeGenerator.processCompilationUnit(idlParsed); | 61 codeGenerator.processCompilationUnit(lineInfo, idlParsed); |
| 61 return codeGenerator._outBuffer.toString(); | 62 return codeGenerator._outBuffer.toString(); |
| 62 }); | 63 }); |
| 63 | 64 |
| 64 class _CodeGenerator { | 65 class _CodeGenerator { |
| 65 /** | 66 /** |
| 66 * Buffer in which generated code is accumulated. | 67 * Buffer in which generated code is accumulated. |
| 67 */ | 68 */ |
| 68 final StringBuffer _outBuffer = new StringBuffer(); | 69 final StringBuffer _outBuffer = new StringBuffer(); |
| 69 | 70 |
| 70 /** | 71 /** |
| 71 * Current indentation level. | 72 * Current indentation level. |
| 72 */ | 73 */ |
| 73 String _indentation = ''; | 74 String _indentation = ''; |
| 74 | 75 |
| 75 /** | 76 /** |
| 76 * Semantic model of the "IDL" input file. | 77 * Semantic model of the "IDL" input file. |
| 77 */ | 78 */ |
| 78 idlModel.Idl _idl; | 79 idlModel.Idl _idl; |
| 79 | 80 |
| 80 /** | 81 /** |
| 81 * Perform basic sanity checking of the IDL (over and above that done by | 82 * Perform basic sanity checking of the IDL (over and above that done by |
| 82 * [extractIdl]). | 83 * [extractIdl]). |
| 83 */ | 84 */ |
| 84 void checkIdl() { | 85 void checkIdl() { |
| 85 _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { | 86 _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { |
| 86 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 87 for (idlModel.FieldDeclaration field in cls.fields) { |
| 88 String fieldName = field.name; | |
| 89 idlModel.FieldType type = field.type; | |
| 87 if (type.isList) { | 90 if (type.isList) { |
| 88 if (_idl.classes.containsKey(type.typeName)) { | 91 if (_idl.classes.containsKey(type.typeName)) { |
| 89 // List of classes is ok | 92 // List of classes is ok |
| 90 } else if (type.typeName == 'int') { | 93 } else if (type.typeName == 'int') { |
| 91 // List of ints is ok | 94 // List of ints is ok |
| 92 } else if (type.typeName == 'String') { | 95 } else if (type.typeName == 'String') { |
| 93 // List of strings is ok | 96 // List of strings is ok |
| 94 } else { | 97 } else { |
| 95 throw new Exception( | 98 throw new Exception( |
| 96 '$name.$fieldName: illegal type (list of ${type.typeName})'); | 99 '$name.$fieldName: illegal type (list of ${type.typeName})'); |
| 97 } | 100 } |
| 98 } | 101 } |
| 99 }); | 102 } |
| 100 }); | 103 }); |
| 101 } | 104 } |
| 102 | 105 |
| 103 /** | 106 /** |
| 104 * Generate a string representing the Dart type which should be used to | 107 * Generate a string representing the Dart type which should be used to |
| 105 * represent [type] when deserialized. | 108 * represent [type] when deserialized. |
| 106 */ | 109 */ |
| 107 String dartType(idlModel.FieldType type) { | 110 String dartType(idlModel.FieldType type) { |
| 108 if (type.isList) { | 111 if (type.isList) { |
| 109 return 'List<${type.typeName}>'; | 112 return 'List<${type.typeName}>'; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 return 'List<$typeStr>'; | 150 return 'List<$typeStr>'; |
| 148 } else { | 151 } else { |
| 149 return typeStr; | 152 return typeStr; |
| 150 } | 153 } |
| 151 } | 154 } |
| 152 | 155 |
| 153 /** | 156 /** |
| 154 * Process the AST in [idlParsed] and store the resulting semantic model in | 157 * Process the AST in [idlParsed] and store the resulting semantic model in |
| 155 * [_idl]. Also perform some error checking. | 158 * [_idl]. Also perform some error checking. |
| 156 */ | 159 */ |
| 157 void extractIdl(CompilationUnit idlParsed) { | 160 void extractIdl(LineInfo lineInfo, CompilationUnit idlParsed) { |
| 158 _idl = new idlModel.Idl(); | 161 _idl = new idlModel.Idl(); |
| 159 for (CompilationUnitMember decl in idlParsed.declarations) { | 162 for (CompilationUnitMember decl in idlParsed.declarations) { |
| 160 if (decl is ClassDeclaration) { | 163 if (decl is ClassDeclaration) { |
| 161 bool isTopLevel = false; | 164 bool isTopLevel = false; |
| 162 for (Annotation annotation in decl.metadata) { | 165 for (Annotation annotation in decl.metadata) { |
| 163 if (annotation.arguments == null && | 166 if (annotation.arguments == null && |
| 164 annotation.name.name == 'topLevel') { | 167 annotation.name.name == 'topLevel') { |
| 165 isTopLevel = true; | 168 isTopLevel = true; |
| 166 } | 169 } |
| 167 } | 170 } |
| 171 String doc = _getNodeDoc(lineInfo, decl); | |
| 168 idlModel.ClassDeclaration cls = | 172 idlModel.ClassDeclaration cls = |
| 169 new idlModel.ClassDeclaration(isTopLevel); | 173 new idlModel.ClassDeclaration(doc, decl.name.name, isTopLevel); |
| 170 _idl.classes[decl.name.name] = cls; | 174 _idl.classes[cls.name] = cls; |
| 171 for (ClassMember classMember in decl.members) { | 175 for (ClassMember classMember in decl.members) { |
| 172 if (classMember is FieldDeclaration) { | 176 if (classMember is FieldDeclaration) { |
| 173 TypeName type = classMember.fields.type; | 177 TypeName type = classMember.fields.type; |
| 174 bool isList = false; | 178 bool isList = false; |
| 175 if (type.name.name == 'List' && | 179 if (type.name.name == 'List' && |
| 176 type.typeArguments != null && | 180 type.typeArguments != null && |
| 177 type.typeArguments.arguments.length == 1) { | 181 type.typeArguments.arguments.length == 1) { |
| 178 isList = true; | 182 isList = true; |
| 179 type = type.typeArguments.arguments[0]; | 183 type = type.typeArguments.arguments[0]; |
| 180 } | 184 } |
| 181 if (type.typeArguments != null) { | 185 if (type.typeArguments != null) { |
| 182 throw new Exception('Cannot handle type arguments in `$type`'); | 186 throw new Exception('Cannot handle type arguments in `$type`'); |
| 183 } | 187 } |
| 188 String doc = _getNodeDoc(lineInfo, classMember); | |
| 184 idlModel.FieldType fieldType = | 189 idlModel.FieldType fieldType = |
| 185 new idlModel.FieldType(type.name.name, isList); | 190 new idlModel.FieldType(type.name.name, isList); |
| 186 for (VariableDeclaration field in classMember.fields.variables) { | 191 for (VariableDeclaration field in classMember.fields.variables) { |
| 187 cls.fields[field.name.name] = fieldType; | 192 // TODO(scheglov) use actual documentation |
|
Paul Berry
2016/01/05 17:49:50
Can you clarify what this means? Isn't `doc` the
| |
| 193 cls.fields.add(new idlModel.FieldDeclaration( | |
| 194 doc, field.name.name, fieldType)); | |
| 188 } | 195 } |
| 189 } else { | 196 } else { |
| 190 throw new Exception('Unexpected class member `$classMember`'); | 197 throw new Exception('Unexpected class member `$classMember`'); |
| 191 } | 198 } |
| 192 } | 199 } |
| 193 } else if (decl is EnumDeclaration) { | 200 } else if (decl is EnumDeclaration) { |
| 194 idlModel.EnumDeclaration enm = new idlModel.EnumDeclaration(); | 201 String doc = _getNodeDoc(lineInfo, decl); |
| 195 _idl.enums[decl.name.name] = enm; | 202 idlModel.EnumDeclaration enm = |
| 203 new idlModel.EnumDeclaration(doc, decl.name.name); | |
| 204 _idl.enums[enm.name] = enm; | |
| 196 for (EnumConstantDeclaration constDecl in decl.constants) { | 205 for (EnumConstantDeclaration constDecl in decl.constants) { |
| 197 enm.values.add(constDecl.name.name); | 206 enm.values.add(constDecl.name.name); |
| 198 } | 207 } |
| 199 } else if (decl is TopLevelVariableDeclaration) { | 208 } else if (decl is TopLevelVariableDeclaration) { |
| 200 // Ignore top level variable declarations; they are present just to make | 209 // Ignore top level variable declarations; they are present just to make |
| 201 // the IDL analyze without warnings. | 210 // the IDL analyze without warnings. |
| 202 } else { | 211 } else { |
| 203 throw new Exception('Unexpected declaration `$decl`'); | 212 throw new Exception('Unexpected declaration `$decl`'); |
| 204 } | 213 } |
| 205 } | 214 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 223 * appropriate. | 232 * appropriate. |
| 224 */ | 233 */ |
| 225 void out([String s = '']) { | 234 void out([String s = '']) { |
| 226 if (s == '') { | 235 if (s == '') { |
| 227 _outBuffer.writeln(''); | 236 _outBuffer.writeln(''); |
| 228 } else { | 237 } else { |
| 229 _outBuffer.writeln('$_indentation$s'); | 238 _outBuffer.writeln('$_indentation$s'); |
| 230 } | 239 } |
| 231 } | 240 } |
| 232 | 241 |
| 242 void outDoc(String documentation) { | |
| 243 if (documentation != null) { | |
| 244 documentation.split('\n').forEach(out); | |
| 245 } | |
| 246 } | |
| 247 | |
| 233 /** | 248 /** |
| 234 * Entry point to the code generator. Interpret the AST in [idlParsed], | 249 * Entry point to the code generator. Interpret the AST in [idlParsed], |
| 235 * generate code, and output it to [_outBuffer]. | 250 * generate code, and output it to [_outBuffer]. |
| 236 */ | 251 */ |
| 237 void processCompilationUnit(CompilationUnit idlParsed) { | 252 void processCompilationUnit(LineInfo lineInfo, CompilationUnit idlParsed) { |
| 238 extractIdl(idlParsed); | 253 extractIdl(lineInfo, idlParsed); |
| 239 checkIdl(); | 254 checkIdl(); |
| 240 out('// Copyright (c) 2015, the Dart project authors. Please see the AUTHOR S file'); | 255 out('// Copyright (c) 2015, the Dart project authors. Please see the AUTHOR S file'); |
| 241 out('// for details. All rights reserved. Use of this source code is governe d by a'); | 256 out('// for details. All rights reserved. Use of this source code is governe d by a'); |
| 242 out('// BSD-style license that can be found in the LICENSE file.'); | 257 out('// BSD-style license that can be found in the LICENSE file.'); |
| 243 out('//'); | 258 out('//'); |
| 244 out('// This file has been automatically generated. Please do not edit it m anually.'); | 259 out('// This file has been automatically generated. Please do not edit it m anually.'); |
| 245 out('// To regenerate the file, use the script "pkg/analyzer/tool/generate_f iles".'); | 260 out('// To regenerate the file, use the script "pkg/analyzer/tool/generate_f iles".'); |
| 246 out(); | 261 out(); |
| 247 out('library analyzer.src.summary.format;'); | 262 out('library analyzer.src.summary.format;'); |
| 248 out(); | 263 out(); |
| 249 out("import 'dart:convert';"); | 264 out("import 'dart:convert';"); |
| 250 out("import 'base.dart' as base;"); | 265 out("import 'base.dart' as base;"); |
| 251 out(); | 266 out(); |
| 252 _idl.enums.forEach((String name, idlModel.EnumDeclaration enm) { | 267 _idl.enums.forEach((String name, idlModel.EnumDeclaration enm) { |
| 268 outDoc(enm.documentation); | |
| 253 out('enum $name {'); | 269 out('enum $name {'); |
| 254 indent(() { | 270 indent(() { |
| 255 for (String value in enm.values) { | 271 for (String value in enm.values) { |
| 256 out('$value,'); | 272 out('$value,'); |
| 257 } | 273 } |
| 258 }); | 274 }); |
| 259 out('}'); | 275 out('}'); |
| 260 out(); | 276 out(); |
| 261 }); | 277 }); |
| 262 _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { | 278 _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) { |
| 279 outDoc(cls.documentation); | |
| 263 out('class $name extends base.SummaryClass {'); | 280 out('class $name extends base.SummaryClass {'); |
| 264 indent(() { | 281 indent(() { |
| 265 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 282 for (idlModel.FieldDeclaration field in cls.fields) { |
| 283 String fieldName = field.name; | |
| 284 idlModel.FieldType type = field.type; | |
| 266 out('${dartType(type)} _$fieldName;'); | 285 out('${dartType(type)} _$fieldName;'); |
| 267 }); | 286 } |
| 268 out(); | 287 out(); |
| 269 out('$name.fromJson(Map json)'); | 288 out('$name.fromJson(Map json)'); |
| 270 indent(() { | 289 indent(() { |
| 271 List<String> initializers = <String>[]; | 290 List<String> initializers = <String>[]; |
| 272 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 291 for (idlModel.FieldDeclaration field in cls.fields) { |
| 292 String fieldName = field.name; | |
| 293 idlModel.FieldType type = field.type; | |
| 273 String convert = 'json[${quoted(fieldName)}]'; | 294 String convert = 'json[${quoted(fieldName)}]'; |
| 274 if (type.isList) { | 295 if (type.isList) { |
| 275 if (type.typeName == 'int' || type.typeName == 'String') { | 296 if (type.typeName == 'int' || type.typeName == 'String') { |
| 276 // No conversion necessary. | 297 // No conversion necessary. |
| 277 } else { | 298 } else { |
| 278 convert = | 299 convert = |
| 279 '$convert?.map((x) => new ${type.typeName}.fromJson(x))?.toL ist()'; | 300 '$convert?.map((x) => new ${type.typeName}.fromJson(x))?.toL ist()'; |
| 280 } | 301 } |
| 281 } else if (_idl.classes.containsKey(type.typeName)) { | 302 } else if (_idl.classes.containsKey(type.typeName)) { |
| 282 convert = | 303 convert = |
| 283 '$convert == null ? null : new ${type.typeName}.fromJson($conv ert)'; | 304 '$convert == null ? null : new ${type.typeName}.fromJson($conv ert)'; |
| 284 } else if (_idl.enums.containsKey(type.typeName)) { | 305 } else if (_idl.enums.containsKey(type.typeName)) { |
| 285 convert = | 306 convert = |
| 286 '$convert == null ? null : ${type.typeName}.values[$convert]'; | 307 '$convert == null ? null : ${type.typeName}.values[$convert]'; |
| 287 } | 308 } |
| 288 initializers.add('_$fieldName = $convert'); | 309 initializers.add('_$fieldName = $convert'); |
| 289 }); | 310 } |
| 290 for (int i = 0; i < initializers.length; i++) { | 311 for (int i = 0; i < initializers.length; i++) { |
| 291 String prefix = i == 0 ? ': ' : ' '; | 312 String prefix = i == 0 ? ': ' : ' '; |
| 292 String suffix = i == initializers.length - 1 ? ';' : ','; | 313 String suffix = i == initializers.length - 1 ? ';' : ','; |
| 293 out('$prefix${initializers[i]}$suffix'); | 314 out('$prefix${initializers[i]}$suffix'); |
| 294 } | 315 } |
| 295 }); | 316 }); |
| 296 out(); | 317 out(); |
| 297 out('@override'); | 318 out('@override'); |
| 298 out('Map<String, Object> toMap() => {'); | 319 out('Map<String, Object> toMap() => {'); |
| 299 indent(() { | 320 indent(() { |
| 300 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 321 for (idlModel.FieldDeclaration field in cls.fields) { |
| 322 String fieldName = field.name; | |
| 301 out('${quoted(fieldName)}: $fieldName,'); | 323 out('${quoted(fieldName)}: $fieldName,'); |
| 302 }); | 324 } |
| 303 }); | 325 }); |
| 304 out('};'); | 326 out('};'); |
| 305 out(); | 327 out(); |
| 306 if (cls.isTopLevel) { | 328 if (cls.isTopLevel) { |
| 307 out('$name.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UT F8.decode(buffer)));'); | 329 out('$name.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UT F8.decode(buffer)));'); |
| 308 out(); | 330 out(); |
| 309 } | 331 } |
| 310 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 332 cls.fields.asMap().forEach((index, field) { |
| 333 String fieldName = field.name; | |
| 334 idlModel.FieldType type = field.type; | |
| 335 if (index != 0) { | |
| 336 out(); | |
| 337 } | |
| 311 String def = defaultValue(type); | 338 String def = defaultValue(type); |
| 312 String defaultSuffix = def == null ? '' : ' ?? $def'; | 339 String defaultSuffix = def == null ? '' : ' ?? $def'; |
| 340 outDoc(field.documentation); | |
| 313 out('${dartType(type)} get $fieldName => _$fieldName$defaultSuffix;'); | 341 out('${dartType(type)} get $fieldName => _$fieldName$defaultSuffix;'); |
| 314 }); | 342 }); |
| 315 }); | 343 }); |
| 316 out('}'); | 344 out('}'); |
| 317 out(); | 345 out(); |
| 318 List<String> builderParams = <String>[]; | 346 List<String> builderParams = <String>[]; |
| 319 out('class ${name}Builder {'); | 347 out('class ${name}Builder {'); |
| 320 indent(() { | 348 indent(() { |
| 321 out('final Map _json = {};'); | 349 out('final Map _json = {};'); |
| 322 out(); | 350 out(); |
| 323 out('bool _finished = false;'); | 351 out('bool _finished = false;'); |
| 324 out(); | 352 out(); |
| 325 out('${name}Builder(base.BuilderContext context);'); | 353 out('${name}Builder(base.BuilderContext context);'); |
| 326 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 354 for (idlModel.FieldDeclaration field in cls.fields) { |
| 355 String fieldName = field.name; | |
| 356 idlModel.FieldType type = field.type; | |
| 327 out(); | 357 out(); |
| 358 outDoc(field.documentation); | |
| 328 String conversion = '_value'; | 359 String conversion = '_value'; |
| 329 String condition = ''; | 360 String condition = ''; |
| 330 if (type.isList) { | 361 if (type.isList) { |
| 331 if (_idl.classes.containsKey(type.typeName)) { | 362 if (_idl.classes.containsKey(type.typeName)) { |
| 332 conversion = '$conversion.map((b) => b.finish()).toList()'; | 363 conversion = '$conversion.map((b) => b.finish()).toList()'; |
| 333 } else { | 364 } else { |
| 334 conversion = '$conversion.toList()'; | 365 conversion = '$conversion.toList()'; |
| 335 } | 366 } |
| 336 condition = ' || _value.isEmpty'; | 367 condition = ' || _value.isEmpty'; |
| 337 } else if (_idl.enums.containsKey(type.typeName)) { | 368 } else if (_idl.enums.containsKey(type.typeName)) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 349 out('if (_value != null) {'); | 380 out('if (_value != null) {'); |
| 350 } else { | 381 } else { |
| 351 out('if (!(_value == null$condition)) {'); | 382 out('if (!(_value == null$condition)) {'); |
| 352 } | 383 } |
| 353 indent(() { | 384 indent(() { |
| 354 out('_json[${quoted(fieldName)}] = $conversion;'); | 385 out('_json[${quoted(fieldName)}] = $conversion;'); |
| 355 }); | 386 }); |
| 356 out('}'); | 387 out('}'); |
| 357 }); | 388 }); |
| 358 out('}'); | 389 out('}'); |
| 359 }); | 390 } |
| 360 if (cls.isTopLevel) { | 391 if (cls.isTopLevel) { |
| 361 out(); | 392 out(); |
| 362 out('List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));'); | 393 out('List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));'); |
| 363 } | 394 } |
| 364 out(); | 395 out(); |
| 365 out('Map finish() {'); | 396 out('Map finish() {'); |
| 366 indent(() { | 397 indent(() { |
| 367 out('assert(!_finished);'); | 398 out('assert(!_finished);'); |
| 368 out('_finished = true;'); | 399 out('_finished = true;'); |
| 369 out('return _json;'); | 400 out('return _json;'); |
| 370 }); | 401 }); |
| 371 out('}'); | 402 out('}'); |
| 372 }); | 403 }); |
| 373 out('}'); | 404 out('}'); |
| 374 out(); | 405 out(); |
| 375 out('${name}Builder encode$name(base.BuilderContext builderContext, {${bui lderParams.join(', ')}}) {'); | 406 out('${name}Builder encode$name(base.BuilderContext builderContext, {${bui lderParams.join(', ')}}) {'); |
| 376 indent(() { | 407 indent(() { |
| 377 out('${name}Builder builder = new ${name}Builder(builderContext);'); | 408 out('${name}Builder builder = new ${name}Builder(builderContext);'); |
| 378 cls.fields.forEach((String fieldName, idlModel.FieldType type) { | 409 for (idlModel.FieldDeclaration field in cls.fields) { |
| 410 String fieldName = field.name; | |
| 379 out('builder.$fieldName = $fieldName;'); | 411 out('builder.$fieldName = $fieldName;'); |
| 380 }); | 412 } |
| 381 out('return builder;'); | 413 out('return builder;'); |
| 382 }); | 414 }); |
| 383 out('}'); | 415 out('}'); |
| 384 out(); | 416 out(); |
| 385 }); | 417 }); |
| 386 } | 418 } |
| 387 | 419 |
| 388 /** | 420 /** |
| 389 * Enclose [s] in quotes, escaping as necessary. | 421 * Enclose [s] in quotes, escaping as necessary. |
| 390 */ | 422 */ |
| 391 String quoted(String s) { | 423 String quoted(String s) { |
| 392 return JSON.encode(s); | 424 return JSON.encode(s); |
| 393 } | 425 } |
| 426 | |
| 427 /** | |
| 428 * Return the documentation text of the given [node], or `null` if the [node] | |
| 429 * does not have a comment. Each line is `\n` separated. | |
| 430 */ | |
| 431 String _getNodeDoc(LineInfo lineInfo, AnnotatedNode node) { | |
| 432 Comment comment = node.documentationComment; | |
| 433 if (comment != null && | |
| 434 comment.isDocumentation && | |
| 435 comment.tokens.length == 1 && | |
| 436 comment.tokens.first.type == TokenType.MULTI_LINE_COMMENT) { | |
| 437 Token token = comment.tokens.first; | |
| 438 int column = lineInfo.getLocation(token.offset).columnNumber; | |
| 439 String indent = ' ' * (column - 1); | |
| 440 return token.lexeme.split('\n').map((String line) { | |
| 441 if (line.startsWith(indent)) { | |
| 442 line = line.substring(indent.length); | |
| 443 } | |
| 444 return line; | |
| 445 }).join('\n'); | |
| 446 } | |
| 447 return null; | |
| 448 } | |
| 394 } | 449 } |
| OLD | NEW |