| 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 |