Skip to content

Latest commit

 

History

History
112 lines (95 loc) · 2.85 KB

custom-productions.md

File metadata and controls

112 lines (95 loc) · 2.85 KB

Custom productions

webidl2.js support custom productions for certain Web IDL implentations (e.g. Gecko) to take advantage of our rich feature set.

webidl2.write(ast, {
  productions: [...] // An array with custom production functions
});

The productions field lets the parser to call the production functions inside the array before calling the library's own ones. The API for such functions looks like the following:

declare function factory(
  tokeniser: Tokeniser
): {
  /* ... whatever fields you want to add for your custom object ... */

  write? (w: Writer) => any; // required only for webidl2.write()
};

The tokeniser object has the following form:

type TokenType =
  | "decimal"
  | "integer"
  | "identifier"
  | "string"
  | "whitespace"
  | "comment"
  | "other";

interface Tokeniser {
  /**
   * Current position.
   */
  position: number;

  /**
   * Tokenises
   */
  constructor(idl: string);
  /**
   * Throws WebIDLParseError at the current position.
   */
  error(message: string): never;
  /**
   * Checks whether a token exists without consuming it.
   */
  probeKind(type: TokenType): boolean;
  /**
   * Checks whether an inline token exists without consuming it.
   * @example `probe("interface")`
   */
  probe(value): boolean;
  /**
   * Consumes a token if exists, or returns null.
   * Pass multiple token types to consume one of them.
   */
  consumeKind(...candidates: TokenType[]);
  /**
   * Consumes an inline token if exists, or returns null.
   * Pass multiple token types to consume one of them.
   * @example `consume("getter", "setter", "deleter")`
   */
  consume(...candidates: string[]);
  /**
   * Consumes an identifier token that matches the value.
   * Use this when you need to consume a custom token.
   * @example `consumeIdentifier("legacycaller")`
   */
  consumeIdentifier(value: string);
  /**
   * Seeks to the position.
   */
  unconsume(position: number);
}

Using existing productions

This library exposes member productions in webidl2/productions. (Note that this only works with ES module import)

  • Argument
  • Attribute
  • Base
  • Constant
  • Constructor
  • Container
  • Default
  • ExtendedAttributes / SimpleExtendedAttribute
  • Field
  • IterableLike
  • Operation
  • Type

You can call Argument.parse(tokeniser) inside your custom production to reuse it.

It also exposes some helper functions:

  • autoParenter: This wraps your object in a proxy that assigns any object's parent field to this. Useful when tracking the parent of member productions.

    const ret = autoParenter(this);
    ret.default = Default.parse(tokeniser);
    default.parent // this
  • argument_list: Receives a tokeniser object and parses arguments separated by commas. Can be used to implement function-like syntax.

  • unescape: Trims preceding underscore _ if the string argument has one.