Skip to content

Commit

Permalink
docs(ast): document more AST nodes (#6000)
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Sep 23, 2024
1 parent 1abfe8f commit 5a0d17c
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 40 deletions.
8 changes: 8 additions & 0 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,14 @@ pub enum VariableDeclarationKind {
AwaitUsing = 4,
}

/// A single variable declaration in a list of [variable declarations](VariableDeclaration).
///
/// ## Examples
/// ```ts
/// // declarators may or may not have initializers
/// let foo, b = 1;
/// // ^^^ id ^ init
/// ```
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
Expand Down
162 changes: 159 additions & 3 deletions crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,26 @@ pub struct TSInterfaceHeritage<'a> {
pub type_parameters: Option<Box<'a, TSTypeParameterInstantiation<'a>>>,
}

/// TypeScript Type Predicate
///
/// ## Examples
/// ```ts
/// function isString(x: unknown): x is string {
/// // parameter_name ^ ^^^^^^ type_annotation
/// return typeof x === 'string';
/// }
/// ```
///
/// ```ts
/// function assertString(x: unknown): asserts x is string {
/// // ^^^^^^^ asserts: true
/// if (typeof x !== 'string') throw new TypeError('x is not a string');
/// }
/// ```
///
/// ## References
/// * [TypeScript Handbook - Type Predicates](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates)
/// * [TypeScript Handbook - Assertion Functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions)
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
Expand All @@ -1255,7 +1275,14 @@ pub struct TSInterfaceHeritage<'a> {
pub struct TSTypePredicate<'a> {
#[serde(flatten)]
pub span: Span,
/// The identifier the predicate operates on
pub parameter_name: TSTypePredicateName<'a>,
/// Does this predicate include an `asserts` modifier?
///
/// ## Example
/// ```ts
/// declare function isString(x: any): asserts x is string; // true
/// ```
pub asserts: bool,
pub type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
}
Expand All @@ -1270,6 +1297,32 @@ pub enum TSTypePredicateName<'a> {
This(TSThisType) = 1,
}

/// TypeScript Module and Namespace Declarations
///
/// ## Examples
/// ```ts
/// declare module 'foo' {
/// // kind ^^^^^^ ^^^^^ id
/// }
/// ```
///
/// ```ts
/// namespace Foo { }
/// declare namespace Bar { }
/// ```
///
/// ```ts
/// declare global {
/// interface Window {
/// customProp: string;
/// }
/// }
/// ```
///
/// ## References
/// * [TypeScript Handbook - Namespaces](https://www.typescriptlang.org/docs/handbook/2/modules.html#namespaces)
/// * [TypeScript Handbook - Module Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation)
/// * [TypeScript Handbook - Global Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation)
#[ast(visit)]
#[scope(
flags(ScopeFlags::TsModuleBlock),
Expand All @@ -1285,8 +1338,12 @@ pub struct TSModuleDeclaration<'a> {
pub id: TSModuleDeclarationName<'a>,
#[scope(enter_before)]
pub body: Option<TSModuleDeclarationBody<'a>>,
/// The keyword used to define this module declaration
/// ```text
/// The keyword used to define this module declaration.
///
/// Helps discriminate between global overrides vs module declarations vs namespace
/// declarations.
///
/// ```ts
/// namespace Foo {}
/// ^^^^^^^^^
/// module 'foo' {}
Expand All @@ -1307,8 +1364,11 @@ pub struct TSModuleDeclaration<'a> {
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[serde(rename_all = "camelCase")]
pub enum TSModuleDeclarationKind {
/// `declare global {}`
Global = 0,
/// `declare module 'foo' {}`
Module = 1,
/// `namespace Foo {}`
Namespace = 2,
}

Expand All @@ -1326,6 +1386,26 @@ impl TSModuleDeclarationKind {
}
}

/// The name of a TypeScript [namespace or module declaration](TSModuleDeclaration).
///
/// Note that it is a syntax error for namespace declarations to have a string literal name.
/// Modules may have either kind.
///
/// ## Examples
/// ```ts
/// // TSModuleDeclarationName::StringLiteral
/// declare module "*.css" {
/// const styles: { [key: string]: string };
/// export default styles;
/// }
/// ```
///
/// ```ts
/// // TSModuleDeclarationName::Identifier
/// namespace Foo {
/// export const bar = 42;
/// }
/// ```
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
Expand Down Expand Up @@ -1461,7 +1541,8 @@ pub enum TSTypeQueryExprName<'a> {
pub struct TSImportType<'a> {
#[serde(flatten)]
pub span: Span,
pub is_type_of: bool, // `typeof import("foo")`
/// `true` for `typeof import("foo")`
pub is_type_of: bool,
pub parameter: TSType<'a>,
pub qualifier: Option<TSTypeName<'a>>,
pub attributes: Option<Box<'a, TSImportAttributes<'a>>>,
Expand Down Expand Up @@ -1556,6 +1637,27 @@ pub struct TSConstructorType<'a> {
pub type_parameters: Option<Box<'a, TSTypeParameterDeclaration<'a>>>,
}

/// TypeScript Mapped Type
///
/// ## Examples
/// ```ts
/// type Maybe<T> = {
/// // _____ constraint
/// [P in keyof T]?: T[P]
/// // ^ type_parameter
/// }
/// ```
///
/// ```ts
/// type ReadonlyDefinite<T> = {
/// // _ type parameter
/// readonly [P in keyof T]-?: T[P]
/// // ^^ `optional` modifier
/// };
/// ```
///
/// ## References
/// * [TypeScript Handbook - Mapped Types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html)
#[ast(visit)]
#[scope]
#[derive(Debug)]
Expand All @@ -1565,10 +1667,33 @@ pub struct TSConstructorType<'a> {
pub struct TSMappedType<'a> {
#[serde(flatten)]
pub span: Span,
/// Key type parameter, e.g. `P` in `[P in keyof T]`.
pub type_parameter: Box<'a, TSTypeParameter<'a>>,
pub name_type: Option<TSType<'a>>,
pub type_annotation: Option<TSType<'a>>,
/// Optional modifier on type annotation
///
/// ## Examples
/// ```ts
/// type Foo = { [P in keyof T]?: T[P] }
/// // ^^ True
/// type Bar = { [P in keyof T]+?: T[P] }
/// // ^^ Plus
/// type Baz = { [P in keyof T]-?: T[P] }
/// // ^^ Minus
/// type Qux = { [P in keyof T]: T[P] }
/// // ^ None
/// ```
pub optional: TSMappedTypeModifierOperator,
/// Readonly modifier before keyed index signature
///
/// ## Examples
/// ```ts
/// type Foo = { readonly [P in keyof T]: T[P] } // True
/// type Bar = { +readonly [P in keyof T]: T[P] } // Plus
/// type Baz = { -readonly [P in keyof T]: T[P] } // Minus
/// type Qux = { [P in keyof T]: T[P] } // None
/// ```
pub readonly: TSMappedTypeModifierOperator,
#[serde(skip)]
#[clone_in(default)]
Expand All @@ -1581,14 +1706,29 @@ pub struct TSMappedType<'a> {
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[serde(rename_all = "camelCase")]
pub enum TSMappedTypeModifierOperator {
/// e.g. `?` in `{ [P in K]?: T }`
True = 0,
/// e.g. `+?` in `{ [P in K]+?: T }`
#[serde(rename = "+")]
Plus = 1,
/// e.g. `-?` in `{ [P in K]-?: T }`
#[serde(rename = "-")]
Minus = 2,
/// No modifier present
None = 3,
}

/// TypeScript Template Literal Type
///
/// ## Example
/// ```ts
/// // Each string part is an element in `quasis`, including empty strings at the beginning/end.
/// // In this example, `quasis` has 3 elements: ["", ".", ""]
/// type Dot<T, U> = `${T}.${U}`;
/// ```
///
/// ## Reference
/// * [TypeScript Handbook - Template Literal Types](https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html#handbook-content)
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
Expand All @@ -1597,7 +1737,9 @@ pub enum TSMappedTypeModifierOperator {
pub struct TSTemplateLiteralType<'a> {
#[serde(flatten)]
pub span: Span,
/// The string parts of the template literal.
pub quasis: Vec<'a, TemplateElement<'a>>,
/// The interpolated expressions in the template literal.
pub types: Vec<'a, TSType<'a>>,
}

Expand All @@ -1613,6 +1755,18 @@ pub struct TSAsExpression<'a> {
pub type_annotation: TSType<'a>,
}

/// TypeScript `satisfies` Expression
///
/// ## Example
/// ```ts
/// const user = {
/// id: 0,
/// name: 'Alice',
/// } satisfies User;
/// ```
///
/// ## Reference
/// * [TypeScript Handbook - The `satisfies` Operator](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator)
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ContentHash)]
Expand All @@ -1621,7 +1775,9 @@ pub struct TSAsExpression<'a> {
pub struct TSSatisfiesExpression<'a> {
#[serde(flatten)]
pub span: Span,
/// The value expression being constrained.
pub expression: Expression<'a>,
/// The type `expression` must satisfy.
pub type_annotation: TSType<'a>,
}

Expand Down
Loading

0 comments on commit 5a0d17c

Please sign in to comment.