Skip to content

Commit 35f28a8

Browse files
committed
Update camelot to handle breaking changes between 4.14 and 5.4
1 parent d969a6e commit 35f28a8

8 files changed

Lines changed: 125 additions & 25 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
FROM alpine:3.20
2+
3+
RUN apk add --no-cache \
4+
bash \
5+
sudo \
6+
build-base \
7+
opam \
8+
m4 \
9+
pkgconfig \
10+
openssl-dev \
11+
libev-dev \
12+
linux-headers \
13+
git \
14+
curl
15+
16+
ARG USERNAME=vscode
17+
ARG USER_UID=1000
18+
ARG USER_GID=1000
19+
20+
RUN addgroup -g $USER_GID $USERNAME \
21+
&& adduser -u $USER_UID -G $USERNAME -D -s /bin/bash $USERNAME \
22+
&& echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
23+
24+
USER $USERNAME
25+
ENV HOME=/home/$USERNAME
26+
27+
RUN opam init --disable-sandboxing --shell-setup -y \
28+
&& opam switch create 5.4.1 ocaml-base-compiler.5.4.1 \
29+
&& eval $(opam env)
30+
31+
WORKDIR /workspaces/app
32+
COPY --chown=$USERNAME:$USERNAME *.opam dune-project* ./
33+
34+
# Install project deps and tools
35+
# TODO: this might not work properly
36+
RUN opam exec -- opam install . --deps-only -y \
37+
&& opam exec -- opam install ocaml-lsp-server dune utop -y
38+
39+
RUN echo 'eval $(opam env)' >> ~/.bashrc

.devcontainer/devcontainer.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/alpine
3+
{
4+
"name": "Camelot Alpine OCaml 5.4.1",
5+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6+
"dockerFile": "Dockerfile",
7+
8+
// Features to add to the dev container. More info: https://containers.dev/features.
9+
// "features": {},
10+
11+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
12+
// "forwardPorts": [],
13+
14+
// Use 'postCreateCommand' to run commands after the container is created.
15+
// "postCreateCommand": "uname -a",
16+
17+
// Configure tool-specific properties.
18+
"customizations": {
19+
"vscode": {
20+
"extensions": ["ocamllabs.ocaml-platform"]
21+
}
22+
},
23+
24+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
25+
"remoteUser": "vscode"
26+
}

camelot.opam

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is generated by dune, edit dune-project instead
22
opam-version: "2.0"
3-
version: "2.0.1"
3+
version: "2.1.0"
44
synopsis: "An OCaml Linter / Style Checker"
55
maintainer: ["William Goeller <william@williamgoeller.com>"]
66
authors: ["Vighnesh Vijay" "Daniel Like" "William Goeller"]
@@ -9,11 +9,11 @@ homepage: "https://github.com/upenn-cis1xx/camelot"
99
bug-reports: "https://github.com/upenn-cis1xx/camelot/issues"
1010
depends: [
1111
"dune" {>= "2.5"}
12-
"ocaml" {>= "4.13.0" & < "4.14.0"}
12+
"ocaml" {>= "5.4.1" & < "5.5.0"}
1313
"ANSITerminal" {>= "0.8"}
1414
"yojson" {>= "1.7.0"}
1515
"camlp-streams" {>= "5.0.1"}
16-
"ppx_expect" {with-test & <= "v0.15.1"}
16+
"ppx_expect" {with-test & >= "v0.17.3"}
1717
"odoc" {with-doc & >= "1.5.0"}
1818
]
1919
dev-repo: "git+https://github.com/upenn-cis1xx/camelot.git"

dune-project

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
(name camelot)
33
(generate_opam_files true)
44

5-
(version 2.0.1)
5+
(version 2.1.0)
66

77
(source (github upenn-cis1xx/camelot))
88
(license "Apache-2.0")
@@ -14,11 +14,11 @@
1414
(synopsis "An OCaml Linter / Style Checker")
1515
(depends
1616
(dune (>= 2.5))
17-
(ocaml (and (>= 4.13.0) (< 4.14.0)))
17+
(ocaml (and (>= 5.4.1) (< 5.5.0)))
1818
(ANSITerminal (>= 0.8))
1919
(yojson (>= 1.7.0))
2020
(camlp-streams (>= 5.0.1))
21-
(ppx_expect (and :with-test (<= v0.15.1)))
21+
(ppx_expect (and :with-test (>= v0.17.3)))
2222
(odoc (and :with-doc (>= 1.5.0)))
2323
)
2424
)

lib/style/match.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ let make_check (pred: Parsetree.pattern -> bool) gen_error override_len enable_u
1212

1313
let rec unwrap_tuple (p : Parsetree.pattern) : Parsetree.pattern list =
1414
begin match p.ppat_desc with
15-
| Ppat_tuple pat_list -> List.concat_map unwrap_tuple pat_list
15+
| Ppat_tuple (pat_list, _) -> List.concat_map (fun (_, pat) -> unwrap_tuple pat) pat_list
1616
| _ -> [p]
1717
end
1818
in
@@ -96,7 +96,7 @@ module MatchListVerbose : EXPRCHECK = struct
9696
begin match pat.ppat_desc with
9797
| Ppat_construct ({txt = Lident "::";_}, Some (_, matchcase)) ->
9898
begin match matchcase.ppat_desc with
99-
| Ppat_tuple ([_; cons_case]) -> is_pat_constr cons_case "[]"
99+
| Ppat_tuple ([_; (_, cons_case)], _) -> is_pat_constr cons_case "[]"
100100
| _ -> false
101101
end
102102
| _ -> false

lib/traverse/descent.ml

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ module T = struct
4949
| Ptyp_var _ -> ()
5050
| Ptyp_arrow (_lab, t1, t2) ->
5151
sub.typ sub t1; sub.typ sub t2
52-
| Ptyp_tuple tyl -> List.iter (sub.typ sub) tyl
52+
(* Unpack the label tuple for 5.4.1 *)
53+
| Ptyp_tuple tyl ->
54+
List.iter (fun (_, t) -> sub.typ sub t) tyl
5355
| Ptyp_constr (lid, tl) ->
5456
iter_loc sub lid; List.iter (sub.typ sub) tl
5557
| Ptyp_object (ol, _o) ->
@@ -60,10 +62,13 @@ module T = struct
6062
| Ptyp_variant (rl, _b, _ll) ->
6163
List.iter (row_field sub) rl
6264
| Ptyp_poly (_, t) -> sub.typ sub t
63-
| Ptyp_package (lid, l) ->
65+
(* Unpack the new package_type record for 5.4.1 *)
66+
| Ptyp_package { ppt_path = lid; ppt_cstrs = l; _ } ->
6467
iter_loc sub lid;
6568
List.iter (iter_tuple (iter_loc sub) (sub.typ sub)) l
6669
| Ptyp_extension x -> sub.extension sub x
70+
| Ptyp_open (lid, t) ->
71+
iter_loc sub lid; sub.typ sub t
6772

6873
let iter_type_declaration sub
6974
{ptype_name; ptype_params; ptype_cstrs;
@@ -113,7 +118,7 @@ module T = struct
113118
sub.attributes sub ptyexn_attributes
114119

115120
let iter_extension_constructor_kind sub = function
116-
Pext_decl(ctl, cto) ->
121+
Pext_decl(_, ctl, cto) ->
117122
iter_constructor_arguments sub ctl; iter_opt (sub.typ sub) cto
118123
| Pext_rebind li ->
119124
iter_loc sub li
@@ -244,6 +249,7 @@ module M = struct
244249
sub.module_expr sub body
245250
| Pmod_apply (m1, m2) ->
246251
sub.module_expr sub m1; sub.module_expr sub m2
252+
| Pmod_apply_unit m -> sub.module_expr sub m
247253
| Pmod_constraint (m, mty) ->
248254
sub.module_expr sub m; sub.module_type sub mty
249255
| Pmod_unpack e -> sub.expr sub e
@@ -284,17 +290,35 @@ module E = struct
284290
| Pexp_let (_r, vbs, e) ->
285291
List.iter (sub.value_binding sub) vbs;
286292
sub.expr sub e
287-
| Pexp_fun (_lab, def, p, e) ->
288-
iter_opt (sub.expr sub) def;
289-
sub.pat sub p;
290-
sub.expr sub e
291-
| Pexp_function pel -> sub.cases sub pel
293+
(* Handle consolidated Pexp_function in >=5.2 *)
294+
| Pexp_function (params, constraint_opt, body) ->
295+
List.iter
296+
(fun param ->
297+
match param.pparam_desc with
298+
| Pparam_val (_lab, def, p) ->
299+
iter_opt (sub.expr sub) def;
300+
sub.pat sub p
301+
| Pparam_newtype _ -> ()
302+
) params;
303+
304+
begin match constraint_opt with
305+
| Some (Pconstraint ty) -> sub.typ sub ty
306+
| Some (Pcoerce (ty1_opt, ty2)) ->
307+
iter_opt (sub.typ sub) ty1_opt;
308+
sub.typ sub ty2
309+
| None -> ()
310+
end;
311+
312+
begin match body with
313+
| Pfunction_body e -> sub.expr sub e
314+
| Pfunction_cases (cases, _loc, _attrs) -> sub.cases sub cases
315+
end
292316
| Pexp_apply (e, l) ->
293317
sub.expr sub e; List.iter (iter_snd (sub.expr sub)) l
294318
| Pexp_match (e, pel) ->
295319
sub.expr sub e; sub.cases sub pel
296320
| Pexp_try (e, pel) -> sub.expr sub e; sub.cases sub pel
297-
| Pexp_tuple el -> List.iter (sub.expr sub) el
321+
| Pexp_tuple el -> List.iter (fun (_, pat) -> (sub.expr sub pat)) el
298322
| Pexp_construct (lid, arg) ->
299323
iter_loc sub lid; iter_opt (sub.expr sub) arg
300324
| Pexp_variant (_lab, eo) ->
@@ -341,7 +365,15 @@ module E = struct
341365
sub.expr sub e; iter_opt (sub.typ sub) t
342366
| Pexp_object cls -> sub.class_structure sub cls
343367
| Pexp_newtype (_s, e) -> sub.expr sub e
344-
| Pexp_pack me -> sub.module_expr sub me
368+
| Pexp_pack (me, pt_opt) ->
369+
sub.module_expr sub me;
370+
(* Unpack and traverse the optional package_type record *)
371+
begin match pt_opt with
372+
| Some { ppt_path = lid; ppt_cstrs = l; _ } ->
373+
iter_loc sub lid;
374+
List.iter (iter_tuple (iter_loc sub) (sub.typ sub)) l
375+
| None -> ()
376+
end
345377
| Pexp_open (o, e) ->
346378
sub.open_declaration sub o; sub.expr sub e
347379
| Pexp_letop {let_; ands; body} ->
@@ -371,7 +403,7 @@ module P = struct
371403
| Ppat_alias (p, s) -> sub.pat sub p; iter_loc sub s
372404
| Ppat_constant _ -> ()
373405
| Ppat_interval _ -> ()
374-
| Ppat_tuple pl -> List.iter (sub.pat sub) pl
406+
| Ppat_tuple (pl, _) -> List.iter (fun (_, pat) -> sub.pat sub pat) pl
375407
| Ppat_construct (l, p) ->
376408
iter_loc sub l; iter_opt (sub.pat sub) (Option.map snd p)
377409
| Ppat_variant (_l, p) -> iter_opt (sub.pat sub) p
@@ -388,6 +420,7 @@ module P = struct
388420
| Ppat_extension x -> sub.extension sub x
389421
| Ppat_open (lid, p) ->
390422
iter_loc sub lid; sub.pat sub p
423+
| Ppat_effect (p1, p2) -> sub.pat sub p1; sub.pat sub p2
391424

392425
end
393426

lib/utils/astutils.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ let is_singleton_list : exp -> bool = fun e ->
6262
begin match e.pexp_desc with
6363
| Pexp_construct ({txt = Lident "::";_}, Some cons) ->
6464
begin match cons.pexp_desc with
65-
| Pexp_tuple [e_id; e_empty] ->
65+
| Pexp_tuple [(_, e_id); (_, e_empty)] ->
6666
(is_exp_const e_id || is_exp_id e_id) && e_empty =| "[]"
6767
| _ -> false
6868
end
@@ -109,7 +109,7 @@ let binding_of_lcase (case: Parsetree.case) : string =
109109
begin match case.pc_lhs.ppat_desc with
110110
| Ppat_construct ({txt = Lident "::"; loc = _}, Some (_, bound)) ->
111111
begin match bound.ppat_desc with
112-
| Ppat_tuple [_; tail] ->
112+
| Ppat_tuple ([_; (_, tail)], _) ->
113113
begin match tail.ppat_desc with
114114
| Ppat_var {txt = t; loc = _} -> t
115115
| _ -> ""
@@ -124,7 +124,7 @@ let uses_func_recursively_list (case: Parsetree.case) func_name tail_binding : b
124124
| Pexp_construct ({txt = Lident "::"; loc = _},
125125
Some bound) ->
126126
begin match bound.pexp_desc with
127-
| Pexp_tuple ([_; tl]) ->
127+
| Pexp_tuple ([_; (_, tl)]) ->
128128
begin match tl.pexp_desc with
129129
| Pexp_apply (func, args) ->
130130
func =~ func_name &&
@@ -161,7 +161,7 @@ let uses_func_recursively_list_any (case: Parsetree.case) func_name tail_binding
161161
let rec body_of_fun (exp: Parsetree.expression) : Parsetree.expression =
162162
let skipped = skip_seq_let exp in
163163
begin match skipped.pexp_desc with
164-
| Pexp_fun (_, _, _, e) -> e |> skip_seq_let |> body_of_fun
164+
| Pexp_function (_, _, Pfunction_body e) -> e |> skip_seq_let |> body_of_fun
165165
| _ -> skipped
166166
end
167167

lib/utils/expeq.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ and exp_desc_eq (el: Parsetree.expression_desc) (er: Parsetree.expression_desc)
1515
| Pexp_apply (el,largs), Pexp_apply (er, rargs) ->
1616
exp_eq el er &&
1717
List.for_all2 (fun (_, l) (_, r) -> exp_eq l r ) largs rargs
18-
| Pexp_tuple ls, Pexp_tuple rs -> List.for_all2 (exp_eq) ls rs
18+
| Pexp_tuple ls, Pexp_tuple rs ->
19+
List.for_all2 (fun (_, l_exp) (_, r_exp) -> exp_eq l_exp r_exp) ls rs (* Handle labeled tuples*)
1920
| Pexp_construct ({txt = Lident l; _}, None), Pexp_construct ({txt = Lident r; _}, None) ->
2021
l = r
2122
| Pexp_construct ({txt = Lident l; _}, Some el), Pexp_construct ({txt = Lident r; _}, Some er) ->
@@ -29,4 +30,5 @@ and value_binding_eq (el: Parsetree.value_binding) (er: Parsetree.value_binding)
2930
and pat_eq (_el: Parsetree.pattern) (_er: Parsetree.pattern) =
3031
false
3132

32-
and const_eq (el: Parsetree.constant) (er: Parsetree.constant) = el = er
33+
and const_eq (c : Parsetree.constant) (d : Parsetree.constant) =
34+
c.pconst_desc = d.pconst_desc

0 commit comments

Comments
 (0)