-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use OMP2 + ppxlib instead of OMP1 (#1482)
Closes #1460 The most visible API change is that `Ast_mapper` (record-based) is replaced by `Ppxlib.Ast_traverse` (object-based). The port is mostly mechanical, replacing fields by methods and `default_mapper` by `super`. Ppxlib has more hooks so it is possible to override `location_stack` in one go for example. OMP (like compiler-libs) provides two ways to print ASTs: `Pprintast` outputs concrete syntax (`let x = 1 in x`) and is provided by ppxlib. `Printast` outputs a form closer to the `Parsetree` representation (`Pexp_let (Ppat_var "x", Pexp_const 1, Pexp_var "x"`), but ppxlib does not provide that. It exposes a s-expression converter, so we use that instead. This is only used in debug messages. `Location` is used for two different things: the type and relative functions are used by ocamlformat as a whole. In ppxlib, the API is slightly different, so there are minor changes. `Location.input_name` however is used by the parser, so we need to refer to the one in compiler libs as `Ocaml_common.Location.input_name`. `parse-wyc` is a special case because it uses a 4.08 parser, so it produces a 4.08 AST. The library is split in two between the parser and associated modules that operate on the 4.08 and the rest that uses the ppxlib AST. The modified parser inserts generated nodes in places that would correspond to parse errors. For example, if it determines that some sequence of tokens can only form an expression (but it's missing some tokens to do so in a valid way), it will emit `[%merlin.hole]` as an expression. Later, an AST mapper walks the AST and needs to determine if an expression is generated or not. This is simple with OMP, but with ppxlib we use two different AST versions: the parser uses 4.08 (from OMP) and the mapper uses 4.11 (at the time; more generally, the one ppxlib uses). So in the Annot module, the mk functions return a 4.08 AST (they are called by the parser), but the is_generated functions expect a 4.11 one (they are called by a mapper after migration).
- Loading branch information
Showing
18 changed files
with
459 additions
and
542 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
(**************************************************************************) | ||
(* *) | ||
(* OCamlFormat *) | ||
(* *) | ||
(* Copyright (c) Facebook, Inc. and its affiliates. *) | ||
(* *) | ||
(* This source code is licensed under the MIT license found in *) | ||
(* the LICENSE file in the root directory of this source tree. *) | ||
(* *) | ||
(**************************************************************************) | ||
|
||
open Migrate_ast | ||
open Parsetree | ||
include Non_overlapping_interval_tree.Make (Location) | ||
|
||
(** Use Ast_mapper to collect all locs in ast, and create tree of them. *) | ||
let of_ast fragment ast src = | ||
let locs = ref [] in | ||
let add_loc loc = locs := loc :: !locs in | ||
let mapper = | ||
object | ||
inherit Ppxlib.Ast_traverse.map as super | ||
|
||
method! location loc = add_loc loc ; loc | ||
|
||
method! pattern p = | ||
( match p.ppat_desc with | ||
| Ppat_record (flds, Open) -> | ||
Option.iter | ||
(Source.loc_of_underscore src flds p.ppat_loc) | ||
~f:add_loc | ||
| _ -> () ) ; | ||
super#pattern p | ||
|
||
method! attribute attr = | ||
(* ignore location of docstrings *) | ||
if Ast.Attr.is_doc attr then attr else super#attribute attr | ||
|
||
(** Ast_traverse recurses down to locations in stacks *) | ||
method! location_stack l = l | ||
|
||
method! expression e = | ||
( match e.pexp_desc with | ||
| Pexp_constant _ -> | ||
locs := Source.loc_of_expr_constant src e :: !locs | ||
| _ -> () ) ; | ||
super#expression e | ||
end | ||
in | ||
Mapper.map_ast fragment mapper ast |> ignore ; | ||
(of_list !locs, !locs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.