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