OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 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 | 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 * Data structures representing an API definition, and visitor base classes | 6 * Data structures representing an API definition, and visitor base classes |
7 * for visiting those data structures. | 7 * for visiting those data structures. |
8 */ | 8 */ |
9 import 'dart:collection'; | 9 import 'dart:collection'; |
10 | 10 |
11 import 'package:html/dom.dart' as dom; | 11 import 'package:html/dom.dart' as dom; |
12 | 12 |
13 /** | 13 /** |
14 * Toplevel container for the API. | 14 * Toplevel container for the API. |
15 */ | 15 */ |
16 class Api extends ApiNode { | 16 class Api extends ApiNode { |
17 final String version; | 17 final String version; |
18 final List<Domain> domains; | 18 final List<Domain> domains; |
19 final Types types; | 19 final Types types; |
20 final Refactorings refactorings; | 20 final Refactorings refactorings; |
21 | 21 |
22 Api(this.version, this.domains, this.types, this.refactorings, | 22 Api(this.version, this.domains, this.types, this.refactorings, |
23 dom.Element html, | 23 dom.Element html, |
24 {bool experimental}) | 24 {bool experimental}) |
25 : super(html, experimental); | 25 : super(html, experimental, false); |
26 } | 26 } |
27 | 27 |
28 /** | 28 /** |
29 * Base class for objects in the API model. | 29 * Base class for objects in the API model. |
30 */ | 30 */ |
31 class ApiNode { | 31 class ApiNode { |
32 /** | 32 /** |
33 * A flag to indicate if this API is experimental. | 33 * A flag to indicate if this API is experimental. |
34 */ | 34 */ |
35 final bool experimental; | 35 final bool experimental; |
36 | 36 |
37 /** | 37 /** |
| 38 * A flag to indicate if this API is deprecated. |
| 39 */ |
| 40 final bool deprecated; |
| 41 |
| 42 /** |
38 * Html element representing this part of the API. | 43 * Html element representing this part of the API. |
39 */ | 44 */ |
40 final dom.Element html; | 45 final dom.Element html; |
41 | 46 |
42 ApiNode(this.html, bool experimental) | 47 ApiNode(this.html, bool experimental, bool deprecated) |
43 : this.experimental = experimental ?? false; | 48 : this.experimental = experimental ?? false, |
| 49 this.deprecated = deprecated ?? false; |
44 } | 50 } |
45 | 51 |
46 /** | 52 /** |
47 * Base class for visiting the API definition. | 53 * Base class for visiting the API definition. |
48 */ | 54 */ |
49 abstract class ApiVisitor<T> { | 55 abstract class ApiVisitor<T> { |
50 /** | 56 /** |
51 * Dispatch the given [type] to the visitor. | 57 * Dispatch the given [type] to the visitor. |
52 */ | 58 */ |
53 T visitTypeDecl(TypeDecl type) => type.accept(this) as T; | 59 T visitTypeDecl(TypeDecl type) => type.accept(this) as T; |
54 T visitTypeEnum(TypeEnum typeEnum); | 60 T visitTypeEnum(TypeEnum typeEnum); |
55 T visitTypeList(TypeList typeList); | 61 T visitTypeList(TypeList typeList); |
56 T visitTypeMap(TypeMap typeMap); | 62 T visitTypeMap(TypeMap typeMap); |
57 T visitTypeObject(TypeObject typeObject); | 63 T visitTypeObject(TypeObject typeObject); |
58 T visitTypeReference(TypeReference typeReference); | 64 T visitTypeReference(TypeReference typeReference); |
59 | 65 |
60 T visitTypeUnion(TypeUnion typeUnion); | 66 T visitTypeUnion(TypeUnion typeUnion); |
61 } | 67 } |
62 | 68 |
63 /** | 69 /** |
64 * Definition of a single domain. | 70 * Definition of a single domain. |
65 */ | 71 */ |
66 class Domain extends ApiNode { | 72 class Domain extends ApiNode { |
67 final String name; | 73 final String name; |
68 final List<Request> requests; | 74 final List<Request> requests; |
69 final List<Notification> notifications; | 75 final List<Notification> notifications; |
70 | 76 |
71 Domain(this.name, this.requests, this.notifications, dom.Element html, | 77 Domain(this.name, this.requests, this.notifications, dom.Element html, |
72 {bool experimental}) | 78 {bool experimental, bool deprecated}) |
73 : super(html, experimental); | 79 : super(html, experimental, deprecated); |
74 } | 80 } |
75 | 81 |
76 /** | 82 /** |
77 * API visitor that visits the entire API hierarchically by default. | 83 * API visitor that visits the entire API hierarchically by default. |
78 */ | 84 */ |
79 class HierarchicalApiVisitor extends ApiVisitor { | 85 class HierarchicalApiVisitor extends ApiVisitor { |
80 /** | 86 /** |
81 * The API to visit. | 87 * The API to visit. |
82 */ | 88 */ |
83 final Api api; | 89 final Api api; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 final String event; | 202 final String event; |
197 | 203 |
198 /** | 204 /** |
199 * Type of the object associated with the "params" key in the notification | 205 * Type of the object associated with the "params" key in the notification |
200 * object, or null if the notification has no parameters. | 206 * object, or null if the notification has no parameters. |
201 */ | 207 */ |
202 final TypeObject params; | 208 final TypeObject params; |
203 | 209 |
204 Notification(this.domainName, this.event, this.params, dom.Element html, | 210 Notification(this.domainName, this.event, this.params, dom.Element html, |
205 {bool experimental}) | 211 {bool experimental}) |
206 : super(html, experimental); | 212 : super(html, experimental, false); |
207 | 213 |
208 /** | 214 /** |
209 * Get the name of the notification, including the domain prefix. | 215 * Get the name of the notification, including the domain prefix. |
210 */ | 216 */ |
211 String get longEvent => '$domainName.$event'; | 217 String get longEvent => '$domainName.$event'; |
212 | 218 |
213 /** | 219 /** |
214 * Get the full type of the notification object, including the common "id" | 220 * Get the full type of the notification object, including the common "id" |
215 * and "error" fields. | 221 * and "error" fields. |
216 */ | 222 */ |
(...skipping 25 matching lines...) Expand all Loading... |
242 */ | 248 */ |
243 final TypeObject feedback; | 249 final TypeObject feedback; |
244 | 250 |
245 /** | 251 /** |
246 * Type of the refactoring options, or null if the refactoring has no options. | 252 * Type of the refactoring options, or null if the refactoring has no options. |
247 */ | 253 */ |
248 final TypeObject options; | 254 final TypeObject options; |
249 | 255 |
250 Refactoring(this.kind, this.feedback, this.options, dom.Element html, | 256 Refactoring(this.kind, this.feedback, this.options, dom.Element html, |
251 {bool experimental}) | 257 {bool experimental}) |
252 : super(html, experimental); | 258 : super(html, experimental, false); |
253 } | 259 } |
254 | 260 |
255 /** | 261 /** |
256 * A collection of refactoring definitions. | 262 * A collection of refactoring definitions. |
257 */ | 263 */ |
258 class Refactorings extends ApiNode with IterableMixin<Refactoring> { | 264 class Refactorings extends ApiNode with IterableMixin<Refactoring> { |
259 final List<Refactoring> refactorings; | 265 final List<Refactoring> refactorings; |
260 | 266 |
261 Refactorings(this.refactorings, dom.Element html, {bool experimental}) | 267 Refactorings(this.refactorings, dom.Element html, {bool experimental}) |
262 : super(html, experimental); | 268 : super(html, experimental, false); |
263 | 269 |
264 @override | 270 @override |
265 Iterator<Refactoring> get iterator => refactorings.iterator; | 271 Iterator<Refactoring> get iterator => refactorings.iterator; |
266 } | 272 } |
267 | 273 |
268 /** | 274 /** |
269 * Description of a request method. | 275 * Description of a request method. |
270 */ | 276 */ |
271 class Request extends ApiNode { | 277 class Request extends ApiNode { |
272 /** | 278 /** |
(...skipping 13 matching lines...) Expand all Loading... |
286 final TypeObject params; | 292 final TypeObject params; |
287 | 293 |
288 /** | 294 /** |
289 * Type of the object associated with the "result" key in the response object, | 295 * Type of the object associated with the "result" key in the response object, |
290 * or null if the response has no results. | 296 * or null if the response has no results. |
291 */ | 297 */ |
292 final TypeObject result; | 298 final TypeObject result; |
293 | 299 |
294 Request( | 300 Request( |
295 this.domainName, this.method, this.params, this.result, dom.Element html, | 301 this.domainName, this.method, this.params, this.result, dom.Element html, |
296 {bool experimental}) | 302 {bool experimental, bool deprecated}) |
297 : super(html, experimental); | 303 : super(html, experimental, deprecated); |
298 | 304 |
299 /** | 305 /** |
300 * Get the name of the request, including the domain prefix. | 306 * Get the name of the request, including the domain prefix. |
301 */ | 307 */ |
302 String get longMethod => '$domainName.$method'; | 308 String get longMethod => '$domainName.$method'; |
303 | 309 |
304 /** | 310 /** |
305 * Get the full type of the request object, including the common "id" and | 311 * Get the full type of the request object, including the common "id" and |
306 * "method" fields. | 312 * "method" fields. |
307 */ | 313 */ |
(...skipping 24 matching lines...) Expand all Loading... |
332 fields.add(new TypeObjectField('result', result, null)); | 338 fields.add(new TypeObjectField('result', result, null)); |
333 } | 339 } |
334 return new TypeObject(fields, null); | 340 return new TypeObject(fields, null); |
335 } | 341 } |
336 } | 342 } |
337 | 343 |
338 /** | 344 /** |
339 * Base class for all possible types. | 345 * Base class for all possible types. |
340 */ | 346 */ |
341 abstract class TypeDecl extends ApiNode { | 347 abstract class TypeDecl extends ApiNode { |
342 TypeDecl(dom.Element html, bool experimental) : super(html, experimental); | 348 TypeDecl(dom.Element html, bool experimental, bool deprecated) |
| 349 : super(html, experimental, deprecated); |
343 | 350 |
344 accept(ApiVisitor visitor); | 351 accept(ApiVisitor visitor); |
345 } | 352 } |
346 | 353 |
347 /** | 354 /** |
348 * Description of a named type definition. | 355 * Description of a named type definition. |
349 */ | 356 */ |
350 class TypeDefinition extends ApiNode { | 357 class TypeDefinition extends ApiNode { |
351 final String name; | 358 final String name; |
352 final TypeDecl type; | 359 final TypeDecl type; |
353 | 360 |
354 TypeDefinition(this.name, this.type, dom.Element html, {bool experimental}) | 361 TypeDefinition(this.name, this.type, dom.Element html, |
355 : super(html, experimental); | 362 {bool experimental, bool deprecated}) |
| 363 : super(html, experimental, deprecated); |
356 } | 364 } |
357 | 365 |
358 /** | 366 /** |
359 * Type of an enum. We represent enums in JSON as strings, so this type | 367 * Type of an enum. We represent enums in JSON as strings, so this type |
360 * declaration simply lists the allowed values. | 368 * declaration simply lists the allowed values. |
361 */ | 369 */ |
362 class TypeEnum extends TypeDecl { | 370 class TypeEnum extends TypeDecl { |
363 final List<TypeEnumValue> values; | 371 final List<TypeEnumValue> values; |
364 | 372 |
365 TypeEnum(this.values, dom.Element html, {bool experimental}) | 373 TypeEnum(this.values, dom.Element html, {bool experimental, bool deprecated}) |
366 : super(html, experimental); | 374 : super(html, experimental, deprecated); |
367 | 375 |
368 @override | 376 @override |
369 accept(ApiVisitor visitor) => visitor.visitTypeEnum(this); | 377 accept(ApiVisitor visitor) => visitor.visitTypeEnum(this); |
370 } | 378 } |
371 | 379 |
372 /** | 380 /** |
373 * Description of a single allowed value for an enum. | 381 * Description of a single allowed value for an enum. |
374 */ | 382 */ |
375 class TypeEnumValue extends ApiNode { | 383 class TypeEnumValue extends ApiNode { |
376 final String value; | 384 final String value; |
377 | 385 |
378 TypeEnumValue(this.value, dom.Element html, {bool experimental}) | 386 TypeEnumValue(this.value, dom.Element html, |
379 : super(html, experimental); | 387 {bool experimental, bool deprecated}) |
| 388 : super(html, experimental, deprecated); |
380 } | 389 } |
381 | 390 |
382 /** | 391 /** |
383 * Type of a JSON list. | 392 * Type of a JSON list. |
384 */ | 393 */ |
385 class TypeList extends TypeDecl { | 394 class TypeList extends TypeDecl { |
386 final TypeDecl itemType; | 395 final TypeDecl itemType; |
387 | 396 |
388 TypeList(this.itemType, dom.Element html, {bool experimental}) | 397 TypeList(this.itemType, dom.Element html, {bool experimental}) |
389 : super(html, experimental); | 398 : super(html, experimental, false); |
390 | 399 |
391 @override | 400 @override |
392 accept(ApiVisitor visitor) => visitor.visitTypeList(this); | 401 accept(ApiVisitor visitor) => visitor.visitTypeList(this); |
393 } | 402 } |
394 | 403 |
395 /** | 404 /** |
396 * Type of a JSON map. | 405 * Type of a JSON map. |
397 */ | 406 */ |
398 class TypeMap extends TypeDecl { | 407 class TypeMap extends TypeDecl { |
399 /** | 408 /** |
400 * Type of map keys. Note that since JSON map keys must always be strings, | 409 * Type of map keys. Note that since JSON map keys must always be strings, |
401 * this must either be a [TypeReference] for [String], or a [TypeReference] | 410 * this must either be a [TypeReference] for [String], or a [TypeReference] |
402 * to a type which is defined in the API as an enum or a synonym for [String]. | 411 * to a type which is defined in the API as an enum or a synonym for [String]. |
403 */ | 412 */ |
404 final TypeReference keyType; | 413 final TypeReference keyType; |
405 | 414 |
406 /** | 415 /** |
407 * Type of map values. | 416 * Type of map values. |
408 */ | 417 */ |
409 final TypeDecl valueType; | 418 final TypeDecl valueType; |
410 | 419 |
411 TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental}) | 420 TypeMap(this.keyType, this.valueType, dom.Element html, {bool experimental}) |
412 : super(html, experimental); | 421 : super(html, experimental, false); |
413 | 422 |
414 @override | 423 @override |
415 accept(ApiVisitor visitor) => visitor.visitTypeMap(this); | 424 accept(ApiVisitor visitor) => visitor.visitTypeMap(this); |
416 } | 425 } |
417 | 426 |
418 /** | 427 /** |
419 * Type of a JSON object with specified fields, some of which may be optional. | 428 * Type of a JSON object with specified fields, some of which may be optional. |
420 */ | 429 */ |
421 class TypeObject extends TypeDecl { | 430 class TypeObject extends TypeDecl { |
422 final List<TypeObjectField> fields; | 431 final List<TypeObjectField> fields; |
423 | 432 |
424 TypeObject(this.fields, dom.Element html, {bool experimental}) | 433 TypeObject(this.fields, dom.Element html, |
425 : super(html, experimental); | 434 {bool experimental, bool deprecated}) |
| 435 : super(html, experimental, deprecated); |
426 | 436 |
427 @override | 437 @override |
428 accept(ApiVisitor visitor) => visitor.visitTypeObject(this); | 438 accept(ApiVisitor visitor) => visitor.visitTypeObject(this); |
429 | 439 |
430 /** | 440 /** |
431 * Return the field with the given [name], or null if there is no such field. | 441 * Return the field with the given [name], or null if there is no such field. |
432 */ | 442 */ |
433 TypeObjectField getField(String name) { | 443 TypeObjectField getField(String name) { |
434 for (TypeObjectField field in fields) { | 444 for (TypeObjectField field in fields) { |
435 if (field.name == name) { | 445 if (field.name == name) { |
(...skipping 11 matching lines...) Expand all Loading... |
447 final String name; | 457 final String name; |
448 final TypeDecl type; | 458 final TypeDecl type; |
449 final bool optional; | 459 final bool optional; |
450 | 460 |
451 /** | 461 /** |
452 * Value that the field is required to contain, or null if it may vary. | 462 * Value that the field is required to contain, or null if it may vary. |
453 */ | 463 */ |
454 final Object value; | 464 final Object value; |
455 | 465 |
456 TypeObjectField(this.name, this.type, dom.Element html, | 466 TypeObjectField(this.name, this.type, dom.Element html, |
457 {this.optional: false, this.value, bool experimental}) | 467 {this.optional: false, this.value, bool experimental, bool deprecated}) |
458 : super(html, experimental); | 468 : super(html, experimental, deprecated); |
459 } | 469 } |
460 | 470 |
461 /** | 471 /** |
462 * A reference to a type which is either defined elsewhere in the API or which | 472 * A reference to a type which is either defined elsewhere in the API or which |
463 * is built-in ([String], [bool], or [int]). | 473 * is built-in ([String], [bool], or [int]). |
464 */ | 474 */ |
465 class TypeReference extends TypeDecl { | 475 class TypeReference extends TypeDecl { |
466 final String typeName; | 476 final String typeName; |
467 | 477 |
468 TypeReference(this.typeName, dom.Element html, {bool experimental}) | 478 TypeReference(this.typeName, dom.Element html, {bool experimental}) |
469 : super(html, experimental) { | 479 : super(html, experimental, false) { |
470 if (typeName.isEmpty) { | 480 if (typeName.isEmpty) { |
471 throw new Exception('Empty type name'); | 481 throw new Exception('Empty type name'); |
472 } | 482 } |
473 } | 483 } |
474 | 484 |
475 @override | 485 @override |
476 accept(ApiVisitor visitor) => visitor.visitTypeReference(this); | 486 accept(ApiVisitor visitor) => visitor.visitTypeReference(this); |
477 } | 487 } |
478 | 488 |
479 /** | 489 /** |
480 * A collection of type definitions. | 490 * A collection of type definitions. |
481 */ | 491 */ |
482 class Types extends ApiNode with IterableMixin<TypeDefinition> { | 492 class Types extends ApiNode with IterableMixin<TypeDefinition> { |
483 final Map<String, TypeDefinition> types; | 493 final Map<String, TypeDefinition> types; |
484 | 494 |
485 Types(this.types, dom.Element html, {bool experimental}) | 495 Types(this.types, dom.Element html, {bool experimental}) |
486 : super(html, experimental); | 496 : super(html, experimental, false); |
487 | 497 |
488 @override | 498 @override |
489 Iterator<TypeDefinition> get iterator => types.values.iterator; | 499 Iterator<TypeDefinition> get iterator => types.values.iterator; |
490 | 500 |
491 Iterable<String> get keys => types.keys; | 501 Iterable<String> get keys => types.keys; |
492 | 502 |
493 TypeDefinition operator [](String typeName) => types[typeName]; | 503 TypeDefinition operator [](String typeName) => types[typeName]; |
494 | 504 |
495 bool containsKey(String typeName) => types.containsKey(typeName); | 505 bool containsKey(String typeName) => types.containsKey(typeName); |
496 } | 506 } |
497 | 507 |
498 /** | 508 /** |
499 * Type which represents a union among multiple choices. | 509 * Type which represents a union among multiple choices. |
500 */ | 510 */ |
501 class TypeUnion extends TypeDecl { | 511 class TypeUnion extends TypeDecl { |
502 final List<TypeDecl> choices; | 512 final List<TypeDecl> choices; |
503 | 513 |
504 /** | 514 /** |
505 * The field that is used to disambiguate this union | 515 * The field that is used to disambiguate this union |
506 */ | 516 */ |
507 final String field; | 517 final String field; |
508 | 518 |
509 TypeUnion(this.choices, this.field, dom.Element html, {bool experimental}) | 519 TypeUnion(this.choices, this.field, dom.Element html, {bool experimental}) |
510 : super(html, experimental); | 520 : super(html, experimental, false); |
511 | 521 |
512 @override | 522 @override |
513 accept(ApiVisitor visitor) => visitor.visitTypeUnion(this); | 523 accept(ApiVisitor visitor) => visitor.visitTypeUnion(this); |
514 } | 524 } |
OLD | NEW |