Add more languages and experimental block keywords

This commit is contained in:
Rijnard van Tonder 2019-06-06 16:34:38 -04:00 committed by GitHub
parent 8d8fb7fc82
commit 265d9410c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 209 additions and 29 deletions

View File

@ -1,9 +1,27 @@
let experimental = true
module Text = struct
module Syntax = struct
let user_defined_delimiters = []
let escapable_string_literals = []
let escape_char =
'\\'
let raw_string_literals = []
let comment_parser = []
end
include Matcher.Make(Syntax)
end
module Dyck = struct
module Syntax = struct
let user_defined_delimiters =
[ ("(", ")")
; ("{", "}")
; ("[", "]")
[ "(", ")"
; "{", "}"
; "[", "]"
]
let escapable_string_literals = []
@ -20,6 +38,8 @@ module Dyck = struct
include Matcher.Make(Syntax)
end
module Json = Dyck
module Latex = struct
module Syntax = struct
open Types
@ -27,7 +47,7 @@ module Latex = struct
let user_defined_delimiters =
Dyck.Syntax.user_defined_delimiters @
[ ({|\if|}, {|\fi|})
[ {|\if|}, {|\fi|}
]
let comment_parser =
@ -105,8 +125,8 @@ module Bash = struct
let user_defined_delimiters =
Dyck.Syntax.user_defined_delimiters @
[ ("if", "fi")
; ("case", "esac")
[ "if ", "fi"
; "case ", "esac"
]
let comment_parser =
@ -121,6 +141,24 @@ module Ruby = struct
open Types
include Generic.Syntax
let user_defined_delimiters =
Generic.Syntax.user_defined_delimiters
@ if experimental then
[ "class", "end"
; "def", "end"
; "do", "end"
; "if", "end"
; "case", "end"
; "unless", "end"
; "while", "end"
; "until", "end"
; "for", "end"
; "begin", "end"
; "module", "end"
]
else
[]
let raw_string_literals =
[ ({|"|}, {|"|})
]
@ -139,6 +177,19 @@ module Elixir = struct
open Types
include Generic.Syntax
let user_defined_delimiters =
Generic.Syntax.user_defined_delimiters
@ if experimental then
[ "fn", "end"
; "do", "end"
; "case", "end"
; "cond", "end"
; "if", "end"
; "<", ">"
]
else
[]
let raw_string_literals =
[ ({|"""|}, {|"""|})
]
@ -202,6 +253,16 @@ module Erlang = struct
open Types
include Generic.Syntax
let user_defined_delimiters =
Generic.Syntax.user_defined_delimiters
@ if experimental then
[ "fun", "end"
; "case", "end"
; "if", "end"
]
else
[]
let comment_parser =
[ Until_newline "%"
]
@ -224,6 +285,8 @@ module C = struct
include Matcher.Make(Syntax)
end
module Csharp = C
module Java = C
module CSS = C
@ -310,6 +373,17 @@ module OCaml = struct
open Types
include Generic.Syntax
let user_defined_delimiters =
Generic.Syntax.user_defined_delimiters
@ if experimental then
[ "begin", "end"
; "struct", "end"
; "sig", "end"
]
else
[]
(* Override ' as escapable string literal, since
these can be used in typing *)
let escapable_string_literals =
@ -328,6 +402,8 @@ module OCaml = struct
include Matcher.Make(Syntax)
end
module Fsharp = OCaml
(** Follow Free Pascal that allows nested comments, although Rosetta takes the opposite view. *)
module Pascal = struct
module Syntax = struct
@ -409,17 +485,24 @@ let select_with_extension extension : (module Types.Matcher.S) =
match extension with
| ".c" | ".h" | ".cc" | ".cpp" | ".hpp" -> (module C)
| ".clj" -> (module Clojure)
| ".cs" -> (module Csharp)
| ".css" -> (module CSS)
| ".dart" -> (module Dart)
| ".elm" -> (module Elm)
| ".erl" -> (module Erlang)
| ".ex" -> (module Elixir)
| ".f" | ".for" | ".f90"
| ".f95" | ".f03" | ".f08" | ".F" | ".F90" -> (module Fortran)
| ".fsx" -> (module Fsharp)
| ".html" | ".xml" -> (module Html)
| ".hs" -> (module Haskell)
| ".go" -> (module Go)
| ".java" -> (module Java)
| ".jl" -> (module Julia)
| ".js" | ".ts" -> (module Javascript)
| ".json" -> (module Json)
| ".ml" | ".mli" -> (module OCaml)
| ".pas" -> (module Pascal)
| ".php" -> (module Php)
| ".py" -> (module Python)
| ".rb" -> (module Ruby)
@ -430,4 +513,5 @@ let select_with_extension extension : (module Types.Matcher.S) =
| ".sh" -> (module Bash)
| ".swift" -> (module Swift)
| ".tex" | ".bib" -> (module Latex)
| ".txt" -> (module Text)
| _ -> (module Generic)

View File

@ -8,6 +8,7 @@ open Location
open Types
let configuration_ref = ref (Configuration.create ())
let weaken_delimiter_hole_matching = false
let debug = false
@ -230,18 +231,32 @@ module Make (Syntax : Syntax.S) = struct
|>> fun result -> (String.concat @@ [from] @ result @ [until])
in
let between_nested_delims p =
(match left_delimiter, right_delimiter with
| Some left_delimiter, Some right_delimiter -> [ (left_delimiter, right_delimiter) ]
| _ -> Syntax.user_defined_delimiters)
let trigger_nested_parsing_prefix =
if weaken_delimiter_hole_matching then
match left_delimiter, right_delimiter with
| Some left_delimiter, Some right_delimiter ->
[ (left_delimiter, right_delimiter) ]
| _ -> Syntax.user_defined_delimiters
else
Syntax.user_defined_delimiters
in
trigger_nested_parsing_prefix
|> List.map ~f:fst
|> List.map ~f:(between_nested_delims p)
|> choice
in
(* applies looser delimiter constraints for matching *)
let reserved =
(match left_delimiter, right_delimiter with
| Some left_delimiter, Some right_delimiter -> [ (left_delimiter, right_delimiter) ]
| _ -> Syntax.user_defined_delimiters)
let trigger_nested_parsing_prefix =
if weaken_delimiter_hole_matching then
match left_delimiter, right_delimiter with
| Some left_delimiter, Some right_delimiter ->
[ (left_delimiter, right_delimiter) ]
| _ -> Syntax.user_defined_delimiters
else
Syntax.user_defined_delimiters
in
trigger_nested_parsing_prefix
|> List.concat_map ~f:(fun (from, until) -> [from; until])
|> List.map ~f:string
|> choice

View File

@ -1,18 +1,4 @@
open MParser
(** Significant, potentially nested delimiters. *)
let parens' p =
char '(' >> p << char ')'
let braces' p =
char '{' >> p << char '}'
let brackets' p =
char '<' >> p << char '>'
let squares' p =
char '[' >> p << char ']'
let between p from until =
string from >> p << string until

View File

@ -45,9 +45,7 @@ let%expect_test "custom_long_delimiters" =
let rewrite_template = {|case nuked blocks esac|} in
run_bash source match_template rewrite_template;
[%expect_exact {|
case nuked blocks esac
|}]
[%expect_exact {|case nuked blocks esac|}]
let%expect_test "custom_long_delimiters_doesn't_work_in_go" =
let source =

View File

@ -38,3 +38,100 @@ let%expect_test "parse_ocaml_apostrophe_ok" =
run (module Matchers.OCaml) source match_template rewrite_template;
[%expect_exact {|'a, int |}]
let%expect_test "strict_nested_matching" =
let source = {|({})|} in
let match_template = {|(:[1])|} in
let rewrite_template = {|:[1]|} in
run (module Matchers.Dyck) source match_template rewrite_template;
[%expect_exact {|{}|}]
let%expect_test "strict_nested_matching" =
let source = {|(})|} in
let match_template = {|(:[1])|} in
let rewrite_template = {|:[1]|} in
run (module Matchers.Dyck) source match_template rewrite_template;
[%expect_exact {|No matches.|}]
(*
let%expect_test "ocaml_blocks" =
let source = {|
module M : sig
type t
end = struct
type t = int
module Nested_M = struct
type r = int
end
end
|}
in
let match_template = {|struct :[1] end|} in
let rewrite_template = {|struct <bye> end|} in
run (module Matchers.OCaml) source match_template rewrite_template;
[%expect_exact {|No matches.|}]
*)
let%expect_test "ocaml_complex_blocks_with_same_end" =
let source = {|
begin
match x with
| _ ->
let module M = struct type t end
begin
begin
match y with
| _ -> ()
end
end
end
|}
in
let match_template = {|begin :[1] end|} in
let rewrite_template = {|-Body->:[1]<-Body-|} in
run (module Matchers.OCaml) source match_template rewrite_template;
[%expect_exact {|
-Body->match x with
| _ ->
let module M = struct type t end
begin
begin
match y with
| _ -> ()
end
end<-Body-
|}]
(* FIXME(#35): "before" triggers "for" block *)
let%expect_test "ruby_blocks" =
let source = {|
class ActionController::Base
before_filter :generate_css_from_less
def generate_css_from_less
Less::More.generate_all
end
end
|}
in
let match_template = {|class :[1] end|} in
let rewrite_template = {|-Block->:[1]<-Block-|} in
run (module Matchers.Ruby) source match_template rewrite_template;
[%expect_exact {|No matches.|}]
let%expect_test "erlang_blocks" =
let source = {|Big = fun(X) -> if X > 10 -> true; true -> false end end.|} in
let match_template = {|fun(:[1]) :[rest] end|} in
let rewrite_template = {|-Block->:[rest]<-Block-|} in
run (module Matchers.Erlang) source match_template rewrite_template;
[%expect_exact {|Big = -Block->-> if X > 10 -> true; true -> false end<-Block-.|}]