44
55library generate_vm_service_dart;
66
7+ import 'package:collection/collection.dart' ;
78import 'package:markdown/markdown.dart' ;
89
910import '../common/generate_common.dart' ;
@@ -13,15 +14,15 @@ import 'src_gen_dart.dart';
1314
1415export 'src_gen_dart.dart' show DartGenerator;
1516
16- String ? _coerceRefType (String ? typeName) {
17+ String _coerceRefType (String typeName) {
1718 if (typeName == 'Object' ) typeName = 'Obj' ;
1819 if (typeName == '@Object' ) typeName = 'ObjRef' ;
1920 if (typeName == 'Null' ) typeName = 'NullVal' ;
2021 if (typeName == '@Null' ) typeName = 'NullValRef' ;
2122 if (typeName == 'Function' ) typeName = 'Func' ;
2223 if (typeName == '@Function' ) typeName = 'FuncRef' ;
2324
24- if (typeName! .startsWith ('@' )) typeName = '${typeName .substring (1 )}Ref' ;
25+ if (typeName.startsWith ('@' )) typeName = '${typeName .substring (1 )}Ref' ;
2526
2627 if (typeName == 'string' ) typeName = 'String' ;
2728 if (typeName == 'map' ) typeName = 'Map' ;
@@ -30,7 +31,7 @@ String? _coerceRefType(String? typeName) {
3031}
3132
3233String typeRefListToString (List <TypeRef > types) =>
33- 'const [${types .map ((e ) => "'${e .name ! }'" ).join (',' )}]' ;
34+ 'const [${types .map ((e ) => "'${e .name }'" ).join (',' )}]' ;
3435
3536final registerServiceImpl = '''
3637_serviceExtensionRegistry.registerExtension(params!['service'], this);
@@ -89,7 +90,7 @@ abstract class Api with ApiParseUtil {
8990 String ? serviceVersion;
9091 List <Method > methods = [];
9192 List <Enum > enums = [];
92- List <Type ? > types = [];
93+ List <Type > types = [];
9394 List <StreamCategory > streamCategories = [];
9495
9596 void parse (List <Node > nodes) {
@@ -132,8 +133,8 @@ abstract class Api with ApiParseUtil {
132133 }
133134 }
134135
135- for (Type ? type in types) {
136- type! .calculateFieldOverrides ();
136+ for (Type type in types) {
137+ type.calculateFieldOverrides ();
137138 }
138139
139140 Method streamListenMethod =
@@ -190,32 +191,30 @@ abstract class Api with ApiParseUtil {
190191
191192 void generate (DartGenerator gen);
192193
193- bool isEnumName (String ? typeName) =>
194- enums.any ((Enum e) => e.name == typeName);
194+ bool isEnumName (String typeName) => enums.any ((Enum e) => e.name == typeName);
195195
196- Type ? getType (String ? name) =>
197- types.firstWhere ((t) => t! .name == name, orElse: () => null );
196+ Type ? getType (String name) => types.firstWhereOrNull ((t) => t.name == name);
198197}
199198
200199class StreamCategory {
201- String ? _name ;
202- List <String >? _events ;
200+ final String name ;
201+ final List <String > events ;
203202
204- StreamCategory (String line) {
203+ factory StreamCategory (String line) {
205204 // Debug | PauseStart, PauseExit, ...
206- _name = line.split ('|' )[0 ].trim ();
205+ String name = line.split ('|' )[0 ].trim ();
207206
208207 line = line.split ('|' )[1 ];
209- _events = line.split (',' ).map ((w) => w.trim ()).toList ();
210- }
208+ List <String > events = line.split (',' ).map ((w) => w.trim ()).toList ();
211209
212- String ? get name => _name;
210+ return StreamCategory ._(name: name, events: events);
211+ }
213212
214- List < String > ? get events => _events ;
213+ StreamCategory ._({ required this .name, required this .events}) ;
215214
216215 void generate (DartGenerator gen) {
217216 gen.writeln ();
218- gen.writeln ('// ${events ! .join (', ' )}' );
217+ gen.writeln ('// ${events .join (', ' )}' );
219218 gen.writeln (
220219 "Stream<Event> get on${name }Event => _getEventController('$name ').stream;" );
221220 }
@@ -258,7 +257,7 @@ class Method extends Member {
258257 .join ());
259258
260259 args.where ((MethodArg a) => a.optional).forEach ((MethodArg arg) {
261- String ? valueRef = arg.name;
260+ String valueRef = arg.name;
262261 // Special case for `getAllocationProfile`. We do not want to add these
263262 // params if they are false.
264263 if (name == 'getAllocationProfile' ) {
@@ -332,7 +331,7 @@ class Method extends Member {
332331
333332class MemberType extends Member {
334333 final Api api;
335- List <TypeRef > types = [];
334+ final List <TypeRef > types = [];
336335
337336 MemberType (this .api);
338337
@@ -353,14 +352,14 @@ class MemberType extends Member {
353352 // @Instance | Sentinel
354353 final token = parser.advance ()! ;
355354 if (token.isName) {
356- unionTypes.add (_coerceRefType (token.text) ! );
355+ unionTypes.add (_coerceRefType (token.text! ) );
357356 }
358357 }
359358 }
360359 parser.consume (')' );
361360 TypeRef ref;
362361 if (unionTypes.length == 1 ) {
363- ref = TypeRef (unionTypes.first).. nullable = nullable;
362+ ref = TypeRef (unionTypes.first, nullable: nullable) ;
364363 } else {
365364 ref = TypeRef ('dynamic' );
366365 }
@@ -371,7 +370,7 @@ class MemberType extends Member {
371370 types.add (ref);
372371 } else {
373372 Token t = parser.expectName ();
374- TypeRef ref = TypeRef (_coerceRefType (t.text));
373+ TypeRef ref = TypeRef (_coerceRefType (t.text! ));
375374 while (parser.consume ('[' )) {
376375 parser.expect (']' );
377376 ref.arrayDepth++ ;
@@ -421,12 +420,12 @@ class MemberType extends Member {
421420}
422421
423422class TypeRef {
424- String ? name;
423+ final String name;
425424 int arrayDepth = 0 ;
426- bool nullable = false ;
425+ final bool nullable;
427426 List <TypeRef >? genericTypes;
428427
429- TypeRef (this .name);
428+ TypeRef (this .name, { this .nullable = false } );
430429
431430 String get ref {
432431 if (arrayDepth == 2 ) {
@@ -436,7 +435,7 @@ class TypeRef {
436435 } else if (genericTypes != null ) {
437436 return '$name <${genericTypes !.join (', ' )}>' ;
438437 } else {
439- return name! .startsWith ('_' ) ? name! .substring (1 ) : name! ;
438+ return name.startsWith ('_' ) ? name.substring (1 ) : name;
440439 }
441440 }
442441
@@ -450,7 +449,7 @@ class TypeRef {
450449 }
451450 }
452451
453- String ? get listTypeArg => arrayDepth == 2
452+ String get listTypeArg => arrayDepth == 2
454453 ? 'List<$name ${nullable ? "?" : "" }>'
455454 : '$name ${nullable ? "?" : "" }' ;
456455
@@ -480,9 +479,9 @@ class TypeRef {
480479
481480class MethodArg extends Member {
482481 final Method parent;
483- TypeRef type;
482+ final TypeRef type;
484483 @override
485- String ? name;
484+ final String name;
486485 bool optional = false ;
487486
488487 MethodArg (this .parent, this .type, this .name);
@@ -539,7 +538,7 @@ class Type extends Member {
539538 bool get isResponse {
540539 if (superName == null ) return false ;
541540 if (name == 'Response' || superName == 'Response' ) return true ;
542- return parent.getType (superName)! .isResponse;
541+ return parent.getType (superName! )! .isResponse;
543542 }
544543
545544 bool get isRef => name! .endsWith ('Ref' );
@@ -549,7 +548,7 @@ class Type extends Member {
549548 return superName == null ? false : getSuper ()! .supportsIdentity;
550549 }
551550
552- Type ? getSuper () => superName == null ? null : api.getType (superName);
551+ Type ? getSuper () => superName == null ? null : api.getType (superName! );
553552
554553 List <TypeField > getAllFields () {
555554 if (superName == null ) return fields;
@@ -575,7 +574,7 @@ class Type extends Member {
575574 gen.write ('class $name ' );
576575 Type ? superType;
577576 if (superName != null ) {
578- superType = parent.getType (superName);
577+ superType = parent.getType (superName! );
579578 gen.write ('extends $superName ' );
580579 }
581580 if (parent.getType ('${name }Ref' ) != null ) {
@@ -963,7 +962,7 @@ void _parseTokenPosTable() {
963962 TypeRef arrayType = type.types.first;
964963 if (arrayType.arrayDepth == 1 ) {
965964 String assertMethodName =
966- 'assertListOf${arrayType .name ! .substring (0 , 1 ).toUpperCase ()}${arrayType .name ! .substring (1 )}' ;
965+ 'assertListOf${arrayType .name .substring (0 , 1 ).toUpperCase ()}${arrayType .name .substring (1 )}' ;
967966 gen.writeln ('$assertMethodName (obj.${field .generatableName }!);' );
968967 } else {
969968 gen.writeln (
@@ -977,7 +976,7 @@ void _parseTokenPosTable() {
977976 gen.writeln (
978977 'if (obj.${field .generatableName } is vms.${typeRef .name }) {' );
979978 String assertMethodName =
980- 'assert${typeRef .name ! .substring (0 , 1 ).toUpperCase ()}${typeRef .name ! .substring (1 )}' ;
979+ 'assert${typeRef .name .substring (0 , 1 ).toUpperCase ()}${typeRef .name .substring (1 )}' ;
981980 gen.writeln ('$assertMethodName (obj.${field .generatableName }!);' );
982981 }
983982 gen.writeln ('} else {' );
@@ -1051,7 +1050,7 @@ class TypeField extends Member {
10511050 void setOverrides () => overrides = true ;
10521051
10531052 @override
1054- String ? get docs {
1053+ String get docs {
10551054 String str = _docs ?? '' ;
10561055 if (type.isMultipleReturns) {
10571056 str += '\n\n [$generatableName ] can be one of '
@@ -1102,9 +1101,9 @@ class TypeField extends Member {
11021101 @override
11031102 void generate (DartGenerator gen) {
11041103 Type ? refType = parent.parent.getType ('${parent .name }Ref' );
1105- var interfaceOverride = refType? .hasField (name) ?? false ;
1104+ bool interfaceOverride = refType? .hasField (name) ?? false ;
11061105
1107- if (docs! .isNotEmpty) gen.writeDocs (docs! );
1106+ if (docs.isNotEmpty) gen.writeDocs (docs);
11081107 if (optional) gen.write ('@optional ' );
11091108 if (overrides || interfaceOverride) gen.write ('@override ' );
11101109 // Special case where Instance extends Obj, but 'classRef' is not optional
@@ -1116,9 +1115,17 @@ class TypeField extends Member {
11161115 gen.writeStatement('covariant late final String valueAsString;');
11171116 } else */
11181117 {
1119- String ? typeName =
1118+ String typeName =
11201119 api.isEnumName (type.name) ? '/*${type .name }*/ String' : type.name;
11211120 if (typeName != 'dynamic' ) {
1121+ // Since this package is used to interact with DWDS as well as the
1122+ // native VM service, we need to be extremely careful when making types
1123+ // non-nullable. DWDS isn't completely compliant with the service
1124+ // protocol specification, meaning that some fields aren't provided in
1125+ // responses even though they're not marked as optional. This has been a
1126+ // headache for years, but until we're able to make DWDS consistent with
1127+ // the native VM service responses and test package:vm_service against
1128+ // it, we need to be extremely defensive in our parsing logic.
11221129 typeName = '$typeName ?' ;
11231130 }
11241131 gen.writeStatement ('$typeName $generatableName ;' );
@@ -1128,7 +1135,7 @@ class TypeField extends Member {
11281135
11291136 void generateNamedParameter (DartGenerator gen, {bool fromParent = false }) {
11301137 if (fromParent) {
1131- String ? typeName =
1138+ String typeName =
11321139 api.isEnumName (type.name) ? '/*${type .name }*/ String' : type.name;
11331140 gen.writeStatement ('required $typeName $generatableName ,' );
11341141 } else {
@@ -1145,15 +1152,15 @@ class Enum extends Member {
11451152
11461153 List <EnumValue > enums = [];
11471154
1148- Enum (this .name, String definition, [ this .docs] ) {
1155+ Enum (this .name, String definition, this .docs) {
11491156 _parse (Tokenizer (definition).tokenize ());
11501157 }
11511158
11521159 Enum ._(this .name, this .docs);
11531160
11541161 factory Enum .merge (Enum e1, Enum e2) {
11551162 final String name = e1.name;
1156- final String docs = [e1.docs, e2.docs].where ((e) => e != null ) .join ('\n ' );
1163+ final String docs = [e1.docs, e2.docs].nonNulls .join ('\n ' );
11571164 final Map <String ?, EnumValue > map = < String ? , EnumValue > {};
11581165 for (EnumValue e in e2.enums.reversed) {
11591166 map[e.name] = e;
@@ -1186,7 +1193,7 @@ class Enum extends Member {
11861193 void generateAssert (DartGenerator gen) {
11871194 gen.writeln ('String assert$name (String obj) {' );
11881195 List <EnumValue > sorted = enums.toList ()
1189- ..sort ((EnumValue e1, EnumValue e2) => e1.name! .compareTo (e2.name! ));
1196+ ..sort ((EnumValue e1, EnumValue e2) => e1.name.compareTo (e2.name));
11901197 for (EnumValue value in sorted) {
11911198 gen.writeln (' if (obj == "${value .name }") return obj;' );
11921199 }
@@ -1201,7 +1208,7 @@ class Enum extends Member {
12011208class EnumValue extends Member {
12021209 final Enum parent;
12031210 @override
1204- final String ? name;
1211+ final String name;
12051212 @override
12061213 final String ? docs;
12071214
@@ -1257,7 +1264,7 @@ class TextOutputVisitor implements NodeVisitor {
12571264
12581265 @override
12591266 void visitText (Text text) {
1260- String ? t = text.text;
1267+ String t = text.text;
12611268 if (_em) {
12621269 t = _coerceRefType (t);
12631270 } else if (_href) {
@@ -1323,7 +1330,7 @@ class MethodParser extends Parser {
13231330
13241331 while (peek ()! .text != ')' ) {
13251332 Token type = expectName ();
1326- TypeRef ref = TypeRef (_coerceRefType (type.text));
1333+ TypeRef ref = TypeRef (_coerceRefType (type.text! ));
13271334 if (peek ()! .text == '[' ) {
13281335 while (consume ('[' )) {
13291336 expect (']' );
@@ -1335,14 +1342,14 @@ class MethodParser extends Parser {
13351342 ref.genericTypes = [];
13361343 while (peek ()! .text != '>' ) {
13371344 Token genericTypeName = expectName ();
1338- ref.genericTypes! .add (TypeRef (_coerceRefType (genericTypeName.text)));
1345+ ref.genericTypes! .add (TypeRef (_coerceRefType (genericTypeName.text! )));
13391346 consume (',' );
13401347 }
13411348 expect ('>' );
13421349 }
13431350
13441351 Token name = expectName ();
1345- MethodArg arg = MethodArg (method, ref, name.text);
1352+ MethodArg arg = MethodArg (method, ref, name.text! );
13461353 if (consume ('[' )) {
13471354 expect ('optional' );
13481355 expect (']' );
@@ -1374,10 +1381,10 @@ class TypeParser extends Parser {
13741381
13751382 Token t = expectName ();
13761383 type.rawName = t.text;
1377- type.name = _coerceRefType (type.rawName);
1384+ type.name = _coerceRefType (type.rawName! );
13781385 if (consume ('extends' )) {
13791386 t = expectName ();
1380- type.superName = _coerceRefType (t.text);
1387+ type.superName = _coerceRefType (t.text! );
13811388 }
13821389
13831390 expect ('{' );
@@ -1431,7 +1438,7 @@ class EnumParser extends Parser {
14311438 t = expectName ();
14321439 consume (',' );
14331440
1434- e.enums.add (EnumValue (e, t.text, docs));
1441+ e.enums.add (EnumValue (e, t.text! , docs));
14351442 }
14361443 }
14371444}
0 commit comments