Skip to content
This repository has been archived by the owner on Oct 18, 2018. It is now read-only.

WIP: Port to OMP #25

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ env:
- OCAML_VERSION=4.02.3
- OCAML_VERSION=4.03.0
- OCAML_VERSION=4.04.2
- OCAML_VERSION=4.05.0
- OCAML_VERSION=4.06.0
17 changes: 0 additions & 17 deletions 4.02/compat.ml

This file was deleted.

17 changes: 0 additions & 17 deletions 4.03/compat.ml

This file was deleted.

17 changes: 0 additions & 17 deletions 4.04/compat.ml

This file was deleted.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ How to configure ocamllint
Similarly to how `ocamlbuild` works, it is necessary to write a plugin to modify
the configuration. It is a dynamically-linked file from which one has to call
`Ocamllint.Plugin.set_config`. The `example_plugin.ml` file is, well, an
example. This plugin disables a warning. It can be built using `make example`.
example. This plugin disables a warning.

When the ppx rewriter is loaded without an argument, it will use a default
configuration:

```
% ocamlfind ppx_tools/rewriter -ppx "ocamlfind ocamllint/ppx_lint.native" -str
% ocamlfind ppx_tools/rewriter -ppx "ocamlfind ocamllint/ppx_lint --as-ppx" -str
'let y = []@[] in let x = 3 in x'
File "", line 1, characters 17-31:
(ocamllint) Useless let binding
Expand All @@ -91,8 +91,8 @@ let _ = let y = [] @ [] in let x = 3 in x
If you pass an option to the rewriter, it will load the configuration:

```
% ocamlfind ppx_tools/rewriter -ppx "ocamlfind ocamllint/ppx_lint.native
_build/example_plugin.cmxs" -str 'let y = []@[] in let x = 3 in x'
% ocamlfind ppx_tools/rewriter -ppx "ocamlfind ocamllint/ppx_lint --as-ppx
--plugin _build/example_plugin.cmxs" -str 'let y = []@[] in let x = 3 in x'
File "", line 1, characters 8-13:
(ocamllint) List operation on litteral: @
let _ = let y = [] @ [] in let x = 3 in x
Expand Down
6 changes: 4 additions & 2 deletions _tags
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
true: package(compiler-libs.common)
true: package(ppx_tools.metaquot)
true: bin_annot
true: package(ocaml-migrate-parsetree)
true: package(ppx_tools_versioned.metaquot_404)
true: package(ppx_tools_versioned)
true: package(str)
"lib": include
<ppx/*>: package(dynlink)
Expand Down
22 changes: 18 additions & 4 deletions lib/ast_tools.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
open Asttypes
open Parsetree
open Migrate_parsetree.Ast_404.Asttypes
open Migrate_parsetree.Ast_404.Parsetree

let rec li_eq li1 li2 =
let open Longident in
Expand Down Expand Up @@ -39,7 +39,7 @@ and expr_list_eq el1 el2 =
with Invalid_argument _ -> false

and label_eq l1 l2 =
let open Ast_convenience.Label in
let open Ppx_tools_404.Ast_convenience.Label in
match explode l1, explode l2 with
| Nolabel, Nolabel -> true
| Labelled s1, Labelled s2
Expand All @@ -54,4 +54,18 @@ and expr_label_list_eq el1 el2 =
List.for_all2 expr_label_eq el1 el2
with Invalid_argument _ -> false

let sigitem_attributes = Compat.sigitem_attributes
let sigitem_attributes { psig_desc } =
match psig_desc with
| Psig_value vd -> [vd.pval_attributes]
| Psig_type (_, tdecls) -> List.map (fun tdecl -> tdecl.ptype_attributes) tdecls
| Psig_typext text -> [text.ptyext_attributes]
| Psig_exception exc -> [exc.pext_attributes]
| Psig_module md -> [md.pmd_attributes]
| Psig_recmodule mds -> List.map (fun md -> md.pmd_attributes) mds
| Psig_modtype pmtd -> [pmtd.pmtd_attributes]
| Psig_open popen -> [popen.popen_attributes]
| Psig_include pincl -> [pincl.pincl_attributes]
| Psig_class pcis
| Psig_class_type pcis -> List.map (fun pct -> pct.pci_attributes) pcis
| Psig_attribute attribute -> [[attribute]]
| Psig_extension (_, attributes) -> [attributes]
4 changes: 2 additions & 2 deletions lib/ast_tools.mli
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
val expr_eq : Parsetree.expression -> Parsetree.expression -> bool
val expr_eq : Migrate_parsetree.Ast_404.Parsetree.expression -> Migrate_parsetree.Ast_404.Parsetree.expression -> bool

(**
Return all attributes for a signature item.
In some cases (e.g. recursive type declarations) there can be several ones.
*)
val sigitem_attributes : Parsetree.signature_item -> Parsetree.attributes list
val sigitem_attributes : Migrate_parsetree.Ast_404.Parsetree.signature_item -> Migrate_parsetree.Ast_404.Parsetree.attributes list
4 changes: 4 additions & 0 deletions lib/ocamllint.mllib
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
Ocamllint
Ocamllint_config
Ocamllint_context
Ocamllint_plugin
Ocamllint_warning
8 changes: 4 additions & 4 deletions lib/ocamllint_rules.ml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
open Ast_tools
open Asttypes
open Parsetree
open Migrate_parsetree.Ast_404.Asttypes
open Migrate_parsetree.Ast_404.Parsetree

(** Allocated litterals *)
let is_allocated_lit exp =
match exp.pexp_desc with
| Pexp_constant _ ->
begin
match Ast_convenience.get_str exp with
match Ppx_tools_404.Ast_convenience.get_str exp with
| Some _ -> true
| None -> false
end
Expand Down Expand Up @@ -229,7 +229,7 @@ let filter_rev_map : type a b . (a -> b option) -> a list -> b list
go []

let extract_ocaml_doc attributes =
let open Ast_convenience in
let open Ppx_tools_404.Ast_convenience in
match find_attr_expr "ocaml.doc" attributes with
| Some e -> get_str e
| None -> None
Expand Down
4 changes: 2 additions & 2 deletions lib/ocamllint_rules.mli
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
val rate_expression : Parsetree.expression -> Ocamllint.Warning.t option
val rate_expression : Migrate_parsetree.Ast_404.Parsetree.expression -> Ocamllint.Warning.t option

val rate_module_name : string -> Ocamllint.Warning.t option

val rate_module_type_name : string -> Ocamllint.Warning.t option

val rate_signature_item : Parsetree.signature_item -> Ocamllint.Warning.t option
val rate_signature_item : Migrate_parsetree.Ast_404.Parsetree.signature_item -> Ocamllint.Warning.t option

val is_snake_case : string -> bool
17 changes: 0 additions & 17 deletions myocamlbuild.ml

This file was deleted.

2 changes: 1 addition & 1 deletion opam
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ depends: [
"ocamlbuild" {build}
"topkg" {build}
"ounit" {test}
"ppx_tools" {>= "5.0"}
"ppx_tools_versioned" {>= "5.0"}
]
available: [ocaml-version >= "4.02.0"]
2 changes: 1 addition & 1 deletion pkg/META
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ requires = "compiler-libs.common,ppx_tools.metaquot"
package "ppx" (
description = "Run ocamllint through a ppx"
requires = "ocamllint"
ppx = "./ppx_lint"
ppx = "./ppx_lint --as-ppx"
)
58 changes: 44 additions & 14 deletions ppx/ppx_lint.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
open Ast_mapper
open Asttypes
open Parsetree
open Migrate_parsetree.Ast_404.Ast_mapper
open Migrate_parsetree.Ast_404.Asttypes
open Migrate_parsetree.Ast_404.Parsetree

module Config : sig
val reset_args : unit -> unit

val args : (Arg.key * Arg.spec * Arg.doc) list

val plugin : unit -> string option
end = struct
let plugin_ref = ref None

let set_plugin s =
plugin_ref := Some s

let plugin () =
!plugin_ref

let reset_args () =
plugin_ref := None

let args =
[ ("--plugin", Arg.String set_plugin, "Load plugin")
]
end

let raise_errorf ?sub ?if_highlight ?loc message =
message |> Printf.kprintf (fun str ->
Expand All @@ -12,8 +35,7 @@ let dynlink ?(loc=Location.none) filename =
try
Dynlink.loadfile filename
with Dynlink.Error error ->
raise_errorf ~loc "Cannot load %s: %s" filename (Dynlink.error_message error)

raise_errorf ~loc "Cannot load %s: %s" filename (Dynlink.error_message error)
let load_config filename =
dynlink filename;
Ocamllint.Plugin.get_config ()
Expand Down Expand Up @@ -48,19 +70,18 @@ let handle_signature_item config sigitem =
let loc = sigitem.psig_loc in
warn_on config ~loc (Ocamllint_rules.rate_signature_item sigitem)

let should_run () =
match tool_name () with
let should_run {Migrate_parsetree.Driver.tool_name} =
match tool_name with
| "ocamlc" -> true
| "ocamlopt" -> true
| _ -> false

let lint_mapper argv =
let config = match argv with
| [] -> Ocamllint.Config.default
| [config_module] -> load_config config_module
| _ -> raise_errorf "Only one plugin can be loaded"
let lint_mapper driver_config _ =
let config = match Config.plugin () with
| None -> Ocamllint.Config.default
| Some config_module -> load_config config_module
in
if should_run () then
if should_run driver_config then
{ default_mapper with
expr = (fun mapper expr ->
handle config expr;
Expand All @@ -78,4 +99,13 @@ let lint_mapper argv =
else
default_mapper

let () = register "lint" lint_mapper
let main () =
Migrate_parsetree.Driver.register
~name:"lint"
~reset_args:Config.reset_args
~args:Config.args
Migrate_parsetree.Versions.ocaml_404
lint_mapper;
Migrate_parsetree.Driver.run_main ()

let () = main ()
19 changes: 14 additions & 5 deletions test/tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@ let warning_opt_to_string = function
| None -> "(nothing)"
| Some w -> Ocamllint.Warning.to_string w

let string_of_expression expr =
let open Migrate_parsetree.Versions in
let migration = migrate ocaml_404 ocaml_current in
let current_expr = migration.copy_expression expr in
Pprintast.string_of_expression current_expr

(** Test rate_expression. Note that the recursion is implemented by the
ast_mapper, so subexpressions are not checked in this test.
*)
let test_expression =
let open Ocamllint.Warning in
let t (expr, r) =
let name =
Printf.sprintf "Rate %s" (Pprintast.string_of_expression expr)
Printf.sprintf "Rate %s" (string_of_expression expr)
in
name >:: fun ctxt ->
assert_equal
Expand Down Expand Up @@ -71,10 +77,13 @@ let test_expression =
]

let string_of_signature_item x =
let open Migrate_parsetree.Versions in
let open Format in
let migration = migrate ocaml_404 ocaml_current in
let current_sig = migration.copy_signature [x] in
ignore (flush_str_formatter ()) ;
let f = str_formatter in
Pprintast.signature f [x];
Pprintast.signature f current_sig;
flush_str_formatter ()

(**
Expand All @@ -93,9 +102,9 @@ let test_signature_item =
r
(Ocamllint_rules.rate_signature_item sigitem)
in
let open Ast_helper in
let open Location in
let open Parsetree in
let open Migrate_parsetree.Ast_404.Ast_helper in
let open Migrate_parsetree.Ast_404.Location in
let open Migrate_parsetree.Ast_404.Parsetree in
List.map t
[ Sig.value @@ Val.mk
~attrs:
Expand Down