package ppxlib_jane

  1. Overview
  2. Docs

Module type Jane_syntax.ASTSource

The module type of our extended ASTs for our novel syntax, instantiated once for each syntactic category. We tend to call the pattern-matching functions here with unusual indentation, not indenting the None branch further so as to avoid merge conflicts with upstream.

type t

The AST for all our Jane Street syntax; one constructor per feature that extends the given syntactic category. Some extensions are handled separately and thus are not listed here.

This type will be something like jane_syntax_ast * Parsetree.attributes in cases where the Jane Syntax encoding of the AST uses attributes. In these cases, the Parsetree.attributes are the *rest* of the attributes after removing Jane Syntax-related attributes. Callers of of_ast should refer to these attributes rather than, for example, pexp_attributes.

type ast

The corresponding OCaml AST

val of_ast : ast -> t option

Given an OCaml AST node, check to see if it corresponds to an embedded term from our novel syntax. If it does, as long as the feature isn't a disabled language extension, then return it; if it's not a piece of novel syntax, return None; if it's an embedded term from a disabled language extension, raise an error.

AN IMPORTANT NOTE: The design of this function is careful to make merge conflicts with upstream less likely: we want no edits at all -- not even indentation -- to surrounding code. This is why we return a t option, not some structure that could include the ast_desc if there is no extension.

Indentation: we *do not change the indentation level* when we match on this function's result! E.g. from type_expect_ in typecore.ml:

  match Jane_syntax.Expression.of_ast sexp with
  | Some jexp ->
      type_expect_jane_syntax
        ~loc
        ~env
        ~expected_mode
        ~ty_expected
        ~explanation
        ~attributes:sexp.pexp_attributes
        jexp
  | None      -> match sexp.pexp_desc with
  | Pexp_ident lid ->
      let path, mode, desc, kind = type_ident env ~recarg lid in
      (* ... *)
  | Pexp_constant(Pconst_string (str, _, _) as cst) ->
      register_allocation expected_mode;
      (* ... *)
  | (* ... *)
  | Pexp_unreachable ->
      re { exp_desc = Texp_unreachable;
           exp_loc = loc; exp_extra = [];
           exp_type = instance ty_expected;
           exp_mode = expected_mode.mode;
           exp_attributes = sexp.pexp_attributes;
           exp_env = env }

Note that we match on the result of this function, forward to type_expect_jane_syntax if we get something, and otherwise do the real match on sexp.pexp_desc *without going up an indentation level*. This is important to reduce the number of merge conflicts.