Skip to content

Latest commit

 

History

History
403 lines (302 loc) · 12.9 KB

README.md

File metadata and controls

403 lines (302 loc) · 12.9 KB

docast

github release npm module type: esm license conventional commits typescript vitest yarn

Docblock Abstract Syntax Tree.


docast is a specification for representing docblock comments as abstract syntax trees.

It implements the unist spec.

Contents

Introduction

This document defines a format for representing docblock comments as abstract syntax trees. Development of docast started in October 2022. This specification is written in a TypeScript-like grammar.

Where this specification fits

docast extends unist, a format for syntax trees, to benefit from its ecosystem of utilities. It also integrates with mdast, a specification for representing markdown.

docast relates to JavaScript and TypeScript in that both languages support docblock comments. docast is language-agnostic, however, and can be used with any programming language that supports docblock comments.

docast relates to JSDoc, TSDoc, and typedoc in that these tools parse docblock comments. These tools also have a limited set of tags that developers are allowed to use. If developers already have a set of tags they're using, they must spend additional time re-configuring those tags for their chosen tool. docast does not enforce any tag semantics — the user does. Tag specifications can be left to an ESLint rule, or a setting akin to jsdoc/check-tag-names or jsdoc.structuredTags.

Types

TypeScript users can integrate docast type definitions into their project by installing the appropriate packages:

yarn add @flex-development/docast

Nodes (abstract)

Node

interface Node extends unist.Node {}

Node (unist.Node) is a syntactic unit in docast syntax trees.

Literal

interface Literal extends Node {
  value: bigint | boolean | number | string | null | undefined
}

Literal represents an abstract interface in docast containing the smallest possible value.

Parent

interface Parent extends unist.Parent {
  children: Child[]
}

Parent (unist.Parent) represents an abstract interface in docast containing other nodes (said to be children).

Its content is limited to docast content and mdast content.

Nodes

BlockTag

interface BlockTag extends Parent, Tag {
  children:
    | Exclude<BlockTagContent, TypeMetadata>[]
    | [TypeMetadata, ...Exclude<BlockTagContent, TypeMetadata>[]]
  data?: BlockTagData | undefined
  type: 'blockTag'
}

BlockTag (Parent) represents top-level metadata.

Block tags should be the only element on their line, except in cases where special meaning is assigned to succeeding text. All text following a block tag name, up until the start of the next block tag name, or comment closer (*/), is considered to be the block tag's tag content.

BlockTag can be used in comment nodes. Its content model is block tag content.

Comment

interface Comment extends Parent {
  children:
    | Exclude<FlowContent, Description>[]
    | [summary: Description, ...Exclude<FlowContent, Description>[]]
  code?: CodeSegment | null | undefined
  data?: CommentData | undefined
  type: 'comment'
}

Comment (Parent) represents a docblock comment in a source file.

The code field represents the segment of code documented by a comment. The value of the code field may be null, undefined, or implement the CodeSegment interface. The code field must not be present if a comment is used only to provide additional information.

Comment can be used in root nodes. Its content model is flow content.

CodeSegment

interface CodeSegment {
  position: unist.Position
  type: string
}

CodeSegment represents the code segment in a file that is documented by a comment.

The value of the type field is the node type of the code segment.

Description

interface Description extends Parent {
  children: DescriptionContent[]
  data?: DescriptionData | undefined
  type: 'description'
}

Description (Parent) represents the text of a comment. It is located at the start of a comment, before any block tags, and may contain Markdown content.

Description can be used in comment nodes. Its content model is description.

InlineTag

interface InlineTag extends Literal, Tag {
  data?: InlineTagData | undefined
  type: 'inlineTag'
  value: string
}

InlineTag (Literal) represents inline metadata.

Inline tags are denoted by wrapping a tag name and any tag content in angle brackets ({ and }).

InlineTag can be used in block tag and description nodes. It cannot contain any children — it is a leaf.

Root

interface Root extends Parent {
  children: Comment[]
  data?: RootData | undefined
  type: 'root'
}

Root (Parent) represents a document.

Root can be used as the root of a tree, never as a child. It can contain comment nodes.

TypeMetadata

interface TypeMetadata extends Parent {
  children: TypeExpression[]
  data?: TypeMetadataData | undefined
  raw: string
  type: 'typeMetadata'
}

TypeMetadata (Parent) represents an inlined type expression (e.g. {number}).

TypeMetadata can be used in block tag nodes. Its content model is type expresssion.

A raw field must be present. Its value is the raw type expression (e.g. number).

Mixins

Tag

interface Tag {
  name: TagName
}

Tag represents metadata associated with a comment.

The name field represents the tag name. Tag names start with an at-sign (@) and may contain any ASCII letter after the at-sign.

TagName

type TagName<T extends string = string> = `@${T}`

Content model

type Content = BlockTagContent | DescriptionContent | FlowContent | PhrasingContent

Nodes are grouped by content type, if applicable. Each node in docast, with the exception of Comment, falls into one or more categories of Content.

BlockTagContent

type BlockTagContent = PhrasingContent | TypeMetadata

Block content represents block tag text, and its markup.

DescriptionContent

type DescriptionContent =
  | mdast.Blockquote
  | mdast.Definition
  | mdast.FootnoteDefinition
  | mdast.List
  | mdast.ListItem
  | mdast.Paragraph
  | mdast.Table
  | mdast.ThematicBreak
  | PhrasingContent

Description content represents description text, and its markup.

FlowContent

type FlowContent = BlockTag | Description

Flow content represents the sections of comment.

PhrasingContent

type PhrasingContent = InlineTag | mdast.Code | mdast.PhrasingContent

Phrasing content represents comment text, and its markup.

TypeExpression

type TypeExpression = TypeExpressionMap[keyof TypeExpressionMap]

TypeExpression content is a type expression.

When developing type expression parsers compatible with docast, the TypeExpressionMap map should be augmented (and exported! 😉) to register custom nodes:

declare module '@flex-development/docast' {
  interface TypeExpressionMap {
    arrayType: ArrayType
    assertionPredicate: AssertionPredicate
    bigint: BigIntLiteral
    boolean: BooleanLiteral
    conditionalType: ConditionalType
    constructorType: ConstructorType
    functionType: FunctionType
    genericType: GenericType
    identifier: Identifier
    inferType: InferType
    intersectionType: IntersectionType
    nonNullableType: NonNullableType
    null: NullLiteral
    nullableType: NullableType
    number: NumberLiteral
    objectLiteralType: ObjectLiteralType
    optionalType: OptionalType
    parenthesizedType: ParenthesizedType
    propertyAccessType: PropertyAccessType
    string: StringLiteral
    super: Super
    templateLiteral: TemplateLiteral
    this: This
    tupleType: TupleType
    typeOperation: TypeOperation
    typePredicate: TypePredicate
    typeSymbol: TypeSymbol
    undefined: UndefinedLiteral
    unionType: UnionType
    variadicType: VariadicType
  }
}

Glossary

See the unist glossary for more terms.

Docblock comment

A specially formatted comment in a source file used to document a segment of code or provide additional information.

Tag content

Any text following a block tag name (e.g. @example, @param), up until the start of the next block tag or comment closer (*/), or any text following an inline tag name, up until the closing punctuator (}).

List of utilities

See the unist list of utilities for more utilities.

Contribute

See CONTRIBUTING.md.

Ideas for new utilities and tools can be posted in docast/ideas.

This project has a code of conduct. By interacting with this repository, organization, or community you agree to abide by its terms.