OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 import 'package:analyzer/src/codegen/tools.dart'; |
| 6 |
| 7 import 'api.dart'; |
| 8 import 'codegen_dart.dart'; |
| 9 import 'from_html.dart'; |
| 10 |
| 11 final GeneratedFile target = |
| 12 new GeneratedFile('lib/protocol/protocol_constants.dart', (String pkgPath) { |
| 13 CodegenVisitor visitor = new CodegenVisitor(readApi(pkgPath)); |
| 14 return visitor.collectCode(visitor.visitApi); |
| 15 }); |
| 16 |
| 17 /** |
| 18 * A visitor that produces Dart code defining constants associated with the API. |
| 19 */ |
| 20 class CodegenVisitor extends DartCodegenVisitor with CodeGenerator { |
| 21 CodegenVisitor(Api api) : super(api) { |
| 22 codeGeneratorSettings.commentLineLength = 79; |
| 23 codeGeneratorSettings.languageName = 'dart'; |
| 24 } |
| 25 |
| 26 /** |
| 27 * Generate all of the constants associates with the [api]. |
| 28 */ |
| 29 void generateConstants() { |
| 30 _ConstantVisitor visitor = new _ConstantVisitor(api); |
| 31 visitor.visitApi(); |
| 32 List<_Constant> constants = visitor.constants; |
| 33 constants.sort((first, second) => first.name.compareTo(second.name)); |
| 34 for (_Constant constant in constants) { |
| 35 generateContant(constant); |
| 36 } |
| 37 } |
| 38 |
| 39 /** |
| 40 * Generate the given [constant]. |
| 41 */ |
| 42 void generateContant(_Constant constant) { |
| 43 write('const String '); |
| 44 write(constant.name); |
| 45 write(' = '); |
| 46 write(constant.value); |
| 47 writeln(';'); |
| 48 } |
| 49 |
| 50 @override |
| 51 visitApi() { |
| 52 outputHeader(year: '2017'); |
| 53 writeln(); |
| 54 generateConstants(); |
| 55 } |
| 56 } |
| 57 |
| 58 /** |
| 59 * A representation of a constant that is to be generated. |
| 60 */ |
| 61 class _Constant { |
| 62 /** |
| 63 * The name of the constant. |
| 64 */ |
| 65 final String name; |
| 66 |
| 67 /** |
| 68 * The value of the constant. |
| 69 */ |
| 70 final String value; |
| 71 |
| 72 /** |
| 73 * Initialize a newly created constant. |
| 74 */ |
| 75 _Constant(this.name, this.value); |
| 76 } |
| 77 |
| 78 /** |
| 79 * A visitor that visits an API to compute a list of constants to be generated. |
| 80 */ |
| 81 class _ConstantVisitor extends HierarchicalApiVisitor { |
| 82 /** |
| 83 * The list of constants to be generated. |
| 84 */ |
| 85 List<_Constant> constants = <_Constant>[]; |
| 86 |
| 87 /** |
| 88 * Initialize a newly created visitor to visit the given [api]. |
| 89 */ |
| 90 _ConstantVisitor(Api api) : super(api); |
| 91 |
| 92 @override |
| 93 void visitNotification(Notification notification) { |
| 94 String domainName = notification.domainName; |
| 95 String event = notification.event; |
| 96 |
| 97 String constantName = _generateName(domainName, 'notification', event); |
| 98 constants.add(new _Constant(constantName, "'$domainName.$event'")); |
| 99 _addFieldConstants(constantName, notification.params); |
| 100 } |
| 101 |
| 102 @override |
| 103 void visitRequest(Request request) { |
| 104 String domainName = request.domainName; |
| 105 String method = request.method; |
| 106 |
| 107 String requestConstantName = _generateName(domainName, 'request', method); |
| 108 constants.add(new _Constant(requestConstantName, "'$domainName.$method'")); |
| 109 _addFieldConstants(requestConstantName, request.params); |
| 110 |
| 111 String responseConstantName = _generateName(domainName, 'response', method); |
| 112 _addFieldConstants(responseConstantName, request.result); |
| 113 } |
| 114 |
| 115 /** |
| 116 * Generate a constant for each of the fields in the given [type], where the |
| 117 * name of each constant will be composed from the [parentName] and the name |
| 118 * of the field. |
| 119 */ |
| 120 void _addFieldConstants(String parentName, TypeObject type) { |
| 121 if (type == null) { |
| 122 return; |
| 123 } |
| 124 type.fields.forEach((TypeObjectField field) { |
| 125 String name = field.name; |
| 126 String fieldConstantName = parentName + '_' + name.toUpperCase(); |
| 127 constants.add(new _Constant(fieldConstantName, "'$name'")); |
| 128 }); |
| 129 } |
| 130 |
| 131 /** |
| 132 * Generate a name from the [domainName], [kind] and [name] components. |
| 133 */ |
| 134 String _generateName(String domainName, String kind, String name) { |
| 135 List<String> components = <String>[]; |
| 136 components.addAll(_split(domainName)); |
| 137 components.add(kind); |
| 138 components.addAll(_split(name)); |
| 139 return components |
| 140 .map((String component) => component.toUpperCase()) |
| 141 .join('_'); |
| 142 } |
| 143 |
| 144 /** |
| 145 * Return the components of the given [string] that are indicated by an upper |
| 146 * case letter. |
| 147 */ |
| 148 Iterable<String> _split(String first) { |
| 149 RegExp regExp = new RegExp('[A-Z]'); |
| 150 List<String> components = <String>[]; |
| 151 int start = 1; |
| 152 int index = first.indexOf(regExp, start); |
| 153 while (index >= 0) { |
| 154 components.add(first.substring(start - 1, index)); |
| 155 start = index + 1; |
| 156 index = first.indexOf(regExp, start); |
| 157 } |
| 158 components.add(first.substring(start - 1)); |
| 159 return components; |
| 160 } |
| 161 } |
OLD | NEW |