mirror of
https://github.com/comby-tools/comby.git
synced 2024-09-11 13:25:36 +03:00
recursive rules with matcher and merge tests
This commit is contained in:
parent
3512864079
commit
55c793f48f
@ -1,49 +1,8 @@
|
|||||||
module Match = Match
|
include Comby_kernel
|
||||||
type match' = Match.t
|
|
||||||
|
|
||||||
module Matchers = struct
|
|
||||||
module Matcher = Matchers.Matcher
|
|
||||||
|
|
||||||
module Configuration = Matchers.Configuration
|
|
||||||
type configuration = Configuration.t
|
|
||||||
|
|
||||||
module Syntax = Matchers.Syntax
|
|
||||||
type syntax = Matchers.Syntax.t
|
|
||||||
module Hole = Matchers.Hole
|
|
||||||
|
|
||||||
module Metasyntax = Matchers.Metasyntax
|
|
||||||
type metasyntax = Matchers.Metasyntax.t
|
|
||||||
|
|
||||||
module Alpha = Matchers.Alpha
|
|
||||||
module Omega = Matchers.Omega
|
|
||||||
|
|
||||||
module Languages = Matchers.Languages
|
|
||||||
end
|
|
||||||
|
|
||||||
module Rule = struct
|
|
||||||
open Language
|
|
||||||
type t = Rule.t
|
|
||||||
type result = Rule.result
|
|
||||||
|
|
||||||
let sat = Rule.sat
|
|
||||||
let result_env = Rule.result_env
|
|
||||||
let create = Rule.create
|
|
||||||
let apply = Rule.apply
|
|
||||||
end
|
|
||||||
|
|
||||||
type rule = Rule.t
|
|
||||||
|
|
||||||
module Replacement = Replacement
|
|
||||||
type replacement = Replacement.result
|
|
||||||
|
|
||||||
module Rewrite = struct
|
|
||||||
include Rewriter.Rewrite
|
|
||||||
include Rewriter.Rewrite_template
|
|
||||||
end
|
|
||||||
|
|
||||||
module Pipeline = struct
|
module Pipeline = struct
|
||||||
module Specification = Configuration.Specification
|
|
||||||
type specification = Specification.t
|
|
||||||
include Configuration.Command_input
|
include Configuration.Command_input
|
||||||
include Pipeline
|
include Pipeline
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Regex = Configuration.Regex
|
||||||
|
@ -1,554 +1,4 @@
|
|||||||
open Core
|
include module type of Comby_kernel
|
||||||
|
|
||||||
(** {2 Match}
|
|
||||||
|
|
||||||
A match is a result of matching a template pattern in an input source.
|
|
||||||
|
|
||||||
A match comprises:
|
|
||||||
(1) an environment of metavariables to values, where values have an associated range.
|
|
||||||
(2) the entire string matched by a match template.
|
|
||||||
(3) the range of the entire matched string. *)
|
|
||||||
module Match : sig
|
|
||||||
module Location : sig
|
|
||||||
type t =
|
|
||||||
{ offset : int
|
|
||||||
; line : int
|
|
||||||
; column : int
|
|
||||||
}
|
|
||||||
[@@deriving eq, sexp]
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
|
|
||||||
val default : t
|
|
||||||
end
|
|
||||||
|
|
||||||
type location = Location.t
|
|
||||||
[@@deriving eq, sexp]
|
|
||||||
|
|
||||||
module Range : sig
|
|
||||||
type t =
|
|
||||||
{ match_start : location [@key "start"]
|
|
||||||
; match_end : location [@key "end"]
|
|
||||||
}
|
|
||||||
[@@deriving eq, sexp]
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
|
|
||||||
val default : t
|
|
||||||
end
|
|
||||||
|
|
||||||
type range = Range.t
|
|
||||||
[@@deriving eq, sexp]
|
|
||||||
|
|
||||||
(** {3 Environment}
|
|
||||||
|
|
||||||
A match environment maps metavariables to values for a given match. *)
|
|
||||||
module Environment : sig
|
|
||||||
type t
|
|
||||||
[@@deriving eq]
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
|
|
||||||
(** [create] creates a new, empty environment *)
|
|
||||||
val create : unit -> t
|
|
||||||
|
|
||||||
(** [vars env] returns all metavariables for this environment. *)
|
|
||||||
val vars : t -> string list
|
|
||||||
|
|
||||||
(** [add range env var value] adds a metavariable [var] to [env] with value
|
|
||||||
[value] and range [range]. If [var] already exists, this function has no
|
|
||||||
effect and returns the existing environment. *)
|
|
||||||
val add : ?range:range -> t -> string -> string -> t
|
|
||||||
|
|
||||||
(** [lookup env ar] returns the value assocated with a metavariable [var]. *)
|
|
||||||
val lookup : t -> string -> string option
|
|
||||||
|
|
||||||
(** [update env var value] updates the [value] of a metavariable [var] in [env]. If
|
|
||||||
the metavariable does not exist, the entry is added. *)
|
|
||||||
val update : t -> string -> string -> t
|
|
||||||
|
|
||||||
(** [lookup_range env var] returns the range associated with metavariable [var] in [env]. *)
|
|
||||||
val lookup_range : t -> string -> range option
|
|
||||||
|
|
||||||
(** [update_range env var value range] updates [env] with the [range]
|
|
||||||
associated with the [value] of [var] *)
|
|
||||||
val update_range : t -> string -> range -> t
|
|
||||||
|
|
||||||
val equal : t -> t -> bool
|
|
||||||
|
|
||||||
val copy : t -> t
|
|
||||||
|
|
||||||
val merge : t -> t -> t
|
|
||||||
|
|
||||||
val to_string : t -> string
|
|
||||||
|
|
||||||
val exists : t -> string -> bool
|
|
||||||
end
|
|
||||||
|
|
||||||
type environment = Environment.t
|
|
||||||
|
|
||||||
(** A match t is:
|
|
||||||
(1) an environment of metavariables to values, where values have an associated range.
|
|
||||||
(2) the entire string matched by a match template.
|
|
||||||
(3) the range of the entire matched string. *)
|
|
||||||
type t =
|
|
||||||
{ range : range
|
|
||||||
; environment : environment
|
|
||||||
; matched : string
|
|
||||||
}
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
|
|
||||||
(** [create] creates a new match with empty range by default. *)
|
|
||||||
val create : ?range:range -> unit -> t
|
|
||||||
|
|
||||||
(** [convert_offset] populates line and column information for a [source] file
|
|
||||||
associated with the match (by default, only the offset is computed
|
|
||||||
matches). For matches [fast] is an experimental option that uses a binary
|
|
||||||
search to perform the conversion quickly. *)
|
|
||||||
val convert_offset : fast:bool -> source:string -> t -> t
|
|
||||||
|
|
||||||
(** [pp] is a grep-like formatted printer for matches. It accepts a (optional
|
|
||||||
file path * match list) *)
|
|
||||||
val pp : Format.formatter -> string option * t list -> unit
|
|
||||||
|
|
||||||
(** [pp] is a JSON formatted printer for (optional file path * match list).
|
|
||||||
One line printed per match. *)
|
|
||||||
val pp_json_lines : Format.formatter -> string option * t list -> unit
|
|
||||||
end
|
|
||||||
|
|
||||||
type match' = Match.t
|
|
||||||
|
|
||||||
(** {2 Matchers}
|
|
||||||
|
|
||||||
Defines modules for matching a pattern in input sources to produce
|
|
||||||
matches. *)
|
|
||||||
module Matchers : sig
|
|
||||||
|
|
||||||
(** {3 Configuration}
|
|
||||||
|
|
||||||
Defines some parameters for changing match behavior. *)
|
|
||||||
module Configuration : sig
|
|
||||||
type t
|
|
||||||
|
|
||||||
type match_kind =
|
|
||||||
| Exact
|
|
||||||
| Fuzzy
|
|
||||||
|
|
||||||
(** [create] creates a new configuration based for some parts of matching
|
|
||||||
behavior. These options are for uncommon use cases and the defaults are
|
|
||||||
usually the right choice.
|
|
||||||
|
|
||||||
- [disable_substring_matching] determines whether a pattern like "a"
|
|
||||||
matches inside a substring, or whole words. Default: [false].
|
|
||||||
|
|
||||||
- [match_kind] determines whether a match template can match anywhere
|
|
||||||
inside a source file (Fuzzy), or must match it exactly (Exact). Default:
|
|
||||||
[Fuzzy].
|
|
||||||
|
|
||||||
- [significant_whitespace] is currently has no effect.
|
|
||||||
|
|
||||||
- [match_newline_toplevel] determines whether matching should terminate
|
|
||||||
on newlines if a hole is not specified inside a recognized block syntax.
|
|
||||||
Default: [false].
|
|
||||||
|
|
||||||
- [fresh] is a generator for fresh values, used to evaluate equality
|
|
||||||
relations. *)
|
|
||||||
val create
|
|
||||||
: ?disable_substring_matching:bool
|
|
||||||
-> ?match_kind:match_kind
|
|
||||||
-> ?significant_whitespace:bool
|
|
||||||
-> ?match_newline_toplevel:bool
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> unit
|
|
||||||
-> t
|
|
||||||
end
|
|
||||||
|
|
||||||
type configuration = Configuration.t
|
|
||||||
|
|
||||||
(** {3 Syntax}
|
|
||||||
|
|
||||||
Defines the syntax structures for the target language (C, Go, etc.) that
|
|
||||||
are significant for matching. *)
|
|
||||||
module Syntax : sig
|
|
||||||
|
|
||||||
(** Defines a set of quoted syntax for strings based on one or more
|
|
||||||
delimiters and associated escape chracter.
|
|
||||||
|
|
||||||
E.g., this supports single and double quotes with escape character '\'
|
|
||||||
as: { delimiters = [ {|"|}, {|'|} ]; escape_character = '\\' } *)
|
|
||||||
type escapable_string_literals =
|
|
||||||
{ delimiters : string list
|
|
||||||
; escape_character: char
|
|
||||||
}
|
|
||||||
|
|
||||||
(** Defines comment syntax as one of Multiline, Nested_multiline with
|
|
||||||
associated left and right delimiters, or Until_newline that defines a
|
|
||||||
comment prefix. associated prefix. *)
|
|
||||||
type comment_kind =
|
|
||||||
| Multiline of string * string
|
|
||||||
| Nested_multiline of string * string
|
|
||||||
| Until_newline of string
|
|
||||||
|
|
||||||
(** Defines syntax as:
|
|
||||||
|
|
||||||
- [user_defined_delimiters] are delimiters treated as code structures
|
|
||||||
(parentheses, brackets, braces, alphabetic words) -
|
|
||||||
[escapable_string_literals] are escapable quoted strings
|
|
||||||
|
|
||||||
- [raw_string literals] are raw quoted strings that have no escape
|
|
||||||
character
|
|
||||||
|
|
||||||
- [comments] are comment structures *)
|
|
||||||
type t =
|
|
||||||
{ user_defined_delimiters : (string * string) list
|
|
||||||
; escapable_string_literals : escapable_string_literals option [@default None]
|
|
||||||
; raw_string_literals : (string * string) list
|
|
||||||
; comments : comment_kind list
|
|
||||||
}
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
|
|
||||||
(** The module signature that defines language syntax for a matcher *)
|
|
||||||
module type S = sig
|
|
||||||
val user_defined_delimiters : (string * string) list
|
|
||||||
val escapable_string_literals : escapable_string_literals option
|
|
||||||
val raw_string_literals : (string * string) list
|
|
||||||
val comments : comment_kind list
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
type syntax = Syntax.t
|
|
||||||
|
|
||||||
(** {3 Hole}
|
|
||||||
|
|
||||||
The kinds of holes with associated matching behavior:
|
|
||||||
|
|
||||||
- [Everything] is the default hole that matches across newlines and within
|
|
||||||
the bounds of code blocks or strings, and lazily between prefix and suffix
|
|
||||||
strings in a given template.
|
|
||||||
|
|
||||||
- [Expression] matches expression-like syntax that corresponds to
|
|
||||||
contiguous well-formed code structures or strings that are whitespace
|
|
||||||
separated.
|
|
||||||
|
|
||||||
- [Alphanum] matches alphanumeric characters and underscore.
|
|
||||||
|
|
||||||
- [Non_space] matches one or more alphanumeric characters and punctuation
|
|
||||||
like ., ;, and - that do not affect balanced syntax. Language dependent.
|
|
||||||
|
|
||||||
- [Line] matches zero or more characters up to a newline, including the
|
|
||||||
newline.
|
|
||||||
|
|
||||||
- [Blank] matches one or more spaces or tabs.
|
|
||||||
|
|
||||||
- [Regex] matches a string based on a regular expression. *)
|
|
||||||
module Hole : sig
|
|
||||||
type sort =
|
|
||||||
| Everything
|
|
||||||
| Expression
|
|
||||||
| Alphanum
|
|
||||||
| Non_space
|
|
||||||
| Line
|
|
||||||
| Blank
|
|
||||||
| Regex
|
|
||||||
end
|
|
||||||
|
|
||||||
(** {3 Metasyntax}
|
|
||||||
|
|
||||||
Defines the metasyntax recognized in templates and associates the
|
|
||||||
metasyntax with the matching behavior of holes. *)
|
|
||||||
module Metasyntax : sig
|
|
||||||
|
|
||||||
(** A hole definition should comprise either a string prefix, suffix, or
|
|
||||||
both which encloses an variable identifier. See example below. *)
|
|
||||||
type hole_definition =
|
|
||||||
| Delimited of string option * string option
|
|
||||||
| Reserved_identifiers of string list
|
|
||||||
|
|
||||||
(** Defines syntax definitions for holes. Zero or more Hole sorts, excluding
|
|
||||||
[Regex] should have an associated [hole_definition]. The [Regex] hole
|
|
||||||
must define a prefix, separator, and suffix. See example below. *)
|
|
||||||
type hole_syntax =
|
|
||||||
| Hole of Hole.sort * hole_definition
|
|
||||||
| Regex of string * char * string
|
|
||||||
|
|
||||||
(** A metasyntax comprises:
|
|
||||||
|
|
||||||
- [identifier] where the list of characters are allowed in identifiers.
|
|
||||||
For example, to allow only contiguous capitalized letters as recognized
|
|
||||||
identifiers within some hole syntax, use:
|
|
||||||
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
|
|
||||||
- [syntax] with one or more hole definitions. For example, the default
|
|
||||||
metasyntax for the [Everything] hole is defined as:
|
|
||||||
|
|
||||||
[ Hole (Everything, Delimited (Some ":[", Some "]")) ]
|
|
||||||
|
|
||||||
A Regex hole must define a prefix, separator, and suffix. The current
|
|
||||||
convention is taken to parse Regex holes as:
|
|
||||||
|
|
||||||
<prefix><identifier><separator><regular expression><suffix>
|
|
||||||
|
|
||||||
A separator is required to syntactically distinguish arbitrary
|
|
||||||
identifier syntax from regular exressions. A suffix is required to
|
|
||||||
syntactically distinguish when to stop parsing a regular expression and
|
|
||||||
resume parsing the rest of the template. *)
|
|
||||||
type t =
|
|
||||||
{ syntax : hole_syntax list
|
|
||||||
; identifier : string
|
|
||||||
}
|
|
||||||
|
|
||||||
(** A module signature for metasyntax to parameterize a matcher *)
|
|
||||||
module type S = sig
|
|
||||||
val syntax : hole_syntax list
|
|
||||||
val identifier : string
|
|
||||||
end
|
|
||||||
|
|
||||||
(** The default metasyntax. It is defined as:
|
|
||||||
|
|
||||||
let default_syntax =
|
|
||||||
[ Hole (Everything, Delimited (Some ":[", Some "]"))
|
|
||||||
; Hole (Expression, Delimited (Some ":[", Some ":e]"))
|
|
||||||
; Hole (Alphanum, Delimited (Some ":[[", Some "]]"))
|
|
||||||
; Hole (Non_space, Delimited (Some ":[", Some ".]"))
|
|
||||||
; Hole (Line, Delimited (Some ":[", Some "\\n]"))
|
|
||||||
; Hole (Blank, Delimited (Some ":[ ", Some "]"))
|
|
||||||
; Regex (":[", '~', "]")
|
|
||||||
]
|
|
||||||
|
|
||||||
let default_identifier =
|
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
|
|
||||||
*)
|
|
||||||
val default_metasyntax : t
|
|
||||||
|
|
||||||
(** A JSON representation of the metasyntax defintion *)
|
|
||||||
val json : t -> string
|
|
||||||
|
|
||||||
(** [create definition] creates a metasyntax module from a definition *)
|
|
||||||
val create : t -> (module S)
|
|
||||||
|
|
||||||
(** [default] returns the default metasyntax module *)
|
|
||||||
val default : (module S)
|
|
||||||
end
|
|
||||||
|
|
||||||
type metasyntax = Metasyntax.t
|
|
||||||
|
|
||||||
(** {3 Matcher}
|
|
||||||
|
|
||||||
Defines the functions that a matcher can perform. *)
|
|
||||||
module Matcher : sig
|
|
||||||
module type S = sig
|
|
||||||
(** [all conf nested template source] finds all matches of [template] in
|
|
||||||
[source]. If [nested] is true, template matching will descend
|
|
||||||
recursively on matched content. *)
|
|
||||||
val all
|
|
||||||
: ?configuration:configuration
|
|
||||||
-> ?nested: bool
|
|
||||||
-> template:string
|
|
||||||
-> source:string
|
|
||||||
-> unit
|
|
||||||
-> match' list
|
|
||||||
|
|
||||||
(** [first conf shift template source] finds the first match of [template] in [source] starting
|
|
||||||
at position [shift] (default 0). *)
|
|
||||||
val first
|
|
||||||
: ?configuration:configuration
|
|
||||||
-> ?shift:int
|
|
||||||
-> string
|
|
||||||
-> string
|
|
||||||
-> match' Or_error.t
|
|
||||||
|
|
||||||
(** [name] returns the name of this matcher (e.g., "C", "Go", etc.). *)
|
|
||||||
val name : string
|
|
||||||
|
|
||||||
(** [extensions] returns the file extensions associated with the language
|
|
||||||
that this matcher supports (e.g., ".c" and "h" for C). *)
|
|
||||||
val extensions : string list
|
|
||||||
|
|
||||||
(** [set_rewrite_template] is currently unused. *)
|
|
||||||
val set_rewrite_template : string -> unit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
(** {3 Alpha Matcher}
|
|
||||||
|
|
||||||
Alpha is the match engine that defines default matchers for languages.
|
|
||||||
*)
|
|
||||||
module Alpha : sig
|
|
||||||
(** [select_with_extension metasyntax file_extension] is a convenience
|
|
||||||
function that returns a matcher associated with a [file_extension]. E.g.,
|
|
||||||
use ".c" to get the C matcher. For a full list of extensions associated
|
|
||||||
with matchers, run comby -list. If [metasyntax] is specified, the matcher
|
|
||||||
will use a custom metasyntax definition instead of the default. *)
|
|
||||||
val select_with_extension : ?metasyntax:metasyntax -> string -> (module Matcher.S) option
|
|
||||||
|
|
||||||
(** [create metasyntax syntax] creates a matcher for a language defined by
|
|
||||||
[syntax]. If [metasyntax] is specified, the matcher will use a custom
|
|
||||||
metasyntax definition instead of the default. *)
|
|
||||||
val create : ?metasyntax:metasyntax -> syntax -> (module Matcher.S)
|
|
||||||
|
|
||||||
(** [all] returns all default matchers. *)
|
|
||||||
val all : (module Matcher.S) list
|
|
||||||
|
|
||||||
(** {4 Supported Matchers} *)
|
|
||||||
module Text : Matcher.S
|
|
||||||
module Paren : Matcher.S
|
|
||||||
module Dyck : Matcher.S
|
|
||||||
module JSON : Matcher.S
|
|
||||||
module JSONC : Matcher.S
|
|
||||||
module GraphQL : Matcher.S
|
|
||||||
module Dhall : Matcher.S
|
|
||||||
module Latex : Matcher.S
|
|
||||||
module Assembly : Matcher.S
|
|
||||||
module Clojure : Matcher.S
|
|
||||||
module Lisp : Matcher.S
|
|
||||||
module Generic : Matcher.S
|
|
||||||
module Bash : Matcher.S
|
|
||||||
module Ruby : Matcher.S
|
|
||||||
module Elixir : Matcher.S
|
|
||||||
module Python : Matcher.S
|
|
||||||
module Html : Matcher.S
|
|
||||||
module Xml : Matcher.S
|
|
||||||
module SQL : Matcher.S
|
|
||||||
module Erlang : Matcher.S
|
|
||||||
module C : Matcher.S
|
|
||||||
module Csharp : Matcher.S
|
|
||||||
module Java : Matcher.S
|
|
||||||
module CSS : Matcher.S
|
|
||||||
module Kotlin : Matcher.S
|
|
||||||
module Scala : Matcher.S
|
|
||||||
module Nim : Matcher.S
|
|
||||||
module Dart : Matcher.S
|
|
||||||
module Php : Matcher.S
|
|
||||||
module Go : Matcher.S
|
|
||||||
module Javascript : Matcher.S
|
|
||||||
module Jsx : Matcher.S
|
|
||||||
module Typescript : Matcher.S
|
|
||||||
module Tsx : Matcher.S
|
|
||||||
module Swift : Matcher.S
|
|
||||||
module Rust : Matcher.S
|
|
||||||
module OCaml : Matcher.S
|
|
||||||
module Reason : Matcher.S
|
|
||||||
module Fsharp : Matcher.S
|
|
||||||
module Pascal : Matcher.S
|
|
||||||
module Julia : Matcher.S
|
|
||||||
module Fortran : Matcher.S
|
|
||||||
module Haskell : Matcher.S
|
|
||||||
module Elm : Matcher.S
|
|
||||||
module Zig : Matcher.S
|
|
||||||
module Coq : Matcher.S
|
|
||||||
module Move : Matcher.S
|
|
||||||
module Solidity : Matcher.S
|
|
||||||
module C_nested_comments : Matcher.S
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
(** {2 Rule}
|
|
||||||
|
|
||||||
Defines types and operations for match rules. *)
|
|
||||||
module Rule : sig
|
|
||||||
type t
|
|
||||||
type result
|
|
||||||
|
|
||||||
(** [sat result] returns true if a result of a rule is satisfied. *)
|
|
||||||
val sat : result -> bool
|
|
||||||
|
|
||||||
(** [result_env] returns a match environment associated with a rule result. *)
|
|
||||||
val result_env : result -> Match.environment option
|
|
||||||
|
|
||||||
(** [create] parses and creates a rule. *)
|
|
||||||
val create : string -> t Or_error.t
|
|
||||||
|
|
||||||
(** [apply matcher substitute_in_place fresh metasyntax rule env] applies a [rule]
|
|
||||||
according to some [matcher] for existing matches in [env]. If
|
|
||||||
[substitute_in_place] is true, rewrite rules substitute their values in
|
|
||||||
place (default true). [fresh] introduces fresh variables for evaluating
|
|
||||||
rules. [metasyntax] uses the custom metasyntax definition. *)
|
|
||||||
val apply
|
|
||||||
: ?matcher:(module Matchers.Matcher.S)
|
|
||||||
-> ?substitute_in_place:bool
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> ?metasyntax:Matchers.Metasyntax.t
|
|
||||||
-> t
|
|
||||||
-> Match.environment
|
|
||||||
-> result
|
|
||||||
end
|
|
||||||
|
|
||||||
type rule = Rule.t
|
|
||||||
|
|
||||||
(** {2 Replacement}
|
|
||||||
|
|
||||||
Defines the result of a rewrite operation. *)
|
|
||||||
module Replacement : sig
|
|
||||||
(** A replacement consists of the replaced range, the replacement content, and
|
|
||||||
the environment associated with the replacement content. *)
|
|
||||||
type t =
|
|
||||||
{ range : Match.range
|
|
||||||
; replacement_content : string
|
|
||||||
; environment : Match.environment
|
|
||||||
}
|
|
||||||
|
|
||||||
(** A replacement result is the rewritten source, and the replacement
|
|
||||||
fragments. *)
|
|
||||||
type result =
|
|
||||||
{ rewritten_source : string
|
|
||||||
; in_place_substitutions : t list
|
|
||||||
}
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
end
|
|
||||||
|
|
||||||
type replacement = Replacement.result
|
|
||||||
|
|
||||||
(** {2 Rewrite}
|
|
||||||
|
|
||||||
Defines rewrite operations. *)
|
|
||||||
module Rewrite : sig
|
|
||||||
(** [all source metasyntax fresh rewrite_template matches] substitutes
|
|
||||||
[rewrite_template] with each match in [matches] to create a rewrite result.
|
|
||||||
If [source] is specified, each rewrite result is substituted in-place in
|
|
||||||
the source. If [source] is not specified, rewritten matches are
|
|
||||||
newline-separated. If [metasyntax] is defined, the rewrite template will
|
|
||||||
respect custom metasyntax definitions.
|
|
||||||
|
|
||||||
If the rewrite template contains the syntax :[id()], then it is
|
|
||||||
substituted with fresh values. [fresh] may be specified to supply custom
|
|
||||||
fresh values. If not specified, fresh variables are generated in increasing
|
|
||||||
rank starting with 1, and incremented. See [substitute] for more. *)
|
|
||||||
val all
|
|
||||||
: ?source:string
|
|
||||||
-> ?metasyntax:Matchers.metasyntax
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> rewrite_template:string
|
|
||||||
-> match' list
|
|
||||||
-> replacement option
|
|
||||||
|
|
||||||
(** [substitute metasyntax fresh template environment] substitutes [template]
|
|
||||||
with the variable and value pairs in the [environment]. It returns the
|
|
||||||
result after substitution, and the list of variables in [environment] that
|
|
||||||
were substituted for. If [metasyntax] is defined, the rewrite template will
|
|
||||||
respect custom metasyntax definitions.
|
|
||||||
|
|
||||||
The syntax :[id()] is substituted with fresh values. If [fresh] is not
|
|
||||||
specified, the default behavior substitutes :[id()] starting with 1, and
|
|
||||||
subsequent :[id()] values increment the ID. If [fresh] is set, substitutes
|
|
||||||
the pattern :[id()] with the value of fresh () as the hole is encountered,
|
|
||||||
left to right. *)
|
|
||||||
val substitute
|
|
||||||
: ?metasyntax:Matchers.metasyntax
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> string
|
|
||||||
-> Match.environment
|
|
||||||
-> (string * string list)
|
|
||||||
end
|
|
||||||
|
|
||||||
(** {2 Pipeline}
|
(** {2 Pipeline}
|
||||||
|
|
||||||
@ -561,35 +11,13 @@ module Pipeline : sig
|
|||||||
| Path of string
|
| Path of string
|
||||||
| String of string
|
| String of string
|
||||||
|
|
||||||
(** {2 Specification}
|
|
||||||
|
|
||||||
Defines an internal type that represents an atomic operation for matching,
|
|
||||||
rule application and rewriting. *)
|
|
||||||
module Specification : sig
|
|
||||||
type t
|
|
||||||
|
|
||||||
(** [create rewrite_template rule match_template] creates a new specification.
|
|
||||||
If [rule] is supplied, it will be applied to matches of [match_template].
|
|
||||||
If [rewrite_template] is supplied, running a specification will return
|
|
||||||
replacements rather than just matches (see [process_single_source] below).
|
|
||||||
*)
|
|
||||||
val create
|
|
||||||
: ?rewrite_template:string
|
|
||||||
-> ?rule:rule
|
|
||||||
-> match_template:string
|
|
||||||
-> unit
|
|
||||||
-> t
|
|
||||||
end
|
|
||||||
|
|
||||||
type specification = Specification.t
|
|
||||||
|
|
||||||
(** The output of running a specification. Matches are a list of matches and
|
(** The output of running a specification. Matches are a list of matches and
|
||||||
the number of matches found. A Replacement consists of the list of
|
the number of matches found. A Replacement consists of the list of
|
||||||
replacement fragments, the rewrite output, and the number of replacements
|
replacement fragments, the rewrite output, and the number of replacements
|
||||||
made. *)
|
made. *)
|
||||||
type output =
|
type output =
|
||||||
| Matches of (match' list * int)
|
| Matches of (Comby_kernel.match' list * int)
|
||||||
| Replacement of (Replacement.t list * string * int)
|
| Replacement of (Comby_kernel.Replacement.t list * string * int)
|
||||||
| Nothing
|
| Nothing
|
||||||
|
|
||||||
(** [execute matcher subst timeout metasyntax fresh config source spec] runs a
|
(** [execute matcher subst timeout metasyntax fresh config source spec] runs a
|
||||||
@ -603,12 +31,15 @@ module Pipeline : sig
|
|||||||
[Rewrite.substitute] for more. *)
|
[Rewrite.substitute] for more. *)
|
||||||
val execute
|
val execute
|
||||||
: (module Matchers.Matcher.S)
|
: (module Matchers.Matcher.S)
|
||||||
-> ?substitute_in_place:bool
|
|
||||||
-> ?timeout:int
|
-> ?timeout:int
|
||||||
-> ?metasyntax:Matchers.metasyntax
|
-> ?metasyntax:Matchers.metasyntax
|
||||||
-> ?fresh:(unit -> string)
|
-> ?fresh:(unit -> string)
|
||||||
-> ?configuration:Matchers.configuration
|
-> ?configuration:Matchers.configuration
|
||||||
-> single_source
|
-> single_source
|
||||||
-> specification
|
-> Matchers.specification
|
||||||
-> output
|
-> output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Regex : sig
|
||||||
|
val to_regex : Matchers.specification -> string
|
||||||
|
end
|
||||||
|
@ -3,7 +3,7 @@ open Camlzip
|
|||||||
|
|
||||||
open Polymorphic_compare
|
open Polymorphic_compare
|
||||||
|
|
||||||
open Language
|
open Comby_kernel
|
||||||
|
|
||||||
let debug =
|
let debug =
|
||||||
Sys.getenv "DEBUG_COMBY"
|
Sys.getenv "DEBUG_COMBY"
|
||||||
@ -105,7 +105,7 @@ let read filename =
|
|||||||
|> Option.value ~default:template
|
|> Option.value ~default:template
|
||||||
|
|
||||||
let create_rule rule =
|
let create_rule rule =
|
||||||
match Option.map rule ~f:Rule.create with
|
match Option.map rule ~f:Matchers.Rule.create with
|
||||||
| None -> None
|
| None -> None
|
||||||
| Some Ok rule -> Some rule
|
| Some Ok rule -> Some rule
|
||||||
| Some Error error ->
|
| Some Error error ->
|
||||||
@ -138,7 +138,7 @@ let parse_toml path =
|
|||||||
let rule = Table.find_opt (Toml.Min.key "rule") t |> to_string |> create_rule in
|
let rule = Table.find_opt (Toml.Min.key "rule") t |> to_string |> create_rule in
|
||||||
let rewrite_template = Table.find_opt (Toml.Min.key "rewrite") t |> to_string in
|
let rewrite_template = Table.find_opt (Toml.Min.key "rewrite") t |> to_string in
|
||||||
if debug then Format.printf "Processed ->%s<-@." match_template;
|
if debug then Format.printf "Processed ->%s<-@." match_template;
|
||||||
(name, (Specification.create ~match_template ?rule ?rewrite_template ()))::acc
|
(name, (Matchers.Specification.create ~match_template ?rule ?rewrite_template ()))::acc
|
||||||
| v ->
|
| v ->
|
||||||
Format.eprintf "Unexpected format, could not parse ->%s<-@." (Toml.Printer.string_of_value v);
|
Format.eprintf "Unexpected format, could not parse ->%s<-@." (Toml.Printer.string_of_value v);
|
||||||
exit 1
|
exit 1
|
||||||
@ -161,7 +161,7 @@ let parse_templates ?(warn_for_missing_file_in_dir = false) paths =
|
|||||||
| Some match_template ->
|
| Some match_template ->
|
||||||
let rule = create_rule @@ read_optional (path ^/ "rule") in
|
let rule = create_rule @@ read_optional (path ^/ "rule") in
|
||||||
let rewrite_template = read_optional (path ^/ "rewrite") in
|
let rewrite_template = read_optional (path ^/ "rewrite") in
|
||||||
Specification.create ~match_template ?rule ?rewrite_template ()
|
Matchers.Specification.create ~match_template ?rule ?rewrite_template ()
|
||||||
|> Option.some
|
|> Option.some
|
||||||
in
|
in
|
||||||
let f acc ~depth:_ ~absolute_path ~is_file =
|
let f acc ~depth:_ ~absolute_path ~is_file =
|
||||||
@ -428,7 +428,7 @@ end
|
|||||||
|
|
||||||
type t =
|
type t =
|
||||||
{ sources : Command_input.t
|
{ sources : Command_input.t
|
||||||
; specifications : Specification.t list
|
; specifications : Matchers.Specification.t list
|
||||||
; run_options : run_options
|
; run_options : run_options
|
||||||
; output_printer : Printer.t
|
; output_printer : Printer.t
|
||||||
; interactive_review : interactive_review option
|
; interactive_review : interactive_review option
|
||||||
@ -499,7 +499,7 @@ let emit_errors { input_options; output_options; _ } =
|
|||||||
Option.value_exn message
|
Option.value_exn message
|
||||||
else
|
else
|
||||||
"UNREACHABLE")
|
"UNREACHABLE")
|
||||||
; (let result = Rule.create input_options.rule in
|
; (let result = Matchers.Rule.create input_options.rule in
|
||||||
Or_error.is_error result
|
Or_error.is_error result
|
||||||
, if Or_error.is_error result then
|
, if Or_error.is_error result then
|
||||||
Format.sprintf "Match rule parse error: %s@." @@
|
Format.sprintf "Match rule parse error: %s@." @@
|
||||||
@ -532,7 +532,7 @@ let emit_warnings { input_options; output_options; _ } =
|
|||||||
let warn_on =
|
let warn_on =
|
||||||
[ (let match_templates =
|
[ (let match_templates =
|
||||||
match input_options.templates, input_options.anonymous_arguments with
|
match input_options.templates, input_options.anonymous_arguments with
|
||||||
| None, Some { match_template; _ } ->
|
| None, Some ({ match_template; _ } : anonymous_arguments) ->
|
||||||
[ match_template ]
|
[ match_template ]
|
||||||
| Some templates, _ ->
|
| Some templates, _ ->
|
||||||
List.map (parse_templates templates) ~f:(fun { match_template; _ } -> match_template)
|
List.map (parse_templates templates) ~f:(fun { match_template; _ } -> match_template)
|
||||||
@ -682,7 +682,7 @@ let select_matcher custom_metasyntax custom_matcher override_matcher file_filter
|
|||||||
let regex_of_specifications specifications =
|
let regex_of_specifications specifications =
|
||||||
Format.sprintf "(%s)"
|
Format.sprintf "(%s)"
|
||||||
@@ String.concat ~sep:")|("
|
@@ String.concat ~sep:")|("
|
||||||
@@ List.map specifications ~f:Specification.to_regex
|
@@ List.map specifications ~f:Regex.to_regex
|
||||||
|
|
||||||
let ripgrep_file_filters specifications args : string list =
|
let ripgrep_file_filters specifications args : string list =
|
||||||
let regex = regex_of_specifications specifications in
|
let regex = regex_of_specifications specifications in
|
||||||
@ -734,28 +734,28 @@ let create
|
|||||||
emit_warnings configuration >>= fun () ->
|
emit_warnings configuration >>= fun () ->
|
||||||
let rule =
|
let rule =
|
||||||
let rule = String.substr_replace_all rule ~pattern:"..." ~with_:":[_]" in
|
let rule = String.substr_replace_all rule ~pattern:"..." ~with_:":[_]" in
|
||||||
Rule.create rule |> Or_error.ok_exn
|
Matchers.Rule.create rule |> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
let specifications =
|
let specifications =
|
||||||
match templates, anonymous_arguments with
|
match templates, anonymous_arguments with
|
||||||
| None, Some { match_template; rewrite_template; _ } ->
|
| None, Some { match_template; rewrite_template; _ } ->
|
||||||
if match_only || count then
|
if match_only || count then
|
||||||
[ Specification.create ~match_template ~rule () ]
|
[ Matchers.Specification.create ~match_template ~rule () ]
|
||||||
else
|
else
|
||||||
[ Specification.create ~match_template ~rewrite_template ~rule () ]
|
[ Matchers.Specification.create ~match_template ~rewrite_template ~rule () ]
|
||||||
| Some templates, _ ->
|
| Some templates, _ ->
|
||||||
parse_templates ~warn_for_missing_file_in_dir:true templates
|
parse_templates ~warn_for_missing_file_in_dir:true templates
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
in
|
in
|
||||||
let specifications =
|
let specifications =
|
||||||
List.map specifications ~f:(fun ({ match_template; _ } as spec) ->
|
List.map specifications ~f:(fun ({ match_template ; _ } as spec) ->
|
||||||
{ spec with match_template =
|
{ spec with match_template =
|
||||||
String.substr_replace_all match_template ~pattern:"..." ~with_:":[_]" })
|
String.substr_replace_all match_template ~pattern:"..." ~with_:":[_]" })
|
||||||
in
|
in
|
||||||
let specifications =
|
let specifications =
|
||||||
if match_only then
|
if match_only then
|
||||||
List.map specifications ~f:(fun { match_template; rule; _ } ->
|
List.map specifications ~f:(fun { match_template; rule; _ } ->
|
||||||
Specification.create ~match_template ?rule ())
|
Matchers.Specification.create ~match_template ?rule ())
|
||||||
else
|
else
|
||||||
specifications
|
specifications
|
||||||
in
|
in
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
|
||||||
module Printer : sig
|
module Printer : sig
|
||||||
type printable_result =
|
type printable_result =
|
||||||
| Matches of
|
| Matches of
|
||||||
@ -85,7 +87,7 @@ type user_input =
|
|||||||
|
|
||||||
type t =
|
type t =
|
||||||
{ sources : Command_input.t
|
{ sources : Command_input.t
|
||||||
; specifications : Specification.t list
|
; specifications : Matchers.Specification.t list
|
||||||
; run_options : run_options
|
; run_options : run_options
|
||||||
; output_printer : Printer.t
|
; output_printer : Printer.t
|
||||||
; interactive_review : interactive_review option
|
; interactive_review : interactive_review option
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
open Core
|
open Core
|
||||||
open Angstrom
|
open Angstrom
|
||||||
|
|
||||||
open Language
|
open Comby_kernel
|
||||||
|
|
||||||
type t =
|
|
||||||
{ match_template : string
|
|
||||||
; rule : Rule.t option
|
|
||||||
; rewrite_template : string option
|
|
||||||
}
|
|
||||||
|
|
||||||
let (|>>) p f =
|
let (|>>) p f =
|
||||||
p >>= fun x -> return (f x)
|
p >>= fun x -> return (f x)
|
||||||
@ -120,7 +114,7 @@ let escape s =
|
|||||||
aux (String.to_list s)
|
aux (String.to_list s)
|
||||||
|> String.of_char_list
|
|> String.of_char_list
|
||||||
|
|
||||||
let to_regex { match_template; _ } =
|
let to_regex Matchers.Specification.{ match_template; _ } =
|
||||||
let state = Buffered.parse extract in
|
let state = Buffered.parse extract in
|
||||||
let state = Buffered.feed state (`String match_template) in
|
let state = Buffered.feed state (`String match_template) in
|
||||||
let extracted =
|
let extracted =
|
||||||
@ -136,6 +130,3 @@ let to_regex { match_template; _ } =
|
|||||||
(* ?s is modifier metasyntax where . matches all chars including newlines. See
|
(* ?s is modifier metasyntax where . matches all chars including newlines. See
|
||||||
regular-expressions.info/modifier.html *)
|
regular-expressions.info/modifier.html *)
|
||||||
Format.sprintf "(%s)" @@ String.concat extracted ~sep:")(\\n|.)*?("
|
Format.sprintf "(%s)" @@ String.concat extracted ~sep:")(\\n|.)*?("
|
||||||
|
|
||||||
let create ?rewrite_template ?rule ~match_template () =
|
|
||||||
{ match_template; rule; rewrite_template }
|
|
3
lib/app/configuration/regex.mli
Normal file
3
lib/app/configuration/regex.mli
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
open Comby_kernel
|
||||||
|
|
||||||
|
val to_regex : Matchers.specification -> string
|
@ -1,11 +0,0 @@
|
|||||||
open Language
|
|
||||||
|
|
||||||
type t =
|
|
||||||
{ match_template : string
|
|
||||||
; rule : Rule.t option
|
|
||||||
; rewrite_template : string option
|
|
||||||
}
|
|
||||||
|
|
||||||
val to_regex : t -> string
|
|
||||||
|
|
||||||
val create : ?rewrite_template:string -> ?rule:Language.Rule.t -> match_template:string -> unit -> t
|
|
@ -1,13 +1,13 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
|
||||||
open Configuration
|
open Configuration
|
||||||
open Command_configuration
|
open Command_configuration
|
||||||
open Command_input
|
open Command_input
|
||||||
open Rewriter
|
|
||||||
open Statistics
|
open Statistics
|
||||||
|
|
||||||
open Match
|
open Matchers
|
||||||
open Language
|
|
||||||
|
|
||||||
let verbose_out_file = "/tmp/comby.out"
|
let verbose_out_file = "/tmp/comby.out"
|
||||||
|
|
||||||
@ -15,32 +15,9 @@ let debug =
|
|||||||
Sys.getenv "DEBUG_COMBY"
|
Sys.getenv "DEBUG_COMBY"
|
||||||
|> Option.is_some
|
|> Option.is_some
|
||||||
|
|
||||||
let infer_equality_constraints environment =
|
|
||||||
let vars = Environment.vars environment in
|
|
||||||
List.fold vars ~init:[] ~f:(fun acc var ->
|
|
||||||
if String.is_suffix var ~suffix:"_equal" then
|
|
||||||
match String.split var ~on:'_' with
|
|
||||||
| _uuid :: target :: _equal ->
|
|
||||||
let expression = Language.Ast.Equal (Variable var, Variable target) in
|
|
||||||
expression::acc
|
|
||||||
| _ -> acc
|
|
||||||
else
|
|
||||||
acc)
|
|
||||||
|
|
||||||
let apply_rule ?(substitute_in_place = true) ?metasyntax matcher rule matches =
|
|
||||||
let open Option in
|
|
||||||
List.filter_map matches ~f:(fun ({ environment; _ } as matched) ->
|
|
||||||
let rule = rule @ infer_equality_constraints environment in
|
|
||||||
let fresh () = Uuid_unix.(Fn.compose Uuid.to_string create ()) in
|
|
||||||
let sat, env = Rule.apply ?metasyntax ~fresh ~substitute_in_place ~matcher rule environment in
|
|
||||||
(if sat then env else None)
|
|
||||||
>>| fun environment -> { matched with environment })
|
|
||||||
|
|
||||||
let timed_run
|
let timed_run
|
||||||
(module Matcher : Matchers.Matcher.S)
|
(module Matcher : Matcher.S)
|
||||||
?(fast_offset_conversion = false)
|
?(fast_offset_conversion = false)
|
||||||
?substitute_in_place
|
|
||||||
?metasyntax
|
|
||||||
~configuration
|
~configuration
|
||||||
~source
|
~source
|
||||||
~specification:(Specification.{ match_template = template; rule; rewrite_template })
|
~specification:(Specification.{ match_template = template; rule; rewrite_template })
|
||||||
@ -48,10 +25,9 @@ let timed_run
|
|||||||
(match rewrite_template with
|
(match rewrite_template with
|
||||||
| Some template -> Matcher.set_rewrite_template template;
|
| Some template -> Matcher.set_rewrite_template template;
|
||||||
| None -> ());
|
| None -> ());
|
||||||
let rule = Option.value rule ~default:[Ast.True] in
|
let rule = Option.value rule ~default:(Rule.create "where true" |> Or_error.ok_exn) in
|
||||||
let options = Rule.options rule in
|
let options = Rule.options rule in
|
||||||
let matches = Matcher.all ~nested:options.nested ~configuration ~template ~source () in
|
let matches = Matcher.all ~rule ~nested:options.nested ~configuration ~template ~source () in
|
||||||
let matches = apply_rule ?substitute_in_place ?metasyntax (module Matcher) rule matches in
|
|
||||||
List.map matches ~f:(Match.convert_offset ~fast:fast_offset_conversion ~source)
|
List.map matches ~f:(Match.convert_offset ~fast:fast_offset_conversion ~source)
|
||||||
|
|
||||||
type output =
|
type output =
|
||||||
@ -74,7 +50,6 @@ let log_to_file path =
|
|||||||
let process_single_source
|
let process_single_source
|
||||||
matcher
|
matcher
|
||||||
?(fast_offset_conversion = false)
|
?(fast_offset_conversion = false)
|
||||||
?(substitute_in_place = false)
|
|
||||||
?(verbose = false)
|
?(verbose = false)
|
||||||
?(timeout = 3)
|
?(timeout = 3)
|
||||||
?metasyntax
|
?metasyntax
|
||||||
@ -95,8 +70,6 @@ let process_single_source
|
|||||||
with_timeout timeout source ~f:(fun () ->
|
with_timeout timeout source ~f:(fun () ->
|
||||||
timed_run
|
timed_run
|
||||||
matcher
|
matcher
|
||||||
?metasyntax
|
|
||||||
~substitute_in_place
|
|
||||||
~fast_offset_conversion
|
~fast_offset_conversion
|
||||||
~configuration
|
~configuration
|
||||||
~specification
|
~specification
|
||||||
@ -222,7 +195,6 @@ let run_interactive
|
|||||||
specifications
|
specifications
|
||||||
matcher
|
matcher
|
||||||
fast_offset_conversion
|
fast_offset_conversion
|
||||||
substitute_in_place
|
|
||||||
match_configuration
|
match_configuration
|
||||||
verbose
|
verbose
|
||||||
timeout
|
timeout
|
||||||
@ -237,7 +209,6 @@ let run_interactive
|
|||||||
process_single_source
|
process_single_source
|
||||||
matcher
|
matcher
|
||||||
~fast_offset_conversion
|
~fast_offset_conversion
|
||||||
~substitute_in_place
|
|
||||||
~verbose
|
~verbose
|
||||||
~timeout
|
~timeout
|
||||||
match_configuration
|
match_configuration
|
||||||
@ -268,7 +239,7 @@ let run
|
|||||||
{ verbose
|
{ verbose
|
||||||
; match_timeout = timeout
|
; match_timeout = timeout
|
||||||
; dump_statistics
|
; dump_statistics
|
||||||
; substitute_in_place
|
; substitute_in_place = _ (* FIXME remove *)
|
||||||
; disable_substring_matching
|
; disable_substring_matching
|
||||||
; fast_offset_conversion
|
; fast_offset_conversion
|
||||||
; match_newline_toplevel
|
; match_newline_toplevel
|
||||||
@ -304,7 +275,6 @@ let run
|
|||||||
process_single_source
|
process_single_source
|
||||||
matcher
|
matcher
|
||||||
~fast_offset_conversion
|
~fast_offset_conversion
|
||||||
~substitute_in_place
|
|
||||||
~verbose
|
~verbose
|
||||||
~timeout
|
~timeout
|
||||||
?metasyntax
|
?metasyntax
|
||||||
@ -327,7 +297,6 @@ let run
|
|||||||
specifications
|
specifications
|
||||||
matcher
|
matcher
|
||||||
fast_offset_conversion
|
fast_offset_conversion
|
||||||
substitute_in_place
|
|
||||||
match_configuration
|
match_configuration
|
||||||
verbose
|
verbose
|
||||||
timeout
|
timeout
|
||||||
@ -339,7 +308,6 @@ let run
|
|||||||
|
|
||||||
let execute
|
let execute
|
||||||
matcher
|
matcher
|
||||||
?substitute_in_place
|
|
||||||
?timeout
|
?timeout
|
||||||
?metasyntax
|
?metasyntax
|
||||||
?fresh
|
?fresh
|
||||||
@ -349,7 +317,6 @@ let execute
|
|||||||
process_single_source
|
process_single_source
|
||||||
matcher
|
matcher
|
||||||
~fast_offset_conversion:false
|
~fast_offset_conversion:false
|
||||||
?substitute_in_place
|
|
||||||
~verbose:false
|
~verbose:false
|
||||||
?timeout
|
?timeout
|
||||||
?metasyntax
|
?metasyntax
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
open Comby_kernel
|
||||||
|
|
||||||
open Configuration
|
open Configuration
|
||||||
open Command_input
|
open Command_input
|
||||||
|
|
||||||
@ -9,25 +11,23 @@ type output =
|
|||||||
val process_single_source
|
val process_single_source
|
||||||
: (module Matchers.Matcher.S)
|
: (module Matchers.Matcher.S)
|
||||||
-> ?fast_offset_conversion:bool
|
-> ?fast_offset_conversion:bool
|
||||||
-> ?substitute_in_place:bool
|
|
||||||
-> ?verbose:bool
|
-> ?verbose:bool
|
||||||
-> ?timeout:int
|
-> ?timeout:int
|
||||||
-> ?metasyntax:Matchers.Metasyntax.t
|
-> ?metasyntax:Matchers.Metasyntax.t
|
||||||
-> ?fresh:(unit -> string)
|
-> ?fresh:(unit -> string)
|
||||||
-> Matchers.Configuration.t
|
-> Matchers.Configuration.t
|
||||||
-> single_source
|
-> single_source
|
||||||
-> Specification.t
|
-> Matchers.Specification.t
|
||||||
-> output
|
-> output
|
||||||
|
|
||||||
val execute
|
val execute
|
||||||
: (module Matchers.Matcher.S)
|
: (module Matchers.Matcher.S)
|
||||||
-> ?substitute_in_place:bool
|
|
||||||
-> ?timeout:int
|
-> ?timeout:int
|
||||||
-> ?metasyntax:Matchers.Metasyntax.t
|
-> ?metasyntax:Matchers.Metasyntax.t
|
||||||
-> ?fresh:(unit -> string)
|
-> ?fresh:(unit -> string)
|
||||||
-> ?configuration:Matchers.Configuration.t
|
-> ?configuration:Matchers.Configuration.t
|
||||||
-> single_source
|
-> single_source
|
||||||
-> Specification.t
|
-> Matchers.Specification.t
|
||||||
-> output
|
-> output
|
||||||
|
|
||||||
val with_timeout : int -> Command_input.single_source -> f:(unit -> 'a list) -> 'a list
|
val with_timeout : int -> Command_input.single_source -> f:(unit -> 'a list) -> 'a list
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
module Match = Match
|
module Match = Match
|
||||||
type match' = Match.t
|
type match' = Match.t
|
||||||
|
|
||||||
|
module Replacement = Replacement
|
||||||
|
type replacement = Replacement.result
|
||||||
|
|
||||||
module Matchers = struct
|
module Matchers = struct
|
||||||
|
|
||||||
|
module Engine = Matchers.Engine
|
||||||
|
module Info = Matchers.Info
|
||||||
|
module Language = Matchers.Language
|
||||||
|
|
||||||
module Matcher = Matchers.Matcher
|
module Matcher = Matchers.Matcher
|
||||||
|
|
||||||
module Configuration = Matchers.Configuration
|
module Configuration = Matchers.Configuration
|
||||||
@ -18,25 +26,20 @@ module Matchers = struct
|
|||||||
module Omega = Matchers.Omega
|
module Omega = Matchers.Omega
|
||||||
|
|
||||||
module Languages = Matchers.Languages
|
module Languages = Matchers.Languages
|
||||||
end
|
|
||||||
|
module Rule = struct
|
||||||
module Rule = struct
|
include Matchers.Rule
|
||||||
open Language
|
include Matchers.Rule.Ast
|
||||||
type t = Rule.t
|
include Matchers.Rule.Parser
|
||||||
type result = Rule.result
|
include Matchers.Evaluate
|
||||||
|
end
|
||||||
let sat = Rule.sat
|
type rule = Rule.t
|
||||||
let result_env = Rule.result_env
|
|
||||||
let create = Rule.create
|
module Specification = Matchers.Specification
|
||||||
let apply = Rule.apply
|
type specification = Specification.t
|
||||||
end
|
|
||||||
|
module Rewrite = struct
|
||||||
type rule = Rule.t
|
include Matchers.Rewriter.Rewrite
|
||||||
|
include Matchers.Rewriter.Rewrite_template
|
||||||
module Replacement = Replacement
|
end
|
||||||
type replacement = Replacement.result
|
|
||||||
|
|
||||||
module Rewrite = struct
|
|
||||||
include Rewriter.Rewrite
|
|
||||||
include Rewriter.Rewrite_template
|
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
open Core_kernel
|
|
||||||
|
|
||||||
(** {2 Match}
|
(** {2 Match}
|
||||||
|
|
||||||
A match is a result of matching a template pattern in an input source.
|
A match is a result of matching a template pattern in an input source.
|
||||||
@ -119,10 +117,48 @@ module Match : sig
|
|||||||
(** [pp] is a JSON formatted printer for (optional file path * match list).
|
(** [pp] is a JSON formatted printer for (optional file path * match list).
|
||||||
One line printed per match. *)
|
One line printed per match. *)
|
||||||
val pp_json_lines : Format.formatter -> string option * t list -> unit
|
val pp_json_lines : Format.formatter -> string option * t list -> unit
|
||||||
|
|
||||||
|
val pp_match_count : Format.formatter -> string option * t list -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
type match' = Match.t
|
type match' = Match.t
|
||||||
|
|
||||||
|
(** {2 Replacement}
|
||||||
|
|
||||||
|
Defines the result of a rewrite operation. *)
|
||||||
|
module Replacement : sig
|
||||||
|
(** A replacement consists of the replaced range, the replacement content, and
|
||||||
|
the environment associated with the replacement content. *)
|
||||||
|
type t =
|
||||||
|
{ range : Match.range
|
||||||
|
; replacement_content : string
|
||||||
|
; environment : Match.environment
|
||||||
|
}
|
||||||
|
|
||||||
|
val to_yojson : t -> Yojson.Safe.json
|
||||||
|
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
||||||
|
|
||||||
|
val to_json
|
||||||
|
: ?path:string
|
||||||
|
-> ?replacements:t list
|
||||||
|
-> ?rewritten_source:string
|
||||||
|
-> diff:string
|
||||||
|
-> unit
|
||||||
|
-> Yojson.Safe.json
|
||||||
|
|
||||||
|
(** A replacement result is the rewritten source, and the replacement
|
||||||
|
fragments. *)
|
||||||
|
type result =
|
||||||
|
{ rewritten_source : string
|
||||||
|
; in_place_substitutions : t list
|
||||||
|
}
|
||||||
|
|
||||||
|
val result_to_yojson : result -> Yojson.Safe.json
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
type replacement = Replacement.result
|
||||||
|
|
||||||
(** {2 Matchers}
|
(** {2 Matchers}
|
||||||
|
|
||||||
Defines modules for matching a pattern in input sources to produce
|
Defines modules for matching a pattern in input sources to produce
|
||||||
@ -170,61 +206,6 @@ module Matchers : sig
|
|||||||
|
|
||||||
type configuration = Configuration.t
|
type configuration = Configuration.t
|
||||||
|
|
||||||
(** {3 Syntax}
|
|
||||||
|
|
||||||
Defines the syntax structures for the target language (C, Go, etc.) that
|
|
||||||
are significant for matching. *)
|
|
||||||
module Syntax : sig
|
|
||||||
|
|
||||||
(** Defines a set of quoted syntax for strings based on one or more
|
|
||||||
delimiters and associated escape chracter.
|
|
||||||
|
|
||||||
E.g., this supports single and double quotes with escape character '\'
|
|
||||||
as: { delimiters = [ {|"|}, {|'|} ]; escape_character = '\\' } *)
|
|
||||||
type escapable_string_literals =
|
|
||||||
{ delimiters : string list
|
|
||||||
; escape_character: char
|
|
||||||
}
|
|
||||||
|
|
||||||
(** Defines comment syntax as one of Multiline, Nested_multiline with
|
|
||||||
associated left and right delimiters, or Until_newline that defines a
|
|
||||||
comment prefix. associated prefix. *)
|
|
||||||
type comment_kind =
|
|
||||||
| Multiline of string * string
|
|
||||||
| Nested_multiline of string * string
|
|
||||||
| Until_newline of string
|
|
||||||
|
|
||||||
(** Defines syntax as:
|
|
||||||
|
|
||||||
- [user_defined_delimiters] are delimiters treated as code structures
|
|
||||||
(parentheses, brackets, braces, alphabetic words) -
|
|
||||||
[escapable_string_literals] are escapable quoted strings
|
|
||||||
|
|
||||||
- [raw_string literals] are raw quoted strings that have no escape
|
|
||||||
character
|
|
||||||
|
|
||||||
- [comments] are comment structures *)
|
|
||||||
type t =
|
|
||||||
{ user_defined_delimiters : (string * string) list
|
|
||||||
; escapable_string_literals : escapable_string_literals option [@default None]
|
|
||||||
; raw_string_literals : (string * string) list
|
|
||||||
; comments : comment_kind list
|
|
||||||
}
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
|
|
||||||
(** The module signature that defines language syntax for a matcher *)
|
|
||||||
module type S = sig
|
|
||||||
val user_defined_delimiters : (string * string) list
|
|
||||||
val escapable_string_literals : escapable_string_literals option
|
|
||||||
val raw_string_literals : (string * string) list
|
|
||||||
val comments : comment_kind list
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
type syntax = Syntax.t
|
|
||||||
|
|
||||||
(** {3 Hole}
|
(** {3 Hole}
|
||||||
|
|
||||||
The kinds of holes with associated matching behavior:
|
The kinds of holes with associated matching behavior:
|
||||||
@ -305,12 +286,18 @@ module Matchers : sig
|
|||||||
; identifier : string
|
; identifier : string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val to_yojson : t -> Yojson.Safe.json
|
||||||
|
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
||||||
|
|
||||||
(** A module signature for metasyntax to parameterize a matcher *)
|
(** A module signature for metasyntax to parameterize a matcher *)
|
||||||
module type S = sig
|
module type S = sig
|
||||||
val syntax : hole_syntax list
|
val syntax : hole_syntax list
|
||||||
val identifier : string
|
val identifier : string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(** A module representing the default metasyntax *)
|
||||||
|
module Default : S
|
||||||
|
|
||||||
(** The default metasyntax. It is defined as:
|
(** The default metasyntax. It is defined as:
|
||||||
|
|
||||||
let default_syntax =
|
let default_syntax =
|
||||||
@ -343,14 +330,15 @@ module Matchers : sig
|
|||||||
(** {3 Matcher}
|
(** {3 Matcher}
|
||||||
|
|
||||||
Defines the functions that a matcher can perform. *)
|
Defines the functions that a matcher can perform. *)
|
||||||
module Matcher : sig
|
module rec Matcher : sig
|
||||||
module type S = sig
|
module type S = sig
|
||||||
(** [all conf nested template source] finds all matches of [template] in
|
(** [all conf nested template source] finds all matches of [template] in
|
||||||
[source]. If [nested] is true, template matching will descend
|
[source]. If [nested] is true, template matching will descend
|
||||||
recursively on matched content. *)
|
recursively on matched content. *)
|
||||||
val all
|
val all
|
||||||
: ?configuration:configuration
|
: ?configuration:configuration
|
||||||
-> ?nested: bool
|
-> ?rule:Rule.t
|
||||||
|
-> ?nested:bool
|
||||||
-> template:string
|
-> template:string
|
||||||
-> source:string
|
-> source:string
|
||||||
-> unit
|
-> unit
|
||||||
@ -363,7 +351,7 @@ module Matchers : sig
|
|||||||
-> ?shift:int
|
-> ?shift:int
|
||||||
-> string
|
-> string
|
||||||
-> string
|
-> string
|
||||||
-> match' Or_error.t
|
-> match' Core_kernel.Or_error.t
|
||||||
|
|
||||||
(** [name] returns the name of this matcher (e.g., "C", "Go", etc.). *)
|
(** [name] returns the name of this matcher (e.g., "C", "Go", etc.). *)
|
||||||
val name : string
|
val name : string
|
||||||
@ -377,175 +365,356 @@ module Matchers : sig
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(** {2 Rule}
|
||||||
|
|
||||||
|
Defines types and operations for match rules. *)
|
||||||
|
and Rule : sig
|
||||||
|
|
||||||
|
module Ast : sig
|
||||||
|
type atom =
|
||||||
|
| Variable of string
|
||||||
|
| String of string
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type antecedent = atom
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type expression =
|
||||||
|
| True
|
||||||
|
| False
|
||||||
|
| Option of string
|
||||||
|
| Equal of atom * atom
|
||||||
|
| Not_equal of atom * atom
|
||||||
|
| Match of atom * (antecedent * consequent) list
|
||||||
|
| RewriteTemplate of string
|
||||||
|
| Rewrite of atom * (antecedent * expression)
|
||||||
|
and consequent = expression list
|
||||||
|
[@@deriving sexp]
|
||||||
|
end
|
||||||
|
|
||||||
|
type t = Ast.expression list
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type options =
|
||||||
|
{ nested : bool
|
||||||
|
}
|
||||||
|
|
||||||
|
val create : string -> t Core_kernel.Or_error.t
|
||||||
|
|
||||||
|
val options : t -> options
|
||||||
|
|
||||||
|
type result
|
||||||
|
|
||||||
|
(** [sat result] returns true if a result of a rule is satisfied. *)
|
||||||
|
val sat : result -> bool
|
||||||
|
|
||||||
|
val result_env : result -> Match.environment option
|
||||||
|
|
||||||
|
(** [apply matcher substitute_in_place fresh metasyntax rule env] applies a [rule]
|
||||||
|
according to some [matcher] for existing matches in [env]. If
|
||||||
|
[substitute_in_place] is true, rewrite rules substitute their values in
|
||||||
|
place (default true). [fresh] introduces fresh variables for evaluating
|
||||||
|
rules. [metasyntax] uses the custom metasyntax definition. *)
|
||||||
|
val apply :
|
||||||
|
?substitute_in_place:bool ->
|
||||||
|
?fresh:(unit -> string) ->
|
||||||
|
?metasyntax:Metasyntax.t ->
|
||||||
|
match_all:(?configuration:Configuration.t ->
|
||||||
|
template:string -> source:string -> unit -> Match.t list) ->
|
||||||
|
Rule.Ast.expression list ->
|
||||||
|
Match.Environment.t -> result
|
||||||
|
end
|
||||||
|
|
||||||
|
type rule = Rule.t
|
||||||
|
|
||||||
|
(** {3 Specification}
|
||||||
|
|
||||||
|
Defines an internal type that represents an atomic operation for matching,
|
||||||
|
rule application and rewriting. *)
|
||||||
|
module Specification : sig
|
||||||
|
type t =
|
||||||
|
{ match_template : string
|
||||||
|
; rule : Rule.t option
|
||||||
|
; rewrite_template : string option
|
||||||
|
}
|
||||||
|
|
||||||
|
(** [create rewrite_template rule match_template] creates a new specification.
|
||||||
|
If [rule] is supplied, it will be applied to matches of [match_template].
|
||||||
|
If [rewrite_template] is supplied, running a specification will return
|
||||||
|
replacements rather than just matches (see [process_single_source] below).
|
||||||
|
*)
|
||||||
|
val create : ?rewrite_template:string -> ?rule:rule -> match_template:string -> unit -> t
|
||||||
|
end
|
||||||
|
|
||||||
|
type specification = Specification.t
|
||||||
|
|
||||||
|
(** {3 Syntax}
|
||||||
|
|
||||||
|
Defines the syntax structures for the target language (C, Go, etc.) that
|
||||||
|
are significant for matching. *)
|
||||||
|
module Syntax : sig
|
||||||
|
|
||||||
|
(** Defines a set of quoted syntax for strings based on one or more
|
||||||
|
delimiters and associated escape chracter.
|
||||||
|
|
||||||
|
E.g., this supports single and double quotes with escape character '\'
|
||||||
|
as: { delimiters = [ {|"|}, {|'|} ]; escape_character = '\\' } *)
|
||||||
|
type escapable_string_literals =
|
||||||
|
{ delimiters : string list
|
||||||
|
; escape_character: char
|
||||||
|
}
|
||||||
|
|
||||||
|
(** Defines comment syntax as one of Multiline, Nested_multiline with
|
||||||
|
associated left and right delimiters, or Until_newline that defines a
|
||||||
|
comment prefix. associated prefix. *)
|
||||||
|
type comment_kind =
|
||||||
|
| Multiline of string * string
|
||||||
|
| Nested_multiline of string * string
|
||||||
|
| Until_newline of string
|
||||||
|
|
||||||
|
(** Defines syntax as:
|
||||||
|
|
||||||
|
- [user_defined_delimiters] are delimiters treated as code structures
|
||||||
|
(parentheses, brackets, braces, alphabetic words) -
|
||||||
|
[escapable_string_literals] are escapable quoted strings
|
||||||
|
|
||||||
|
- [raw_string literals] are raw quoted strings that have no escape
|
||||||
|
character
|
||||||
|
|
||||||
|
- [comments] are comment structures *)
|
||||||
|
type t =
|
||||||
|
{ user_defined_delimiters : (string * string) list
|
||||||
|
; escapable_string_literals : escapable_string_literals option [@default None]
|
||||||
|
; raw_string_literals : (string * string) list
|
||||||
|
; comments : comment_kind list
|
||||||
|
}
|
||||||
|
|
||||||
|
val to_yojson : t -> Yojson.Safe.json
|
||||||
|
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
||||||
|
|
||||||
|
(** The module signature that defines language syntax for a matcher *)
|
||||||
|
module type S = sig
|
||||||
|
val user_defined_delimiters : (string * string) list
|
||||||
|
val escapable_string_literals : escapable_string_literals option
|
||||||
|
val raw_string_literals : (string * string) list
|
||||||
|
val comments : comment_kind list
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
type syntax = Syntax.t
|
||||||
|
|
||||||
|
module Info : sig
|
||||||
|
module type S = sig
|
||||||
|
val name : string
|
||||||
|
val extensions : string list
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Language : sig
|
||||||
|
module type S = sig
|
||||||
|
module Info : Info.S
|
||||||
|
module Syntax : Syntax.S
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Languages : sig
|
||||||
|
module Text : Language.S
|
||||||
|
module Paren : Language.S
|
||||||
|
module Dyck : Language.S
|
||||||
|
module JSON : Language.S
|
||||||
|
module JSONC : Language.S
|
||||||
|
module GraphQL : Language.S
|
||||||
|
module Dhall : Language.S
|
||||||
|
module Latex : Language.S
|
||||||
|
module Assembly : Language.S
|
||||||
|
module Clojure : Language.S
|
||||||
|
module Lisp : Language.S
|
||||||
|
module Generic : Language.S
|
||||||
|
module Bash : Language.S
|
||||||
|
module Ruby : Language.S
|
||||||
|
module Elixir : Language.S
|
||||||
|
module Python : Language.S
|
||||||
|
module Html : Language.S
|
||||||
|
module Xml : Language.S
|
||||||
|
module SQL : Language.S
|
||||||
|
module Erlang : Language.S
|
||||||
|
module C : Language.S
|
||||||
|
module Csharp : Language.S
|
||||||
|
module Java : Language.S
|
||||||
|
module CSS : Language.S
|
||||||
|
module Kotlin : Language.S
|
||||||
|
module Scala : Language.S
|
||||||
|
module Nim : Language.S
|
||||||
|
module Dart : Language.S
|
||||||
|
module Php : Language.S
|
||||||
|
module Go : Language.S
|
||||||
|
module Javascript : Language.S
|
||||||
|
module Jsx : Language.S
|
||||||
|
module Typescript : Language.S
|
||||||
|
module Tsx : Language.S
|
||||||
|
module Swift : Language.S
|
||||||
|
module Rust : Language.S
|
||||||
|
module OCaml : Language.S
|
||||||
|
module Reason : Language.S
|
||||||
|
module Fsharp : Language.S
|
||||||
|
module Pascal : Language.S
|
||||||
|
module Julia : Language.S
|
||||||
|
module Fortran : Language.S
|
||||||
|
module Haskell : Language.S
|
||||||
|
module Elm : Language.S
|
||||||
|
module Zig : Language.S
|
||||||
|
module Coq : Language.S
|
||||||
|
module Move : Language.S
|
||||||
|
module Solidity : Language.S
|
||||||
|
module C_nested_comments : Language.S
|
||||||
|
|
||||||
|
val all : (module Language.S) list
|
||||||
|
|
||||||
|
val select_with_extension : string -> (module Language.S) option
|
||||||
|
end
|
||||||
|
|
||||||
|
module Engine : sig
|
||||||
|
module type S = sig
|
||||||
|
module Make : Language.S -> Metasyntax.S -> Matcher.S
|
||||||
|
|
||||||
|
(** {4 Supported Matchers} *)
|
||||||
|
module Text : Matcher.S
|
||||||
|
module Paren : Matcher.S
|
||||||
|
module Dyck : Matcher.S
|
||||||
|
module JSON : Matcher.S
|
||||||
|
module JSONC : Matcher.S
|
||||||
|
module GraphQL : Matcher.S
|
||||||
|
module Dhall : Matcher.S
|
||||||
|
module Latex : Matcher.S
|
||||||
|
module Assembly : Matcher.S
|
||||||
|
module Clojure : Matcher.S
|
||||||
|
module Lisp : Matcher.S
|
||||||
|
module Generic : Matcher.S
|
||||||
|
module Bash : Matcher.S
|
||||||
|
module Ruby : Matcher.S
|
||||||
|
module Elixir : Matcher.S
|
||||||
|
module Python : Matcher.S
|
||||||
|
module Html : Matcher.S
|
||||||
|
module Xml : Matcher.S
|
||||||
|
module SQL : Matcher.S
|
||||||
|
module Erlang : Matcher.S
|
||||||
|
module C : Matcher.S
|
||||||
|
module Csharp : Matcher.S
|
||||||
|
module Java : Matcher.S
|
||||||
|
module CSS : Matcher.S
|
||||||
|
module Kotlin : Matcher.S
|
||||||
|
module Scala : Matcher.S
|
||||||
|
module Nim : Matcher.S
|
||||||
|
module Dart : Matcher.S
|
||||||
|
module Php : Matcher.S
|
||||||
|
module Go : Matcher.S
|
||||||
|
module Javascript : Matcher.S
|
||||||
|
module Jsx : Matcher.S
|
||||||
|
module Typescript : Matcher.S
|
||||||
|
module Tsx : Matcher.S
|
||||||
|
module Swift : Matcher.S
|
||||||
|
module Rust : Matcher.S
|
||||||
|
module OCaml : Matcher.S
|
||||||
|
module Reason : Matcher.S
|
||||||
|
module Fsharp : Matcher.S
|
||||||
|
module Pascal : Matcher.S
|
||||||
|
module Julia : Matcher.S
|
||||||
|
module Fortran : Matcher.S
|
||||||
|
module Haskell : Matcher.S
|
||||||
|
module Elm : Matcher.S
|
||||||
|
module Zig: Matcher.S
|
||||||
|
module Coq: Matcher.S
|
||||||
|
module Move: Matcher.S
|
||||||
|
module Solidity: Matcher.S
|
||||||
|
module C_nested_comments : Matcher.S
|
||||||
|
|
||||||
|
(** [all] returns all default matchers. *)
|
||||||
|
val all : (module Matcher.S) list
|
||||||
|
|
||||||
|
(** [select_with_extension metasyntax file_extension] is a convenience
|
||||||
|
function that returns a matcher associated with a [file_extension]. E.g.,
|
||||||
|
use ".c" to get the C matcher. For a full list of extensions associated
|
||||||
|
with matchers, run comby -list. If [metasyntax] is specified, the matcher
|
||||||
|
will use a custom metasyntax definition instead of the default. *)
|
||||||
|
val select_with_extension : ?metasyntax:Metasyntax.t -> string -> (module Matcher.S) option
|
||||||
|
|
||||||
|
|
||||||
|
(** [create metasyntax syntax] creates a matcher for a language defined by
|
||||||
|
[syntax]. If [metasyntax] is specified, the matcher will use a custom
|
||||||
|
metasyntax definition instead of the default. *)
|
||||||
|
val create : ?metasyntax:Metasyntax.t -> Syntax.t -> (module Matcher.S)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
(** {3 Alpha Matcher}
|
(** {3 Alpha Matcher}
|
||||||
|
|
||||||
Alpha is the match engine that defines default matchers for languages.
|
Alpha is the match engine that defines default matchers for languages.
|
||||||
*)
|
*)
|
||||||
module Alpha : sig
|
module Alpha : Engine.S
|
||||||
(** [select_with_extension metasyntax file_extension] is a convenience
|
|
||||||
function that returns a matcher associated with a [file_extension]. E.g.,
|
|
||||||
use ".c" to get the C matcher. For a full list of extensions associated
|
|
||||||
with matchers, run comby -list. If [metasyntax] is specified, the matcher
|
|
||||||
will use a custom metasyntax definition instead of the default. *)
|
|
||||||
val select_with_extension : ?metasyntax:metasyntax -> string -> (module Matcher.S) option
|
|
||||||
|
|
||||||
(** [create metasyntax syntax] creates a matcher for a language defined by
|
(** {3 Omega Matcher}
|
||||||
[syntax]. If [metasyntax] is specified, the matcher will use a custom
|
|
||||||
metasyntax definition instead of the default. *)
|
|
||||||
val create : ?metasyntax:metasyntax -> syntax -> (module Matcher.S)
|
|
||||||
|
|
||||||
(** [all] returns all default matchers. *)
|
Alternative, partial, experimental match engine.
|
||||||
val all : (module Matcher.S) list
|
*)
|
||||||
|
module Omega : Engine.S
|
||||||
|
|
||||||
(** {4 Supported Matchers} *)
|
(** {3 Rewrite}
|
||||||
module Text : Matcher.S
|
|
||||||
module Paren : Matcher.S
|
Defines rewrite operations. *)
|
||||||
module Dyck : Matcher.S
|
module Rewrite : sig
|
||||||
module JSON : Matcher.S
|
(** [all source metasyntax fresh rewrite_template matches] substitutes
|
||||||
module JSONC : Matcher.S
|
[rewrite_template] with each match in [matches] to create a rewrite result.
|
||||||
module GraphQL : Matcher.S
|
If [source] is specified, each rewrite result is substituted in-place in
|
||||||
module Dhall : Matcher.S
|
the source. If [source] is not specified, rewritten matches are
|
||||||
module Latex : Matcher.S
|
newline-separated. If [metasyntax] is defined, the rewrite template will
|
||||||
module Assembly : Matcher.S
|
respect custom metasyntax definitions.
|
||||||
module Clojure : Matcher.S
|
|
||||||
module Lisp : Matcher.S
|
If the rewrite template contains the syntax :[id()], then it is
|
||||||
module Generic : Matcher.S
|
substituted with fresh values. [fresh] may be specified to supply custom
|
||||||
module Bash : Matcher.S
|
fresh values. If not specified, fresh variables are generated in increasing
|
||||||
module Ruby : Matcher.S
|
rank starting with 1, and incremented. See [substitute] for more. *)
|
||||||
module Elixir : Matcher.S
|
val all
|
||||||
module Python : Matcher.S
|
: ?source:string
|
||||||
module Html : Matcher.S
|
-> ?metasyntax:metasyntax
|
||||||
module Xml : Matcher.S
|
-> ?fresh:(unit -> string)
|
||||||
module SQL : Matcher.S
|
-> rewrite_template:string
|
||||||
module Erlang : Matcher.S
|
-> match' list
|
||||||
module C : Matcher.S
|
-> replacement option
|
||||||
module Csharp : Matcher.S
|
|
||||||
module Java : Matcher.S
|
(** [substitute metasyntax fresh template environment] substitutes [template]
|
||||||
module CSS : Matcher.S
|
with the variable and value pairs in the [environment]. It returns the
|
||||||
module Kotlin : Matcher.S
|
result after substitution, and the list of variables in [environment] that
|
||||||
module Scala : Matcher.S
|
were substituted for. If [metasyntax] is defined, the rewrite template will
|
||||||
module Nim : Matcher.S
|
respect custom metasyntax definitions.
|
||||||
module Dart : Matcher.S
|
|
||||||
module Php : Matcher.S
|
The syntax :[id()] is substituted with fresh values. If [fresh] is not
|
||||||
module Go : Matcher.S
|
specified, the default behavior substitutes :[id()] starting with 1, and
|
||||||
module Javascript : Matcher.S
|
subsequent :[id()] values increment the ID. If [fresh] is set, substitutes
|
||||||
module Jsx : Matcher.S
|
the pattern :[id()] with the value of fresh () as the hole is encountered,
|
||||||
module Typescript : Matcher.S
|
left to right. *)
|
||||||
module Tsx : Matcher.S
|
val substitute
|
||||||
module Swift : Matcher.S
|
: ?metasyntax:metasyntax
|
||||||
module Rust : Matcher.S
|
-> ?fresh:(unit -> string)
|
||||||
module OCaml : Matcher.S
|
-> string
|
||||||
module Reason : Matcher.S
|
-> Match.environment
|
||||||
module Fsharp : Matcher.S
|
-> (string * string list)
|
||||||
module Pascal : Matcher.S
|
|
||||||
module Julia : Matcher.S
|
type syntax =
|
||||||
module Fortran : Matcher.S
|
{ variable: string
|
||||||
module Haskell : Matcher.S
|
; pattern: string
|
||||||
module Elm : Matcher.S
|
}
|
||||||
module Zig : Matcher.S
|
|
||||||
module Coq : Matcher.S
|
type extracted =
|
||||||
module Move : Matcher.S
|
| Hole of syntax
|
||||||
module Solidity : Matcher.S
|
| Constant of string
|
||||||
module C_nested_comments : Matcher.S
|
|
||||||
|
module Make : Metasyntax.S -> sig
|
||||||
|
val parse : string -> extracted list option
|
||||||
|
val variables : string -> syntax list
|
||||||
|
end
|
||||||
|
|
||||||
|
val get_offsets_for_holes : syntax list -> string -> (string * int) list
|
||||||
|
|
||||||
|
val get_offsets_after_substitution : (string * int) list -> Match.environment -> (string * int) list
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
(** {2 Rule}
|
|
||||||
|
|
||||||
Defines types and operations for match rules. *)
|
|
||||||
module Rule : sig
|
|
||||||
type t
|
|
||||||
type result
|
|
||||||
|
|
||||||
(** [sat result] returns true if a result of a rule is satisfied. *)
|
|
||||||
val sat : result -> bool
|
|
||||||
|
|
||||||
(** [result_env] returns a match environment associated with a rule result. *)
|
|
||||||
val result_env : result -> Match.environment option
|
|
||||||
|
|
||||||
(** [create] parses and creates a rule. *)
|
|
||||||
val create : string -> t Or_error.t
|
|
||||||
|
|
||||||
(** [apply matcher substitute_in_place fresh metasyntax rule env] applies a [rule]
|
|
||||||
according to some [matcher] for existing matches in [env]. If
|
|
||||||
[substitute_in_place] is true, rewrite rules substitute their values in
|
|
||||||
place (default true). [fresh] introduces fresh variables for evaluating
|
|
||||||
rules. [metasyntax] uses the custom metasyntax definition. *)
|
|
||||||
val apply
|
|
||||||
: ?matcher:(module Matchers.Matcher.S)
|
|
||||||
-> ?substitute_in_place:bool
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> ?metasyntax:Matchers.Metasyntax.t
|
|
||||||
-> t
|
|
||||||
-> Match.environment
|
|
||||||
-> result
|
|
||||||
end
|
|
||||||
|
|
||||||
type rule = Rule.t
|
|
||||||
|
|
||||||
(** {2 Replacement}
|
|
||||||
|
|
||||||
Defines the result of a rewrite operation. *)
|
|
||||||
module Replacement : sig
|
|
||||||
(** A replacement consists of the replaced range, the replacement content, and
|
|
||||||
the environment associated with the replacement content. *)
|
|
||||||
type t =
|
|
||||||
{ range : Match.range
|
|
||||||
; replacement_content : string
|
|
||||||
; environment : Match.environment
|
|
||||||
}
|
|
||||||
|
|
||||||
(** A replacement result is the rewritten source, and the replacement
|
|
||||||
fragments. *)
|
|
||||||
type result =
|
|
||||||
{ rewritten_source : string
|
|
||||||
; in_place_substitutions : t list
|
|
||||||
}
|
|
||||||
|
|
||||||
val to_yojson : t -> Yojson.Safe.json
|
|
||||||
val of_yojson : Yojson.Safe.json -> (t, string) Result.t
|
|
||||||
end
|
|
||||||
|
|
||||||
type replacement = Replacement.result
|
|
||||||
|
|
||||||
(** {2 Rewrite}
|
|
||||||
|
|
||||||
Defines rewrite operations. *)
|
|
||||||
module Rewrite : sig
|
|
||||||
(** [all source metasyntax fresh rewrite_template matches] substitutes
|
|
||||||
[rewrite_template] with each match in [matches] to create a rewrite result.
|
|
||||||
If [source] is specified, each rewrite result is substituted in-place in
|
|
||||||
the source. If [source] is not specified, rewritten matches are
|
|
||||||
newline-separated. If [metasyntax] is defined, the rewrite template will
|
|
||||||
respect custom metasyntax definitions.
|
|
||||||
|
|
||||||
If the rewrite template contains the syntax :[id()], then it is
|
|
||||||
substituted with fresh values. [fresh] may be specified to supply custom
|
|
||||||
fresh values. If not specified, fresh variables are generated in increasing
|
|
||||||
rank starting with 1, and incremented. See [substitute] for more. *)
|
|
||||||
val all
|
|
||||||
: ?source:string
|
|
||||||
-> ?metasyntax:Matchers.metasyntax
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> rewrite_template:string
|
|
||||||
-> match' list
|
|
||||||
-> replacement option
|
|
||||||
|
|
||||||
(** [substitute metasyntax fresh template environment] substitutes [template]
|
|
||||||
with the variable and value pairs in the [environment]. It returns the
|
|
||||||
result after substitution, and the list of variables in [environment] that
|
|
||||||
were substituted for. If [metasyntax] is defined, the rewrite template will
|
|
||||||
respect custom metasyntax definitions.
|
|
||||||
|
|
||||||
The syntax :[id()] is substituted with fresh values. If [fresh] is not
|
|
||||||
specified, the default behavior substitutes :[id()] starting with 1, and
|
|
||||||
subsequent :[id()] values increment the ID. If [fresh] is set, substitutes
|
|
||||||
the pattern :[id()] with the value of fresh () as the hole is encountered,
|
|
||||||
left to right. *)
|
|
||||||
val substitute
|
|
||||||
: ?metasyntax:Matchers.metasyntax
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> string
|
|
||||||
-> Match.environment
|
|
||||||
-> (string * string list)
|
|
||||||
end
|
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
(preprocess (pps ppx_deriving.show ppx_deriving.eq ppx_sexp_conv))
|
(preprocess (pps ppx_deriving.show ppx_deriving.eq ppx_sexp_conv))
|
||||||
(libraries
|
(libraries
|
||||||
core_kernel
|
core_kernel
|
||||||
comby-kernel.language
|
|
||||||
comby-kernel.match
|
comby-kernel.match
|
||||||
comby-kernel.matchers
|
comby-kernel.matchers
|
||||||
comby-kernel.replacement
|
comby-kernel.replacement))
|
||||||
comby-kernel.rewriter))
|
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
open Core_kernel
|
|
||||||
|
|
||||||
type atom =
|
|
||||||
| Variable of string
|
|
||||||
| String of string
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
type antecedent = atom
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
type expression =
|
|
||||||
| True
|
|
||||||
| False
|
|
||||||
| Option of string
|
|
||||||
| Equal of atom * atom
|
|
||||||
| Not_equal of atom * atom
|
|
||||||
| Match of atom * (antecedent * consequent) list
|
|
||||||
| RewriteTemplate of string
|
|
||||||
| Rewrite of atom * (antecedent * expression)
|
|
||||||
and consequent = expression list
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
let (=) left right = Equal (left, right)
|
|
||||||
|
|
||||||
let (<>) left right = Not_equal (left, right)
|
|
||||||
|
|
||||||
type t = expression list
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
module Script = struct
|
|
||||||
module Specification = struct
|
|
||||||
type t =
|
|
||||||
{ match_template : string
|
|
||||||
; rule : expression list option
|
|
||||||
; rewrite_template : string option
|
|
||||||
}
|
|
||||||
[@@deriving sexp]
|
|
||||||
end
|
|
||||||
|
|
||||||
type spec = Specification.t
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
type op =
|
|
||||||
| And
|
|
||||||
| Or
|
|
||||||
| Not
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
type exp =
|
|
||||||
| Exp of op * exp list
|
|
||||||
| Spec of spec
|
|
||||||
[@@deriving sexp]
|
|
||||||
|
|
||||||
type t = exp list
|
|
||||||
[@@deriving sexp]
|
|
||||||
end
|
|
@ -1,6 +0,0 @@
|
|||||||
(library
|
|
||||||
(name language)
|
|
||||||
(public_name comby-kernel.language)
|
|
||||||
(instrumentation (backend bisect_ppx))
|
|
||||||
(preprocess (pps ppx_sexp_conv))
|
|
||||||
(libraries comby-kernel.parsers comby-kernel.match comby-kernel.rewriter core_kernel))
|
|
@ -1,10 +0,0 @@
|
|||||||
open Core_kernel
|
|
||||||
|
|
||||||
type t =
|
|
||||||
{ nested : bool
|
|
||||||
}
|
|
||||||
|
|
||||||
let of_rule (rule : Ast.t) : t =
|
|
||||||
List.fold rule ~init:{ nested = false } ~f:(fun acc -> function
|
|
||||||
| Option name when String.(name = Syntax.option_nested) -> { nested = true }
|
|
||||||
| _ -> acc)
|
|
@ -1,5 +0,0 @@
|
|||||||
type t =
|
|
||||||
{ nested : bool
|
|
||||||
}
|
|
||||||
|
|
||||||
val of_rule : Ast.t -> t
|
|
@ -1,195 +0,0 @@
|
|||||||
open Core_kernel
|
|
||||||
open Angstrom
|
|
||||||
|
|
||||||
open Ast
|
|
||||||
|
|
||||||
let alphanum =
|
|
||||||
satisfy (function
|
|
||||||
| 'a' .. 'z'
|
|
||||||
| 'A' .. 'Z'
|
|
||||||
| '0' .. '9' -> true
|
|
||||||
| _ -> false)
|
|
||||||
|
|
||||||
let variable_parser =
|
|
||||||
(string Syntax.variable_left_delimiter
|
|
||||||
*> (many (alphanum <|> char '_') >>| String.of_char_list)
|
|
||||||
<* string Syntax.variable_right_delimiter)
|
|
||||||
|
|
||||||
(** Interpret escape sequences inside quotes *)
|
|
||||||
let char_token_s =
|
|
||||||
(char '\\' *> any_char >>|
|
|
||||||
function
|
|
||||||
| 'r' -> Char.to_string '\r'
|
|
||||||
| 'n' -> Char.to_string '\n'
|
|
||||||
| 't' -> Char.to_string '\t'
|
|
||||||
| '\\' -> Char.to_string '\\'
|
|
||||||
| c -> Format.sprintf {|\%c|} c)
|
|
||||||
<|> (any_char >>| String.of_char)
|
|
||||||
|
|
||||||
(** With escape sequences *)
|
|
||||||
let quote s =
|
|
||||||
(string s *> (many_till char_token_s (string s)))
|
|
||||||
>>| String.concat
|
|
||||||
|
|
||||||
let raw s =
|
|
||||||
(string s *> (many_till any_char (string s)))
|
|
||||||
>>| String.of_char_list
|
|
||||||
|
|
||||||
let quoted_parser =
|
|
||||||
choice [ quote {|"|}; quote {|'|}; raw {|`|} ]
|
|
||||||
|
|
||||||
let operator_parser =
|
|
||||||
choice
|
|
||||||
[ string Syntax.equal
|
|
||||||
; string Syntax.not_equal
|
|
||||||
]
|
|
||||||
|
|
||||||
let any_char_except ~reserved =
|
|
||||||
List.fold reserved
|
|
||||||
~init:(return `OK)
|
|
||||||
~f:(fun acc reserved_sequence ->
|
|
||||||
option `End_of_input
|
|
||||||
(peek_string (String.length reserved_sequence)
|
|
||||||
>>= fun s ->
|
|
||||||
if String.equal s reserved_sequence then
|
|
||||||
return `Reserved_sequence
|
|
||||||
else
|
|
||||||
acc))
|
|
||||||
>>= function
|
|
||||||
| `OK -> any_char
|
|
||||||
| `End_of_input -> any_char
|
|
||||||
| `Reserved_sequence -> fail "reserved sequence hit"
|
|
||||||
|
|
||||||
let value_parser ~reserved () =
|
|
||||||
match reserved with
|
|
||||||
| [] -> fail "no value allowed to scan here"
|
|
||||||
| reserved -> many (any_char_except ~reserved)
|
|
||||||
|
|
||||||
let map_special s =
|
|
||||||
if String.is_prefix s ~prefix:"~" then
|
|
||||||
Variable (Format.sprintf ":[%s]" s)
|
|
||||||
else if String.equal s "_" then
|
|
||||||
Variable ":[_]"
|
|
||||||
else
|
|
||||||
String s
|
|
||||||
|
|
||||||
let antecedent_parser ?(reserved = []) () =
|
|
||||||
choice
|
|
||||||
[ (quoted_parser >>| fun value -> String value)
|
|
||||||
; (value_parser ~reserved () >>| fun value -> map_special (String.of_char_list value))
|
|
||||||
]
|
|
||||||
|
|
||||||
let atom_parser ?(reserved = []) () =
|
|
||||||
choice
|
|
||||||
[ (variable_parser >>| fun variable -> Variable variable)
|
|
||||||
; (quoted_parser >>| fun value -> String value)
|
|
||||||
; (value_parser ~reserved () >>| fun value -> String (String.of_char_list value))
|
|
||||||
]
|
|
||||||
|
|
||||||
let rewrite_template_parser =
|
|
||||||
quoted_parser >>| fun value -> RewriteTemplate value
|
|
||||||
|
|
||||||
let ignore p =
|
|
||||||
p *> return ()
|
|
||||||
|
|
||||||
let make_equality_expression left operator right =
|
|
||||||
if String.equal operator Syntax.equal then
|
|
||||||
Equal (left, right)
|
|
||||||
else
|
|
||||||
Not_equal (left, right)
|
|
||||||
|
|
||||||
let is_whitespace = function
|
|
||||||
| ' ' | '\t' | '\r' | '\n' -> true
|
|
||||||
| _ -> false
|
|
||||||
|
|
||||||
let spaces =
|
|
||||||
take_while is_whitespace
|
|
||||||
|
|
||||||
let spaces1 =
|
|
||||||
satisfy is_whitespace *>
|
|
||||||
take_while is_whitespace *>
|
|
||||||
return ()
|
|
||||||
|
|
||||||
let optional_trailing c = option () (skip (Char.equal c))
|
|
||||||
|
|
||||||
let option_parser = spaces *> string Syntax.option_nested <* spaces >>| fun _ -> Option "nested"
|
|
||||||
|
|
||||||
let true' = lift (fun _ -> True) (spaces *> string Syntax.true' <* spaces)
|
|
||||||
|
|
||||||
let false' = lift (fun _ -> False) (spaces *> string Syntax.false' <* spaces)
|
|
||||||
|
|
||||||
(** <atom> [==, !=] <atom> *)
|
|
||||||
let operator_parser =
|
|
||||||
lift3
|
|
||||||
make_equality_expression
|
|
||||||
(spaces *> atom_parser ())
|
|
||||||
(spaces *> operator_parser)
|
|
||||||
(spaces *> atom_parser ())
|
|
||||||
<* spaces
|
|
||||||
|
|
||||||
let make_rewrite_expression atom match_template rewrite_template =
|
|
||||||
Rewrite (atom, (match_template, rewrite_template))
|
|
||||||
|
|
||||||
let make_match_expression atom cases =
|
|
||||||
Match (atom, cases)
|
|
||||||
|
|
||||||
(** rewrite <atom> { <atom> -> <atom> } *)
|
|
||||||
let rewrite_pattern_parser =
|
|
||||||
lift3
|
|
||||||
make_rewrite_expression
|
|
||||||
(string Syntax.start_rewrite_pattern *> spaces *> atom_parser () <* spaces <* char '{' <* spaces)
|
|
||||||
(antecedent_parser ~reserved:[" ->"] () <* spaces <* string Syntax.arrow <* spaces)
|
|
||||||
(spaces *> rewrite_template_parser <* spaces <* char '}' <* spaces)
|
|
||||||
|
|
||||||
(** <atom> -> atom [, <expr>], [,] *)
|
|
||||||
let match_arrow_parser expression_parser =
|
|
||||||
both
|
|
||||||
(antecedent_parser ~reserved:[" ->"] () <* spaces <* string Syntax.arrow <* spaces)
|
|
||||||
(spaces *> sep_by (char ',') expression_parser <* spaces <* optional_trailing ',' <* spaces)
|
|
||||||
|
|
||||||
(** [|] <match_arrow> *)
|
|
||||||
let first_case_parser expression_parser =
|
|
||||||
spaces *> option () (ignore @@ string Syntax.pipe_operator *> spaces) *>
|
|
||||||
match_arrow_parser expression_parser
|
|
||||||
|
|
||||||
(** | <match_arrow> *)
|
|
||||||
let case_parser expression_parser =
|
|
||||||
spaces *> string Syntax.pipe_operator *> spaces *>
|
|
||||||
match_arrow_parser expression_parser
|
|
||||||
|
|
||||||
(** [|] <match_arrow> | <match_arrow> *)
|
|
||||||
let case_block expression_parser =
|
|
||||||
first_case_parser expression_parser >>= fun case ->
|
|
||||||
many (case_parser expression_parser) >>= fun cases ->
|
|
||||||
return (case :: cases)
|
|
||||||
|
|
||||||
(** match <atom> { <case_parser> } *)
|
|
||||||
let match_pattern_parser expression_parser =
|
|
||||||
string Syntax.start_match_pattern *> spaces *>
|
|
||||||
lift2
|
|
||||||
make_match_expression
|
|
||||||
(atom_parser () <* spaces <* char '{' <* spaces)
|
|
||||||
(case_block expression_parser <* char '}' <* spaces)
|
|
||||||
|
|
||||||
let expression_parser =
|
|
||||||
fix (fun expression_parser ->
|
|
||||||
choice
|
|
||||||
[ match_pattern_parser expression_parser
|
|
||||||
; rewrite_pattern_parser
|
|
||||||
; operator_parser
|
|
||||||
; true'
|
|
||||||
; false'
|
|
||||||
; option_parser
|
|
||||||
])
|
|
||||||
|
|
||||||
(** where <expression> [,] *)
|
|
||||||
let parse =
|
|
||||||
spaces *> string Syntax.rule_prefix *>
|
|
||||||
spaces1 *> sep_by1 (spaces *> char ',' <* spaces) expression_parser
|
|
||||||
<* optional_trailing ','
|
|
||||||
<* spaces
|
|
||||||
|
|
||||||
let create rule =
|
|
||||||
match parse_string ~consume:All (parse <* end_of_input) rule with
|
|
||||||
| Ok rule -> Ok rule
|
|
||||||
| Error error -> Or_error.error_string error
|
|
@ -1,5 +0,0 @@
|
|||||||
include Types
|
|
||||||
|
|
||||||
let create = Parser.create
|
|
||||||
|
|
||||||
include Evaluate
|
|
@ -1,7 +0,0 @@
|
|||||||
open Core_kernel
|
|
||||||
|
|
||||||
include module type of Types
|
|
||||||
|
|
||||||
val create : string -> t Or_error.t
|
|
||||||
|
|
||||||
include Engine
|
|
@ -1,25 +0,0 @@
|
|||||||
open Matchers
|
|
||||||
open Match
|
|
||||||
|
|
||||||
type t = Ast.t
|
|
||||||
|
|
||||||
type result = bool * environment option
|
|
||||||
|
|
||||||
type options = Options.t
|
|
||||||
|
|
||||||
module type Engine = sig
|
|
||||||
val options : t -> Options.t
|
|
||||||
|
|
||||||
val sat : result -> bool
|
|
||||||
|
|
||||||
val result_env : result -> environment option
|
|
||||||
|
|
||||||
val apply
|
|
||||||
: ?matcher:(module Matcher.S)
|
|
||||||
-> ?substitute_in_place:bool
|
|
||||||
-> ?fresh:(unit -> string)
|
|
||||||
-> ?metasyntax:Matchers.Metasyntax.t
|
|
||||||
-> t
|
|
||||||
-> environment
|
|
||||||
-> result
|
|
||||||
end
|
|
File diff suppressed because it is too large
Load Diff
@ -3,4 +3,4 @@
|
|||||||
(public_name comby-kernel.matchers)
|
(public_name comby-kernel.matchers)
|
||||||
(instrumentation (backend bisect_ppx))
|
(instrumentation (backend bisect_ppx))
|
||||||
(preprocess (pps ppx_here ppx_sexp_conv ppx_sexp_message ppx_deriving_yojson))
|
(preprocess (pps ppx_here ppx_sexp_conv ppx_sexp_message ppx_deriving_yojson))
|
||||||
(libraries comby-kernel.parsers comby-kernel.match angstrom core_kernel mparser mparser-pcre re yojson ppx_deriving_yojson))
|
(libraries comby-kernel.replacement comby-kernel.parsers comby-kernel.match angstrom core_kernel mparser mparser-pcre re yojson ppx_deriving_yojson))
|
||||||
|
@ -1,19 +1,15 @@
|
|||||||
open Core_kernel
|
open Core_kernel
|
||||||
|
|
||||||
open Match
|
open Match
|
||||||
open Rewriter
|
open Rule
|
||||||
|
|
||||||
open Ast
|
open Ast
|
||||||
|
|
||||||
module Configuration = Matchers.Configuration
|
let debug =
|
||||||
|
match Sys.getenv "DEBUG_COMBY" with
|
||||||
|
| exception Not_found -> false
|
||||||
|
| _ -> true
|
||||||
|
|
||||||
type t = Ast.t
|
type result = bool * Match.environment option
|
||||||
|
|
||||||
type result = bool * environment option
|
|
||||||
|
|
||||||
type options = Options.t
|
|
||||||
|
|
||||||
let options = Options.of_rule
|
|
||||||
|
|
||||||
let sat = fst
|
let sat = fst
|
||||||
|
|
||||||
@ -42,21 +38,20 @@ let counter =
|
|||||||
uuid_for_id_counter := !uuid_for_id_counter + 1;
|
uuid_for_id_counter := !uuid_for_id_counter + 1;
|
||||||
Format.sprintf "gu3ssme_%012d" !uuid_for_id_counter
|
Format.sprintf "gu3ssme_%012d" !uuid_for_id_counter
|
||||||
|
|
||||||
|
let equal_in_environment var value env =
|
||||||
|
match Environment.lookup env var with
|
||||||
|
| None -> false, Some env
|
||||||
|
| Some var_value -> String.equal var_value value, Some env
|
||||||
|
|
||||||
let rec apply
|
let rec apply
|
||||||
?(matcher = (module Matchers.Alpha.Generic : Matchers.Matcher.S))
|
|
||||||
?(substitute_in_place = true)
|
?(substitute_in_place = true)
|
||||||
?(fresh = counter)
|
?(fresh = counter)
|
||||||
?metasyntax
|
?metasyntax
|
||||||
|
~(match_all:(?configuration:Configuration.t -> template:string -> source:string -> unit -> Match.t list))
|
||||||
predicates
|
predicates
|
||||||
env =
|
env =
|
||||||
let open Option in
|
let open Option in
|
||||||
let (module Matcher) = matcher in
|
|
||||||
|
|
||||||
let equal_in_environment var value env =
|
|
||||||
match Environment.lookup env var with
|
|
||||||
| None -> false, Some env
|
|
||||||
| Some var_value -> String.equal var_value value, Some env
|
|
||||||
in
|
|
||||||
(* accepts only one expression *)
|
(* accepts only one expression *)
|
||||||
let rec rule_match ?(rewrite_context : rewrite_context option) env =
|
let rec rule_match ?(rewrite_context : rewrite_context option) env =
|
||||||
function
|
function
|
||||||
@ -79,14 +74,18 @@ let rec apply
|
|||||||
let sat, env = rule_match env (Equal (left, right)) in
|
let sat, env = rule_match env (Equal (left, right)) in
|
||||||
not sat, env
|
not sat, env
|
||||||
| Match (Variable variable, cases) ->
|
| Match (Variable variable, cases) ->
|
||||||
|
if debug then Format.printf "ENV: %s@." (Environment.to_string env);
|
||||||
let result =
|
let result =
|
||||||
Environment.lookup env variable >>= fun source ->
|
Environment.lookup env variable >>= fun source ->
|
||||||
let evaluate template case_expression =
|
let evaluate template case_expression =
|
||||||
let configuration = match_configuration_of_syntax template in
|
let configuration = match_configuration_of_syntax template in
|
||||||
Matcher.all ~configuration ~template ~source () |> function
|
if debug then Format.printf "Running for template %s source %s@." template source;
|
||||||
| [] -> None
|
match_all ~configuration ~template ~source () |> function
|
||||||
|
| [] ->
|
||||||
|
None
|
||||||
| matches ->
|
| matches ->
|
||||||
(* merge environments. overwrite behavior is undefined *)
|
(* merge environments. overwrite behavior is undefined *)
|
||||||
|
if debug then Format.printf "Matches: %a@." Match.pp (None, matches);
|
||||||
let fold_matches (sat, out) { environment; _ } =
|
let fold_matches (sat, out) { environment; _ } =
|
||||||
let fold_cases (sat, out) predicate =
|
let fold_cases (sat, out) predicate =
|
||||||
if sat then
|
if sat then
|
||||||
@ -138,7 +137,7 @@ let rec apply
|
|||||||
let result =
|
let result =
|
||||||
Environment.lookup env variable >>= fun source ->
|
Environment.lookup env variable >>= fun source ->
|
||||||
let configuration = Configuration.create ~match_kind:Fuzzy () in
|
let configuration = Configuration.create ~match_kind:Fuzzy () in
|
||||||
let matches = Matcher.all ~configuration ~template ~source () in
|
let matches = match_all ~configuration ~template ~source () in
|
||||||
let source = if substitute_in_place then Some source else None in
|
let source = if substitute_in_place then Some source else None in
|
||||||
let result = Rewrite.all ?metasyntax ?source ~rewrite_template matches in
|
let result = Rewrite.all ?metasyntax ?source ~rewrite_template matches in
|
||||||
match result with
|
match result with
|
@ -1,12 +1,20 @@
|
|||||||
module Configuration = Configuration
|
module Configuration = Configuration
|
||||||
module Languages = Languages
|
module Languages = Languages
|
||||||
module Metasyntax = Metasyntax
|
module Metasyntax = Metasyntax
|
||||||
|
module Rule = Rule
|
||||||
|
module Evaluate = Evaluate
|
||||||
|
|
||||||
module Alpha = Engine.Make(Alpha.Make)
|
module Alpha = Engine.Make(Alpha.Make)
|
||||||
module Omega = Engine.Make(Omega.Make)
|
module Omega = Engine.Make(Omega.Make)
|
||||||
|
|
||||||
module Engine = Types.Engine
|
module Engine = Types.Engine
|
||||||
module Matcher = Types.Matcher
|
module Matcher = Types.Matcher
|
||||||
|
module Info = Types.Info
|
||||||
module Syntax = Types.Syntax
|
module Syntax = Types.Syntax
|
||||||
module Hole = Types.Hole
|
module Hole = Types.Hole
|
||||||
module Language = Types.Language
|
module Language = Types.Language
|
||||||
|
module Script = Script
|
||||||
|
|
||||||
|
module Specification = Specification
|
||||||
|
|
||||||
|
module Rewriter = Rewriter
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
module Configuration = Configuration
|
module Configuration = Configuration
|
||||||
module Languages = Languages
|
module Languages = Languages
|
||||||
module Metasyntax = Metasyntax
|
module Metasyntax = Metasyntax
|
||||||
|
module Rule = Rule
|
||||||
|
module Evaluate = Evaluate
|
||||||
|
|
||||||
module Alpha : Types.Engine.S
|
module Alpha : Types.Engine.S
|
||||||
module Omega : Types.Engine.S
|
module Omega : Types.Engine.S
|
||||||
|
|
||||||
module Engine = Types.Engine
|
module Engine = Types.Engine
|
||||||
module Matcher = Types.Matcher
|
module Matcher = Types.Matcher
|
||||||
|
module Info = Types.Info
|
||||||
module Syntax = Types.Syntax
|
module Syntax = Types.Syntax
|
||||||
module Hole = Types.Hole
|
module Hole = Types.Hole
|
||||||
module Language = Types.Language
|
module Language = Types.Language
|
||||||
|
module Script : module type of Script
|
||||||
|
|
||||||
|
module Specification : module type of Specification
|
||||||
|
|
||||||
|
module Rewriter = Rewriter
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,10 @@ let debug =
|
|||||||
identifiers that contain -, etc. *)
|
identifiers that contain -, etc. *)
|
||||||
let match_context_syntax =
|
let match_context_syntax =
|
||||||
let identifier = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" in
|
let identifier = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" in
|
||||||
Matchers.Metasyntax.{ default_metasyntax with identifier }
|
Metasyntax.{ default_metasyntax with identifier }
|
||||||
|
|
||||||
let match_context_metasyntax =
|
let match_context_metasyntax =
|
||||||
Matchers.Metasyntax.(create match_context_syntax)
|
Metasyntax.(create match_context_syntax)
|
||||||
|
|
||||||
module Match_context_metasyntax = (val match_context_metasyntax)
|
module Match_context_metasyntax = (val match_context_metasyntax)
|
||||||
module Match_context_template = Rewrite_template.Make(Match_context_metasyntax)
|
module Match_context_template = Rewrite_template.Make(Match_context_metasyntax)
|
||||||
@ -69,10 +69,10 @@ let substitute_match_contexts ?fresh (matches: Match.t list) source replacements
|
|||||||
*)
|
*)
|
||||||
let substitute_in_rewrite_template
|
let substitute_in_rewrite_template
|
||||||
?fresh
|
?fresh
|
||||||
?(metasyntax = Matchers.Metasyntax.default_metasyntax)
|
?(metasyntax = Metasyntax.default_metasyntax)
|
||||||
rewrite_template
|
rewrite_template
|
||||||
({ environment; _ } : Match.t) =
|
({ environment; _ } : Match.t) =
|
||||||
let (module M) = Matchers.Metasyntax.create metasyntax in
|
let (module M) = Metasyntax.create metasyntax in
|
||||||
let module Template_parser = Rewrite_template.Make(M) in
|
let module Template_parser = Rewrite_template.Make(M) in
|
||||||
let variables = Template_parser.variables rewrite_template in
|
let variables = Template_parser.variables rewrite_template in
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
emit result separated by newlines *)
|
emit result separated by newlines *)
|
||||||
val all
|
val all
|
||||||
: ?source:string
|
: ?source:string
|
||||||
-> ?metasyntax:Matchers.Metasyntax.t
|
-> ?metasyntax:Types.Metasyntax.t
|
||||||
-> ?fresh:(unit -> string)
|
-> ?fresh:(unit -> string)
|
||||||
-> rewrite_template:string
|
-> rewrite_template:string
|
||||||
-> Match.t list
|
-> Match.t list
|
@ -8,7 +8,10 @@ let debug =
|
|||||||
| exception Not_found -> false
|
| exception Not_found -> false
|
||||||
| _ -> true
|
| _ -> true
|
||||||
|
|
||||||
type syntax = { variable: string; pattern: string }
|
type syntax =
|
||||||
|
{ variable: string
|
||||||
|
; pattern: string
|
||||||
|
}
|
||||||
[@@deriving sexp_of]
|
[@@deriving sexp_of]
|
||||||
|
|
||||||
type extracted =
|
type extracted =
|
||||||
@ -16,7 +19,7 @@ type extracted =
|
|||||||
| Constant of string
|
| Constant of string
|
||||||
[@@deriving sexp_of]
|
[@@deriving sexp_of]
|
||||||
|
|
||||||
module Make (Metasyntax : Matchers.Metasyntax.S) = struct
|
module Make (Metasyntax : Types.Metasyntax.S) = struct
|
||||||
|
|
||||||
let alphanum =
|
let alphanum =
|
||||||
satisfy (function
|
satisfy (function
|
||||||
@ -148,7 +151,7 @@ let sub_counter =
|
|||||||
Format.sprintf "sub_%d" !uuid_for_sub_counter
|
Format.sprintf "sub_%d" !uuid_for_sub_counter
|
||||||
|
|
||||||
let replacement_sentinel metasyntax =
|
let replacement_sentinel metasyntax =
|
||||||
let open Matchers.Metasyntax in
|
let open Types.Metasyntax in
|
||||||
List.find_map metasyntax.syntax ~f:(function
|
List.find_map metasyntax.syntax ~f:(function
|
||||||
| Hole (Everything, Delimited (left, right)) ->
|
| Hole (Everything, Delimited (left, right)) ->
|
||||||
let left = Option.value left ~default:"" in
|
let left = Option.value left ~default:"" in
|
||||||
@ -162,7 +165,7 @@ let replacement_sentinel metasyntax =
|
|||||||
| None -> failwith "A custom metasyntax must define syntax for an Everything hole or Regex to customize rewriting"
|
| None -> failwith "A custom metasyntax must define syntax for an Everything hole or Regex to customize rewriting"
|
||||||
|
|
||||||
(** Parse the first :[id(label)] label encountered in the template. *)
|
(** Parse the first :[id(label)] label encountered in the template. *)
|
||||||
let parse_first_label ?(metasyntax = Matchers.Metasyntax.default_metasyntax) template =
|
let parse_first_label ?(metasyntax = Metasyntax.default_metasyntax) template =
|
||||||
let label = take_while (function | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' | '_' -> true | _ -> false) in
|
let label = take_while (function | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' | '_' -> true | _ -> false) in
|
||||||
let left, right = replacement_sentinel metasyntax in
|
let left, right = replacement_sentinel metasyntax in
|
||||||
let parser =
|
let parser =
|
||||||
@ -178,7 +181,7 @@ let parse_first_label ?(metasyntax = Matchers.Metasyntax.default_metasyntax) tem
|
|||||||
| Error _ -> None
|
| Error _ -> None
|
||||||
|
|
||||||
let substitute_fresh
|
let substitute_fresh
|
||||||
?(metasyntax = Matchers.Metasyntax.default_metasyntax)
|
?(metasyntax = Metasyntax.default_metasyntax)
|
||||||
?(fresh = counter)
|
?(fresh = counter)
|
||||||
template =
|
template =
|
||||||
let label_table = String.Table.create () in
|
let label_table = String.Table.create () in
|
||||||
@ -202,8 +205,8 @@ let substitute_fresh
|
|||||||
done;
|
done;
|
||||||
!template_ref
|
!template_ref
|
||||||
|
|
||||||
let substitute ?(metasyntax = Matchers.Metasyntax.default_metasyntax) ?fresh template env =
|
let substitute ?(metasyntax = Metasyntax.default_metasyntax) ?fresh template env =
|
||||||
let (module M) = Matchers.Metasyntax.create metasyntax in
|
let (module M) = Metasyntax.create metasyntax in
|
||||||
let module Template_parser = Make(M) in
|
let module Template_parser = Make(M) in
|
||||||
let vars = Template_parser.variables template in
|
let vars = Template_parser.variables template in
|
||||||
let template = substitute_fresh ~metasyntax ?fresh template in
|
let template = substitute_fresh ~metasyntax ?fresh template in
|
||||||
@ -240,7 +243,7 @@ let of_match_context
|
|||||||
in
|
in
|
||||||
let after_part = String.slice source end_index (String.length source) in
|
let after_part = String.slice source end_index (String.length source) in
|
||||||
let hole_id = fresh () in
|
let hole_id = fresh () in
|
||||||
let left, right = replacement_sentinel Matchers.Metasyntax.default_metasyntax in
|
let left, right = replacement_sentinel Metasyntax.default_metasyntax in
|
||||||
let rewrite_template = String.concat [before_part; left; hole_id; right; after_part] in
|
let rewrite_template = String.concat [before_part; left; hole_id; right; after_part] in
|
||||||
hole_id, rewrite_template
|
hole_id, rewrite_template
|
||||||
|
|
@ -1,4 +1,3 @@
|
|||||||
open Matchers
|
|
||||||
open Match
|
open Match
|
||||||
|
|
||||||
type syntax = { variable: string; pattern: string }
|
type syntax = { variable: string; pattern: string }
|
235
lib/kernel/matchers/rule.ml
Normal file
235
lib/kernel/matchers/rule.ml
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
open Core_kernel
|
||||||
|
open Angstrom
|
||||||
|
|
||||||
|
module Ast = struct
|
||||||
|
type atom =
|
||||||
|
| Variable of string
|
||||||
|
| String of string
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type antecedent = atom
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type expression =
|
||||||
|
| True
|
||||||
|
| False
|
||||||
|
| Option of string
|
||||||
|
| Equal of atom * atom
|
||||||
|
| Not_equal of atom * atom
|
||||||
|
| Match of atom * (antecedent * consequent) list
|
||||||
|
| RewriteTemplate of string
|
||||||
|
| Rewrite of atom * (antecedent * expression)
|
||||||
|
and consequent = expression list
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
let (=) left right = Equal (left, right)
|
||||||
|
|
||||||
|
let (<>) left right = Not_equal (left, right)
|
||||||
|
end
|
||||||
|
|
||||||
|
module Parser = struct
|
||||||
|
open Ast
|
||||||
|
|
||||||
|
let alphanum =
|
||||||
|
satisfy (function
|
||||||
|
| 'a' .. 'z'
|
||||||
|
| 'A' .. 'Z'
|
||||||
|
| '0' .. '9' -> true
|
||||||
|
| _ -> false)
|
||||||
|
|
||||||
|
let variable_parser =
|
||||||
|
(string Syntax.variable_left_delimiter
|
||||||
|
*> (many (alphanum <|> char '_') >>| String.of_char_list)
|
||||||
|
<* string Syntax.variable_right_delimiter)
|
||||||
|
|
||||||
|
(** Interpret escape sequences inside quotes *)
|
||||||
|
let char_token_s =
|
||||||
|
(char '\\' *> any_char >>|
|
||||||
|
function
|
||||||
|
| 'r' -> Char.to_string '\r'
|
||||||
|
| 'n' -> Char.to_string '\n'
|
||||||
|
| 't' -> Char.to_string '\t'
|
||||||
|
| '\\' -> Char.to_string '\\'
|
||||||
|
| c -> Format.sprintf {|\%c|} c)
|
||||||
|
<|> (any_char >>| String.of_char)
|
||||||
|
|
||||||
|
(** With escape sequences *)
|
||||||
|
let quote s =
|
||||||
|
(string s *> (many_till char_token_s (string s)))
|
||||||
|
>>| String.concat
|
||||||
|
|
||||||
|
let raw s =
|
||||||
|
(string s *> (many_till any_char (string s)))
|
||||||
|
>>| String.of_char_list
|
||||||
|
|
||||||
|
let quoted_parser =
|
||||||
|
choice [ quote {|"|}; quote {|'|}; raw {|`|} ]
|
||||||
|
|
||||||
|
let operator_parser =
|
||||||
|
choice
|
||||||
|
[ string Syntax.equal
|
||||||
|
; string Syntax.not_equal
|
||||||
|
]
|
||||||
|
|
||||||
|
let any_char_except ~reserved =
|
||||||
|
List.fold reserved
|
||||||
|
~init:(return `OK)
|
||||||
|
~f:(fun acc reserved_sequence ->
|
||||||
|
option `End_of_input
|
||||||
|
(peek_string (String.length reserved_sequence)
|
||||||
|
>>= fun s ->
|
||||||
|
if String.equal s reserved_sequence then
|
||||||
|
return `Reserved_sequence
|
||||||
|
else
|
||||||
|
acc))
|
||||||
|
>>= function
|
||||||
|
| `OK -> any_char
|
||||||
|
| `End_of_input -> any_char
|
||||||
|
| `Reserved_sequence -> fail "reserved sequence hit"
|
||||||
|
|
||||||
|
let value_parser ~reserved () =
|
||||||
|
match reserved with
|
||||||
|
| [] -> fail "no value allowed to scan here"
|
||||||
|
| reserved -> many (any_char_except ~reserved)
|
||||||
|
|
||||||
|
let map_special s =
|
||||||
|
if String.is_prefix s ~prefix:"~" then
|
||||||
|
Variable (Format.sprintf ":[%s]" s)
|
||||||
|
else if String.equal s "_" then
|
||||||
|
Variable ":[_]"
|
||||||
|
else
|
||||||
|
String s
|
||||||
|
|
||||||
|
let antecedent_parser ?(reserved = []) () =
|
||||||
|
choice
|
||||||
|
[ (quoted_parser >>| fun value -> String value)
|
||||||
|
; (value_parser ~reserved () >>| fun value -> map_special (String.of_char_list value))
|
||||||
|
]
|
||||||
|
|
||||||
|
let atom_parser () =
|
||||||
|
choice
|
||||||
|
[ (variable_parser >>| fun variable -> Variable variable)
|
||||||
|
; (quoted_parser >>| fun value -> String value)
|
||||||
|
; (value_parser ~reserved:[] () >>| fun value -> String (String.of_char_list value))
|
||||||
|
]
|
||||||
|
|
||||||
|
let rewrite_template_parser =
|
||||||
|
quoted_parser >>| fun value -> RewriteTemplate value
|
||||||
|
|
||||||
|
let ignore p =
|
||||||
|
p *> return ()
|
||||||
|
|
||||||
|
let make_equality_expression left operator right =
|
||||||
|
if String.equal operator Syntax.equal then
|
||||||
|
Equal (left, right)
|
||||||
|
else
|
||||||
|
Not_equal (left, right)
|
||||||
|
|
||||||
|
let is_whitespace = function
|
||||||
|
| ' ' | '\t' | '\r' | '\n' -> true
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
|
let spaces =
|
||||||
|
take_while is_whitespace
|
||||||
|
|
||||||
|
let spaces1 =
|
||||||
|
satisfy is_whitespace *>
|
||||||
|
take_while is_whitespace *>
|
||||||
|
return ()
|
||||||
|
|
||||||
|
let optional_trailing c = option () (skip (Char.equal c))
|
||||||
|
|
||||||
|
let option_parser = spaces *> string Syntax.option_nested <* spaces >>| fun _ -> Option "nested"
|
||||||
|
|
||||||
|
let true' = lift (fun _ -> True) (spaces *> string Syntax.true' <* spaces)
|
||||||
|
|
||||||
|
let false' = lift (fun _ -> False) (spaces *> string Syntax.false' <* spaces)
|
||||||
|
|
||||||
|
(** <atom> [==, !=] <atom> *)
|
||||||
|
let operator_parser =
|
||||||
|
lift3
|
||||||
|
make_equality_expression
|
||||||
|
(spaces *> atom_parser ())
|
||||||
|
(spaces *> operator_parser)
|
||||||
|
(spaces *> atom_parser ())
|
||||||
|
<* spaces
|
||||||
|
|
||||||
|
let make_rewrite_expression atom match_template rewrite_template =
|
||||||
|
Rewrite (atom, (match_template, rewrite_template))
|
||||||
|
|
||||||
|
let make_match_expression atom cases =
|
||||||
|
Match (atom, cases)
|
||||||
|
|
||||||
|
(** rewrite <atom> { <atom> -> <atom> } *)
|
||||||
|
let rewrite_pattern_parser =
|
||||||
|
lift3
|
||||||
|
make_rewrite_expression
|
||||||
|
(string Syntax.start_rewrite_pattern *> spaces *> atom_parser () <* spaces <* char '{' <* spaces)
|
||||||
|
(antecedent_parser ~reserved:[" ->"] () <* spaces <* string Syntax.arrow <* spaces)
|
||||||
|
(spaces *> rewrite_template_parser <* spaces <* char '}' <* spaces)
|
||||||
|
|
||||||
|
(** <atom> -> atom [, <expr>], [,] *)
|
||||||
|
let match_arrow_parser expression_parser =
|
||||||
|
both
|
||||||
|
(antecedent_parser ~reserved:[" ->"] () <* spaces <* string Syntax.arrow <* spaces)
|
||||||
|
(spaces *> sep_by (char ',') expression_parser <* spaces <* optional_trailing ',' <* spaces)
|
||||||
|
|
||||||
|
(** [|] <match_arrow> *)
|
||||||
|
let first_case_parser expression_parser =
|
||||||
|
spaces *> option () (ignore @@ string Syntax.pipe_operator *> spaces) *>
|
||||||
|
match_arrow_parser expression_parser
|
||||||
|
|
||||||
|
(** | <match_arrow> *)
|
||||||
|
let case_parser expression_parser =
|
||||||
|
spaces *> string Syntax.pipe_operator *> spaces *>
|
||||||
|
match_arrow_parser expression_parser
|
||||||
|
|
||||||
|
(** [|] <match_arrow> | <match_arrow> *)
|
||||||
|
let case_block expression_parser =
|
||||||
|
first_case_parser expression_parser >>= fun case ->
|
||||||
|
many (case_parser expression_parser) >>= fun cases ->
|
||||||
|
return (case :: cases)
|
||||||
|
|
||||||
|
(** match <atom> { <case_parser> } *)
|
||||||
|
let match_pattern_parser expression_parser =
|
||||||
|
string Syntax.start_match_pattern *> spaces *>
|
||||||
|
lift2
|
||||||
|
make_match_expression
|
||||||
|
(atom_parser () <* spaces <* char '{' <* spaces)
|
||||||
|
(case_block expression_parser <* char '}' <* spaces)
|
||||||
|
|
||||||
|
let expression_parser =
|
||||||
|
fix (fun expression_parser ->
|
||||||
|
choice
|
||||||
|
[ match_pattern_parser expression_parser
|
||||||
|
; rewrite_pattern_parser
|
||||||
|
; operator_parser
|
||||||
|
; true'
|
||||||
|
; false'
|
||||||
|
; option_parser
|
||||||
|
])
|
||||||
|
|
||||||
|
(** where <expression> [,] *)
|
||||||
|
let parse =
|
||||||
|
spaces *> string Syntax.rule_prefix *>
|
||||||
|
spaces1 *> sep_by1 (spaces *> char ',' <* spaces) expression_parser
|
||||||
|
<* optional_trailing ','
|
||||||
|
<* spaces
|
||||||
|
|
||||||
|
let create rule =
|
||||||
|
match parse_string ~consume:All (parse <* end_of_input) rule with
|
||||||
|
| Ok rule -> Ok rule
|
||||||
|
| Error error -> Or_error.error_string error
|
||||||
|
end
|
||||||
|
|
||||||
|
type t = Ast.expression list
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type options =
|
||||||
|
{ nested : bool
|
||||||
|
}
|
||||||
|
|
||||||
|
let options rule =
|
||||||
|
List.fold rule ~init:{ nested = false } ~f:(fun acc -> function
|
||||||
|
| Ast.Option name when String.(name = Syntax.option_nested) -> { nested = true }
|
||||||
|
| _ -> acc)
|
@ -1,9 +1,26 @@
|
|||||||
|
open Core_kernel
|
||||||
open Angstrom
|
open Angstrom
|
||||||
|
|
||||||
|
open Rule
|
||||||
open Parser
|
open Parser
|
||||||
|
|
||||||
open Ast
|
open Ast
|
||||||
open Script
|
|
||||||
|
type spec = Specification.t
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type op =
|
||||||
|
| And
|
||||||
|
| Or
|
||||||
|
| Not
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type exp =
|
||||||
|
| Exp of op * exp list
|
||||||
|
| Spec of spec
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
type t = exp list
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
let ignore p =
|
let ignore p =
|
||||||
p *> return ()
|
p *> return ()
|
||||||
@ -26,7 +43,7 @@ let spec =
|
|||||||
(option None (spaces *> string Syntax.arrow *> spaces *> atom_parser () >>| fun x -> Some x))
|
(option None (spaces *> string Syntax.arrow *> spaces *> atom_parser () >>| fun x -> Some x))
|
||||||
in
|
in
|
||||||
match_rewrite_parser >>= fun (match_template_atom, rewrite_template_atom) ->
|
match_rewrite_parser >>= fun (match_template_atom, rewrite_template_atom) ->
|
||||||
(option None (spaces1 *> Parser.parse >>| fun x -> Some x)) >>= fun rule ->
|
(option None (spaces1 *> parse >>| fun x -> Some x)) >>= fun rule ->
|
||||||
let match_template = Sexplib.Sexp.to_string_hum (sexp_of_atom match_template_atom) in
|
let match_template = Sexplib.Sexp.to_string_hum (sexp_of_atom match_template_atom) in
|
||||||
let rewrite_template =
|
let rewrite_template =
|
||||||
match rewrite_template_atom with
|
match rewrite_template_atom with
|
||||||
@ -36,10 +53,10 @@ let spec =
|
|||||||
return [(Spec (Specification.{ match_template; rule; rewrite_template }))]
|
return [(Spec (Specification.{ match_template; rule; rewrite_template }))]
|
||||||
|
|
||||||
let unop syntax exp_parser =
|
let unop syntax exp_parser =
|
||||||
choice (List.map string syntax) *> spaces *> exp_parser >>| fun exp -> [Exp (Not, exp)]
|
choice (List.map ~f:string syntax) *> spaces *> exp_parser >>| fun exp -> [Exp (Not, exp)]
|
||||||
|
|
||||||
let binop syntax op =
|
let binop syntax op =
|
||||||
spaces *> choice (List.map string syntax) *> spaces *> return (fun left right -> [Exp (op, left@right)])
|
spaces *> choice (List.map ~f:string syntax) *> spaces *> return (fun left right -> [Exp (op, left@right)])
|
||||||
|
|
||||||
let exp_parser =
|
let exp_parser =
|
||||||
fix (fun exp ->
|
fix (fun exp ->
|
||||||
@ -56,4 +73,4 @@ let parse script =
|
|||||||
parse_string ~consume:All parser script
|
parse_string ~consume:All parser script
|
||||||
|
|
||||||
let to_string exp =
|
let to_string exp =
|
||||||
Sexplib.Sexp.to_string_hum (Script.sexp_of_t exp)
|
Sexplib.Sexp.to_string_hum (sexp_of_t exp)
|
12
lib/kernel/matchers/specification.ml
Normal file
12
lib/kernel/matchers/specification.ml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
open Core_kernel
|
||||||
|
|
||||||
|
type t =
|
||||||
|
{ match_template : string
|
||||||
|
; rule : Rule.t option
|
||||||
|
; rewrite_template : string option
|
||||||
|
}
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
|
||||||
|
let create ?rewrite_template ?rule ~match_template () =
|
||||||
|
{ match_template; rule; rewrite_template }
|
8
lib/kernel/matchers/specification.mli
Normal file
8
lib/kernel/matchers/specification.mli
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
type t =
|
||||||
|
{ match_template : string
|
||||||
|
; rule : Rule.t option
|
||||||
|
; rewrite_template : string option
|
||||||
|
}
|
||||||
|
[@@deriving sexp]
|
||||||
|
|
||||||
|
val create : ?rewrite_template:string -> ?rule:Rule.t -> match_template:string -> unit -> t
|
@ -43,7 +43,6 @@ module Language = struct
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
type dimension =
|
type dimension =
|
||||||
| Code
|
| Code
|
||||||
| Escapable_string_literal
|
| Escapable_string_literal
|
||||||
@ -119,6 +118,7 @@ module Matcher = struct
|
|||||||
module type S = sig
|
module type S = sig
|
||||||
val all
|
val all
|
||||||
: ?configuration:Configuration.t
|
: ?configuration:Configuration.t
|
||||||
|
-> ?rule:Rule.t
|
||||||
-> ?nested: bool
|
-> ?nested: bool
|
||||||
-> template:string
|
-> template:string
|
||||||
-> source:string
|
-> source:string
|
||||||
@ -135,7 +135,6 @@ module Matcher = struct
|
|||||||
include Info.S
|
include Info.S
|
||||||
|
|
||||||
val set_rewrite_template : string -> unit
|
val set_rewrite_template : string -> unit
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
(library
|
|
||||||
(name rewriter)
|
|
||||||
(public_name comby-kernel.rewriter)
|
|
||||||
(instrumentation (backend bisect_ppx))
|
|
||||||
(preprocess (pps ppx_deriving_yojson ppx_sexp_message ppx_sexp_conv))
|
|
||||||
(libraries comby-kernel.matchers comby-kernel.replacement core_kernel))
|
|
@ -1,6 +1,8 @@
|
|||||||
open Core
|
open Core
|
||||||
open Command.Let_syntax
|
open Command.Let_syntax
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
|
||||||
open Configuration
|
open Configuration
|
||||||
open Command_configuration
|
open Command_configuration
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ let substitute_environment_only_and_exit metasyntax_path anonymous_arguments jso
|
|||||||
Match.Environment.of_yojson json
|
Match.Environment.of_yojson json
|
||||||
|> function
|
|> function
|
||||||
| Ok environment ->
|
| Ok environment ->
|
||||||
let substituted, _ = Rewriter.Rewrite_template.substitute ~metasyntax rewrite_template environment in
|
let substituted, _ = Matchers.Rewrite.substitute ~metasyntax rewrite_template environment in
|
||||||
Format.printf "%s@." substituted;
|
Format.printf "%s@." substituted;
|
||||||
exit 0
|
exit 0
|
||||||
| Error err ->
|
| Error err ->
|
||||||
|
@ -17,7 +17,6 @@ let timeout =
|
|||||||
| None -> 30 (* seconds *)
|
| None -> 30 (* seconds *)
|
||||||
| Some t -> Int.of_string t
|
| Some t -> Int.of_string t
|
||||||
|
|
||||||
|
|
||||||
let max_request_length =
|
let max_request_length =
|
||||||
match Sys.getenv "MAX_REQUEST_LENGTH" with
|
match Sys.getenv "MAX_REQUEST_LENGTH" with
|
||||||
| None -> Int.max_value
|
| None -> Int.max_value
|
||||||
@ -49,7 +48,7 @@ let perform_match request =
|
|||||||
in
|
in
|
||||||
let run ?rule () =
|
let run ?rule () =
|
||||||
let configuration = Matchers.Configuration.create ~match_kind:Fuzzy () in
|
let configuration = Matchers.Configuration.create ~match_kind:Fuzzy () in
|
||||||
let specification = Pipeline.Specification.create ~match_template ?rule () in
|
let specification = Matchers.Specification.create ~match_template ?rule () in
|
||||||
let matches =
|
let matches =
|
||||||
Pipeline.execute
|
Pipeline.execute
|
||||||
matcher
|
matcher
|
||||||
@ -87,10 +86,10 @@ let perform_rewrite request =
|
|||||||
| Some matcher -> matcher
|
| Some matcher -> matcher
|
||||||
| None -> (module Matchers.Alpha.Generic)
|
| None -> (module Matchers.Alpha.Generic)
|
||||||
in
|
in
|
||||||
let source_substitution, substitute_in_place =
|
let source_substitution =
|
||||||
match substitution_kind with
|
match substitution_kind with
|
||||||
| "newline_separated" -> None, false
|
| "newline_separated" -> None
|
||||||
| "in_place" | _ -> Some source, true
|
| "in_place" | _ -> Some source
|
||||||
in
|
in
|
||||||
let default =
|
let default =
|
||||||
Out.Rewrite.to_string
|
Out.Rewrite.to_string
|
||||||
@ -101,11 +100,10 @@ let perform_rewrite request =
|
|||||||
in
|
in
|
||||||
let run ?rule () =
|
let run ?rule () =
|
||||||
let configuration = Configuration.create ~match_kind:Fuzzy () in
|
let configuration = Configuration.create ~match_kind:Fuzzy () in
|
||||||
let specification = Pipeline.Specification.create ~match_template ?rule () in
|
let specification = Matchers.Specification.create ~match_template ?rule () in
|
||||||
let matches =
|
let matches =
|
||||||
Pipeline.execute
|
Pipeline.execute
|
||||||
matcher
|
matcher
|
||||||
~substitute_in_place
|
|
||||||
~configuration
|
~configuration
|
||||||
(String source)
|
(String source)
|
||||||
specification
|
specification
|
||||||
@ -113,8 +111,8 @@ let perform_rewrite request =
|
|||||||
| Matches (m, _) -> m
|
| Matches (m, _) -> m
|
||||||
| _ -> []
|
| _ -> []
|
||||||
in
|
in
|
||||||
Rewrite.all matches ?source:source_substitution ~rewrite_template
|
Comby_kernel.Matchers.Rewrite.all matches ?source:source_substitution ~rewrite_template
|
||||||
|> Option.value_map ~default ~f:(fun Replacement.{ rewritten_source; in_place_substitutions } ->
|
|> Option.value_map ~default ~f:(fun Comby_kernel.Replacement.{ rewritten_source; in_place_substitutions } ->
|
||||||
Out.Rewrite.to_string
|
Out.Rewrite.to_string
|
||||||
{ rewritten_source
|
{ rewritten_source
|
||||||
; in_place_substitutions
|
; in_place_substitutions
|
||||||
@ -143,7 +141,7 @@ let perform_environment_substitution request =
|
|||||||
let code, result =
|
let code, result =
|
||||||
200,
|
200,
|
||||||
Out.Substitution.to_string
|
Out.Substitution.to_string
|
||||||
{ result = fst @@ Rewrite.substitute rewrite_template environment
|
{ result = fst @@ Comby_kernel.Matchers.Rewrite.substitute rewrite_template environment
|
||||||
; id
|
; id
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Comby
|
open Comby_kernel
|
||||||
open Match
|
open Match
|
||||||
|
|
||||||
module In = struct
|
module In = struct
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
|
||||||
let configuration = Matchers.Configuration.create ~match_kind:Fuzzy ()
|
let configuration = Matchers.Configuration.create ~match_kind:Fuzzy ()
|
||||||
|
|
||||||
let create syntax =
|
let create syntax =
|
||||||
@ -144,10 +146,7 @@ let%expect_test "custom_metasyntax_rewrite" =
|
|||||||
let metasyntax = Matchers.Metasyntax.{ syntax; identifier = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" } in
|
let metasyntax = Matchers.Metasyntax.{ syntax; identifier = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" } in
|
||||||
let matcher = Option.value_exn (Matchers.Alpha.select_with_extension ~metasyntax ".go") in
|
let matcher = Option.value_exn (Matchers.Alpha.select_with_extension ~metasyntax ".go") in
|
||||||
|
|
||||||
(* KNOWN LIMITATION/BUG: if ? is a prefix it conflicts with ? optional syntax
|
let specification = Matchers.Specification.create ~match_template:"$A(?B)" ~rewrite_template:"??B -> $A$A" () in
|
||||||
for variable names and substitution. Expect should be ?bar here. Remove
|
|
||||||
optional syntax. *)
|
|
||||||
let specification = Configuration.Specification.create ~match_template:"$A(?B)" ~rewrite_template:"??B -> $A$A" () in
|
|
||||||
let result = Pipeline.execute matcher ~metasyntax (String "simple(bar)") specification in
|
let result = Pipeline.execute matcher ~metasyntax (String "simple(bar)") specification in
|
||||||
let output = match result with
|
let output = match result with
|
||||||
| Replacement (_, result, _) -> result
|
| Replacement (_, result, _) -> result
|
||||||
@ -157,7 +156,7 @@ let%expect_test "custom_metasyntax_rewrite" =
|
|||||||
print_string output;
|
print_string output;
|
||||||
[%expect_exact {|bar -> simplesimple|}];
|
[%expect_exact {|bar -> simplesimple|}];
|
||||||
|
|
||||||
let specification = Configuration.Specification.create ~match_template:"$A(?B)" ~rewrite_template:"$id() $id(a) $id(a)" () in
|
let specification = Matchers.Specification.create ~match_template:"$A(?B)" ~rewrite_template:"$id() $id(a) $id(a)" () in
|
||||||
let result = Pipeline.execute matcher ~metasyntax (String "simple(bar)") specification in
|
let result = Pipeline.execute matcher ~metasyntax (String "simple(bar)") specification in
|
||||||
let output = match result with
|
let output = match result with
|
||||||
| Replacement (_, result, _) -> result
|
| Replacement (_, result, _) -> result
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
test_cli_helper
|
test_cli_helper
|
||||||
test_script
|
test_script
|
||||||
test_extract_regex
|
test_extract_regex
|
||||||
test_alpha
|
|
||||||
test_omega
|
|
||||||
test_cli
|
test_cli
|
||||||
test_cli_list
|
test_cli_list
|
||||||
test_statistics
|
test_statistics
|
||||||
@ -17,57 +15,23 @@
|
|||||||
test_rewrite_parts
|
test_rewrite_parts
|
||||||
test_parse_rewrite_template
|
test_parse_rewrite_template
|
||||||
test_substitute
|
test_substitute
|
||||||
|
test_rewrite_rule
|
||||||
test_rewrite_rule_alpha
|
test_integration
|
||||||
test_rewrite_rule_omega
|
test_match_rule
|
||||||
|
test_python_string_literals
|
||||||
test_integration_alpha
|
test_hole_extensions
|
||||||
test_integration_omega
|
test_generic
|
||||||
|
test_string_literals
|
||||||
test_match_rule_alpha
|
test_c_style_comments
|
||||||
test_match_rule_omega
|
test_nested_comments
|
||||||
|
test_c
|
||||||
test_python_string_literals_alpha
|
test_bash
|
||||||
test_python_string_literals_omega
|
test_go
|
||||||
|
test_c_separators
|
||||||
test_hole_extensions_alpha
|
test_pipeline
|
||||||
test_hole_extensions_omega
|
test_user_defined_language
|
||||||
|
test_nested_matches
|
||||||
test_generic_alpha
|
test_regex_holes
|
||||||
test_generic_omega
|
|
||||||
|
|
||||||
test_string_literals_alpha
|
|
||||||
test_string_literals_omega
|
|
||||||
|
|
||||||
test_c_style_comments_alpha
|
|
||||||
test_c_style_comments_omega
|
|
||||||
|
|
||||||
test_nested_comments_alpha
|
|
||||||
test_nested_comments_omega
|
|
||||||
|
|
||||||
test_c_alpha
|
|
||||||
test_c_omega
|
|
||||||
|
|
||||||
test_bash_alpha
|
|
||||||
test_bash_omega
|
|
||||||
|
|
||||||
test_go_alpha
|
|
||||||
test_go_omega
|
|
||||||
|
|
||||||
test_c_separators_alpha
|
|
||||||
test_c_separators_omega
|
|
||||||
|
|
||||||
test_pipeline_alpha
|
|
||||||
test_pipeline_omega
|
|
||||||
|
|
||||||
test_user_defined_language_alpha
|
|
||||||
test_user_defined_language_omega
|
|
||||||
|
|
||||||
test_nested_matches_alpha
|
|
||||||
test_nested_matches_omega
|
|
||||||
|
|
||||||
test_regex_holes_alpha
|
|
||||||
test_regex_holes_omega
|
|
||||||
)
|
)
|
||||||
(inline_tests)
|
(inline_tests)
|
||||||
(preprocess (pps ppx_expect ppx_sexp_message ppx_deriving_yojson))
|
(preprocess (pps ppx_expect ppx_sexp_message ppx_deriving_yojson))
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
include Matchers.Alpha
|
|
||||||
module Rule = Language.Rule
|
|
@ -1,24 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
open Test_alpha
|
let run (module M: Matchers.Matcher.S) source match_template rewrite_template =
|
||||||
|
M.first ~configuration match_template source
|
||||||
let run_bash source match_template rewrite_template =
|
|
||||||
Bash.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let run_go source match_template rewrite_template =
|
|
||||||
Go.first ~configuration match_template source
|
|
||||||
|> function
|
|> function
|
||||||
| Ok result ->
|
| Ok result ->
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
Rewrite.all ~source ~rewrite_template [result]
|
||||||
@ -45,11 +32,17 @@ let%expect_test "custom_long_delimiters" =
|
|||||||
let match_template = {|case :[1] esac|} in
|
let match_template = {|case :[1] esac|} in
|
||||||
let rewrite_template = {|case nuked blocks esac|} in
|
let rewrite_template = {|case nuked blocks esac|} in
|
||||||
|
|
||||||
run_bash source match_template rewrite_template;
|
run (module Alpha.Bash) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
case nuked blocks esac
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega.Bash) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
case nuked blocks esac
|
case nuked blocks esac
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "custom_long_delimiters_doesn't_work_in_go" =
|
let%expect_test "custom_long_delimiters_doesn't_work_in_go" =
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
@ -67,7 +60,17 @@ let%expect_test "custom_long_delimiters_doesn't_work_in_go" =
|
|||||||
let match_template = {|case :[1] esac|} in
|
let match_template = {|case :[1] esac|} in
|
||||||
let rewrite_template = {|case nuked blocks esac|} in
|
let rewrite_template = {|case nuked blocks esac|} in
|
||||||
|
|
||||||
run_go source match_template rewrite_template;
|
run (module Alpha.Go) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
case nuked blocks esac
|
||||||
|
|
||||||
|
case
|
||||||
|
block 2
|
||||||
|
esac
|
||||||
|
esac
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega.Go) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
case nuked blocks esac
|
case nuked blocks esac
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
open Test_omega
|
|
||||||
|
|
||||||
let run_bash source match_template rewrite_template =
|
|
||||||
Bash.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let run_go source match_template rewrite_template =
|
|
||||||
Go.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let%expect_test "custom_long_delimiters" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
case
|
|
||||||
case
|
|
||||||
block 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
case
|
|
||||||
block 2
|
|
||||||
esac
|
|
||||||
esac
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|case :[1] esac|} in
|
|
||||||
let rewrite_template = {|case nuked blocks esac|} in
|
|
||||||
|
|
||||||
run_bash source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
case nuked blocks esac
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "custom_long_delimiters_doesn't_work_in_go" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
case
|
|
||||||
case
|
|
||||||
block 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
case
|
|
||||||
block 2
|
|
||||||
esac
|
|
||||||
esac
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|case :[1] esac|} in
|
|
||||||
let rewrite_template = {|case nuked blocks esac|} in
|
|
||||||
|
|
||||||
run_go source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
case nuked blocks esac
|
|
||||||
|
|
||||||
case
|
|
||||||
block 2
|
|
||||||
esac
|
|
||||||
esac
|
|
||||||
|}]
|
|
@ -1,13 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
open Test_alpha
|
let run (module E : Engine.S) source match_template rewrite_template =
|
||||||
|
E.C.first ~configuration match_template source
|
||||||
let run source match_template rewrite_template =
|
|
||||||
C.first ~configuration match_template source
|
|
||||||
|> function
|
|> function
|
||||||
| Ok result ->
|
| Ok result ->
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
Rewrite.all ~source ~rewrite_template [result]
|
||||||
@ -22,7 +20,9 @@ let%expect_test "comments_1" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|expect|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|expect|}]
|
[%expect_exact {|expect|}]
|
||||||
|
|
||||||
let%expect_test "comments_2" =
|
let%expect_test "comments_2" =
|
||||||
@ -30,7 +30,9 @@ let%expect_test "comments_2" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|expect|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|expect|}]
|
[%expect_exact {|expect|}]
|
||||||
|
|
||||||
let%expect_test "comments_3" =
|
let%expect_test "comments_3" =
|
||||||
@ -38,7 +40,9 @@ let%expect_test "comments_3" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|expect|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|expect|}]
|
[%expect_exact {|expect|}]
|
||||||
|
|
||||||
let%expect_test "comments_4" =
|
let%expect_test "comments_4" =
|
||||||
@ -46,7 +50,9 @@ let%expect_test "comments_4" =
|
|||||||
let match_template = {|match this :[1]end|} in
|
let match_template = {|match this :[1]end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|expect|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|expect|}]
|
[%expect_exact {|expect|}]
|
||||||
|
|
||||||
let%expect_test "comments_5" =
|
let%expect_test "comments_5" =
|
||||||
@ -54,7 +60,9 @@ let%expect_test "comments_5" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|expect|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|expect|}]
|
[%expect_exact {|expect|}]
|
||||||
|
|
||||||
let%expect_test "comments_6" =
|
let%expect_test "comments_6" =
|
||||||
@ -62,7 +70,9 @@ let%expect_test "comments_6" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|nothing matches|} in
|
let rewrite_template = {|nothing matches|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|nothing matches|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|nothing matches|}]
|
[%expect_exact {|nothing matches|}]
|
||||||
|
|
||||||
let%expect_test "comments_7" =
|
let%expect_test "comments_7" =
|
||||||
@ -70,7 +80,9 @@ let%expect_test "comments_7" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|nothing matches|} in
|
let rewrite_template = {|nothing matches|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|nothing matches|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|nothing matches|}]
|
[%expect_exact {|nothing matches|}]
|
||||||
|
|
||||||
let%expect_test "comments_8" =
|
let%expect_test "comments_8" =
|
||||||
@ -78,7 +90,9 @@ let%expect_test "comments_8" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|nothing matches|} in
|
let rewrite_template = {|nothing matches|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|nothing matches|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|nothing matches|}]
|
[%expect_exact {|nothing matches|}]
|
||||||
|
|
||||||
let%expect_test "comments_9" =
|
let%expect_test "comments_9" =
|
||||||
@ -86,7 +100,9 @@ let%expect_test "comments_9" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|/* don't match this (a) end */ do (b)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|/* don't match this (a) end */ do (b)|}]
|
[%expect_exact {|/* don't match this (a) end */ do (b)|}]
|
||||||
|
|
||||||
let%expect_test "comments_10" =
|
let%expect_test "comments_10" =
|
||||||
@ -94,7 +110,9 @@ let%expect_test "comments_10" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|/* don't match this (a) end */ do ()|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|/* don't match this (a) end */ do ()|}]
|
[%expect_exact {|/* don't match this (a) end */ do ()|}]
|
||||||
|
|
||||||
let%expect_test "comments_11" =
|
let%expect_test "comments_11" =
|
||||||
@ -102,5 +120,7 @@ let%expect_test "comments_11" =
|
|||||||
let match_template = {|match this :[1] end|} in
|
let match_template = {|match this :[1] end|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|do (b) /* don't match this (a) end */|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|do (b) /* don't match this (a) end */|}]
|
[%expect_exact {|do (b) /* don't match this (a) end */|}]
|
@ -1,106 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
open Test_omega
|
|
||||||
|
|
||||||
let run source match_template rewrite_template =
|
|
||||||
C.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let%expect_test "comments_1" =
|
|
||||||
let source = {|match this /**/ expect end|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|expect|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_2" =
|
|
||||||
let source = {|match this /* */ expect end|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|expect|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_3" =
|
|
||||||
let source = {|match this /* blah blah */ expect /**/ end|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|expect|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_4" =
|
|
||||||
let source = {|match this expect/**/end|} in
|
|
||||||
let match_template = {|match this :[1]end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|expect|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_5" =
|
|
||||||
let source = {|match this expect /**/end|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|expect|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_6" =
|
|
||||||
let source = {|/* don't match this (a) end */|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|nothing matches|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|nothing matches|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_7" =
|
|
||||||
let source = {|/* don't match /**/ this (a) end */|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|nothing matches|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|nothing matches|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_8" =
|
|
||||||
let source = {|(/* don't match this (a) end */)|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|nothing matches|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|nothing matches|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_9" =
|
|
||||||
let source = {|/* don't match this (a) end */ do match this (b) end|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|/* don't match this (a) end */ do (b)|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_10" =
|
|
||||||
let source = {|/* don't match this (a) end */ do match this () end|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|/* don't match this (a) end */ do ()|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_11" =
|
|
||||||
let source = {|do match this (b) end /* don't match this (a) end */|} in
|
|
||||||
let match_template = {|match this :[1] end|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|do (b) /* don't match this (a) end */|}]
|
|
@ -1,13 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
include Test_omega
|
let run (module E : Engine.S) source match_template rewrite_template =
|
||||||
|
E.C.first ~configuration match_template source
|
||||||
let run source match_template rewrite_template =
|
|
||||||
C.first ~configuration match_template source
|
|
||||||
|> function
|
|> function
|
||||||
| Ok result ->
|
| Ok result ->
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
Rewrite.all ~source ~rewrite_template [result]
|
||||||
@ -21,17 +19,23 @@ let%expect_test "whitespace_should_not_matter_between_separators" =
|
|||||||
let source = {|*p|} in
|
let source = {|*p|} in
|
||||||
let match_template = {|*:[1]|} in
|
let match_template = {|*:[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|p|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|p|}];
|
[%expect_exact {|p|}];
|
||||||
|
|
||||||
let source = {|* p|} in
|
let source = {|* p|} in
|
||||||
let match_template = {|*:[1]|} in
|
let match_template = {|*:[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {| p|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {| p|}];
|
[%expect_exact {| p|}];
|
||||||
|
|
||||||
let source = {|* p|} in
|
let source = {|* p|} in
|
||||||
let match_template = {|* :[1]|} in
|
let match_template = {|* :[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|p|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|p|}]
|
[%expect_exact {|p|}]
|
@ -1,37 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_alpha
|
|
||||||
|
|
||||||
let run source match_template rewrite_template =
|
|
||||||
C.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let%expect_test "whitespace_should_not_matter_between_separators" =
|
|
||||||
let source = {|*p|} in
|
|
||||||
let match_template = {|*:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|p|}];
|
|
||||||
|
|
||||||
let source = {|* p|} in
|
|
||||||
let match_template = {|*:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {| p|}];
|
|
||||||
|
|
||||||
let source = {|* p|} in
|
|
||||||
let match_template = {|* :[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|p|}]
|
|
@ -1,24 +1,27 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
include Test_omega
|
let match_all ?(configuration = configuration) (module E : Engine.S) template source =
|
||||||
|
E.C.all ~configuration ~template ~source ()
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
let all ?(configuration = configuration) engine template source rewrite_template =
|
||||||
C.all ~configuration ~template ~source ()
|
match_all ~configuration engine template source
|
||||||
|
|> (fun matches ->
|
||||||
|
Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
||||||
|
|> (fun { rewritten_source; _ } -> rewritten_source)
|
||||||
|
|> print_string
|
||||||
|
|
||||||
let%expect_test "rewrite_comments_1" =
|
let%expect_test "rewrite_comments_1" =
|
||||||
let template = "replace this :[1] end" in
|
let template = "replace this :[1] end" in
|
||||||
let source = "/* don't replace this () end */ do replace this () end" in
|
let source = "/* don't replace this () end */ do replace this () end" in
|
||||||
let rewrite_template = "X" in
|
let rewrite_template = "X" in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches ->
|
[%expect_exact "/* don't replace this () end */ do X"];
|
||||||
Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
all (module Omega) template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "/* don't replace this () end */ do X"]
|
[%expect_exact "/* don't replace this () end */ do X"]
|
||||||
|
|
||||||
let%expect_test "rewrite_comments_2" =
|
let%expect_test "rewrite_comments_2" =
|
||||||
@ -45,20 +48,54 @@ let%expect_test "rewrite_comments_2" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
{|
|
||||||
|> print_string;
|
if (real_condition_body_must_be_empty) {}
|
||||||
|
|}];
|
||||||
|
all (module Omega) template source rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{|
|
{|
|
||||||
if (real_condition_body_must_be_empty) {}
|
if (real_condition_body_must_be_empty) {}
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "capture_comments" =
|
let%expect_test "capture_comments" =
|
||||||
let template = {|if (:[1]) { :[2] }|} in
|
let template = {|if (:[1]) { :[2] }|} in
|
||||||
let source = {|if (true) { /* some comment */ console.log(z); }|} in
|
let source = {|if (true) { /* some comment */ console.log(z); }|} in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
match_all (module Alpha) template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 48, "line": 1, "column": 49 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "true",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 4, "line": 1, "column": 5 },
|
||||||
|
"end": { "offset": 8, "line": 1, "column": 9 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"variable": "2",
|
||||||
|
"value": "console.log(z);",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 31, "line": 1, "column": 32 },
|
||||||
|
"end": { "offset": 46, "line": 1, "column": 47 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "if (true) { /* some comment */ console.log(z); }"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
match_all (module Omega) template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -87,6 +124,7 @@ let%expect_test "capture_comments" =
|
|||||||
}
|
}
|
||||||
]|}]
|
]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "single_quote_in_comment" =
|
let%expect_test "single_quote_in_comment" =
|
||||||
let template =
|
let template =
|
||||||
{| {:[1]} |}
|
{| {:[1]} |}
|
||||||
@ -105,15 +143,19 @@ let%expect_test "single_quote_in_comment" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
{|
|
||||||
|> print_string;
|
{test}
|
||||||
|
|}];
|
||||||
|
|
||||||
|
all (module Omega) template source rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{|
|
{|
|
||||||
{test}
|
{test}
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "single_quote_in_comment" =
|
let%expect_test "single_quote_in_comment" =
|
||||||
let template =
|
let template =
|
||||||
{| {:[1]} |}
|
{| {:[1]} |}
|
||||||
@ -136,10 +178,18 @@ let%expect_test "single_quote_in_comment" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
{|
|
||||||
|> print_string;
|
{
|
||||||
|
a = 1;
|
||||||
|
/* Events with mask == AE_NONE are not set. So let's initiaize the
|
||||||
|
* vector with it. */
|
||||||
|
for (i = 0; i < setsize; i++)
|
||||||
|
}
|
||||||
|
|}];
|
||||||
|
|
||||||
|
all (module Omega) template source rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{|
|
{|
|
||||||
{
|
{
|
||||||
@ -150,6 +200,7 @@ let%expect_test "single_quote_in_comment" =
|
|||||||
}
|
}
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "single_quote_in_comment" =
|
let%expect_test "single_quote_in_comment" =
|
||||||
let template =
|
let template =
|
||||||
{| {:[1]} |}
|
{| {:[1]} |}
|
||||||
@ -171,10 +222,17 @@ let%expect_test "single_quote_in_comment" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
{|
|
||||||
|> print_string;
|
{
|
||||||
|
a = 1;
|
||||||
|
/* ' */
|
||||||
|
for (i = 0; i < setsize; i++)
|
||||||
|
}
|
||||||
|
|}];
|
||||||
|
|
||||||
|
all (module Omega) template source rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{|
|
{|
|
||||||
{
|
{
|
||||||
@ -184,6 +242,7 @@ let%expect_test "single_quote_in_comment" =
|
|||||||
}
|
}
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "give_back_the_comment_characters_for_newline_comments_too" =
|
let%expect_test "give_back_the_comment_characters_for_newline_comments_too" =
|
||||||
let template =
|
let template =
|
||||||
{| {:[1]} |}
|
{| {:[1]} |}
|
||||||
@ -203,10 +262,15 @@ let%expect_test "give_back_the_comment_characters_for_newline_comments_too" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
{|
|
||||||
|> print_string;
|
{
|
||||||
|
// a comment
|
||||||
|
}
|
||||||
|
|}];
|
||||||
|
|
||||||
|
all (module Omega) template source rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{|
|
{|
|
||||||
{
|
{
|
||||||
@ -214,6 +278,7 @@ let%expect_test "give_back_the_comment_characters_for_newline_comments_too" =
|
|||||||
}
|
}
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "comments_in_templates_imply_whitespace" =
|
let%expect_test "comments_in_templates_imply_whitespace" =
|
||||||
let template =
|
let template =
|
||||||
{|
|
{|
|
||||||
@ -235,9 +300,9 @@ a
|
|||||||
{|erased|}
|
{|erased|}
|
||||||
in
|
in
|
||||||
|
|
||||||
all template source
|
all (module Alpha) template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
{|erased|}];
|
||||||
|> print_string;
|
all (module Omega) template source rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{|erased|}]
|
{|erased|}]
|
@ -1,243 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_alpha
|
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
|
||||||
C.all ~configuration ~template ~source ()
|
|
||||||
|
|
||||||
let%expect_test "rewrite_comments_1" =
|
|
||||||
let template = "replace this :[1] end" in
|
|
||||||
let source = "/* don't replace this () end */ do replace this () end" in
|
|
||||||
let rewrite_template = "X" in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches ->
|
|
||||||
Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "/* don't replace this () end */ do X"]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_comments_2" =
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
if (:[1]) { :[2] }
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
/* if (fake_condition_body_must_be_non_empty) { fake_body; } */
|
|
||||||
// if (fake_condition_body_must_be_non_empty) { fake_body; }
|
|
||||||
if (real_condition_body_must_be_empty) {
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
if (:[1]) {}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact
|
|
||||||
{|
|
|
||||||
if (real_condition_body_must_be_empty) {}
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "capture_comments" =
|
|
||||||
let template = {|if (:[1]) { :[2] }|} in
|
|
||||||
let source = {|if (true) { /* some comment */ console.log(z); }|} in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 48, "line": 1, "column": 49 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "true",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 4, "line": 1, "column": 5 },
|
|
||||||
"end": { "offset": 8, "line": 1, "column": 9 }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"variable": "2",
|
|
||||||
"value": "console.log(z);",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 31, "line": 1, "column": 32 },
|
|
||||||
"end": { "offset": 46, "line": 1, "column": 47 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "if (true) { /* some comment */ console.log(z); }"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "single_quote_in_comment" =
|
|
||||||
let template =
|
|
||||||
{| {:[1]} |}
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
/*'*/
|
|
||||||
{test}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
{:[1]}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact
|
|
||||||
{|
|
|
||||||
{test}
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "single_quote_in_comment" =
|
|
||||||
let template =
|
|
||||||
{| {:[1]} |}
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
{
|
|
||||||
a = 1;
|
|
||||||
/* Events with mask == AE_NONE are not set. So let's initiaize the
|
|
||||||
* vector with it. */
|
|
||||||
for (i = 0; i < setsize; i++)
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
{:[1]}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact
|
|
||||||
{|
|
|
||||||
{
|
|
||||||
a = 1;
|
|
||||||
/* Events with mask == AE_NONE are not set. So let's initiaize the
|
|
||||||
* vector with it. */
|
|
||||||
for (i = 0; i < setsize; i++)
|
|
||||||
}
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "single_quote_in_comment" =
|
|
||||||
let template =
|
|
||||||
{| {:[1]} |}
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
{
|
|
||||||
a = 1;
|
|
||||||
/* ' */
|
|
||||||
for (i = 0; i < setsize; i++)
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
{:[1]}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact
|
|
||||||
{|
|
|
||||||
{
|
|
||||||
a = 1;
|
|
||||||
/* ' */
|
|
||||||
for (i = 0; i < setsize; i++)
|
|
||||||
}
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "give_back_the_comment_characters_for_newline_comments_too" =
|
|
||||||
let template =
|
|
||||||
{| {:[1]} |}
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
{
|
|
||||||
// a comment
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
{:[1]}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact
|
|
||||||
{|
|
|
||||||
{
|
|
||||||
// a comment
|
|
||||||
}
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_in_templates_imply_whitespace" =
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
/* f */
|
|
||||||
// q
|
|
||||||
a
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
// idgaf
|
|
||||||
/* fooo */
|
|
||||||
a
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|erased|}
|
|
||||||
in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact
|
|
||||||
{|erased|}]
|
|
@ -1252,7 +1252,7 @@ let%expect_test "test_custom_metasyntax_partial_rule_support" =
|
|||||||
let command = Format.sprintf "%s %s" binary_path command_args in
|
let command = Format.sprintf "%s %s" binary_path command_args in
|
||||||
let result = read_expect_stdin_and_stdout command source in
|
let result = read_expect_stdin_and_stdout command source in
|
||||||
print_string result;
|
print_string result;
|
||||||
[%expect "a b"]
|
[%expect "$C b"]
|
||||||
|
|
||||||
let%expect_test "test_custom_metasyntax_reserved_identifiers" =
|
let%expect_test "test_custom_metasyntax_reserved_identifiers" =
|
||||||
let source = "fun f -> (fun x -> f (x x)) (fun x -> f (x x))" in
|
let source = "fun f -> (fun x -> f (x x)) (fun x -> f (x x))" in
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Configuration
|
open Comby
|
||||||
|
|
||||||
let%expect_test "basic" =
|
let%expect_test "basic" =
|
||||||
let match_template = "for :[i], :[x] := range :[list] {:[body]}" in
|
let match_template = "for :[i], :[x] := range :[list] {:[body]}" in
|
||||||
let spec = Specification.create ~match_template () in
|
let spec = Matchers.Specification.create ~match_template () in
|
||||||
let result = Specification.to_regex spec in
|
let result = Regex.to_regex spec in
|
||||||
print_string result;
|
print_string result;
|
||||||
[%expect_exact {|(for\s+)(\n|.)*?(,\s+)(\n|.)*?(\s+:=\s+range\s+)(\n|.)*?(\s+\{)(\n|.)*?(\})|}];
|
[%expect_exact {|(for\s+)(\n|.)*?(,\s+)(\n|.)*?(\s+:=\s+range\s+)(\n|.)*?(\s+\{)(\n|.)*?(\})|}];
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Matchers
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
include Test_alpha
|
let run (module E : Engine.S) ?(configuration = configuration) source match_template rewrite_template =
|
||||||
|
E.Generic.first ~configuration match_template source
|
||||||
let run ?(configuration = configuration) source match_template rewrite_template =
|
|
||||||
Generic.first ~configuration match_template source
|
|
||||||
|> function
|
|> function
|
||||||
| Ok result ->
|
| Ok result ->
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
Rewrite.all ~source ~rewrite_template [result]
|
||||||
@ -19,8 +16,7 @@ let run ?(configuration = configuration) source match_template rewrite_template
|
|||||||
(* this is too annoying to fix every time the grammar changes. *)
|
(* this is too annoying to fix every time the grammar changes. *)
|
||||||
print_string ""
|
print_string ""
|
||||||
|
|
||||||
let run_all ?(m = (module Generic : Matchers.Matcher.S)) ?(configuration = configuration) source match_template rewrite_template =
|
let run_all (module M : Matchers.Matcher.S) ?(configuration = configuration) source match_template rewrite_template =
|
||||||
let (module M) = m in
|
|
||||||
M.all ~configuration ~template:match_template ~source ()
|
M.all ~configuration ~template:match_template ~source ()
|
||||||
|> function
|
|> function
|
||||||
| [] -> print_string "No matches."
|
| [] -> print_string "No matches."
|
||||||
@ -29,332 +25,446 @@ let run_all ?(m = (module Generic : Matchers.Matcher.S)) ?(configuration = confi
|
|||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> (fun { rewritten_source; _ } -> rewritten_source)
|
||||||
|> print_string
|
|> print_string
|
||||||
|
|
||||||
|
let run_match (module M : Matchers.Matcher.S) source match_template =
|
||||||
|
M.all ~configuration ~template:match_template ~source ()
|
||||||
|
|> function
|
||||||
|
| [] -> print_string "No matches."
|
||||||
|
| hd :: _ ->
|
||||||
|
print_string (Yojson.Safe.to_string (Match.to_yojson hd))
|
||||||
|
|
||||||
let%expect_test "basic" =
|
let%expect_test "basic" =
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|:[1]|} in
|
let match_template = {|:[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a b c d|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a b c d|}];
|
[%expect_exact {|a b c d|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[1] c d|} in
|
let match_template = {|a :[1] c d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b|}];
|
[%expect_exact {|b|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[1] d|} in
|
let match_template = {|a :[1] d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
[%expect_exact {|b c|}];
|
[%expect_exact {|b c|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[1]|} in
|
let match_template = {|a :[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b c d|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b c d|}];
|
[%expect_exact {|b c d|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|:[1] c d|} in
|
let match_template = {|:[1] c d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a b|}];
|
[%expect_exact {|a b|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|:[1] :[2]|} in
|
let match_template = {|:[1] :[2]|} in
|
||||||
let rewrite_template = {|(:[1]) (:[2])|} in
|
let rewrite_template = {|(:[1]) (:[2])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a) (b c d)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a) (b c d)|}];
|
[%expect_exact {|(a) (b c d)|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|:[2] :[1]|} in
|
let match_template = {|:[2] :[1]|} in
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
let rewrite_template = {|(:[2]) (:[1])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a) (b c d)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a) (b c d)|}];
|
[%expect_exact {|(a) (b c d)|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[2] :[1] d|} in
|
let match_template = {|a :[2] :[1] d|} in
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
let rewrite_template = {|(:[2]) (:[1])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(b) (c)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(b) (c)|}];
|
[%expect_exact {|(b) (c)|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[2] :[1]|} in
|
let match_template = {|a :[2] :[1]|} in
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
let rewrite_template = {|(:[2]) (:[1])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(b) (c d)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(b) (c d)|}];
|
[%expect_exact {|(b) (c d)|}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[2] c :[1]|} in
|
let match_template = {|a :[2] c :[1]|} in
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
let rewrite_template = {|(:[2]) (:[1])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(b) (d)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(b) (d)|}];
|
[%expect_exact {|(b) (d)|}];
|
||||||
|
|
||||||
let source = {|x:|} in
|
let source = {|x:|} in
|
||||||
let match_template = {|:[1]:|} in
|
let match_template = {|:[1]:|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|x|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|x|}]
|
[%expect_exact {|x|}]
|
||||||
|
|
||||||
let%expect_test "basic_failures" =
|
let%expect_test "basic_failures" =
|
||||||
let source = {|a x b bbq|} in
|
let source = {|a x b bbq|} in
|
||||||
let match_template = {|a :[1] b c|} in
|
let match_template = {|a :[1] b c|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {||}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {||}];
|
[%expect_exact {||}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[2] d :[1]|} in
|
let match_template = {|a :[2] d :[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact
|
||||||
|
{||}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact
|
[%expect_exact
|
||||||
{||}];
|
{||}];
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
let source = {|a b c d|} in
|
||||||
let match_template = {|a :[2] b :[1]|} in
|
let match_template = {|a :[2] b :[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {||}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {||}]
|
[%expect_exact {||}]
|
||||||
|
|
||||||
let%expect_test "delimiter_matching" =
|
let%expect_test "delimiter_matching" =
|
||||||
let source = {|foo(bar)|} in
|
let source = {|foo(bar)|} in
|
||||||
let match_template = {|:[1](bar)|} in
|
let match_template = {|:[1](bar)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|foo|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|foo|}];
|
[%expect_exact {|foo|}];
|
||||||
|
|
||||||
let source = {|(a b c) d|} in
|
let source = {|(a b c) d|} in
|
||||||
let match_template = {|(:[1]) d|} in
|
let match_template = {|(:[1]) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a b c|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a b c|}];
|
[%expect_exact {|a b c|}];
|
||||||
|
|
||||||
let source = {|(a b c) d|} in
|
let source = {|(a b c) d|} in
|
||||||
let match_template = {|(:[1] b :[2]) d|} in
|
let match_template = {|(:[1] b :[2]) d|} in
|
||||||
let rewrite_template = {|(:[1]) (:[2])|} in
|
let rewrite_template = {|(:[1]) (:[2])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a) (c)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a) (c)|}];
|
[%expect_exact {|(a) (c)|}];
|
||||||
|
|
||||||
let source = {|q(a b c) d|} in
|
let source = {|q(a b c) d|} in
|
||||||
let match_template = {|q(:[1] b :[2]) d|} in
|
let match_template = {|q(:[1] b :[2]) d|} in
|
||||||
let rewrite_template = {|(:[1]) (:[2])|} in
|
let rewrite_template = {|(:[1]) (:[2])|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a) (c)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a) (c)|}];
|
[%expect_exact {|(a) (c)|}];
|
||||||
|
|
||||||
let source = {|((a) b)|} in
|
let source = {|((a) b)|} in
|
||||||
let match_template = {|(:[1] b)|} in
|
let match_template = {|(:[1] b)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a)|}];
|
[%expect_exact {|(a)|}];
|
||||||
|
|
||||||
let source = {|((a b c)) d|} in
|
let source = {|((a b c)) d|} in
|
||||||
let match_template = {|(:[1]) d|} in
|
let match_template = {|(:[1]) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a b c)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a b c)|}];
|
[%expect_exact {|(a b c)|}];
|
||||||
|
|
||||||
let source = {|((a b c)) d|} in
|
let source = {|((a b c)) d|} in
|
||||||
let match_template = {|(:[1]) d|} in
|
let match_template = {|(:[1]) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(a b c)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(a b c)|}];
|
[%expect_exact {|(a b c)|}];
|
||||||
|
|
||||||
let source = {|((a b c) q) d|} in
|
let source = {|((a b c) q) d|} in
|
||||||
let match_template = {|((:[1]) q) d|} in
|
let match_template = {|((:[1]) q) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a b c|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a b c|}];
|
[%expect_exact {|a b c|}];
|
||||||
|
|
||||||
let source = {|((a b c) q) d|} in
|
let source = {|((a b c) q) d|} in
|
||||||
let match_template = {|((:[1] c) q) d|} in
|
let match_template = {|((:[1] c) q) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a b|}];
|
[%expect_exact {|a b|}];
|
||||||
|
|
||||||
let source = {|((a b () c) q) d|} in
|
let source = {|((a b () c) q) d|} in
|
||||||
let match_template = {|((:[1] () c) q) d|} in
|
let match_template = {|((:[1] () c) q) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a b|}];
|
[%expect_exact {|a b|}];
|
||||||
|
|
||||||
let source = {|((a ((x) d) b c)) d|} in
|
let source = {|((a ((x) d) b c)) d|} in
|
||||||
let match_template = {|((a :[1] :[2] c)) d|} in
|
let match_template = {|((a :[1] :[2] c)) d|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|((x) d)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|((x) d)|}];
|
[%expect_exact {|((x) d)|}];
|
||||||
|
|
||||||
let source = {|((a ((x) d) b c)) d|} in
|
let source = {|((a ((x) d) b c)) d|} in
|
||||||
let match_template = {|((a (:[1]) :[2] c)) d|} in
|
let match_template = {|((a (:[1]) :[2] c)) d|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(x) d b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(x) d b|}];
|
[%expect_exact {|(x) d b|}];
|
||||||
|
|
||||||
let source = {|(b (c) d)|} in
|
let source = {|(b (c) d)|} in
|
||||||
let match_template = {|(:[1])|} in
|
let match_template = {|(:[1])|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b (c) d|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b (c) d|}];
|
[%expect_exact {|b (c) d|}];
|
||||||
|
|
||||||
let source = {|(b (c) d.)|} in
|
let source = {|(b (c) d.)|} in
|
||||||
let match_template = {|(:[1].)|} in
|
let match_template = {|(:[1].)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b (c) d|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b (c) d|}];
|
[%expect_exact {|b (c) d|}];
|
||||||
|
|
||||||
let source = {|(b (c.) d.)|} in
|
let source = {|(b (c.) d.)|} in
|
||||||
let match_template = {|(:[1].)|} in
|
let match_template = {|(:[1].)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b (c.) d|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b (c.) d|}];
|
[%expect_exact {|b (c.) d|}];
|
||||||
|
|
||||||
let source = {|(b. (c) d.)|} in
|
let source = {|(b. (c) d.)|} in
|
||||||
let match_template = {|(:[1].)|} in
|
let match_template = {|(:[1].)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b. (c) d|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b. (c) d|}];
|
[%expect_exact {|b. (c) d|}];
|
||||||
|
|
||||||
let source = {|(b (c) d.)|} in
|
let source = {|(b (c) d.)|} in
|
||||||
let match_template = {|(b :[1] d.)|} in
|
let match_template = {|(b :[1] d.)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(c)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(c)|}];
|
[%expect_exact {|(c)|}];
|
||||||
|
|
||||||
let source = {|outer(inner(dst,src),src)|} in
|
let source = {|outer(inner(dst,src),src)|} in
|
||||||
let match_template = {|outer(:[1],src)|} in
|
let match_template = {|outer(:[1],src)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|inner(dst,src)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|inner(dst,src)|}];
|
[%expect_exact {|inner(dst,src)|}];
|
||||||
|
|
||||||
let source = {|(b ((c)) d.)|} in
|
let source = {|(b ((c)) d.)|} in
|
||||||
let match_template = {|(b :[1] d.)|} in
|
let match_template = {|(b :[1] d.)|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|((c))|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|((c))|}];
|
[%expect_exact {|((c))|}];
|
||||||
|
|
||||||
let source = {|a b c|} in
|
let source = {|a b c|} in
|
||||||
let match_template = {|a :[1] c|} in
|
let match_template = {|a :[1] c|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b|}];
|
[%expect_exact {|b|}];
|
||||||
|
|
||||||
let source = {|x = foo;|} in
|
let source = {|x = foo;|} in
|
||||||
let match_template = {|x = :[1];|} in
|
let match_template = {|x = :[1];|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|foo|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|foo|}];
|
[%expect_exact {|foo|}];
|
||||||
|
|
||||||
let source = {|((a {{x} d} b c)) d|} in
|
let source = {|((a {{x} d} b c)) d|} in
|
||||||
let match_template = {|((a {:[1] d} :[2] c)) d|} in
|
let match_template = {|((a {:[1] d} :[2] c)) d|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{x} b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{x} b|}];
|
[%expect_exact {|{x} b|}];
|
||||||
|
|
||||||
let source = {|((a {([{x}]) d} b c)) d|} in
|
let source = {|((a {([{x}]) d} b c)) d|} in
|
||||||
let match_template = {|((a {:[1] d} :[2] c)) d|} in
|
let match_template = {|((a {:[1] d} :[2] c)) d|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|([{x}]) b|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|([{x}]) b|}];
|
[%expect_exact {|([{x}]) b|}];
|
||||||
|
|
||||||
let source = {|(((((x)))))|} in
|
let source = {|(((((x)))))|} in
|
||||||
let match_template = {|(((:[1])))|} in
|
let match_template = {|(((:[1])))|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|((x))|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|((x))|}];
|
[%expect_exact {|((x))|}];
|
||||||
|
|
||||||
let source = {|((((y(x)z))))|} in
|
let source = {|((((y(x)z))))|} in
|
||||||
let match_template = {|(((:[1])))|} in
|
let match_template = {|(((:[1])))|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(y(x)z)|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(y(x)z)|}];
|
[%expect_exact {|(y(x)z)|}];
|
||||||
|
|
||||||
let source = {|((((y(x)z))))|} in
|
let source = {|((((y(x)z))))|} in
|
||||||
let match_template = {|(((:[1]):[2]))|} in
|
let match_template = {|(((:[1]):[2]))|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(y(x)z) |}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(y(x)z) |}];
|
[%expect_exact {|(y(x)z) |}];
|
||||||
|
|
||||||
let source = {|(((x)z))|} in
|
let source = {|(((x)z))|} in
|
||||||
let match_template = {|(((:[1]):[2]))|} in
|
let match_template = {|(((:[1]):[2]))|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|x z|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|x z|}];
|
[%expect_exact {|x z|}];
|
||||||
|
|
||||||
let source = {|((((x))z))|} in
|
let source = {|((((x))z))|} in
|
||||||
let match_template = {|(((:[1]):[2]))|} in
|
let match_template = {|(((:[1]):[2]))|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(x) z|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|(x) z|}];
|
[%expect_exact {|(x) z|}];
|
||||||
|
|
||||||
let source = {|lolwtfbbq|} in
|
let source = {|lolwtfbbq|} in
|
||||||
let match_template = {|lol:[1]bbq|} in
|
let match_template = {|lol:[1]bbq|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|wtf|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|wtf|}];
|
[%expect_exact {|wtf|}];
|
||||||
|
|
||||||
let source = {|x = foo; x = bar;|} in
|
let source = {|x = foo; x = bar;|} in
|
||||||
let match_template = {|x = :[1];|} in
|
let match_template = {|x = :[1];|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|foo x = bar;|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|foo x = bar;|}];
|
[%expect_exact {|foo x = bar;|}];
|
||||||
|
|
||||||
let source = {|[ no match prefix ] x = foo; [ no match suffix ]|} in
|
let source = {|[ no match prefix ] x = foo; [ no match suffix ]|} in
|
||||||
let match_template = {|x = :[1];|} in
|
let match_template = {|x = :[1];|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|[ no match prefix ] foo [ no match suffix ]|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|[ no match prefix ] foo [ no match suffix ]|}];
|
[%expect_exact {|[ no match prefix ] foo [ no match suffix ]|}];
|
||||||
|
|
||||||
let source = {|x = a; x = b; x = c|} in
|
let source = {|x = a; x = b; x = c|} in
|
||||||
let match_template = {|x = :[1];|} in
|
let match_template = {|x = :[1];|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a x = b; x = c|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a x = b; x = c|}];
|
[%expect_exact {|a x = b; x = c|}];
|
||||||
|
|
||||||
let source = {|x = ( x = x; );|} in
|
let source = {|x = ( x = x; );|} in
|
||||||
let match_template = {|x = :[1];|} in
|
let match_template = {|x = :[1];|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|( x = x; )|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|( x = x; )|}];
|
[%expect_exact {|( x = x; )|}];
|
||||||
|
|
||||||
let source = {|( x = x = x; )|} in
|
let source = {|( x = x = x; )|} in
|
||||||
let match_template = {|x = :[1];|} in
|
let match_template = {|x = :[1];|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|( x = x )|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|( x = x )|}];
|
[%expect_exact {|( x = x )|}];
|
||||||
|
|
||||||
let source = {|xxx a b d c 1 2 3 b d d blah|} in
|
let source = {|xxx a b d c 1 2 3 b d d blah|} in
|
||||||
let match_template = {|a :[1] c :[2] d|} in
|
let match_template = {|a :[1] c :[2] d|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|xxx b d 1 2 3 b d blah|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|xxx b d 1 2 3 b d blah|}];
|
[%expect_exact {|xxx b d 1 2 3 b d blah|}];
|
||||||
|
|
||||||
let source = {|howevenlolwtfbbqispossible|} in
|
let source = {|howevenlolwtfbbqispossible|} in
|
||||||
let match_template = {|lol:[1]bbq|} in
|
let match_template = {|lol:[1]bbq|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|howevenwtfispossible|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|howevenwtfispossible|}];
|
[%expect_exact {|howevenwtfispossible|}];
|
||||||
|
|
||||||
let source = {|lolhowevenlolwtfbbqispossiblebbq|} in
|
let source = {|lolhowevenlolwtfbbqispossiblebbq|} in
|
||||||
let match_template = {|lol:[1]bbq|} in
|
let match_template = {|lol:[1]bbq|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|howevenlolwtfispossiblebbq|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|howevenlolwtfispossiblebbq|}];
|
[%expect_exact {|howevenlolwtfispossiblebbq|}];
|
||||||
|
|
||||||
let source = {|hello my name is bob the builder|} in
|
let source = {|hello my name is bob the builder|} in
|
||||||
let match_template = {|:[alongidentifiername] :[2] :[3] :[xyz] :[5] :[6]|} in
|
let match_template = {|:[alongidentifiername] :[2] :[3] :[xyz] :[5] :[6]|} in
|
||||||
let rewrite_template = {|:[alongidentifiername] :[2] :[3] :[xyz] :[5] :[6]|} in
|
let rewrite_template = {|:[alongidentifiername] :[2] :[3] :[xyz] :[5] :[6]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|hello my name is bob the builder|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|hello my name is bob the builder|}];
|
[%expect_exact {|hello my name is bob the builder|}];
|
||||||
|
|
||||||
let source = {|www.testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n-280x428.jpg|} in
|
let source = {|www.testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n-280x428.jpg|} in
|
||||||
let match_template = {|www.:[1]-:[2].jpg|} in
|
let match_template = {|www.:[1]-:[2].jpg|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n 280x428|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n 280x428|}];
|
[%expect_exact {|testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n 280x428|}];
|
||||||
|
|
||||||
let source = {|https://api.github.com/repos/dmjacobsen/slurm/commits/716c1499695c68afcab848a1b49653574b4fc167|} in
|
let source = {|https://api.github.com/repos/dmjacobsen/slurm/commits/716c1499695c68afcab848a1b49653574b4fc167|} in
|
||||||
let match_template = {|:[1]api.:[2]/repos/:[3]s/:[4]|} in
|
let match_template = {|:[1]api.:[2]/repos/:[3]s/:[4]|} in
|
||||||
let rewrite_template = {|:[1] :[2] :[3] :[4]|} in
|
let rewrite_template = {|:[1] :[2] :[3] :[4]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|https:// github.com dmjacobsen/slurm/commit 716c1499695c68afcab848a1b49653574b4fc167|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|https:// github.com dmjacobsen/slurm/commit 716c1499695c68afcab848a1b49653574b4fc167|}];
|
[%expect_exact {|https:// github.com dmjacobsen/slurm/commit 716c1499695c68afcab848a1b49653574b4fc167|}];
|
||||||
|
|
||||||
let source =
|
let source =
|
||||||
@ -369,7 +479,12 @@ let%expect_test "delimiter_matching" =
|
|||||||
in
|
in
|
||||||
let match_template = {|memcpy(:[1], :[2], :[3]);|} in
|
let match_template = {|memcpy(:[1], :[2], :[3]);|} in
|
||||||
let rewrite_template = {|:[1], :[2], :[3]|} in
|
let rewrite_template = {|:[1], :[2], :[3]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|assert(stream->md_len + md_len -
|
||||||
|
si.foo_data_begin <= MAD_BUFFER_MDLEN);
|
||||||
|
*stream->foo_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.foo_data_begin
|
||||||
|
stream->md_len += frame_used;|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|assert(stream->md_len + md_len -
|
[%expect_exact {|assert(stream->md_len + md_len -
|
||||||
si.foo_data_begin <= MAD_BUFFER_MDLEN);
|
si.foo_data_begin <= MAD_BUFFER_MDLEN);
|
||||||
*stream->foo_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.foo_data_begin
|
*stream->foo_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.foo_data_begin
|
||||||
@ -382,7 +497,9 @@ let%expect_test "significant_whitespace" =
|
|||||||
let source = {|two spaces|} in
|
let source = {|two spaces|} in
|
||||||
let match_template = {|:[1] :[2]|} in
|
let match_template = {|:[1] :[2]|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|two spaces|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|two spaces|}];
|
[%expect_exact {|two spaces|}];
|
||||||
|
|
||||||
(* FIXME: this should fail. also test case where separators do or do not need
|
(* FIXME: this should fail. also test case where separators do or do not need
|
||||||
@ -391,46 +508,48 @@ let%expect_test "significant_whitespace" =
|
|||||||
let source = {|two spaces|} in
|
let source = {|two spaces|} in
|
||||||
let match_template = {|:[1] :[2]|} in
|
let match_template = {|:[1] :[2]|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|two spaces|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|two spaces|}]
|
[%expect_exact {|two spaces|}]
|
||||||
|
|
||||||
let%expect_test "contextual_matching" =
|
let%expect_test "contextual_matching" =
|
||||||
let run = run_all in
|
|
||||||
|
|
||||||
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
||||||
let match_template = {|memcpy(:[1], :[2], :[3])|} in
|
let match_template = {|memcpy(:[1], :[2], :[3])|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run_all (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|dst1; dst2;|}];
|
||||||
|
run_all (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|dst1; dst2;|}];
|
[%expect_exact {|dst1; dst2;|}];
|
||||||
|
|
||||||
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
||||||
let match_template = {|memcpy(:[1], :[2], :[3])|} in
|
let match_template = {|memcpy(:[1], :[2], :[3])|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
run source match_template rewrite_template;
|
run_all (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|dst1; dst2;|}];
|
||||||
|
run_all (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|dst1; dst2;|}]
|
[%expect_exact {|dst1; dst2;|}]
|
||||||
|
|
||||||
let%expect_test "contextual_matching_with_short_hole_syntax" =
|
let%expect_test "contextual_matching_with_short_hole_syntax" =
|
||||||
let run = run_all in
|
|
||||||
|
|
||||||
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
||||||
let match_template = {|memcpy(:[[1]], :[2], :[3])|} in
|
let match_template = {|memcpy(:[[1]], :[2], :[3])|} in
|
||||||
let rewrite_template = {|:[[1]]|} in
|
let rewrite_template = {|:[[1]]|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|dst1; dst2;|}];
|
||||||
|
run_all (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|dst1; dst2;|}]
|
[%expect_exact {|dst1; dst2;|}]
|
||||||
|
|
||||||
let%expect_test "trivial_empty_case" =
|
let%expect_test "trivial_empty_case" =
|
||||||
let source = "" in
|
let source = "" in
|
||||||
let match_template = "" in
|
let match_template = "" in
|
||||||
begin
|
|
||||||
Generic.all ~configuration ~template:match_template ~source ()
|
run_match (module Alpha.Generic) source match_template;
|
||||||
|> function
|
[%expect_exact {|{"range":{"start":{"offset":0,"line":1,"column":1},"end":{"offset":0,"line":1,"column":1}},"environment":[],"matched":""}|}];
|
||||||
| [] -> print_string "No matches."
|
run_match (module Omega.Generic) source match_template;
|
||||||
| hd :: _ ->
|
|
||||||
print_string (Yojson.Safe.to_string (Match.to_yojson hd))
|
|
||||||
end;
|
|
||||||
[%expect_exact {|{"range":{"start":{"offset":0,"line":1,"column":1},"end":{"offset":0,"line":1,"column":1}},"environment":[],"matched":""}|}]
|
[%expect_exact {|{"range":{"start":{"offset":0,"line":1,"column":1},"end":{"offset":0,"line":1,"column":1}},"environment":[],"matched":""}|}]
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline" =
|
let%expect_test "test_top_level_hole_stops_at_newline_false_implies_default_generic" =
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
a = b
|
a = b
|
||||||
@ -449,8 +568,9 @@ let%expect_test "test_top_level_hole_stops_at_newline" =
|
|||||||
in
|
in
|
||||||
let match_template = ":[1] = :[2]" in
|
let match_template = ":[1] = :[2]" in
|
||||||
let rewrite_template = "line" in
|
let rewrite_template = "line" in
|
||||||
let configuration = { (Configuration.create ()) with match_newline_toplevel = false } in
|
let configuration = Configuration.create ~match_newline_toplevel:false () in
|
||||||
run_all ~configuration source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha.Generic) ~configuration source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
line
|
line
|
||||||
line
|
line
|
||||||
@ -464,80 +584,14 @@ line
|
|||||||
line
|
line
|
||||||
)
|
)
|
||||||
line
|
line
|
||||||
|}]
|
|}];
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline_for_example" =
|
(* Unimplemented: Does not stop at newline *)
|
||||||
let source =
|
run_all (module Omega.Generic) ~configuration source match_template rewrite_template;
|
||||||
{|
|
|
||||||
for i, x := range derp {
|
|
||||||
do not match
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, x := range derp {
|
|
||||||
do match
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = "for i, x := :[_] { do match }" in
|
|
||||||
let rewrite_template = "erased" in
|
|
||||||
let configuration = { (Configuration.create ()) with match_newline_toplevel = false } in
|
|
||||||
run_all ~configuration source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
for i, x := range derp {
|
|
||||||
do not match
|
|
||||||
}
|
|
||||||
|
|
||||||
erased
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline_for_example" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
for i, x := range derp {
|
|
||||||
do not match
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, x := range derp {
|
|
||||||
do match
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = "for i, x := :[_] { do match }" in
|
|
||||||
let rewrite_template = "erased" in
|
|
||||||
let configuration = { (Configuration.create ()) with match_newline_toplevel = false } in
|
|
||||||
run_all ~configuration source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
for i, x := range derp {
|
|
||||||
do not match
|
|
||||||
}
|
|
||||||
|
|
||||||
erased
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline_false" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
a = b
|
|
||||||
c = d
|
|
||||||
(
|
|
||||||
e = f
|
|
||||||
(
|
|
||||||
g = h
|
|
||||||
i = j
|
|
||||||
)
|
|
||||||
k = l
|
|
||||||
m = n
|
|
||||||
)
|
|
||||||
o = p
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = ":[1] = :[2]" in
|
|
||||||
let rewrite_template = "line" in
|
|
||||||
let configuration = { (Configuration.create ()) with match_newline_toplevel = true } in
|
|
||||||
run_all ~configuration source match_template rewrite_template;
|
|
||||||
[%expect_exact {|line|}]
|
[%expect_exact {|line|}]
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline_for_example_false" =
|
|
||||||
|
let%expect_test "test_top_level_hole_stops_at_newline_for_example_generic_go_false" =
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
for i, x := range derp {
|
for i, x := range derp {
|
||||||
@ -551,13 +605,24 @@ let%expect_test "test_top_level_hole_stops_at_newline_for_example_false" =
|
|||||||
in
|
in
|
||||||
let match_template = "for i, x := :[_] { do match }" in
|
let match_template = "for i, x := :[_] { do match }" in
|
||||||
let rewrite_template = "erased" in
|
let rewrite_template = "erased" in
|
||||||
let configuration = { (Configuration.create ()) with match_newline_toplevel = true } in
|
let configuration = Configuration.create ~match_newline_toplevel:false () in
|
||||||
run_all ~configuration source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha.Generic) ~configuration source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
for i, x := range derp {
|
||||||
|
do not match
|
||||||
|
}
|
||||||
|
|
||||||
|
erased
|
||||||
|
|}];
|
||||||
|
|
||||||
|
(* Unimplemented: Does not stop at newline *)
|
||||||
|
run_all (module Omega.Generic) ~configuration source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
erased
|
erased
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline_for_example_false" =
|
let%expect_test "test_top_level_hole_stops_at_newline_for_example_generic_go_true" =
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
for i, x := range derp {
|
for i, x := range derp {
|
||||||
@ -571,12 +636,44 @@ let%expect_test "test_top_level_hole_stops_at_newline_for_example_false" =
|
|||||||
in
|
in
|
||||||
let match_template = "for i, x := :[_] { do match }" in
|
let match_template = "for i, x := :[_] { do match }" in
|
||||||
let rewrite_template = "erased" in
|
let rewrite_template = "erased" in
|
||||||
let configuration = { (Configuration.create ()) with match_newline_toplevel = true } in
|
let configuration = Configuration.create ~match_newline_toplevel:true () in
|
||||||
run_all ~configuration source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha.Generic) ~configuration source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
erased
|
||||||
|
|}];
|
||||||
|
run_all (module Omega.Generic) ~configuration source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
erased
|
erased
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
let%expect_test "test_top_level_hole_stops_at_newline_generic_true" =
|
||||||
|
let source =
|
||||||
|
{|
|
||||||
|
a = b
|
||||||
|
c = d
|
||||||
|
(
|
||||||
|
e = f
|
||||||
|
(
|
||||||
|
g = h
|
||||||
|
i = j
|
||||||
|
)
|
||||||
|
k = l
|
||||||
|
m = n
|
||||||
|
)
|
||||||
|
o = p
|
||||||
|
|}
|
||||||
|
in
|
||||||
|
let match_template = ":[1] = :[2]" in
|
||||||
|
let rewrite_template = "line" in
|
||||||
|
let configuration = Configuration.create ~match_newline_toplevel:true () in
|
||||||
|
|
||||||
|
run_all (module Alpha.Generic) ~configuration source match_template rewrite_template;
|
||||||
|
[%expect_exact {|line|}];
|
||||||
|
run_all (module Omega.Generic) ~configuration source match_template rewrite_template;
|
||||||
|
[%expect_exact {|line|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_crosses_newlines_for_html_by_default" =
|
let%expect_test "test_top_level_hole_crosses_newlines_for_html_by_default" =
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
@ -587,7 +684,16 @@ let%expect_test "test_top_level_hole_crosses_newlines_for_html_by_default" =
|
|||||||
in
|
in
|
||||||
let match_template = "<foo>:[x]</foo>" in
|
let match_template = "<foo>:[x]</foo>" in
|
||||||
let rewrite_template = ":[x]" in
|
let rewrite_template = ":[x]" in
|
||||||
run_all ~m:(module Matchers.Alpha.Html) ~configuration source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha.Html) ~configuration source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
|
||||||
|
stuff
|
||||||
|
|
||||||
|
|}];
|
||||||
|
|
||||||
|
(* Unimplemented: Has no effect *)
|
||||||
|
run_all (module Omega.Html) ~configuration source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
|
|
||||||
stuff
|
stuff
|
@ -1,477 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Matchers
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let run ?(configuration = configuration) source match_template rewrite_template =
|
|
||||||
Generic.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
(* this is too annoying to fix every time the grammar changes. *)
|
|
||||||
print_string ""
|
|
||||||
|
|
||||||
let run_all ?(configuration = configuration) source match_template rewrite_template =
|
|
||||||
Generic.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
|
||||||
| results ->
|
|
||||||
Option.value_exn (Rewrite.all ~source ~rewrite_template results)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
|
|
||||||
let%expect_test "basic" =
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a b c d|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[1] c d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[1] d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b c|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b c d|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|:[1] c d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a b|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|:[1] :[2]|} in
|
|
||||||
let rewrite_template = {|(:[1]) (:[2])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a) (b c d)|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|:[2] :[1]|} in
|
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a) (b c d)|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[2] :[1] d|} in
|
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(b) (c)|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[2] :[1]|} in
|
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(b) (c d)|}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[2] c :[1]|} in
|
|
||||||
let rewrite_template = {|(:[2]) (:[1])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(b) (d)|}];
|
|
||||||
|
|
||||||
let source = {|x:|} in
|
|
||||||
let match_template = {|:[1]:|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|x|}]
|
|
||||||
|
|
||||||
let%expect_test "basic_failures" =
|
|
||||||
let source = {|a x b bbq|} in
|
|
||||||
let match_template = {|a :[1] b c|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {||}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[2] d :[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact
|
|
||||||
{||}];
|
|
||||||
|
|
||||||
let source = {|a b c d|} in
|
|
||||||
let match_template = {|a :[2] b :[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {||}]
|
|
||||||
|
|
||||||
let%expect_test "delimiter_matching" =
|
|
||||||
let source = {|(a b c) d|} in
|
|
||||||
let match_template = {|(:[1]) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a b c|}];
|
|
||||||
|
|
||||||
let source = {|(a b c) d|} in
|
|
||||||
let match_template = {|(:[1] b :[2]) d|} in
|
|
||||||
let rewrite_template = {|(:[1]) (:[2])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a) (c)|}];
|
|
||||||
|
|
||||||
let source = {|q(a b c) d|} in
|
|
||||||
let match_template = {|q(:[1] b :[2]) d|} in
|
|
||||||
let rewrite_template = {|(:[1]) (:[2])|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a) (c)|}];
|
|
||||||
|
|
||||||
let source = {|((a) b)|} in
|
|
||||||
let match_template = {|(:[1] b)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a)|}];
|
|
||||||
|
|
||||||
let source = {|((a b c)) d|} in
|
|
||||||
let match_template = {|(:[1]) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a b c)|}];
|
|
||||||
|
|
||||||
let source = {|((a b c)) d|} in
|
|
||||||
let match_template = {|(:[1]) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(a b c)|}];
|
|
||||||
|
|
||||||
let source = {|((a b c) q) d|} in
|
|
||||||
let match_template = {|((:[1]) q) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a b c|}];
|
|
||||||
|
|
||||||
let source = {|((a b c) q) d|} in
|
|
||||||
let match_template = {|((:[1] c) q) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a b|}];
|
|
||||||
|
|
||||||
let source = {|((a b () c) q) d|} in
|
|
||||||
let match_template = {|((:[1] () c) q) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a b|}];
|
|
||||||
|
|
||||||
let source = {|((a ((x) d) b c)) d|} in
|
|
||||||
let match_template = {|((a :[1] :[2] c)) d|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|((x) d)|}];
|
|
||||||
|
|
||||||
let source = {|((a ((x) d) b c)) d|} in
|
|
||||||
let match_template = {|((a (:[1]) :[2] c)) d|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(x) d b|}];
|
|
||||||
|
|
||||||
let source = {|(b (c) d)|} in
|
|
||||||
let match_template = {|(:[1])|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b (c) d|}];
|
|
||||||
|
|
||||||
let source = {|(b (c) d.)|} in
|
|
||||||
let match_template = {|(:[1].)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b (c) d|}];
|
|
||||||
|
|
||||||
let source = {|(b (c.) d.)|} in
|
|
||||||
let match_template = {|(:[1].)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b (c.) d|}];
|
|
||||||
|
|
||||||
let source = {|(b. (c) d.)|} in
|
|
||||||
let match_template = {|(:[1].)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b. (c) d|}];
|
|
||||||
|
|
||||||
let source = {|(b (c) d.)|} in
|
|
||||||
let match_template = {|(b :[1] d.)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(c)|}];
|
|
||||||
|
|
||||||
let source = {|outer(inner(dst,src),src)|} in
|
|
||||||
let match_template = {|outer(:[1],src)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|inner(dst,src)|}];
|
|
||||||
|
|
||||||
let source = {|(b ((c)) d.)|} in
|
|
||||||
let match_template = {|(b :[1] d.)|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|((c))|}];
|
|
||||||
|
|
||||||
let source = {|a b c|} in
|
|
||||||
let match_template = {|a :[1] c|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b|}];
|
|
||||||
|
|
||||||
let source = {|x = foo;|} in
|
|
||||||
let match_template = {|x = :[1];|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|foo|}];
|
|
||||||
|
|
||||||
let source = {|((a {{x} d} b c)) d|} in
|
|
||||||
let match_template = {|((a {:[1] d} :[2] c)) d|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{x} b|}];
|
|
||||||
|
|
||||||
let source = {|((a {([{x}]) d} b c)) d|} in
|
|
||||||
let match_template = {|((a {:[1] d} :[2] c)) d|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|([{x}]) b|}];
|
|
||||||
|
|
||||||
let source = {|(((((x)))))|} in
|
|
||||||
let match_template = {|(((:[1])))|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|((x))|}];
|
|
||||||
|
|
||||||
let source = {|((((y(x)z))))|} in
|
|
||||||
let match_template = {|(((:[1])))|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(y(x)z)|}];
|
|
||||||
|
|
||||||
let source = {|((((y(x)z))))|} in
|
|
||||||
let match_template = {|(((:[1]):[2]))|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(y(x)z) |}];
|
|
||||||
|
|
||||||
let source = {|(((x)z))|} in
|
|
||||||
let match_template = {|(((:[1]):[2]))|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|x z|}];
|
|
||||||
|
|
||||||
let source = {|((((x))z))|} in
|
|
||||||
let match_template = {|(((:[1]):[2]))|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(x) z|}];
|
|
||||||
|
|
||||||
let source = {|lolwtfbbq|} in
|
|
||||||
let match_template = {|lol:[1]bbq|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|wtf|}];
|
|
||||||
|
|
||||||
let source = {|x = foo; x = bar;|} in
|
|
||||||
let match_template = {|x = :[1];|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|foo x = bar;|}];
|
|
||||||
|
|
||||||
let source = {|[ no match prefix ] x = foo; [ no match suffix ]|} in
|
|
||||||
let match_template = {|x = :[1];|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|[ no match prefix ] foo [ no match suffix ]|}];
|
|
||||||
|
|
||||||
let source = {|x = a; x = b; x = c|} in
|
|
||||||
let match_template = {|x = :[1];|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a x = b; x = c|}];
|
|
||||||
|
|
||||||
let source = {|x = ( x = x; );|} in
|
|
||||||
let match_template = {|x = :[1];|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|( x = x; )|}];
|
|
||||||
|
|
||||||
let source = {|( x = x = x; )|} in
|
|
||||||
let match_template = {|x = :[1];|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|( x = x )|}];
|
|
||||||
|
|
||||||
let source = {|xxx a b d c 1 2 3 b d d blah|} in
|
|
||||||
let match_template = {|a :[1] c :[2] d|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|xxx b d 1 2 3 b d blah|}];
|
|
||||||
|
|
||||||
let source = {|howevenlolwtfbbqispossible|} in
|
|
||||||
let match_template = {|lol:[1]bbq|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|howevenwtfispossible|}];
|
|
||||||
|
|
||||||
let source = {|lolhowevenlolwtfbbqispossiblebbq|} in
|
|
||||||
let match_template = {|lol:[1]bbq|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|howevenlolwtfispossiblebbq|}];
|
|
||||||
|
|
||||||
let source = {|hello my name is bob the builder|} in
|
|
||||||
let match_template = {|:[alongidentifiername] :[2] :[3] :[xyz] :[5] :[6]|} in
|
|
||||||
let rewrite_template = {|:[alongidentifiername] :[2] :[3] :[xyz] :[5] :[6]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|hello my name is bob the builder|}];
|
|
||||||
|
|
||||||
let source = {|www.testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n-280x428.jpg|} in
|
|
||||||
let match_template = {|www.:[1]-:[2].jpg|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|testdofooname.com/picsinsideit/stunningpictureofkays1381737242g8k4n 280x428|}];
|
|
||||||
|
|
||||||
let source = {|https://api.github.com/repos/dmjacobsen/slurm/commits/716c1499695c68afcab848a1b49653574b4fc167|} in
|
|
||||||
let match_template = {|:[1]api.:[2]/repos/:[3]s/:[4]|} in
|
|
||||||
let rewrite_template = {|:[1] :[2] :[3] :[4]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|https:// github.com dmjacobsen/slurm/commit 716c1499695c68afcab848a1b49653574b4fc167|}];
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
assert(stream->md_len + md_len -
|
|
||||||
si.foo_data_begin <= MAD_BUFFER_MDLEN);
|
|
||||||
memcpy(*stream->foo_data + stream->md_len,
|
|
||||||
mad_bit_nextbyte(&stream->ptr),
|
|
||||||
frame_used = md_len - si.foo_data_begin);
|
|
||||||
stream->md_len += frame_used;
|
|
||||||
|} |> format
|
|
||||||
in
|
|
||||||
let match_template = {|memcpy(:[1], :[2], :[3]);|} in
|
|
||||||
let rewrite_template = {|:[1], :[2], :[3]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|assert(stream->md_len + md_len -
|
|
||||||
si.foo_data_begin <= MAD_BUFFER_MDLEN);
|
|
||||||
*stream->foo_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.foo_data_begin
|
|
||||||
stream->md_len += frame_used;|}]
|
|
||||||
|
|
||||||
let%expect_test "significant_whitespace" =
|
|
||||||
let configuration = Configuration.create ~match_kind:Fuzzy ~significant_whitespace:true () in
|
|
||||||
let run = run ~configuration in
|
|
||||||
|
|
||||||
let source = {|two spaces|} in
|
|
||||||
let match_template = {|:[1] :[2]|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|two spaces|}];
|
|
||||||
|
|
||||||
(* FIXME: this should fail. also test case where separators do or do not need
|
|
||||||
whitespace. e.g., strict about strcpy(src,dst) matching a template
|
|
||||||
strcpy(:[1],:[2]) versus strcpy(:[1], :[2]) *)
|
|
||||||
let source = {|two spaces|} in
|
|
||||||
let match_template = {|:[1] :[2]|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|two spaces|}]
|
|
||||||
|
|
||||||
let%expect_test "contextual_matching" =
|
|
||||||
let run = run_all in
|
|
||||||
|
|
||||||
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
|
||||||
let match_template = {|memcpy(:[1], :[2], :[3])|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|dst1; dst2;|}];
|
|
||||||
|
|
||||||
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
|
||||||
let match_template = {|memcpy(:[1], :[2], :[3])|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|dst1; dst2;|}]
|
|
||||||
|
|
||||||
let%expect_test "contextual_matching_with_short_hole_syntax" =
|
|
||||||
let run = run_all in
|
|
||||||
|
|
||||||
let source = {|memcpy(dst1, src1, 1); memcpy(dst2, src2, 2);|} in
|
|
||||||
let match_template = {|memcpy(:[[1]], :[2], :[3])|} in
|
|
||||||
let rewrite_template = {|:[[1]]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|dst1; dst2;|}]
|
|
||||||
|
|
||||||
let%expect_test "trivial_empty_case" =
|
|
||||||
let source = "" in
|
|
||||||
let match_template = "" in
|
|
||||||
begin
|
|
||||||
Generic.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
|
||||||
| hd :: _ ->
|
|
||||||
print_string (Yojson.Safe.to_string (Match.to_yojson hd))
|
|
||||||
end;
|
|
||||||
[%expect_exact {|{"range":{"start":{"offset":0,"line":1,"column":1},"end":{"offset":0,"line":1,"column":1}},"environment":[],"matched":""}|}]
|
|
||||||
|
|
||||||
let%expect_test "trivial_empty_case" =
|
|
||||||
let source = "" in
|
|
||||||
let match_template = "" in
|
|
||||||
begin
|
|
||||||
Generic.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
|
||||||
| hd :: _ ->
|
|
||||||
print_string (Yojson.Safe.to_string (Match.to_yojson hd))
|
|
||||||
end;
|
|
||||||
[%expect_exact {|{"range":{"start":{"offset":0,"line":1,"column":1},"end":{"offset":0,"line":1,"column":1}},"environment":[],"matched":""}|}]
|
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
a = b
|
|
||||||
c = d
|
|
||||||
(
|
|
||||||
e = f
|
|
||||||
(
|
|
||||||
g = h
|
|
||||||
i = j
|
|
||||||
)
|
|
||||||
k = l
|
|
||||||
m = n
|
|
||||||
)
|
|
||||||
o = p
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = ":[1] = :[2]" in
|
|
||||||
let rewrite_template = "line" in
|
|
||||||
run_all source match_template rewrite_template;
|
|
||||||
[%expect_exact {|line|}]
|
|
||||||
|
|
||||||
let%expect_test "test_top_level_hole_stops_at_newline_for_example" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
for i, x := range derp {
|
|
||||||
do not match
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, x := range derp {
|
|
||||||
do match
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = "for i, x :[_] { do match }" in
|
|
||||||
let rewrite_template = "line" in
|
|
||||||
run_all source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
line
|
|
||||||
|}]
|
|
@ -1,18 +1,15 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Match
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
include Test_alpha
|
let run ?(rule = "where true") (module E : Engine.S) source match_template rewrite_template =
|
||||||
|
let rule = Rule.create rule |> Or_error.ok_exn in
|
||||||
let run ?(rule = "where true") source match_template rewrite_template =
|
E.Go.first ~configuration match_template source
|
||||||
let rule = Language.Rule.create rule |> Or_error.ok_exn in
|
|
||||||
Go.first ~configuration match_template source
|
|
||||||
|> function
|
|> function
|
||||||
| Ok ({environment; _ } as result) ->
|
| Ok ({environment; _ } as result) ->
|
||||||
if Rule.(sat @@ apply rule environment) then
|
if Rule.(sat @@ apply ~match_all:(E.Go.all ~rule:[Ast.True] ~nested:false) rule environment) then
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
Rewrite.all ~source ~rewrite_template [result]
|
||||||
|> (fun x -> Option.value_exn x)
|
|> (fun x -> Option.value_exn x)
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> (fun { rewritten_source; _ } -> rewritten_source)
|
||||||
@ -47,12 +44,20 @@ let%expect_test "gosimple_s1000" =
|
|||||||
:[3]
|
:[3]
|
||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
x := <-ch
|
||||||
|
fmt.Println(x)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
x := <-ch
|
x := <-ch
|
||||||
fmt.Println(x)
|
fmt.Println(x)
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "gosimple_s1001" =
|
let%expect_test "gosimple_s1001" =
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
@ -78,7 +83,12 @@ let%expect_test "gosimple_s1001" =
|
|||||||
|
|
||||||
let rule = {|where :[index_define] == :[index_use], :[src_element_define] == :[src_element_use]|} in
|
let rule = {|where :[index_define] == :[index_use], :[src_element_define] == :[src_element_use]|} in
|
||||||
|
|
||||||
run ~rule source match_template rewrite_template;
|
run (module Alpha) ~rule source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
copy(dst, src)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega) ~rule source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
copy(dst, src)
|
copy(dst, src)
|
||||||
|}]
|
|}]
|
||||||
@ -98,5 +108,7 @@ let%expect_test "gosimple_s1003" =
|
|||||||
|
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
run (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|Index|}];
|
||||||
|
run (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|Index|}]
|
[%expect_exact {|Index|}]
|
@ -1,102 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Match
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let run ?(rule = "where true") source match_template rewrite_template =
|
|
||||||
let rule = Language.Rule.create rule |> Or_error.ok_exn in
|
|
||||||
Go.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok ({environment; _ } as result) ->
|
|
||||||
if Rule.(sat @@ apply rule environment) then
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
else
|
|
||||||
assert false
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let%expect_test "gosimple_s1000" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
select {
|
|
||||||
case x := <-ch:
|
|
||||||
fmt.Println(x)
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let match_template =
|
|
||||||
{|
|
|
||||||
select {
|
|
||||||
case :[1] := :[2]:
|
|
||||||
:[3]
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
:[1] := :[2]
|
|
||||||
:[3]
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
x := <-ch
|
|
||||||
fmt.Println(x)
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "gosimple_s1001" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
for i, x := range src {
|
|
||||||
dst[i] = x
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let match_template =
|
|
||||||
{|
|
|
||||||
for :[index_define], :[src_element_define] := range :[src_array] {
|
|
||||||
:[dst_array][:[index_use]] = :[src_element_use]
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template =
|
|
||||||
{|
|
|
||||||
copy(:[dst_array], :[src_array])
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rule = {|where :[index_define] == :[index_use], :[src_element_define] == :[src_element_use]|} in
|
|
||||||
|
|
||||||
run ~rule source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
copy(dst, src)
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "gosimple_s1003" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
if strings.Index(x, y) != -1 { ignore }
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let match_template =
|
|
||||||
{|
|
|
||||||
if strings.:[1](x, y) != -1 { :[_] }
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|Index|}]
|
|
@ -1,8 +1,10 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
open Comby_kernel
|
||||||
|
|
||||||
let configuration = Matchers.Configuration.create ~match_kind:Fuzzy ()
|
open Matchers
|
||||||
|
|
||||||
|
let configuration = Configuration.create ~match_kind:Fuzzy ()
|
||||||
|
|
||||||
let format s =
|
let format s =
|
||||||
let s = String.chop_prefix_exn ~prefix:"\n" s in
|
let s = String.chop_prefix_exn ~prefix:"\n" s in
|
||||||
@ -28,11 +30,10 @@ let print_only_match matches =
|
|||||||
let run ?(configuration = configuration) (module M : Matchers.Matcher.S) source match_template ?rule rewrite_template =
|
let run ?(configuration = configuration) (module M : Matchers.Matcher.S) source match_template ?rule rewrite_template =
|
||||||
let rule =
|
let rule =
|
||||||
match rule with
|
match rule with
|
||||||
| Some rule -> Language.Rule.create rule |> Or_error.ok_exn
|
| Some rule -> Matchers.Rule.create rule |> Or_error.ok_exn
|
||||||
| None -> Language.Rule.create "where true" |> Or_error.ok_exn
|
| None -> Rule.create "where true" |> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
M.all ~configuration ~template:match_template ~source ()
|
M.all ~rule ~configuration ~template:match_template ~source ()
|
||||||
|> List.filter ~f:(fun { Match.environment; _ } -> Language.Rule.(sat @@ apply ~matcher:(module M) rule environment))
|
|
||||||
|> function
|
|> function
|
||||||
| [] -> print_string "No matches."
|
| [] -> print_string "No matches."
|
||||||
| results ->
|
| results ->
|
||||||
@ -51,7 +52,7 @@ let run_nested
|
|||||||
match rule with
|
match rule with
|
||||||
| None -> true
|
| None -> true
|
||||||
| Some rule ->
|
| Some rule ->
|
||||||
let options = Language.Rule.create rule |> Or_error.ok_exn |> Language.Rule.options in
|
let options = Rule.create rule |> Or_error.ok_exn |> Rule.options in
|
||||||
options.nested
|
options.nested
|
||||||
in
|
in
|
||||||
M.all ~configuration ~nested ~template:match_template ~source ()
|
M.all ~configuration ~nested ~template:match_template ~source ()
|
||||||
@ -63,10 +64,6 @@ let run_nested
|
|||||||
|> print_string
|
|> print_string
|
||||||
|
|
||||||
(** Rule tests *)
|
(** Rule tests *)
|
||||||
let sat ?(env = Match.Environment.create ()) rule =
|
|
||||||
let rule = Language.Rule.create rule |> Or_error.ok_exn in
|
|
||||||
Format.sprintf "%b" (Language.Rule.(sat @@ apply rule env))
|
|
||||||
|
|
||||||
let make_env bindings =
|
let make_env bindings =
|
||||||
List.fold bindings
|
List.fold bindings
|
||||||
~init:(Match.Environment.create ())
|
~init:(Match.Environment.create ())
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
include Test_alpha
|
let run_all (module E : Engine.S) ?(configuration = configuration) source match_template rewrite_template =
|
||||||
|
E.Generic.all ~configuration ~template:match_template ~source ()
|
||||||
let run_all ?(configuration = configuration) source match_template rewrite_template =
|
|
||||||
Generic.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> function
|
|> function
|
||||||
| [] -> print_string "No matches."
|
| [] -> print_string "No matches."
|
||||||
| results ->
|
| results ->
|
||||||
@ -16,23 +14,28 @@ let run_all ?(configuration = configuration) source match_template rewrite_templ
|
|||||||
|> print_string
|
|> print_string
|
||||||
|
|
||||||
let%expect_test "non_space" =
|
let%expect_test "non_space" =
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
let source = {| foo. foo.bar.quux derp|} in
|
||||||
let match_template = {|:[x.]|} in
|
let match_template = {|:[x.]|} in
|
||||||
let rewrite_template = {|{:[x]}|} in
|
let rewrite_template = {|{:[x]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {| {foo.} {foo.bar.quux} {derp}|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {| {foo.} {foo.bar.quux} {derp}|}]
|
[%expect_exact {| {foo.} {foo.bar.quux} {derp}|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "only_space" =
|
let%expect_test "only_space" =
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
let source = {| foo. foo.bar.quux derp|} in
|
||||||
let match_template = {|:[ x]|} in
|
let match_template = {|:[ x]|} in
|
||||||
let rewrite_template = {|{:[x]}|} in
|
let rewrite_template = {|{:[x]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{ }foo.{ }foo.bar.quux{ }derp|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{ }foo.{ }foo.bar.quux{ }derp|}]
|
[%expect_exact {|{ }foo.{ }foo.bar.quux{ }derp|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "up_to_newline" =
|
let%expect_test "up_to_newline" =
|
||||||
let run = run_all in
|
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
foo.
|
foo.
|
||||||
@ -41,28 +44,42 @@ derp
|
|||||||
|} in
|
|} in
|
||||||
let match_template = {|:[x\n]|} in
|
let match_template = {|:[x\n]|} in
|
||||||
let rewrite_template = {|{:[x]}|} in
|
let rewrite_template = {|{:[x]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{
|
||||||
|
}{foo.
|
||||||
|
}{foo.bar.quux
|
||||||
|
}{derp
|
||||||
|
}|}];
|
||||||
|
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{
|
[%expect_exact {|{
|
||||||
}{foo.
|
}{foo.
|
||||||
}{foo.bar.quux
|
}{foo.bar.quux
|
||||||
}{derp
|
}{derp
|
||||||
}|}]
|
}|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_empty_in_newline_hole" =
|
let%expect_test "match_empty_in_newline_hole" =
|
||||||
let run = run_all in
|
|
||||||
let source =
|
let source =
|
||||||
{|stuff
|
{|stuff
|
||||||
after
|
after
|
||||||
|} in
|
|} in
|
||||||
let match_template = {|stuff:[x\n]|} in
|
let match_template = {|stuff:[x\n]|} in
|
||||||
let rewrite_template = {|{->:[x]<-}|} in
|
let rewrite_template = {|{->:[x]<-}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{->
|
||||||
|
<-}after
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{->
|
[%expect_exact {|{->
|
||||||
<-}after
|
<-}after
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "leading_indentation" =
|
let%expect_test "leading_indentation" =
|
||||||
let run = run_all in
|
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
foo. bar bazz
|
foo. bar bazz
|
||||||
@ -71,106 +88,149 @@ let%expect_test "leading_indentation" =
|
|||||||
|} in
|
|} in
|
||||||
let match_template = {|:[ leading_indentation]:[rest\n]|} in
|
let match_template = {|:[ leading_indentation]:[rest\n]|} in
|
||||||
let rewrite_template = {|{:[leading_indentation]}:[rest]|} in
|
let rewrite_template = {|{:[leading_indentation]}:[rest]|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
{ }foo. bar bazz
|
||||||
|
{ }foo.bar.quux
|
||||||
|
{ }derp
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
{ }foo. bar bazz
|
{ }foo. bar bazz
|
||||||
{ }foo.bar.quux
|
{ }foo.bar.quux
|
||||||
{ }derp
|
{ }derp
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "non_space_partial_match" =
|
let%expect_test "non_space_partial_match" =
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
let source = {| foo. foo.bar.quux derp|} in
|
||||||
let match_template = {|foo.:[x.]ux|} in
|
let match_template = {|foo.:[x.]ux|} in
|
||||||
let rewrite_template = {|{:[x]}|} in
|
let rewrite_template = {|{:[x]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {| foo. {bar.qu} derp|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {| foo. {bar.qu} derp|}]
|
[%expect_exact {| foo. {bar.qu} derp|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "non_space_does_not_match_reserved_delimiters" =
|
let%expect_test "non_space_does_not_match_reserved_delimiters" =
|
||||||
let run = run_all in
|
|
||||||
let source = {|fo.o(x)|} in
|
let source = {|fo.o(x)|} in
|
||||||
let match_template = {|:[f.]|} in
|
let match_template = {|:[f.]|} in
|
||||||
let rewrite_template = {|{:[f]}|} in
|
let rewrite_template = {|{:[f]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{fo.o}({x})|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{fo.o}({x})|}]
|
[%expect_exact {|{fo.o}({x})|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "non_space_only_hole" =
|
let%expect_test "non_space_only_hole" =
|
||||||
let run = run_all in
|
|
||||||
let source = {|a.b c.d|} in
|
let source = {|a.b c.d|} in
|
||||||
let match_template = {|:[x.]|} in
|
let match_template = {|:[x.]|} in
|
||||||
let rewrite_template = {|>:[x]<|} in
|
let rewrite_template = {|>:[x]<|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|>a.b< >c.d<|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|>a.b< >c.d<|}]
|
[%expect_exact {|>a.b< >c.d<|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "alphanum_partial_match" =
|
let%expect_test "alphanum_partial_match" =
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
let source = {| foo. foo.bar.quux derp|} in
|
||||||
let match_template = {|foo.b:[x]r.quux|} in
|
let match_template = {|foo.b:[x]r.quux|} in
|
||||||
let rewrite_template = {|{:[x]}|} in
|
let rewrite_template = {|{:[x]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {| foo. {a} derp|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {| foo. {a} derp|}]
|
[%expect_exact {| foo. {a} derp|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "newline_matcher_should_not_be_sat_on_space" =
|
let%expect_test "newline_matcher_should_not_be_sat_on_space" =
|
||||||
let run = run_all in
|
|
||||||
let source =
|
let source =
|
||||||
{|a b c d
|
{|a b c d
|
||||||
e f g h|} in
|
e f g h|} in
|
||||||
let match_template = {|:[line\n] |} in
|
let match_template = {|:[line\n] |} in
|
||||||
let rewrite_template = {|{:[line]}|} in
|
let rewrite_template = {|{:[line]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{a b c d
|
||||||
|
}e f g h|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{a b c d
|
[%expect_exact {|{a b c d
|
||||||
}e f g h|}];
|
}e f g h|}];
|
||||||
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
let source =
|
||||||
{|a b c d
|
{|a b c d
|
||||||
e f g h|} in
|
e f g h|} in
|
||||||
let match_template = {|:[line\n]:[next]|} in
|
let match_template = {|:[line\n]:[next]|} in
|
||||||
let rewrite_template = {|{:[line]}|} in
|
let rewrite_template = {|{:[line]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{a b c d
|
||||||
|
}|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{a b c d
|
[%expect_exact {|{a b c d
|
||||||
}|}];
|
}|}];
|
||||||
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
let source =
|
||||||
{|a b c d
|
{|a b c d
|
||||||
e f g h
|
e f g h
|
||||||
|} in
|
|} in
|
||||||
let match_template = {|:[line1\n]:[next\n]|} in
|
let match_template = {|:[line1\n]:[next\n]|} in
|
||||||
let rewrite_template = {|{:[line1]|:[next]}|} in
|
let rewrite_template = {|{:[line1]|:[next]}|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|{a b c d
|
||||||
|
|e f g h
|
||||||
|
}|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|{a b c d
|
[%expect_exact {|{a b c d
|
||||||
|e f g h
|
|e f g h
|
||||||
}|}]
|
}|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "implicit_equals" =
|
let%expect_test "implicit_equals" =
|
||||||
let run = run_all in
|
|
||||||
let source = {|a b a|} in
|
let source = {|a b a|} in
|
||||||
let match_template = {|:[[x]] :[[m]] :[[x]]|} in
|
let match_template = {|:[[x]] :[[m]] :[[x]]|} in
|
||||||
let rewrite_template = {|:[m]|} in
|
let rewrite_template = {|:[m]|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|b|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|b|}]
|
[%expect_exact {|b|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "implicit_equals_does_not_apply_to_underscore" =
|
let%expect_test "implicit_equals_does_not_apply_to_underscore" =
|
||||||
let run = run_all in
|
|
||||||
let source = {|a b c|} in
|
let source = {|a b c|} in
|
||||||
let match_template = {|:[[x]] :[[_]] :[[_]]|} in
|
let match_template = {|:[[x]] :[[_]] :[[_]]|} in
|
||||||
let rewrite_template = {|:[x]|} in
|
let rewrite_template = {|:[x]|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|a|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|a|}]
|
[%expect_exact {|a|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "expression_hole" =
|
let%expect_test "expression_hole" =
|
||||||
let run = run_all in
|
|
||||||
let source = {|(b, c, d) [ ] { { } } { } ()()|} in
|
let source = {|(b, c, d) [ ] { { } } { } ()()|} in
|
||||||
let match_template = {|:[x:e]|} in
|
let match_template = {|:[x:e]|} in
|
||||||
let rewrite_template = {|>:[x]<|} in
|
let rewrite_template = {|>:[x]<|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|>(b, c, d)< >[ ]< >{ { } }< >{ }< >()()<|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
[%expect_exact {|>(b, c, d)< >[ ]< >{ { } }< >{ }< >()()<|}]
|
[%expect_exact {|>(b, c, d)< >[ ]< >{ { } }< >{ }< >()()<|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "expression_hole" =
|
let%expect_test "expression_hole" =
|
||||||
let run = run_all in
|
|
||||||
let source = {|a(b, c, d)e [][] { { } }|} in
|
let source = {|a(b, c, d)e [][] { { } }|} in
|
||||||
let match_template = {|:[x:e]|} in
|
let match_template = {|:[x:e]|} in
|
||||||
let rewrite_template = {|>:[x]<|} in
|
let rewrite_template = {|>:[x]<|} in
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|>a(b, c, d)e< >[][]< >{ { } }<|}]
|
run_all (module Alpha) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|>a(b, c, d)e< >[][]< >{ { } }<|}];
|
||||||
|
run_all (module Omega) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|>a(b, c, d)e< >[][]< >{ { } }<|}];
|
@ -1,176 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let run_all ?(configuration = configuration) source match_template rewrite_template =
|
|
||||||
Generic.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
|
||||||
| results ->
|
|
||||||
Option.value_exn (Rewrite.all ~source ~rewrite_template results)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
|
|
||||||
let%expect_test "non_space" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
|
||||||
let match_template = {|:[x.]|} in
|
|
||||||
let rewrite_template = {|{:[x]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {| {foo.} {foo.bar.quux} {derp}|}]
|
|
||||||
|
|
||||||
let%expect_test "only_space" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
|
||||||
let match_template = {|:[ x]|} in
|
|
||||||
let rewrite_template = {|{:[x]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{ }foo.{ }foo.bar.quux{ }derp|}]
|
|
||||||
|
|
||||||
let%expect_test "up_to_newline" =
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
foo.
|
|
||||||
foo.bar.quux
|
|
||||||
derp
|
|
||||||
|} in
|
|
||||||
let match_template = {|:[x\n]|} in
|
|
||||||
let rewrite_template = {|{:[x]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{
|
|
||||||
}{foo.
|
|
||||||
}{foo.bar.quux
|
|
||||||
}{derp
|
|
||||||
}|}]
|
|
||||||
|
|
||||||
let%expect_test "match_empty_in_newline_hole" =
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
|
||||||
{|stuff
|
|
||||||
after
|
|
||||||
|} in
|
|
||||||
let match_template = {|stuff:[x\n]|} in
|
|
||||||
let rewrite_template = {|{->:[x]<-}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{->
|
|
||||||
<-}after
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "leading_indentation" =
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
foo. bar bazz
|
|
||||||
foo.bar.quux
|
|
||||||
derp
|
|
||||||
|} in
|
|
||||||
let match_template = {|:[ leading_indentation]:[rest\n]|} in
|
|
||||||
let rewrite_template = {|{:[leading_indentation]}:[rest]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
{ }foo. bar bazz
|
|
||||||
{ }foo.bar.quux
|
|
||||||
{ }derp
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "non_space_partial_match" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
|
||||||
let match_template = {|foo.:[x.]ux|} in
|
|
||||||
let rewrite_template = {|{:[x]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {| foo. {bar.qu} derp|}]
|
|
||||||
|
|
||||||
let%expect_test "non_space_does_not_match_reserved_delimiters" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {|fo.o(x)|} in
|
|
||||||
let match_template = {|:[f.]|} in
|
|
||||||
let rewrite_template = {|{:[f]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{fo.o}({x})|}]
|
|
||||||
|
|
||||||
let%expect_test "non_space_only_hole" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {|a.b c.d|} in
|
|
||||||
let match_template = {|:[x.]|} in
|
|
||||||
let rewrite_template = {|>:[x]<|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|>a.b< >c.d<|}]
|
|
||||||
|
|
||||||
let%expect_test "alphanum_partial_match" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {| foo. foo.bar.quux derp|} in
|
|
||||||
let match_template = {|foo.b:[x]r.quux|} in
|
|
||||||
let rewrite_template = {|{:[x]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {| foo. {a} derp|}]
|
|
||||||
|
|
||||||
let%expect_test "newline_matcher_should_not_be_sat_on_space" =
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
|
||||||
{|a b c d
|
|
||||||
e f g h|} in
|
|
||||||
let match_template = {|:[line\n] |} in
|
|
||||||
let rewrite_template = {|{:[line]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{a b c d
|
|
||||||
}e f g h|}];
|
|
||||||
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
|
||||||
{|a b c d
|
|
||||||
e f g h|} in
|
|
||||||
let match_template = {|:[line\n]:[next]|} in
|
|
||||||
let rewrite_template = {|{:[line]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{a b c d
|
|
||||||
}|}];
|
|
||||||
|
|
||||||
let run = run_all in
|
|
||||||
let source =
|
|
||||||
{|a b c d
|
|
||||||
e f g h
|
|
||||||
|} in
|
|
||||||
let match_template = {|:[line1\n]:[next\n]|} in
|
|
||||||
let rewrite_template = {|{:[line1]|:[next]}|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|{a b c d
|
|
||||||
|e f g h
|
|
||||||
}|}]
|
|
||||||
|
|
||||||
let%expect_test "implicit_equals" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {|a b a|} in
|
|
||||||
let match_template = {|:[[x]] :[[m]] :[[x]]|} in
|
|
||||||
let rewrite_template = {|:[m]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|b|}]
|
|
||||||
|
|
||||||
let%expect_test "implicit_equals_does_not_apply_to_underscore" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {|a b c|} in
|
|
||||||
let match_template = {|:[[x]] :[[_]] :[[_]]|} in
|
|
||||||
let rewrite_template = {|:[x]|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|a|}]
|
|
||||||
|
|
||||||
let%expect_test "expression_hole" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {|(b, c, d) [ ] { { } } { } ()()|} in
|
|
||||||
let match_template = {|:[x:e]|} in
|
|
||||||
let rewrite_template = {|>:[x]<|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|>(b, c, d)< >[ ]< >{ { } }< >{ }< >()()<|}]
|
|
||||||
|
|
||||||
let%expect_test "expression_hole" =
|
|
||||||
let run = run_all in
|
|
||||||
let source = {|a(b, c, d)e [][] { { } }|} in
|
|
||||||
let match_template = {|:[x:e]|} in
|
|
||||||
let rewrite_template = {|>:[x]<|} in
|
|
||||||
run source match_template rewrite_template;
|
|
||||||
[%expect_exact {|>a(b, c, d)e< >[][]< >{ { } }<|}]
|
|
@ -1,13 +1,17 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
|
||||||
include Test_alpha
|
let all ?(configuration = configuration) (module E : Engine.S) template source =
|
||||||
|
E.Generic.all ~configuration ~template ~source ()
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
let rewrite_all engine template source rewrite_template =
|
||||||
Generic.all ~configuration ~template ~source ()
|
all engine template source
|
||||||
|
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
||||||
|
|> (fun { rewritten_source; _ } -> rewritten_source)
|
||||||
|
|
||||||
let print_matches matches =
|
let print_matches matches =
|
||||||
List.map matches ~f:Match.to_yojson
|
List.map matches ~f:Match.to_yojson
|
||||||
@ -18,15 +22,34 @@ let print_matches matches =
|
|||||||
let%expect_test "dont_get_stuck" =
|
let%expect_test "dont_get_stuck" =
|
||||||
let template = "" in
|
let template = "" in
|
||||||
let source = "a" in
|
let source = "a" in
|
||||||
let matches = all ~configuration template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[]|}]
|
[%expect_exact {|[]|}]
|
||||||
|
|
||||||
let%expect_test "dont_get_stuck" =
|
let%expect_test "dont_get_stuck" =
|
||||||
let template = "a" in
|
let template = "a" in
|
||||||
let source = "a" in
|
let source = "a" in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 1, "line": 1, "column": 2 }
|
||||||
|
},
|
||||||
|
"environment": [],
|
||||||
|
"matched": "a"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
all (module Omega) template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -41,8 +64,38 @@ let%expect_test "dont_get_stuck" =
|
|||||||
let%expect_test "dont_get_stuck" =
|
let%expect_test "dont_get_stuck" =
|
||||||
let template = "a" in
|
let template = "a" in
|
||||||
let source = "aaa" in
|
let source = "aaa" in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 1, "line": 1, "column": 2 }
|
||||||
|
},
|
||||||
|
"environment": [],
|
||||||
|
"matched": "a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 1, "line": 1, "column": 2 },
|
||||||
|
"end": { "offset": 2, "line": 1, "column": 3 }
|
||||||
|
},
|
||||||
|
"environment": [],
|
||||||
|
"matched": "a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 2, "line": 1, "column": 3 },
|
||||||
|
"end": { "offset": 3, "line": 1, "column": 4 }
|
||||||
|
},
|
||||||
|
"environment": [],
|
||||||
|
"matched": "a"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
all (module Omega) template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -75,9 +128,11 @@ let%expect_test "rewrite_awesome_1" =
|
|||||||
let source = "xreplace this () end" in
|
let source = "xreplace this () end" in
|
||||||
let rewrite_template = "X" in
|
let rewrite_template = "X" in
|
||||||
|
|
||||||
all template source
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|> print_string;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact "xX"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "xX"]
|
[%expect_exact "xX"]
|
||||||
|
|
||||||
@ -86,17 +141,42 @@ let%expect_test "rewrite_whole_template_matches" =
|
|||||||
let source = {|rewrite hello world <- this string|} in
|
let source = {|rewrite hello world <- this string|} in
|
||||||
let rewrite_template = "?" in
|
let rewrite_template = "?" in
|
||||||
|
|
||||||
all template source
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|> print_string;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact "?"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "?"]
|
[%expect_exact "?"]
|
||||||
|
|
||||||
let%expect_test "single_token" =
|
let%expect_test "single_token" =
|
||||||
let template = {|:[[1]] this|} in
|
let template = {|:[[1]] this|} in
|
||||||
let source = {|the problem is this|} in
|
let source = {|the problem is this|} in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 12, "line": 1, "column": 13 },
|
||||||
|
"end": { "offset": 19, "line": 1, "column": 20 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "is",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 12, "line": 1, "column": 13 },
|
||||||
|
"end": { "offset": 14, "line": 1, "column": 15 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "is this"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
all (module Omega) template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -118,11 +198,35 @@ let%expect_test "single_token" =
|
|||||||
]|}]
|
]|}]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "single_token_with_preceding_whitespace" =
|
let%expect_test "single_token_with_preceding_whitespace" =
|
||||||
let template = {| :[[1]] this|} in
|
let template = {| :[[1]] this|} in
|
||||||
let source = {|the problem is this|} in
|
let source = {|the problem is this|} in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 11, "line": 1, "column": 12 },
|
||||||
|
"end": { "offset": 19, "line": 1, "column": 20 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "is",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 12, "line": 1, "column": 13 },
|
||||||
|
"end": { "offset": 14, "line": 1, "column": 15 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": " is this"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
all (module Omega) template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -147,9 +251,12 @@ let%expect_test "single_token_rewrite" =
|
|||||||
let template = {| :[[1]] this|} in
|
let template = {| :[[1]] this|} in
|
||||||
let source = {|the problem is this|} in
|
let source = {|the problem is this|} in
|
||||||
let rewrite_template = ":[1]" in
|
let rewrite_template = ":[1]" in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact "the problemis"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "the problemis"]
|
[%expect_exact "the problemis"]
|
||||||
|
|
||||||
@ -157,9 +264,12 @@ let%expect_test "single_token_match_inside_paren_no_succeeding_whitespace" =
|
|||||||
let template = {|:[[1]](:[[2]])|} in
|
let template = {|:[[1]](:[[2]])|} in
|
||||||
let source = {|foo(bar)|} in
|
let source = {|foo(bar)|} in
|
||||||
let rewrite_template = ":[1] : :[2]" in
|
let rewrite_template = ":[1] : :[2]" in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact "foo : bar"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "foo : bar"]
|
[%expect_exact "foo : bar"]
|
||||||
|
|
||||||
@ -167,9 +277,12 @@ let%expect_test "whitespace_hole_rewrite" =
|
|||||||
let template = {|:[ w]this|} in
|
let template = {|:[ w]this|} in
|
||||||
let rewrite_template = "space:[ w]here" in
|
let rewrite_template = "space:[ w]here" in
|
||||||
let source = {| this|} in
|
let source = {| this|} in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact "space here"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "space here"]
|
[%expect_exact "space here"]
|
||||||
|
|
||||||
@ -177,9 +290,12 @@ let%expect_test "punctuation_hole_rewrite" =
|
|||||||
let template = {|:[x.]|} in
|
let template = {|:[x.]|} in
|
||||||
let rewrite_template = "->:[x.]<-" in
|
let rewrite_template = "->:[x.]<-" in
|
||||||
let source = {|now.this. is,pod|racing|} in
|
let source = {|now.this. is,pod|racing|} in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact "->now.this.<- ->is,pod|racing<-"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "->now.this.<- ->is,pod|racing<-"]
|
[%expect_exact "->now.this.<- ->is,pod|racing<-"]
|
||||||
|
|
||||||
@ -189,21 +305,47 @@ let%expect_test "newline_hole_rewrite" =
|
|||||||
let source = {|now.this.
|
let source = {|now.this.
|
||||||
is,pod|racing
|
is,pod|racing
|
||||||
|} in
|
|} in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact "->now.this.
|
||||||
|
<-->is,pod|racing
|
||||||
|
<-"];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact "->now.this.
|
[%expect_exact "->now.this.
|
||||||
<-->is,pod|racing
|
<-->is,pod|racing
|
||||||
<-"]
|
<-"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "shift_or_at_least_dont_get_stuck" =
|
let%expect_test "shift_or_at_least_dont_get_stuck" =
|
||||||
let template = ":[1]" in
|
let template = ":[1]" in
|
||||||
let source = "a" in
|
let source = "a" in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 1, "line": 1, "column": 2 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "a",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 1, "line": 1, "column": 2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "a"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -224,11 +366,35 @@ let%expect_test "shift_or_at_least_dont_get_stuck" =
|
|||||||
}
|
}
|
||||||
]|}]
|
]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "shift_or_at_least_dont_get_stuck" =
|
let%expect_test "shift_or_at_least_dont_get_stuck" =
|
||||||
let template = ":[1]" in
|
let template = ":[1]" in
|
||||||
let source = "aa" in
|
let source = "aa" in
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
all (module Alpha) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 2, "line": 1, "column": 3 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "aa",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 2, "line": 1, "column": 3 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "aa"
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -262,8 +428,12 @@ let%expect_test "nested_rewrite1" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
|
|
||||||
let matches = all template source in
|
all (module Alpha) ~configuration template source
|
||||||
print_matches matches;
|
|> print_matches;
|
||||||
|
[%expect_exact "[]"];
|
||||||
|
|
||||||
|
all (module Omega) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact "[]"]
|
[%expect_exact "[]"]
|
||||||
|
|
||||||
(* FIXME(RVT) nested rewrites *)
|
(* FIXME(RVT) nested rewrites *)
|
||||||
@ -289,9 +459,18 @@ let%expect_test "nested_rewrite2" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
let rewrite_template = "for :[defines] := range :[var_use] {:[inner_body]}" in
|
let rewrite_template = "for :[defines] := range :[var_use] {:[inner_body]}" in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact {|for _, field := range fields.List {
|
||||||
|
if field.Names != nil {
|
||||||
|
for _, fieldName := range field.Names {
|
||||||
|
stuff with fields and things
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}|}];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact {|for _, field := range fields.List {
|
[%expect_exact {|for _, field := range fields.List {
|
||||||
if field.Names != nil {
|
if field.Names != nil {
|
||||||
@ -314,9 +493,14 @@ let%expect_test "match_:[[1]]" =
|
|||||||
|}
|
|}
|
||||||
in
|
in
|
||||||
let rewrite_template = "next(:[1])" in
|
let rewrite_template = "next(:[1])" in
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all (module Alpha) template source rewrite_template
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|> print_string;
|
||||||
|
[%expect_exact {|
|
||||||
|
col_names =next(reader)}
|
||||||
|
|}];
|
||||||
|
|
||||||
|
rewrite_all (module Omega) template source rewrite_template
|
||||||
|> print_string;
|
|> print_string;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
col_names =next(reader)}
|
col_names =next(reader)}
|
@ -1,323 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|
|
||||||
let print_matches matches =
|
|
||||||
List.map matches ~f:Match.to_yojson
|
|
||||||
|> (fun matches -> `List matches)
|
|
||||||
|> Yojson.Safe.pretty_to_string
|
|
||||||
|> print_string
|
|
||||||
|
|
||||||
let%expect_test "dont_get_stuck" =
|
|
||||||
let template = "" in
|
|
||||||
let source = "a" in
|
|
||||||
let matches = all ~configuration template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[]|}]
|
|
||||||
|
|
||||||
let%expect_test "dont_get_stuck" =
|
|
||||||
let template = "a" in
|
|
||||||
let source = "a" in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 1, "line": 1, "column": 2 }
|
|
||||||
},
|
|
||||||
"environment": [],
|
|
||||||
"matched": "a"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "dont_get_stuck" =
|
|
||||||
let template = "a" in
|
|
||||||
let source = "aaa" in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 1, "line": 1, "column": 2 }
|
|
||||||
},
|
|
||||||
"environment": [],
|
|
||||||
"matched": "a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 1, "line": 1, "column": 2 },
|
|
||||||
"end": { "offset": 2, "line": 1, "column": 3 }
|
|
||||||
},
|
|
||||||
"environment": [],
|
|
||||||
"matched": "a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 2, "line": 1, "column": 3 },
|
|
||||||
"end": { "offset": 3, "line": 1, "column": 4 }
|
|
||||||
},
|
|
||||||
"environment": [],
|
|
||||||
"matched": "a"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_awesome_1" =
|
|
||||||
let template = "replace this :[1] end" in
|
|
||||||
let source = "xreplace this () end" in
|
|
||||||
let rewrite_template = "X" in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "xX"]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_whole_template_matches" =
|
|
||||||
let template = {|rewrite :[1] <- this string|} in
|
|
||||||
let source = {|rewrite hello world <- this string|} in
|
|
||||||
let rewrite_template = "?" in
|
|
||||||
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "?"]
|
|
||||||
|
|
||||||
let%expect_test "single_token" =
|
|
||||||
let template = {|:[[1]] this|} in
|
|
||||||
let source = {|the problem is this|} in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 12, "line": 1, "column": 13 },
|
|
||||||
"end": { "offset": 19, "line": 1, "column": 20 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "is",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 12, "line": 1, "column": 13 },
|
|
||||||
"end": { "offset": 14, "line": 1, "column": 15 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "is this"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "single_token_with_preceding_whitespace" =
|
|
||||||
let template = {| :[[1]] this|} in
|
|
||||||
let source = {|the problem is this|} in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 11, "line": 1, "column": 12 },
|
|
||||||
"end": { "offset": 19, "line": 1, "column": 20 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "is",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 12, "line": 1, "column": 13 },
|
|
||||||
"end": { "offset": 14, "line": 1, "column": 15 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": " is this"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "single_token_rewrite" =
|
|
||||||
let template = {| :[[1]] this|} in
|
|
||||||
let source = {|the problem is this|} in
|
|
||||||
let rewrite_template = ":[1]" in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "the problemis"]
|
|
||||||
|
|
||||||
let%expect_test "single_token_match_inside_paren_no_succeeding_whitespace" =
|
|
||||||
let template = {|:[[1]](:[[2]])|} in
|
|
||||||
let source = {|foo(bar)|} in
|
|
||||||
let rewrite_template = ":[1] : :[2]" in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "foo : bar"]
|
|
||||||
|
|
||||||
let%expect_test "whitespace_hole_rewrite" =
|
|
||||||
let template = {|:[ w]this|} in
|
|
||||||
let rewrite_template = "space:[ w]here" in
|
|
||||||
let source = {| this|} in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "space here"]
|
|
||||||
|
|
||||||
let%expect_test "punctuation_hole_rewrite" =
|
|
||||||
let template = {|:[x.]|} in
|
|
||||||
let rewrite_template = "->:[x.]<-" in
|
|
||||||
let source = {|now.this. is,pod|racing|} in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "->now.this.<- ->is,pod|racing<-"]
|
|
||||||
|
|
||||||
let%expect_test "newline_hole_rewrite" =
|
|
||||||
let template = {|:[x\n]|} in
|
|
||||||
let rewrite_template = {|->:[x\n]<-|} in
|
|
||||||
let source = {|now.this.
|
|
||||||
is,pod|racing
|
|
||||||
|} in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact "->now.this.
|
|
||||||
<-->is,pod|racing
|
|
||||||
<-"]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "shift_or_at_least_dont_get_stuck" =
|
|
||||||
let template = ":[1]" in
|
|
||||||
let source = "a" in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 1, "line": 1, "column": 2 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "a",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 1, "line": 1, "column": 2 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "a"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "shift_or_at_least_dont_get_stuck" =
|
|
||||||
let template = ":[1]" in
|
|
||||||
let source = "aa" in
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 2, "line": 1, "column": 3 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "aa",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 2, "line": 1, "column": 3 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "aa"
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "nested_rewrite1" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
x x y strcpy(strcpy(dst1, src1), src2); blah blah XXX
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
strcpy(:[1], :[2])
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
|
|
||||||
let matches = all template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact "[]"]
|
|
||||||
|
|
||||||
(* FIXME(RVT) nested rewrites *)
|
|
||||||
let%expect_test "nested_rewrite2" =
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
if :[var_check] != nil {
|
|
||||||
for :[defines] := range :[var_use] {:[inner_body]}
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
if fields.List != nil {
|
|
||||||
for _, field := range fields.List {
|
|
||||||
if field.Names != nil {
|
|
||||||
for _, fieldName := range field.Names {
|
|
||||||
stuff with fields and things
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let rewrite_template = "for :[defines] := range :[var_use] {:[inner_body]}" in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|for _, field := range fields.List {
|
|
||||||
if field.Names != nil {
|
|
||||||
for _, fieldName := range field.Names {
|
|
||||||
stuff with fields and things
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}|}]
|
|
||||||
|
|
||||||
let%expect_test "match_:[[1]]" =
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
:[[1]].next()
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
col_names = reader.next()
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let rewrite_template = "next(:[1])" in
|
|
||||||
all template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|
|
|
||||||
col_names =next(reader)}
|
|
||||||
|}]
|
|
@ -1,53 +1,82 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
open Match
|
open Match
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
|
||||||
include Test_alpha
|
let sat ?(env = Match.Environment.create ()) (module E : Engine.S) rule =
|
||||||
|
let rule = Rule.create rule |> Or_error.ok_exn in
|
||||||
|
Format.sprintf "%b" Rule.(sat @@ apply ~match_all:(E.Generic.all ~rule:[Ast.True] ~nested:false) rule env)
|
||||||
|
|
||||||
|
let run (module E : Engine.S) template source rule =
|
||||||
|
let (module M : Matcher.S) = (module E.Generic) in
|
||||||
|
M.all ~configuration ~template ~source ()
|
||||||
|
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply ~match_all:(M.all ~rule:[Ast.True] ~nested:false) rule environment))
|
||||||
|
|
||||||
let%expect_test "rule_sat" =
|
let%expect_test "rule_sat" =
|
||||||
let rule = {| where "x" != "y" |} in
|
let rule = {| where "x" != "y" |} in
|
||||||
sat rule |> print_string;
|
sat (module Alpha) rule |> print_string;
|
||||||
|
[%expect_exact {|true|}];
|
||||||
|
sat (module Omega) rule |> print_string;
|
||||||
[%expect_exact {|true|}];
|
[%expect_exact {|true|}];
|
||||||
|
|
||||||
let rule = {| where "x" != "x" |} in
|
let rule = {| where "x" != "x" |} in
|
||||||
sat rule |> print_string;
|
sat (module Alpha) rule |> print_string;
|
||||||
|
[%expect_exact {|false|}];
|
||||||
|
sat (module Omega) rule |> print_string;
|
||||||
[%expect_exact {|false|}];
|
[%expect_exact {|false|}];
|
||||||
|
|
||||||
let rule = {| where "x" == "x" |} in
|
let rule = {| where "x" == "x" |} in
|
||||||
sat rule |> print_string;
|
sat (module Alpha) rule |> print_string;
|
||||||
|
[%expect_exact {|true|}];
|
||||||
|
sat (module Omega) rule |> print_string;
|
||||||
[%expect_exact {|true|}];
|
[%expect_exact {|true|}];
|
||||||
|
|
||||||
let rule = {| where "x" == "y" |} in
|
let rule = {| where "x" == "y" |} in
|
||||||
sat rule |> print_string;
|
sat (module Alpha) rule |> print_string;
|
||||||
|
[%expect_exact {|false|}];
|
||||||
|
sat (module Omega) rule |> print_string;
|
||||||
[%expect_exact {|false|}];
|
[%expect_exact {|false|}];
|
||||||
|
|
||||||
let rule = {| where :[x] == "y" |} in
|
let rule = {| where :[x] == "y" |} in
|
||||||
sat rule |> print_string;
|
sat (module Alpha) rule |> print_string;
|
||||||
|
[%expect_exact {|false|}];
|
||||||
|
sat (module Omega) rule |> print_string;
|
||||||
[%expect_exact {|false|}];
|
[%expect_exact {|false|}];
|
||||||
|
|
||||||
let rule = {| where :[x] == :[x] |} in
|
let rule = {| where :[x] == :[x] |} in
|
||||||
sat rule |> print_string;
|
sat (module Alpha) rule |> print_string;
|
||||||
|
[%expect_exact {|false|}];
|
||||||
|
sat (module Omega) rule |> print_string;
|
||||||
[%expect_exact {|false|}]
|
[%expect_exact {|false|}]
|
||||||
|
|
||||||
let%expect_test "rule_sat_with_env" =
|
let%expect_test "rule_sat_with_env" =
|
||||||
let env = make_env ["1", "x"; "2", "y"; "3", "x"] in
|
let env = make_env ["1", "x"; "2", "y"; "3", "x"] in
|
||||||
|
|
||||||
let rule = {| where :[1] == :[3], :[1] != :[2] |} in
|
let rule = {| where :[1] == :[3], :[1] != :[2] |} in
|
||||||
sat ~env rule |> print_string;
|
sat (module Alpha) ~env rule |> print_string;
|
||||||
|
[%expect_exact {|true|}];
|
||||||
|
sat (module Omega) ~env rule |> print_string;
|
||||||
[%expect_exact {|true|}];
|
[%expect_exact {|true|}];
|
||||||
|
|
||||||
let rule = {| where :[1] == :[3], :[1] != "y" |} in
|
let rule = {| where :[1] == :[3], :[1] != "y" |} in
|
||||||
sat ~env rule |> print_string;
|
sat (module Alpha) ~env rule |> print_string;
|
||||||
|
[%expect_exact {|true|}];
|
||||||
|
sat (module Omega) ~env rule |> print_string;
|
||||||
[%expect_exact {|true|}];
|
[%expect_exact {|true|}];
|
||||||
|
|
||||||
let rule = {| where :[1] == :[3], :[1] == "x" |} in
|
let rule = {| where :[1] == :[3], :[1] == "x" |} in
|
||||||
sat ~env rule |> print_string;
|
sat (module Alpha) ~env rule |> print_string;
|
||||||
|
[%expect_exact {|true|}];
|
||||||
|
sat (module Omega) ~env rule |> print_string;
|
||||||
[%expect_exact {|true|}];
|
[%expect_exact {|true|}];
|
||||||
|
|
||||||
let rule = {| where :[1] == :[2], :[1] != :[2] |} in
|
let rule = {| where :[1] == :[2], :[1] != :[2] |} in
|
||||||
sat ~env rule |> print_string;
|
sat (module Alpha) ~env rule |> print_string;
|
||||||
|
[%expect_exact {|false|}];
|
||||||
|
sat (module Omega) ~env rule |> print_string;
|
||||||
[%expect_exact {|false|}]
|
[%expect_exact {|false|}]
|
||||||
|
|
||||||
let%expect_test "where_true" =
|
let%expect_test "where_true" =
|
||||||
@ -68,12 +97,34 @@ let%expect_test "where_true" =
|
|||||||
let rule =
|
let rule =
|
||||||
{| where true
|
{| where true
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 11, "line": 1, "column": 12 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "b,c",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 1, "line": 1, "column": 2 },
|
||||||
|
"end": { "offset": 4, "line": 1, "column": 5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "(b,c) => {}"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -117,12 +168,15 @@ let%expect_test "match_sat" =
|
|||||||
| ":[_],:[_]" -> false
|
| ":[_],:[_]" -> false
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}];
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}];
|
[] |}];
|
||||||
@ -133,12 +187,11 @@ let%expect_test "match_sat" =
|
|||||||
| ":[_],:[_]" -> true
|
| ":[_],:[_]" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -161,6 +214,30 @@ let%expect_test "match_sat" =
|
|||||||
}
|
}
|
||||||
] |}];
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 11, "line": 1, "column": 12 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "b,c",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 1, "line": 1, "column": 2 },
|
||||||
|
"end": { "offset": 4, "line": 1, "column": 5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "(b,c) => {}"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
(a) => {}
|
(a) => {}
|
||||||
@ -176,12 +253,34 @@ let%expect_test "match_sat" =
|
|||||||
| ":[_]" -> true
|
| ":[_]" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 9, "line": 1, "column": 10 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "a",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 1, "line": 1, "column": 2 },
|
||||||
|
"end": { "offset": 2, "line": 1, "column": 3 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "(a) => {}"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -212,12 +311,34 @@ let%expect_test "match_sat" =
|
|||||||
| ":[_]" -> :[1] == "a"
|
| ":[_]" -> :[1] == "a"
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 9, "line": 1, "column": 10 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "a",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 1, "line": 1, "column": 2 },
|
||||||
|
"end": { "offset": 2, "line": 1, "column": 3 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "(a) => {}"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -247,17 +368,20 @@ let%expect_test "match_sat" =
|
|||||||
| ":[_]" -> :[1] == "b"
|
| ":[_]" -> :[1] == "b"
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}]
|
[] |}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_s_suffix" =
|
let%expect_test "match_s_suffix" =
|
||||||
let template = ":[1]s" in
|
let template = ":[1]s" in
|
||||||
|
|
||||||
@ -266,12 +390,34 @@ let%expect_test "match_s_suffix" =
|
|||||||
let rule =
|
let rule =
|
||||||
{| where true
|
{| where true
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 5, "line": 1, "column": 6 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "name",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 4, "line": 1, "column": 5 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "names"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -302,12 +448,34 @@ let%expect_test "match_s_suffix" =
|
|||||||
let rule =
|
let rule =
|
||||||
{| where true
|
{| where true
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 5, "line": 1, "column": 6 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "names",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 5, "line": 1, "column": 6 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "names"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -330,6 +498,7 @@ let%expect_test "match_s_suffix" =
|
|||||||
}
|
}
|
||||||
] |}]
|
] |}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "configuration_choice_based_on_case" =
|
let%expect_test "configuration_choice_based_on_case" =
|
||||||
let template = ":[1]" in
|
let template = ":[1]" in
|
||||||
|
|
||||||
@ -340,12 +509,16 @@ let%expect_test "configuration_choice_based_on_case" =
|
|||||||
| "ame" -> true
|
| "ame" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}];
|
[] |}];
|
||||||
@ -359,12 +532,34 @@ let%expect_test "configuration_choice_based_on_case" =
|
|||||||
| "names" -> true
|
| "names" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 5, "line": 1, "column": 6 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "names",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 5, "line": 1, "column": 6 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "names"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -396,19 +591,20 @@ let%expect_test "configuration_choice_based_on_case" =
|
|||||||
| "names" -> true
|
| "names" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}]
|
[] |}]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_using_environment_merge" =
|
let%expect_test "match_using_environment_merge" =
|
||||||
let template = "{:[1]}" in
|
let template = "{:[1]}" in
|
||||||
|
|
||||||
@ -417,12 +613,11 @@ let%expect_test "match_using_environment_merge" =
|
|||||||
let rule =
|
let rule =
|
||||||
{| where match :[1] { | "{ :[x] : :[y] }" -> :[x] == :[y] }
|
{| where match :[1] { | "{ :[x] : :[y] }" -> :[x] == :[y] }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -445,6 +640,30 @@ let%expect_test "match_using_environment_merge" =
|
|||||||
}
|
}
|
||||||
] |}];
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 21, "line": 1, "column": 22 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "{ a : a } { a : a }",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 1, "line": 1, "column": 2 },
|
||||||
|
"end": { "offset": 20, "line": 1, "column": 21 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "{{ a : a } { a : a }}"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
|
||||||
let template = "{:[1]}" in
|
let template = "{:[1]}" in
|
||||||
|
|
||||||
let source = "{{ a : a } { a : b }}" in
|
let source = "{{ a : a } { a : b }}" in
|
||||||
@ -452,17 +671,20 @@ let%expect_test "match_using_environment_merge" =
|
|||||||
let rule =
|
let rule =
|
||||||
{| where match :[1] { | "{ :[x] : :[y] }" -> :[x] == :[y] }
|
{| where match :[1] { | "{ :[x] : :[y] }" -> :[x] == :[y] }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}]
|
[] |}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "nested_matches" =
|
let%expect_test "nested_matches" =
|
||||||
let template = ":[1]" in
|
let template = ":[1]" in
|
||||||
|
|
||||||
@ -477,12 +699,34 @@ let%expect_test "nested_matches" =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 37, "line": 1, "column": 38 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "{ { foo : { bar : { baz : qux } } } }",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 37, "line": 1, "column": 38 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "{ { foo : { bar : { baz : qux } } } }"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -518,17 +762,20 @@ let%expect_test "nested_matches" =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}]
|
[] |}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_on_template" =
|
let%expect_test "match_on_template" =
|
||||||
let template = ":[1]" in
|
let template = ":[1]" in
|
||||||
|
|
||||||
@ -539,12 +786,34 @@ let%expect_test "match_on_template" =
|
|||||||
| "poodles" -> true
|
| "poodles" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 6, "line": 1, "column": 7 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "oodles",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 6, "line": 1, "column": 7 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "oodles"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -576,12 +845,34 @@ let%expect_test "match_on_template" =
|
|||||||
| "poodles" -> true
|
| "poodles" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 6, "line": 1, "column": 7 }
|
||||||
|
},
|
||||||
|
"environment": [
|
||||||
|
{
|
||||||
|
"variable": "1",
|
||||||
|
"value": "poodle",
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 6, "line": 1, "column": 7 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"matched": "poodle"
|
||||||
|
}
|
||||||
|
] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[
|
[
|
||||||
@ -613,12 +904,16 @@ let%expect_test "match_on_template" =
|
|||||||
| "poodle" -> true
|
| "poodle" -> true
|
||||||
}
|
}
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
run (module Alpha) template source rule
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|> print_matches;
|
||||||
[%expect {|
|
[%expect {|
|
||||||
[] |}];
|
[] |}];
|
||||||
|
|
||||||
|
run (module Omega) template source rule
|
||||||
|
|> print_matches;
|
||||||
|
[%expect {|
|
||||||
|
[] |}]
|
@ -1,624 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Match
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let%expect_test "rule_sat" =
|
|
||||||
let rule = {| where "x" != "y" |} in
|
|
||||||
sat rule |> print_string;
|
|
||||||
[%expect_exact {|true|}];
|
|
||||||
|
|
||||||
let rule = {| where "x" != "x" |} in
|
|
||||||
sat rule |> print_string;
|
|
||||||
[%expect_exact {|false|}];
|
|
||||||
|
|
||||||
let rule = {| where "x" == "x" |} in
|
|
||||||
sat rule |> print_string;
|
|
||||||
[%expect_exact {|true|}];
|
|
||||||
|
|
||||||
let rule = {| where "x" == "y" |} in
|
|
||||||
sat rule |> print_string;
|
|
||||||
[%expect_exact {|false|}];
|
|
||||||
|
|
||||||
let rule = {| where :[x] == "y" |} in
|
|
||||||
sat rule |> print_string;
|
|
||||||
[%expect_exact {|false|}];
|
|
||||||
|
|
||||||
let rule = {| where :[x] == :[x] |} in
|
|
||||||
sat rule |> print_string;
|
|
||||||
[%expect_exact {|false|}]
|
|
||||||
|
|
||||||
let%expect_test "rule_sat_with_env" =
|
|
||||||
let env = make_env ["1", "x"; "2", "y"; "3", "x"] in
|
|
||||||
|
|
||||||
let rule = {| where :[1] == :[3], :[1] != :[2] |} in
|
|
||||||
sat ~env rule |> print_string;
|
|
||||||
[%expect_exact {|true|}];
|
|
||||||
|
|
||||||
let rule = {| where :[1] == :[3], :[1] != "y" |} in
|
|
||||||
sat ~env rule |> print_string;
|
|
||||||
[%expect_exact {|true|}];
|
|
||||||
|
|
||||||
let rule = {| where :[1] == :[3], :[1] == "x" |} in
|
|
||||||
sat ~env rule |> print_string;
|
|
||||||
[%expect_exact {|true|}];
|
|
||||||
|
|
||||||
let rule = {| where :[1] == :[2], :[1] != :[2] |} in
|
|
||||||
sat ~env rule |> print_string;
|
|
||||||
[%expect_exact {|false|}]
|
|
||||||
|
|
||||||
let%expect_test "where_true" =
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
(:[1]) => {}
|
|
||||||
|}
|
|
||||||
|> format
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
(b,c) => {}
|
|
||||||
|}
|
|
||||||
|> format
|
|
||||||
in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where true
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 11, "line": 1, "column": 12 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "b,c",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 1, "line": 1, "column": 2 },
|
|
||||||
"end": { "offset": 4, "line": 1, "column": 5 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "(b,c) => {}"
|
|
||||||
}
|
|
||||||
] |}]
|
|
||||||
|
|
||||||
let%expect_test "match_sat" =
|
|
||||||
let template =
|
|
||||||
{|
|
|
||||||
(:[1]) => {}
|
|
||||||
|}
|
|
||||||
|> format
|
|
||||||
in
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
(b,c) => {}
|
|
||||||
|}
|
|
||||||
|> format
|
|
||||||
in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where
|
|
||||||
match :[1] {
|
|
||||||
| ":[_],:[_]" -> false
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}];
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where
|
|
||||||
match :[1] {
|
|
||||||
| ":[_],:[_]" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 11, "line": 1, "column": 12 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "b,c",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 1, "line": 1, "column": 2 },
|
|
||||||
"end": { "offset": 4, "line": 1, "column": 5 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "(b,c) => {}"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
(a) => {}
|
|
||||||
(b,c) => {}
|
|
||||||
|}
|
|
||||||
|> format
|
|
||||||
in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where
|
|
||||||
match :[1] {
|
|
||||||
| ":[_],:[_]" -> false
|
|
||||||
| ":[_]" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 9, "line": 1, "column": 10 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "a",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 1, "line": 1, "column": 2 },
|
|
||||||
"end": { "offset": 2, "line": 1, "column": 3 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "(a) => {}"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where
|
|
||||||
match :[1] {
|
|
||||||
| ":[_],:[_]" -> false
|
|
||||||
| ":[_]" -> :[1] == "a"
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 9, "line": 1, "column": 10 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "a",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 1, "line": 1, "column": 2 },
|
|
||||||
"end": { "offset": 2, "line": 1, "column": 3 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "(a) => {}"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where
|
|
||||||
match :[1] {
|
|
||||||
| ":[_],:[_]" -> false
|
|
||||||
| ":[_]" -> :[1] == "b"
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_s_suffix" =
|
|
||||||
let template = ":[1]s" in
|
|
||||||
|
|
||||||
let source = "names" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where true
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 5, "line": 1, "column": 6 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "name",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 4, "line": 1, "column": 5 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "names"
|
|
||||||
}
|
|
||||||
] |}]
|
|
||||||
|
|
||||||
let%expect_test "match_s_suffix" =
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "names" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where true
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 5, "line": 1, "column": 6 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "names",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 5, "line": 1, "column": 6 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "names"
|
|
||||||
}
|
|
||||||
] |}]
|
|
||||||
|
|
||||||
let%expect_test "configuration_choice_based_on_case" =
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "names" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] {
|
|
||||||
| "ame" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}];
|
|
||||||
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "names" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] {
|
|
||||||
| "names" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 5, "line": 1, "column": 6 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "names",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 5, "line": 1, "column": 6 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "names"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "namesXXXXX" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] {
|
|
||||||
| "names" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_using_environment_merge" =
|
|
||||||
let template = "{:[1]}" in
|
|
||||||
|
|
||||||
let source = "{{ a : a } { a : a }}" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] { | "{ :[x] : :[y] }" -> :[x] == :[y] }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 21, "line": 1, "column": 22 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "{ a : a } { a : a }",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 1, "line": 1, "column": 2 },
|
|
||||||
"end": { "offset": 20, "line": 1, "column": 21 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "{{ a : a } { a : a }}"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let template = "{:[1]}" in
|
|
||||||
|
|
||||||
let source = "{{ a : a } { a : b }}" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] { | "{ :[x] : :[y] }" -> :[x] == :[y] }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "nested_matches" =
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "{ { foo : { bar : { baz : qux } } } }" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] {
|
|
||||||
| "{ :[foo] : :[tail1] }" -> match :[tail1] {
|
|
||||||
| "{ :[bar] : :[tail2] }" -> match :[tail2] {
|
|
||||||
| "{ baz : :[qux] }" -> :[qux] == "qux", :[bar] == "bar"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 37, "line": 1, "column": 38 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "{ { foo : { bar : { baz : qux } } } }",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 37, "line": 1, "column": 38 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "{ { foo : { bar : { baz : qux } } } }"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "{ { foo : { bar : { baz : qux } } } }" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match :[1] {
|
|
||||||
| "{ :[foo] : :[tail1] }" -> match :[tail1] {
|
|
||||||
| "{ :[bar] : :[tail2] }" -> match :[tail2] {
|
|
||||||
| "{ baz : :[qux] }" -> :[qux] == "fail"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_on_template" =
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "oodles" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match "p:[1]" {
|
|
||||||
| "poodles" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 6, "line": 1, "column": 7 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "oodles",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 6, "line": 1, "column": 7 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "oodles"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "poodle" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match ":[1]s" {
|
|
||||||
| "poodles" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 6, "line": 1, "column": 7 }
|
|
||||||
},
|
|
||||||
"environment": [
|
|
||||||
{
|
|
||||||
"variable": "1",
|
|
||||||
"value": "poodle",
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 6, "line": 1, "column": 7 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"matched": "poodle"
|
|
||||||
}
|
|
||||||
] |}];
|
|
||||||
|
|
||||||
let template = ":[1]" in
|
|
||||||
|
|
||||||
let source = "poodle" in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{| where match ":[1]," {
|
|
||||||
| "poodle" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
Generic.all ~configuration ~template ~source ()
|
|
||||||
|> List.filter ~f:(fun { environment; _ } -> Rule.(sat @@ apply rule environment))
|
|
||||||
|> print_matches;
|
|
||||||
[%expect {|
|
|
||||||
[] |}];
|
|
27
test/common/test_nested_comments.ml
Normal file
27
test/common/test_nested_comments.ml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
|
open Test_helpers
|
||||||
|
|
||||||
|
(* See https://stackoverflow.com/questions/6698039/nested-comments-in-c-c *)
|
||||||
|
let%expect_test "nested_multiline_ocaml" =
|
||||||
|
let source = {|int nest = /*/*/ 0 */**/ 1;|} in
|
||||||
|
let template = {|0 * 1|} in
|
||||||
|
|
||||||
|
(* 0 is not commented out *)
|
||||||
|
Alpha.C.all ~configuration ~template ~source ()
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "0 */**/ 1" ]|}];
|
||||||
|
Omega.C.all ~configuration ~template ~source ()
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "0 */**/ 1" ]|}];
|
||||||
|
|
||||||
|
(* 0 is commented out *)
|
||||||
|
Alpha.C_nested_comments.all ~configuration ~template ~source ()
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[]|}];
|
||||||
|
Omega.C_nested_comments.all ~configuration ~template ~source ()
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[]|}];
|
@ -1,19 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_alpha
|
|
||||||
|
|
||||||
(* See https://stackoverflow.com/questions/6698039/nested-comments-in-c-c *)
|
|
||||||
let%expect_test "nested_multiline_ocaml" =
|
|
||||||
let source = {|int nest = /*/*/ 0 */**/ 1;|} in
|
|
||||||
let template = {|0 * 1|} in
|
|
||||||
(* 0 is not commented out *)
|
|
||||||
let matches_no_nesting = C.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches_no_nesting;
|
|
||||||
[%expect_exact {|[ "0 */**/ 1" ]|}];
|
|
||||||
|
|
||||||
let matches_no_nesting = C_nested_comments.all ~configuration ~template ~source () in
|
|
||||||
(* 0 is commented out *)
|
|
||||||
print_only_match matches_no_nesting;
|
|
||||||
[%expect_exact {|[]|}];
|
|
@ -1,19 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
(* See https://stackoverflow.com/questions/6698039/nested-comments-in-c-c *)
|
|
||||||
let%expect_test "nested_multiline_ocaml" =
|
|
||||||
let source = {|int nest = /*/*/ 0 */**/ 1;|} in
|
|
||||||
let template = {|0 * 1|} in
|
|
||||||
(* 0 is not commented out *)
|
|
||||||
let matches_no_nesting = C.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches_no_nesting;
|
|
||||||
[%expect_exact {|[ "0 */**/ 1" ]|}];
|
|
||||||
|
|
||||||
let matches_no_nesting = C_nested_comments.all ~configuration ~template ~source () in
|
|
||||||
(* 0 is commented out *)
|
|
||||||
print_only_match matches_no_nesting;
|
|
||||||
[%expect_exact {|[]|}];
|
|
@ -1,10 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
|
||||||
include Test_alpha
|
open Matchers
|
||||||
|
|
||||||
let run = run_nested (module Matchers.Alpha.Generic)
|
let run (module E : Engine.S) = run_nested (module E.Generic)
|
||||||
|
|
||||||
let%expect_test "nested_matches" =
|
let%expect_test "nested_matches" =
|
||||||
let source = {|
|
let source = {|
|
||||||
@ -23,7 +24,18 @@ q{
|
|||||||
}
|
}
|
||||||
|} in
|
|} in
|
||||||
let match_template = {|:[[f]]{:[x]}|} in
|
let match_template = {|:[[f]]{:[x]}|} in
|
||||||
run source match_template ();
|
|
||||||
|
run (module Alpha) source match_template ();
|
||||||
|
[%expect_exact {|2:a{\n b{\n c{\n d{e}\n }\n }\n }
|
||||||
|
3:b{\n c{\n d{e}\n }\n }
|
||||||
|
4:c{\n d{e}\n }
|
||||||
|
5:d{e}
|
||||||
|
10:q{\n b{\n f{}\n }\n}
|
||||||
|
11:b{\n f{}\n }
|
||||||
|
12:f{}
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega) source match_template ();
|
||||||
[%expect_exact {|2:a{\n b{\n c{\n d{e}\n }\n }\n }
|
[%expect_exact {|2:a{\n b{\n c{\n d{e}\n }\n }\n }
|
||||||
3:b{\n c{\n d{e}\n }\n }
|
3:b{\n c{\n d{e}\n }\n }
|
||||||
4:c{\n d{e}\n }
|
4:c{\n d{e}\n }
|
||||||
@ -33,21 +45,39 @@ q{
|
|||||||
12:f{}
|
12:f{}
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "nested_matches" =
|
let%expect_test "nested_matches" =
|
||||||
let source = {|a(b(c(d(e))))|} in
|
let source = {|a(b(c(d(e))))|} in
|
||||||
let match_template = {|:[[f]](:[x])|} in
|
let match_template = {|:[[f]](:[x])|} in
|
||||||
run source match_template ();
|
|
||||||
|
run (module Alpha) source match_template ();
|
||||||
|
[%expect_exact {|1:a(b(c(d(e))))
|
||||||
|
1:b(c(d(e)))
|
||||||
|
1:c(d(e))
|
||||||
|
1:d(e)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega) source match_template ();
|
||||||
[%expect_exact {|1:a(b(c(d(e))))
|
[%expect_exact {|1:a(b(c(d(e))))
|
||||||
1:b(c(d(e)))
|
1:b(c(d(e)))
|
||||||
1:c(d(e))
|
1:c(d(e))
|
||||||
1:d(e)
|
1:d(e)
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "nested_matches_from_rule" =
|
let%expect_test "nested_matches_from_rule" =
|
||||||
let source = {|a(b(c(d(e))))|} in
|
let source = {|a(b(c(d(e))))|} in
|
||||||
let match_template = {|:[[f]](:[x])|} in
|
let match_template = {|:[[f]](:[x])|} in
|
||||||
let rule = {|where nested|} in
|
let rule = {|where nested|} in
|
||||||
run ~rule source match_template ();
|
|
||||||
|
run (module Alpha) ~rule source match_template ();
|
||||||
|
[%expect_exact {|1:a(b(c(d(e))))
|
||||||
|
1:b(c(d(e)))
|
||||||
|
1:c(d(e))
|
||||||
|
1:d(e)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega) ~rule source match_template ();
|
||||||
[%expect_exact {|1:a(b(c(d(e))))
|
[%expect_exact {|1:a(b(c(d(e))))
|
||||||
1:b(c(d(e)))
|
1:b(c(d(e)))
|
||||||
1:c(d(e))
|
1:c(d(e))
|
@ -1,53 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
let run = run_nested (module Matchers.Omega.Generic)
|
|
||||||
|
|
||||||
let%expect_test "nested_matches" =
|
|
||||||
let source = {|
|
|
||||||
a{
|
|
||||||
b{
|
|
||||||
c{
|
|
||||||
d{e}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
q{
|
|
||||||
b{
|
|
||||||
f{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|} in
|
|
||||||
let match_template = {|:[[f]]{:[x]}|} in
|
|
||||||
run source match_template ();
|
|
||||||
[%expect_exact {|2:a{\n b{\n c{\n d{e}\n }\n }\n }
|
|
||||||
3:b{\n c{\n d{e}\n }\n }
|
|
||||||
4:c{\n d{e}\n }
|
|
||||||
5:d{e}
|
|
||||||
10:q{\n b{\n f{}\n }\n}
|
|
||||||
11:b{\n f{}\n }
|
|
||||||
12:f{}
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "nested_matches" =
|
|
||||||
let source = {|a(b(c(d(e))))|} in
|
|
||||||
let match_template = {|:[[f]](:[x])|} in
|
|
||||||
run source match_template ();
|
|
||||||
[%expect_exact {|1:a(b(c(d(e))))
|
|
||||||
1:b(c(d(e)))
|
|
||||||
1:c(d(e))
|
|
||||||
1:d(e)
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "nested_matches_from_rule" =
|
|
||||||
let source = {|a(b(c(d(e))))|} in
|
|
||||||
let match_template = {|:[[f]](:[x])|} in
|
|
||||||
let rule = {|where nested|} in
|
|
||||||
run ~rule source match_template ();
|
|
||||||
[%expect_exact {|1:a(b(c(d(e))))
|
|
||||||
1:b(c(d(e)))
|
|
||||||
1:c(d(e))
|
|
||||||
1:d(e)
|
|
||||||
|}]
|
|
@ -1,9 +1,7 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
module Alpha = Test_alpha
|
|
||||||
module Omega = Test_omega
|
|
||||||
|
|
||||||
let to_string format matches =
|
let to_string format matches =
|
||||||
let f = match format with
|
let f = match format with
|
||||||
@ -13,11 +11,11 @@ let to_string format matches =
|
|||||||
Format.asprintf "%a" f (Some "file", matches)
|
Format.asprintf "%a" f (Some "file", matches)
|
||||||
|
|
||||||
let run source match_template format : (string * string) =
|
let run source match_template format : (string * string) =
|
||||||
let specification = Configuration.Specification.create ~match_template () in
|
let specification = Matchers.Specification.create ~match_template () in
|
||||||
let run ~fast =
|
let run ~fast =
|
||||||
let result =
|
let result =
|
||||||
Pipeline.process_single_source
|
Pipeline.process_single_source
|
||||||
(module Omega.C)
|
(module Matchers.Omega.C)
|
||||||
~fast_offset_conversion:fast
|
~fast_offset_conversion:fast
|
||||||
configuration
|
configuration
|
||||||
(String source)
|
(String source)
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
include Matchers.Omega
|
|
||||||
module Rule = Language.Rule
|
|
@ -1,5 +1,6 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Matchers
|
||||||
open Rewriter
|
open Rewriter
|
||||||
open Rewrite_template
|
open Rewrite_template
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Language
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
open Rule
|
||||||
|
|
||||||
let rule_parses rule =
|
let rule_parses rule =
|
||||||
match Rule.create rule with
|
match Rule.create rule with
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
open Configuration
|
open Configuration
|
||||||
open Command_configuration
|
open Command_configuration
|
||||||
|
|
||||||
include Test_alpha
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
let configuration =
|
let configuration (module E : Engine.S) =
|
||||||
{ matcher = (module Generic : Matchers.Matcher.S)
|
{ matcher = (module E.Generic : Matchers.Matcher.S)
|
||||||
; sources = `String "source"
|
; sources = `String "source"
|
||||||
; specifications = []
|
; specifications = []
|
||||||
; run_options =
|
; run_options =
|
@ -1,56 +0,0 @@
|
|||||||
open Configuration
|
|
||||||
open Command_configuration
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let configuration =
|
|
||||||
{ matcher = (module Generic : Matchers.Matcher.S)
|
|
||||||
; sources = `String "source"
|
|
||||||
; specifications = []
|
|
||||||
; run_options =
|
|
||||||
{ verbose = false
|
|
||||||
; match_timeout = 3
|
|
||||||
; dump_statistics = false
|
|
||||||
; substitute_in_place = true
|
|
||||||
; disable_substring_matching = false
|
|
||||||
; fast_offset_conversion = false
|
|
||||||
; match_newline_toplevel = false
|
|
||||||
; bound_count = None
|
|
||||||
; compute_mode = `Sequential
|
|
||||||
}
|
|
||||||
; output_printer = (fun _ -> ())
|
|
||||||
; interactive_review = None
|
|
||||||
; extension = None
|
|
||||||
; metasyntax = None
|
|
||||||
}
|
|
||||||
|
|
||||||
(* TODO restore this, can't access the Parallel_hack module *)
|
|
||||||
(*
|
|
||||||
let%expect_test "interactive_paths" =
|
|
||||||
let _, count =
|
|
||||||
let scheduler = Scheduler.create ~number_of_workers:1 () in
|
|
||||||
Pipeline.with_scheduler scheduler ~f:(
|
|
||||||
Pipeline.process_paths_for_interactive
|
|
||||||
~sequential:false
|
|
||||||
~f:(fun ~input: _ ~path:_ -> (None, 0)) [])
|
|
||||||
in
|
|
||||||
print_string (Format.sprintf "%d" count);
|
|
||||||
[%expect_exact {|0|}]
|
|
||||||
|
|
||||||
let%expect_test "launch_editor" =
|
|
||||||
let configuration =
|
|
||||||
{ configuration
|
|
||||||
with interactive_review =
|
|
||||||
Some
|
|
||||||
{ editor = "vim"
|
|
||||||
; default_is_accept = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
in
|
|
||||||
let result =
|
|
||||||
try Pipeline.run configuration; "passed"
|
|
||||||
with _exc -> "Not a tty"
|
|
||||||
in
|
|
||||||
print_string result;
|
|
||||||
[%expect_exact {|Not a tty|}]
|
|
||||||
*)
|
|
@ -1,44 +1,78 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
|
||||||
include Test_alpha
|
let all (module E : Engine.S) ~template ~source =
|
||||||
|
E.Python.all ~configuration ~template ~source ()
|
||||||
|
|
||||||
let%expect_test "matched_contains_raw_literal_quotes" =
|
let%expect_test "matched_contains_raw_literal_quotes" =
|
||||||
let source = {|"""blah"""|} in
|
let source = {|"""blah"""|} in
|
||||||
let template = {|""":[[1]]"""|} in
|
let template = {|""":[[1]]"""|} in
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
all (module Alpha) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "\"\"\"blah\"\"\"" ]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
[%expect_exact {|[ "\"\"\"blah\"\"\"" ]|}]
|
[%expect_exact {|[ "\"\"\"blah\"\"\"" ]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "interpreted_string_does_not_match_raw_literal" =
|
let%expect_test "interpreted_string_does_not_match_raw_literal" =
|
||||||
let source = {|"""blah""" "blah"|} in
|
let source = {|"""blah""" "blah"|} in
|
||||||
let template = {|":[[1]]"|} in
|
let template = {|":[[1]]"|} in
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
all (module Alpha) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "\"blah\"" ]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
[%expect_exact {|[ "\"blah\"" ]|}]
|
[%expect_exact {|[ "\"blah\"" ]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "interpreted_string_does_not_match_raw_literal_containing_quote" =
|
let%expect_test "interpreted_string_does_not_match_raw_literal_containing_quote" =
|
||||||
let source = {|"""blah""" """bl"ah""" "blah"|} in
|
let source = {|"""blah""" """bl"ah""" "blah"|} in
|
||||||
let template = {|":[[1]]"|} in
|
let template = {|":[[1]]"|} in
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
all (module Alpha) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "\"blah\"" ]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
[%expect_exact {|[ "\"blah\"" ]|}]
|
[%expect_exact {|[ "\"blah\"" ]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "raw_string_matches_string_containing_quote" =
|
let%expect_test "raw_string_matches_string_containing_quote" =
|
||||||
let source = {|"""bl"ah"""|} in
|
let source = {|"""bl"ah"""|} in
|
||||||
let template = {|""":[1]"""|} in
|
let template = {|""":[1]"""|} in
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
all (module Alpha) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "\"\"\"bl\"ah\"\"\"" ]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
[%expect_exact {|[ "\"\"\"bl\"ah\"\"\"" ]|}]
|
[%expect_exact {|[ "\"\"\"bl\"ah\"\"\"" ]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "invalid_raw_string_in_python_but_matches_because_ignores_after" =
|
let%expect_test "invalid_raw_string_in_python_but_matches_because_ignores_after" =
|
||||||
let source = {|"""""""|} in
|
let source = {|"""""""|} in
|
||||||
let template = {|""":[1]"""|} in
|
let template = {|""":[1]"""|} in
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
all (module Alpha) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
|
[%expect_exact {|[ "\"\"\"\"\"\"" ]|}];
|
||||||
|
|
||||||
|
all (module Omega) ~template ~source
|
||||||
|
|> print_only_match;
|
||||||
[%expect_exact {|[ "\"\"\"\"\"\"" ]|}]
|
[%expect_exact {|[ "\"\"\"\"\"\"" ]|}]
|
||||||
|
|
||||||
|
|
||||||
(* Disabled: this works by luck in Alpha, but it shouldn't. It is empty list in Omega. Should be explicitly supported *)
|
(* Disabled: this works by luck in Alpha, but it shouldn't. It is empty list in Omega. Should be explicitly supported *)
|
||||||
(*
|
(*
|
||||||
let%expect_test "raw_string_captures_escape_sequences" =
|
let%expect_test "raw_string_captures_escape_sequences" =
|
@ -1,50 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let%expect_test "matched_contains_raw_literal_quotes" =
|
|
||||||
let source = {|"""blah"""|} in
|
|
||||||
let template = {|""":[[1]]"""|} in
|
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
|
||||||
[%expect_exact {|[ "\"\"\"blah\"\"\"" ]|}]
|
|
||||||
|
|
||||||
let%expect_test "interpreted_string_does_not_match_raw_literal" =
|
|
||||||
let source = {|"""blah""" "blah"|} in
|
|
||||||
let template = {|":[[1]]"|} in
|
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
|
||||||
[%expect_exact {|[ "\"blah\"" ]|}]
|
|
||||||
|
|
||||||
let%expect_test "interpreted_string_does_not_match_raw_literal_containing_quote" =
|
|
||||||
let source = {|"""blah""" """bl"ah""" "blah"|} in
|
|
||||||
let template = {|":[[1]]"|} in
|
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
|
||||||
[%expect_exact {|[ "\"blah\"" ]|}]
|
|
||||||
|
|
||||||
let%expect_test "raw_string_matches_string_containing_quote" =
|
|
||||||
let source = {|"""bl"ah"""|} in
|
|
||||||
let template = {|""":[1]"""|} in
|
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
|
||||||
[%expect_exact {|[ "\"\"\"bl\"ah\"\"\"" ]|}]
|
|
||||||
|
|
||||||
let%expect_test "invalid_raw_string_in_python_but_matches_because_ignores_after" =
|
|
||||||
let source = {|"""""""|} in
|
|
||||||
let template = {|""":[1]"""|} in
|
|
||||||
let matches = Python.all ~configuration ~template ~source () in
|
|
||||||
print_only_match matches;
|
|
||||||
[%expect_exact {|[ "\"\"\"\"\"\"" ]|}]
|
|
||||||
|
|
||||||
(* Disabled: this works by luck in Alpha, but it shouldn't. It is empty list in Omega. Should be explicitly supported *)
|
|
||||||
(*
|
|
||||||
let%expect_test "raw_string_captures_escape_sequences" =
|
|
||||||
let source = {|"""\""""|} in
|
|
||||||
let template = {|""":[1]"""|} in
|
|
||||||
let matches = Python.all ~configuration ~template ~source in
|
|
||||||
print_only_match matches;
|
|
||||||
[%expect_exact {|[ "\"\"\"\\\"\"\"" ]|}]
|
|
||||||
*)
|
|
@ -1,111 +1,149 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
open Matchers.Alpha
|
open Matchers
|
||||||
|
|
||||||
let%expect_test "regex_holes_simple" =
|
let%expect_test "regex_holes_simple" =
|
||||||
let source = {|foo|} in
|
let source = {|foo|} in
|
||||||
let match_template = {|:[x~\w+]|} in
|
let match_template = {|:[x~\w+]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(foo)|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(foo)|}]
|
[%expect_exact {|(foo)|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_simple_posix" =
|
let%expect_test "regex_holes_simple_posix" =
|
||||||
let source = {|foo|} in
|
let source = {|foo|} in
|
||||||
let match_template = {|:[x~[[:alpha:]]]|} in
|
let match_template = {|:[x~[[:alpha:]]]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(f)(o)(o)|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(f)(o)(o)|}]
|
[%expect_exact {|(f)(o)(o)|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_substring" =
|
let%expect_test "regex_holes_substring" =
|
||||||
let source = {|foo()|} in
|
let source = {|foo()|} in
|
||||||
let match_template = {|:[x~o\w]()|} in
|
let match_template = {|:[x~o\w]()|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|f(oo)|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|f(oo)|}]
|
[%expect_exact {|f(oo)|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_empty_string_terminates" =
|
let%expect_test "regex_holes_empty_string_terminates" =
|
||||||
let source = {|foo()|} in
|
let source = {|foo()|} in
|
||||||
let match_template = {|:[x~|]|} in
|
let match_template = {|:[x~|]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|()f()o()o()(())|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|()f()o()o()(())|}]
|
[%expect_exact {|()f()o()o()(())|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_repetition_takes_precedence" =
|
let%expect_test "regex_holes_repetition_takes_precedence" =
|
||||||
let source = {|foobar()|} in
|
let source = {|foobar()|} in
|
||||||
(* this will _not_ match because bar is consumed by \w before we look ahead *)
|
(* this will _not_ match because bar is consumed by \w before we look ahead *)
|
||||||
let match_template = {|:[x~\w+]bar()|} in
|
let match_template = {|:[x~\w+]bar()|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|No matches.|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|No matches.|}]
|
[%expect_exact {|No matches.|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_negated_match" =
|
let%expect_test "regex_holes_negated_match" =
|
||||||
let source = {|(literally_anyting_except_close_paren?!@#$%^&*[])|} in
|
let source = {|(literally_anyting_except_close_paren?!@#$%^&*[])|} in
|
||||||
let match_template = {|(:[x~[^)]+])|} in
|
let match_template = {|(:[x~[^)]+])|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(literally_anyting_except_close_paren?!@#$%^&*[])|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(literally_anyting_except_close_paren?!@#$%^&*[])|}];
|
[%expect_exact {|(literally_anyting_except_close_paren?!@#$%^&*[])|}];
|
||||||
|
|
||||||
let source = {|(arg1, arg2, arg3)|} in
|
let source = {|(arg1, arg2, arg3)|} in
|
||||||
let match_template = {|:[x~[^,() ]+]|} in
|
let match_template = {|:[x~[^,() ]+]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|((arg1), (arg2), (arg3))|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|((arg1), (arg2), (arg3))|}]
|
[%expect_exact {|((arg1), (arg2), (arg3))|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_dot_star_ok_and_this_is_for_newline" =
|
let%expect_test "regex_holes_dot_star_ok_and_this_is_for_newline" =
|
||||||
let source = "foo()\nbar()" in
|
let source = "foo()\nbar()" in
|
||||||
let match_template = {|:[x~.*]|} in
|
let match_template = {|:[x~.*]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(foo())()
|
||||||
|
(bar())|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(foo())()
|
[%expect_exact {|(foo())()
|
||||||
(bar())|}]
|
(bar())|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional" =
|
let%expect_test "regex_holes_optional" =
|
||||||
let source = "nonovember no november no vember" in
|
let source = "nonovember no november no vember" in
|
||||||
let match_template = {|:[x~no(vember)?]|} in
|
let match_template = {|:[x~no(vember)?]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(no)(november) (no) (november) (no) vember|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(no)(november) (no) (november) (no) vember|}]
|
[%expect_exact {|(no)(november) (no) (november) (no) vember|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional_spaces" =
|
let%expect_test "regex_holes_optional_spaces" =
|
||||||
let source = "nonovember no november no vember" in
|
let source = "nonovember no november no vember" in
|
||||||
let match_template = {|no :[x~(vember)?]|} in
|
let match_template = {|no :[x~(vember)?]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|nonovember ()november (vember)|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|nonovember ()november (vember)|}]
|
[%expect_exact {|nonovember ()november (vember)|}]
|
||||||
|
|
||||||
(* Note: Known limitation: this behavior does _not_ allow (optional)? to match
|
|
||||||
empty string to sat template. Because of something tricky. *)
|
|
||||||
let%expect_test "regex_holes_optional_doesnt_work_outside_regex" =
|
let%expect_test "regex_holes_optional_doesnt_work_outside_regex" =
|
||||||
let source = "no" in
|
let source = "no" in
|
||||||
let match_template = {|no:[x~(vember)?]|} in
|
let match_template = {|no:[x~(vember)?]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
(* Note: Known Alpha limitation: this behavior does _not_ allow (optional)? to match
|
||||||
|
empty string to sat template. Because of something tricky. *)
|
||||||
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|No matches.|}];
|
[%expect_exact {|No matches.|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|()|}];
|
||||||
|
|
||||||
let source = "foo bar foobar" in
|
let source = "foo bar foobar" in
|
||||||
let match_template = {|:[x~\s*?]|} in
|
let match_template = {|:[x~\s*?]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|()f()o()o() ()b()a()r() ()f()o()o()b()a()r|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|()f()o()o() ()b()a()r() ()f()o()o()b()a()r|}];
|
[%expect_exact {|()f()o()o() ()b()a()r() ()f()o()o()b()a()r|}];
|
||||||
|
|
||||||
let source = "foo bar foobar" in
|
let source = "foo bar foobar" in
|
||||||
let match_template = {|:[x~\s*]|} in
|
let match_template = {|:[x~\s*]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|()f()o()o( )()b()a()r( )()f()o()o()b()a()r|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|()f()o()o( )()b()a()r( )()f()o()o()b()a()r|}]
|
[%expect_exact {|()f()o()o( )()b()a()r( )()f()o()o()b()a()r|}]
|
||||||
|
|
||||||
|
|
||||||
@ -114,17 +152,23 @@ let%expect_test "regex_holes_optional_strip_no_from_november_outside_regex" =
|
|||||||
let match_template = {|no:[x~(vember)?]|} in
|
let match_template = {|no:[x~(vember)?]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|()(vember) () (vember) () vember|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|()(vember) () (vember) () vember|}]
|
[%expect_exact {|()(vember) () (vember) () vember|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional_strip_no_from_november_inside_regex" =
|
let%expect_test "regex_holes_optional_strip_no_from_november_inside_regex" =
|
||||||
let source = "nonovember no november no vember" in
|
let source = "nonovember no november no vember" in
|
||||||
let match_template = {|:[x~no(vember)?]|} in
|
let match_template = {|:[x~no(vember)?]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(no)(november) (no) (november) (no) vember|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(no)(november) (no) (november) (no) vember|}]
|
[%expect_exact {|(no)(november) (no) (november) (no) vember|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "leading_spaces_beginning_line_anchor" =
|
let%expect_test "leading_spaces_beginning_line_anchor" =
|
||||||
let source = {|
|
let source = {|
|
||||||
a
|
a
|
||||||
@ -135,10 +179,14 @@ let%expect_test "leading_spaces_beginning_line_anchor" =
|
|||||||
let match_template = {|:[x~^(\s+)]|} in
|
let match_template = {|:[x~^(\s+)]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|( )a( )b( )c
|
||||||
|
|}];
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|( )a( )b( )c
|
[%expect_exact {|( )a( )b( )c
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "spaces_star" =
|
let%expect_test "spaces_star" =
|
||||||
let source = {|
|
let source = {|
|
||||||
a
|
a
|
||||||
@ -150,8 +198,18 @@ let%expect_test "spaces_star" =
|
|||||||
let match_template = {|:[x~\s*]|} in
|
let match_template = {|:[x~\s*]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
(* The <spaces><empty space>chars is how this behaves on https://regexr.com/59ft0 as well, see replace *)
|
(* The <spaces><empty space>chars is how this behaves on
|
||||||
|
https://regexr.com/59ft0 as well, see replace *)
|
||||||
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(
|
||||||
|
)()a(
|
||||||
|
)()b(
|
||||||
|
)()c(
|
||||||
|
)()d(
|
||||||
|
)|}];
|
||||||
|
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(
|
[%expect_exact {|(
|
||||||
)()a(
|
)()a(
|
||||||
)()b(
|
)()b(
|
||||||
@ -159,6 +217,7 @@ let%expect_test "spaces_star" =
|
|||||||
)()d(
|
)()d(
|
||||||
)|}]
|
)|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "end_line_anchor" =
|
let%expect_test "end_line_anchor" =
|
||||||
let source = {|
|
let source = {|
|
||||||
aaa bbb
|
aaa bbb
|
||||||
@ -169,12 +228,19 @@ ccc ddd
|
|||||||
let match_template = {|:[x~\w+ bbb$]|} in
|
let match_template = {|:[x~\w+ bbb$]|} in
|
||||||
let rewrite_template = {|(:[x])|} in
|
let rewrite_template = {|(:[x])|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
(aaa bbb)aaa bbb ccc
|
||||||
|
ccc ddd
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
(aaa bbb)aaa bbb ccc
|
(aaa bbb)aaa bbb ccc
|
||||||
ccc ddd
|
ccc ddd
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "word_boundaries" =
|
let%expect_test "word_boundaries" =
|
||||||
let source = {|
|
let source = {|
|
||||||
foo(bar, baz(),
|
foo(bar, baz(),
|
||||||
@ -186,7 +252,15 @@ foo(bar, baz(),
|
|||||||
let match_template = {|:[x~\b\w+\b]|} in
|
let match_template = {|:[x~\b\w+\b]|} in
|
||||||
let rewrite_template = {|(>:[x]<)|} in
|
let rewrite_template = {|(>:[x]<)|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
(>foo<)((>bar<), (>baz<)(),
|
||||||
|
|
||||||
|
|
||||||
|
(>qux<).(>derp<))
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
(>foo<)((>bar<), (>baz<)(),
|
(>foo<)((>bar<), (>baz<)(),
|
||||||
|
|
||||||
@ -194,6 +268,7 @@ foo(bar, baz(),
|
|||||||
(>qux<).(>derp<))
|
(>qux<).(>derp<))
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
(* I previously assumed [^ ] would not match newlines, but it does, and is the
|
(* I previously assumed [^ ] would not match newlines, but it does, and is the
|
||||||
same as regexr https://regexr.com/59fst. To not match newlines, see the next
|
same as regexr https://regexr.com/59fst. To not match newlines, see the next
|
||||||
test with [^\s] *)
|
test with [^\s] *)
|
||||||
@ -208,7 +283,15 @@ foo(bar, baz(),
|
|||||||
let match_template = {|:[x~[^, ]+]|} in
|
let match_template = {|:[x~[^, ]+]|} in
|
||||||
let rewrite_template = {|(>:[x]<)|} in
|
let rewrite_template = {|(>:[x]<)|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|(>
|
||||||
|
foo(bar<), (>baz()<),(>
|
||||||
|
|
||||||
|
|
||||||
|
<) (>qux.derp)
|
||||||
|
<)|}];
|
||||||
|
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|(>
|
[%expect_exact {|(>
|
||||||
foo(bar<), (>baz()<),(>
|
foo(bar<), (>baz()<),(>
|
||||||
|
|
||||||
@ -216,6 +299,7 @@ foo(bar<), (>baz()<),(>
|
|||||||
<) (>qux.derp)
|
<) (>qux.derp)
|
||||||
<)|}]
|
<)|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "do_not_match_whitespace" =
|
let%expect_test "do_not_match_whitespace" =
|
||||||
let source = {|
|
let source = {|
|
||||||
foo(bar, baz(),
|
foo(bar, baz(),
|
||||||
@ -227,7 +311,15 @@ foo(bar, baz(),
|
|||||||
let match_template = {|:[x~[^,\s]+]|} in
|
let match_template = {|:[x~[^,\s]+]|} in
|
||||||
let rewrite_template = {|(>:[x]<)|} in
|
let rewrite_template = {|(>:[x]<)|} in
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
run (module Alpha.Generic) source match_template rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
(>foo(bar<), (>baz()<),
|
||||||
|
|
||||||
|
|
||||||
|
(>qux.derp)<)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega.Generic) source match_template rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
(>foo(bar<), (>baz()<),
|
(>foo(bar<), (>baz()<),
|
||||||
|
|
||||||
@ -235,6 +327,7 @@ foo(bar, baz(),
|
|||||||
(>qux.derp)<)
|
(>qux.derp)<)
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "eof_anchor" =
|
let%expect_test "eof_anchor" =
|
||||||
let source = {|
|
let source = {|
|
||||||
setScore(5)
|
setScore(5)
|
||||||
@ -261,7 +354,23 @@ setScore(4/3)
|
|||||||
in
|
in
|
||||||
let rewrite_template = "setScore( /*CHECK ME*/ :[1])" in
|
let rewrite_template = "setScore( /*CHECK ME*/ :[1])" in
|
||||||
|
|
||||||
run (module Generic) source match_template ~rule rewrite_template;
|
run (module Alpha.Generic) source match_template ~rule rewrite_template;
|
||||||
|
[%expect_exact {|
|
||||||
|
setScore(5)
|
||||||
|
setScore(6)
|
||||||
|
setScore( /*CHECK ME*/ 6.5)
|
||||||
|
setScore( /*CHECK ME*/ "")
|
||||||
|
setScore( /*CHECK ME*/ "hi")
|
||||||
|
setScore( /*CHECK ME*/ "hi" + "there")
|
||||||
|
setScore( /*CHECK ME*/ 'ho')
|
||||||
|
setScore( /*CHECK ME*/ x)
|
||||||
|
setScore( /*CHECK ME*/ null)
|
||||||
|
setScore( /*CHECK ME*/ 4/3.0)
|
||||||
|
setScore( /*CHECK ME*/ 4.0/3.0)
|
||||||
|
setScore( /*CHECK ME*/ 4/3)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega.Generic) source match_template ~rule rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
setScore(5)
|
setScore(5)
|
||||||
setScore(6)
|
setScore(6)
|
@ -1,286 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
open Matchers.Omega
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_simple" =
|
|
||||||
let source = {|foo|} in
|
|
||||||
let match_template = {|:[x~\w+]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(foo)|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_simple_posix" =
|
|
||||||
let source = {|foo|} in
|
|
||||||
let match_template = {|:[x~[[:alpha:]]]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(f)(o)(o)|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_substring" =
|
|
||||||
let source = {|foo()|} in
|
|
||||||
let match_template = {|:[x~o\w]()|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|f(oo)|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_empty_string_terminates" =
|
|
||||||
let source = {|foo()|} in
|
|
||||||
let match_template = {|:[x~|]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|()f()o()o()(())|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_repetition_takes_precedence" =
|
|
||||||
let source = {|foobar()|} in
|
|
||||||
(* this will _not_ match because bar is consumed by \w before we look ahead *)
|
|
||||||
let match_template = {|:[x~\w+]bar()|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|No matches.|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_negated_match" =
|
|
||||||
let source = {|(literally_anyting_except_close_paren?!@#$%^&*[])|} in
|
|
||||||
let match_template = {|(:[x~[^)]+])|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(literally_anyting_except_close_paren?!@#$%^&*[])|}];
|
|
||||||
|
|
||||||
let source = {|(arg1, arg2, arg3)|} in
|
|
||||||
let match_template = {|:[x~[^,() ]+]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|((arg1), (arg2), (arg3))|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_dot_star_ok_and_this_is_for_newline" =
|
|
||||||
let source = "foo()\nbar()" in
|
|
||||||
let match_template = {|:[x~.*]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(foo())()
|
|
||||||
(bar())|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional" =
|
|
||||||
let source = "nonovember no november no vember" in
|
|
||||||
let match_template = {|:[x~no(vember)?]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(no)(november) (no) (november) (no) vember|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional_spaces" =
|
|
||||||
let source = "nonovember no november no vember" in
|
|
||||||
let match_template = {|no :[x~(vember)?]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|nonovember ()november (vember)|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional_doesnt_work_outside_regex" =
|
|
||||||
let source = "no" in
|
|
||||||
let match_template = {|no:[x~(vember)?]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|()|}];
|
|
||||||
|
|
||||||
let source = "foo bar foobar" in
|
|
||||||
let match_template = {|:[x~\s*?]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|()f()o()o() ()b()a()r() ()f()o()o()b()a()r|}];
|
|
||||||
|
|
||||||
let source = "foo bar foobar" in
|
|
||||||
let match_template = {|:[x~\s*]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|()f()o()o( )()b()a()r( )()f()o()o()b()a()r|}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional_strip_no_from_november_outside_regex" =
|
|
||||||
let source = "nonovember no november no vember" in
|
|
||||||
let match_template = {|no:[x~(vember)?]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|()(vember) () (vember) () vember|}]
|
|
||||||
|
|
||||||
let%expect_test "regex_holes_optional_strip_no_from_november_inside_regex" =
|
|
||||||
let source = "nonovember no november no vember" in
|
|
||||||
let match_template = {|:[x~no(vember)?]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(no)(november) (no) (november) (no) vember|}]
|
|
||||||
|
|
||||||
let%expect_test "leading_spaces_beginning_line_anchor" =
|
|
||||||
let source = {|
|
|
||||||
a
|
|
||||||
b
|
|
||||||
c
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~^(\s+)]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|( )a( )b( )c
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "spaces_star" =
|
|
||||||
let source = {|
|
|
||||||
a
|
|
||||||
b
|
|
||||||
c
|
|
||||||
d
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~\s*]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
(* The <spaces><empty space>chars is how this behaves on https://regexr.com/59ft0 as well, see replace *)
|
|
||||||
[%expect_exact {|(
|
|
||||||
)()a(
|
|
||||||
)()b(
|
|
||||||
)()c(
|
|
||||||
)()d(
|
|
||||||
)|}]
|
|
||||||
|
|
||||||
let%expect_test "end_line_anchor" =
|
|
||||||
let source = {|
|
|
||||||
aaa bbb
|
|
||||||
aaa bbb ccc
|
|
||||||
ccc ddd
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~\w+ bbb$]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
(aaa bbb)aaa bbb ccc
|
|
||||||
ccc ddd
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "start_of_input_and_exact" =
|
|
||||||
let source = {|aaa bbb|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~^\w+ bbb$]|} in
|
|
||||||
let rewrite_template = {|(:[x])|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(aaa bbb)|}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "word_boundaries" =
|
|
||||||
let source = {|
|
|
||||||
foo(bar, baz(),
|
|
||||||
|
|
||||||
|
|
||||||
qux.derp)
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~\b\w+\b]|} in
|
|
||||||
let rewrite_template = {|(>:[x]<)|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
(>foo<)((>bar<), (>baz<)(),
|
|
||||||
|
|
||||||
|
|
||||||
(>qux<).(>derp<))
|
|
||||||
|}]
|
|
||||||
|
|
||||||
(* I previously assumed [^ ] would not match newlines, but it does, and is the
|
|
||||||
same as regexr https://regexr.com/59fst. To not match newlines, see the next
|
|
||||||
test with [^\s] *)
|
|
||||||
let%expect_test "do_not_match_space" =
|
|
||||||
let source = {|
|
|
||||||
foo(bar, baz(),
|
|
||||||
|
|
||||||
|
|
||||||
qux.derp)
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~[^, ]+]|} in
|
|
||||||
let rewrite_template = {|(>:[x]<)|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|(>
|
|
||||||
foo(bar<), (>baz()<),(>
|
|
||||||
|
|
||||||
|
|
||||||
<) (>qux.derp)
|
|
||||||
<)|}]
|
|
||||||
|
|
||||||
let%expect_test "do_not_match_whitespace" =
|
|
||||||
let source = {|
|
|
||||||
foo(bar, baz(),
|
|
||||||
|
|
||||||
|
|
||||||
qux.derp)
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|:[x~[^,\s]+]|} in
|
|
||||||
let rewrite_template = {|(>:[x]<)|} in
|
|
||||||
|
|
||||||
run (module Generic) source match_template rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
(>foo(bar<), (>baz()<),
|
|
||||||
|
|
||||||
|
|
||||||
(>qux.derp)<)
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "eof_anchor" =
|
|
||||||
let source = {|
|
|
||||||
setScore(5)
|
|
||||||
setScore(6)
|
|
||||||
setScore(6.5)
|
|
||||||
setScore("")
|
|
||||||
setScore("hi")
|
|
||||||
setScore("hi" + "there")
|
|
||||||
setScore('ho')
|
|
||||||
setScore(x)
|
|
||||||
setScore(null)
|
|
||||||
setScore(4/3.0)
|
|
||||||
setScore(4.0/3.0)
|
|
||||||
setScore(4/3)
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|setScore(:[1])|} in
|
|
||||||
let rule = {|
|
|
||||||
where match :[1] {
|
|
||||||
| ":[~^\\d+$]" -> false
|
|
||||||
| ":[_]" -> true
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let rewrite_template = "setScore( /*CHECK ME*/ :[1])" in
|
|
||||||
|
|
||||||
run (module Generic) source match_template ~rule rewrite_template;
|
|
||||||
[%expect_exact {|
|
|
||||||
setScore(5)
|
|
||||||
setScore(6)
|
|
||||||
setScore( /*CHECK ME*/ 6.5)
|
|
||||||
setScore( /*CHECK ME*/ "")
|
|
||||||
setScore( /*CHECK ME*/ "hi")
|
|
||||||
setScore( /*CHECK ME*/ "hi" + "there")
|
|
||||||
setScore( /*CHECK ME*/ 'ho')
|
|
||||||
setScore( /*CHECK ME*/ x)
|
|
||||||
setScore( /*CHECK ME*/ null)
|
|
||||||
setScore( /*CHECK ME*/ 4/3.0)
|
|
||||||
setScore( /*CHECK ME*/ 4.0/3.0)
|
|
||||||
setScore( /*CHECK ME*/ 4/3)
|
|
||||||
|}]
|
|
@ -1,21 +1,19 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Match
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
include Test_alpha
|
open Matchers
|
||||||
|
open Match
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
let all ?(configuration = configuration) template source =
|
||||||
C.all ~configuration ~template ~source ()
|
Alpha.C.all ~configuration ~template ~source ()
|
||||||
|
|
||||||
module Template_parser = Rewrite_template.Make(Matchers.Metasyntax.Default)
|
module Template_parser = Rewrite.Make(Metasyntax.Default)
|
||||||
|
|
||||||
let%expect_test "get_offsets_for_holes" =
|
let%expect_test "get_offsets_for_holes" =
|
||||||
let rewrite_template = {|1234:[1]1234:[2]|} in
|
let rewrite_template = {|1234:[1]1234:[2]|} in
|
||||||
let variables = Template_parser.variables rewrite_template in
|
let variables = Template_parser.variables rewrite_template in
|
||||||
let offsets = Rewrite_template.get_offsets_for_holes variables rewrite_template in
|
let offsets = Rewrite.get_offsets_for_holes variables rewrite_template in
|
||||||
print_s [%message (offsets : (string * int) list)];
|
print_s [%message (offsets : (string * int) list)];
|
||||||
[%expect_exact {|(offsets ((2 8) (1 4)))
|
[%expect_exact {|(offsets ((2 8) (1 4)))
|
||||||
|}]
|
|}]
|
||||||
@ -23,13 +21,13 @@ let%expect_test "get_offsets_for_holes" =
|
|||||||
let%expect_test "get_offsets_for_holes_after_substitution_1" =
|
let%expect_test "get_offsets_for_holes_after_substitution_1" =
|
||||||
let rewrite_template = {|1234:[1]1234:[2]|} in
|
let rewrite_template = {|1234:[1]1234:[2]|} in
|
||||||
let variables = Template_parser.variables rewrite_template in
|
let variables = Template_parser.variables rewrite_template in
|
||||||
let offsets = Rewrite_template.get_offsets_for_holes variables rewrite_template in
|
let offsets = Rewrite.get_offsets_for_holes variables rewrite_template in
|
||||||
let environment =
|
let environment =
|
||||||
Environment.create ()
|
Environment.create ()
|
||||||
|> (fun environment -> Environment.add environment "1" "333")
|
|> (fun environment -> Environment.add environment "1" "333")
|
||||||
|> (fun environment -> Environment.add environment "2" "22")
|
|> (fun environment -> Environment.add environment "2" "22")
|
||||||
in
|
in
|
||||||
let result = Rewrite_template.get_offsets_after_substitution offsets environment in
|
let result = Rewrite.get_offsets_after_substitution offsets environment in
|
||||||
print_s [%message (result : (string * int) list)];
|
print_s [%message (result : (string * int) list)];
|
||||||
[%expect_exact {|(result ((2 11) (1 4)))
|
[%expect_exact {|(result ((2 11) (1 4)))
|
||||||
|}]
|
|}]
|
||||||
@ -37,14 +35,14 @@ let%expect_test "get_offsets_for_holes_after_substitution_1" =
|
|||||||
let%expect_test "get_offsets_for_holes_after_substitution_1" =
|
let%expect_test "get_offsets_for_holes_after_substitution_1" =
|
||||||
let rewrite_template = {|1234:[1]1234:[3]11:[2]|} in
|
let rewrite_template = {|1234:[1]1234:[3]11:[2]|} in
|
||||||
let variables = Template_parser.variables rewrite_template in
|
let variables = Template_parser.variables rewrite_template in
|
||||||
let offsets = Rewrite_template.get_offsets_for_holes variables rewrite_template in
|
let offsets = Rewrite.get_offsets_for_holes variables rewrite_template in
|
||||||
let environment =
|
let environment =
|
||||||
Environment.create ()
|
Environment.create ()
|
||||||
|> (fun environment -> Environment.add environment "1" "333")
|
|> (fun environment -> Environment.add environment "1" "333")
|
||||||
|> (fun environment -> Environment.add environment "3" "333")
|
|> (fun environment -> Environment.add environment "3" "333")
|
||||||
|> (fun environment -> Environment.add environment "2" "22")
|
|> (fun environment -> Environment.add environment "2" "22")
|
||||||
in
|
in
|
||||||
let result = Rewrite_template.get_offsets_after_substitution offsets environment in
|
let result = Rewrite.get_offsets_after_substitution offsets environment in
|
||||||
print_s [%message (result : (string * int) list)];
|
print_s [%message (result : (string * int) list)];
|
||||||
[%expect_exact {|(result ((2 16) (3 11) (1 4)))
|
[%expect_exact {|(result ((2 16) (3 11) (1 4)))
|
||||||
|}]
|
|}]
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Match
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
include Test_alpha
|
let run_rule (module E : Engine.S) source match_template rewrite_template rule =
|
||||||
|
let (module M : Matcher.S) = (module E.Generic) in
|
||||||
let run_rule source match_template rewrite_template rule =
|
M.first ~configuration match_template source
|
||||||
Generic.first ~configuration match_template source
|
|
||||||
|> function
|
|> function
|
||||||
| Error _ -> print_string "bad"
|
| Error _ -> print_string "bad"
|
||||||
| Ok result ->
|
| Ok result ->
|
||||||
match result with
|
match result with
|
||||||
| ({ environment; _ } as m) ->
|
| ({ environment; _ } as m) ->
|
||||||
let e = Rule.(result_env @@ apply rule environment) in
|
let e = Rule.(result_env @@ apply ~match_all:(M.all ~rule:[Ast.True] ~nested:false) rule environment) in
|
||||||
match e with
|
match e with
|
||||||
| None -> print_string "bad bad"
|
| None -> print_string "bad bad"
|
||||||
| Some e ->
|
| Some e ->
|
||||||
@ -34,11 +32,14 @@ let%expect_test "rewrite_rule" =
|
|||||||
{|
|
{|
|
||||||
where rewrite :[1] { "int" -> "expect" }
|
where rewrite :[1] { "int" -> "expect" }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
run_rule (module Alpha) source match_template rewrite_template rule;
|
||||||
|
[%expect_exact {|expect|}];
|
||||||
|
|
||||||
|
run_rule (module Omega) source match_template rewrite_template rule;
|
||||||
[%expect_exact {|expect|}]
|
[%expect_exact {|expect|}]
|
||||||
|
|
||||||
let%expect_test "sequenced_rewrite_rule" =
|
let%expect_test "sequenced_rewrite_rule" =
|
||||||
@ -52,11 +53,14 @@ let%expect_test "sequenced_rewrite_rule" =
|
|||||||
rewrite :[a] { "a" -> "qqq" },
|
rewrite :[a] { "a" -> "qqq" },
|
||||||
rewrite :[rest] { "{ b : { :[other] } }" -> "{ :[other] }" }
|
rewrite :[rest] { "{ b : { :[other] } }" -> "{ :[other] }" }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
run_rule (module Alpha) source match_template rewrite_template rule;
|
||||||
|
[%expect_exact {|{ { qqq : { c : d } } }|}];
|
||||||
|
|
||||||
|
run_rule (module Omega) source match_template rewrite_template rule;
|
||||||
[%expect_exact {|{ { qqq : { c : d } } }|}]
|
[%expect_exact {|{ { qqq : { c : d } } }|}]
|
||||||
|
|
||||||
let%expect_test "rewrite_rule_for_list" =
|
let%expect_test "rewrite_rule_for_list" =
|
||||||
@ -68,11 +72,14 @@ let%expect_test "rewrite_rule_for_list" =
|
|||||||
{|
|
{|
|
||||||
where rewrite :[contents] { ":[[x]]," -> ":[[x]];" }
|
where rewrite :[contents] { ":[[x]]," -> ":[[x]];" }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
run_rule (module Alpha) source match_template rewrite_template rule;
|
||||||
|
[%expect_exact {|[1; 2; 3; 4;]|}];
|
||||||
|
|
||||||
|
run_rule (module Omega) source match_template rewrite_template rule;
|
||||||
[%expect_exact {|[1; 2; 3; 4;]|}]
|
[%expect_exact {|[1; 2; 3; 4;]|}]
|
||||||
|
|
||||||
let%expect_test "rewrite_rule_for_list_strip_last" =
|
let%expect_test "rewrite_rule_for_list_strip_last" =
|
||||||
@ -84,11 +91,14 @@ let%expect_test "rewrite_rule_for_list_strip_last" =
|
|||||||
{|
|
{|
|
||||||
where rewrite :[contents] { ":[x], " -> ":[x]; " }
|
where rewrite :[contents] { ":[x], " -> ":[x]; " }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
run_rule (module Alpha) source match_template rewrite_template rule;
|
||||||
|
[%expect_exact {|[1; 2; 3; 4]|}];
|
||||||
|
|
||||||
|
run_rule (module Omega) source match_template rewrite_template rule;
|
||||||
[%expect_exact {|[1; 2; 3; 4]|}]
|
[%expect_exact {|[1; 2; 3; 4]|}]
|
||||||
|
|
||||||
let%expect_test "haskell_example" =
|
let%expect_test "haskell_example" =
|
||||||
@ -105,17 +115,25 @@ let%expect_test "haskell_example" =
|
|||||||
{|
|
{|
|
||||||
where rewrite :[contents] { "," -> "++" }
|
where rewrite :[contents] { "," -> "++" }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
run_rule (module Alpha) source match_template rewrite_template rule;
|
||||||
|
[%expect_exact {|
|
||||||
|
( "blah blah blah"
|
||||||
|
++ "blah"
|
||||||
|
)
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run_rule (module Omega) source match_template rewrite_template rule;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
( "blah blah blah"
|
( "blah blah blah"
|
||||||
++ "blah"
|
++ "blah"
|
||||||
)
|
)
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "rewrite_freeform_antecedent_pattern" =
|
let%expect_test "rewrite_freeform_antecedent_pattern" =
|
||||||
let source = {|
|
let source = {|
|
||||||
(concat
|
(concat
|
||||||
@ -129,11 +147,16 @@ let%expect_test "rewrite_freeform_antecedent_pattern" =
|
|||||||
{|
|
{|
|
||||||
where rewrite :[contents] { concat [:[x]] -> "nice" }
|
where rewrite :[contents] { concat [:[x]] -> "nice" }
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
run_rule (module Alpha) source match_template rewrite_template rule;
|
||||||
|
[%expect_exact {|(
|
||||||
|
(nice)
|
||||||
|
)|}];
|
||||||
|
|
||||||
|
run_rule (module Omega) source match_template rewrite_template rule;
|
||||||
[%expect_exact {|(
|
[%expect_exact {|(
|
||||||
(nice)
|
(nice)
|
||||||
)|}]
|
)|}]
|
@ -1,139 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Match
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let run_rule source match_template rewrite_template rule =
|
|
||||||
Generic.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Error _ -> print_string "bad"
|
|
||||||
| Ok result ->
|
|
||||||
match result with
|
|
||||||
| ({ environment; _ } as m) ->
|
|
||||||
let e = Rule.(result_env @@ apply rule environment) in
|
|
||||||
match e with
|
|
||||||
| None -> print_string "bad bad"
|
|
||||||
| Some e ->
|
|
||||||
{ m with environment = e }
|
|
||||||
|> List.return
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
|
|
||||||
let%expect_test "rewrite_rule" =
|
|
||||||
let source = {|int|} in
|
|
||||||
let match_template = {|:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where rewrite :[1] { "int" -> "expect" }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
|
||||||
[%expect_exact {|expect|}]
|
|
||||||
|
|
||||||
let%expect_test "sequenced_rewrite_rule" =
|
|
||||||
let source = {|{ { a : { b : { c : d } } } }|} in
|
|
||||||
let match_template = {|{ :[a] : :[rest] }|} in
|
|
||||||
let rewrite_template = {|{ :[a] : :[rest] }|} in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where
|
|
||||||
rewrite :[a] { "a" -> "qqq" },
|
|
||||||
rewrite :[rest] { "{ b : { :[other] } }" -> "{ :[other] }" }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
|
||||||
[%expect_exact {|{ { qqq : { c : d } } }|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_rule_for_list" =
|
|
||||||
let source = {|[1, 2, 3, 4,]|} in
|
|
||||||
let match_template = {|[:[contents]]|} in
|
|
||||||
let rewrite_template = {|[:[contents]]|} in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where rewrite :[contents] { ":[[x]]," -> ":[[x]];" }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
|
||||||
[%expect_exact {|[1; 2; 3; 4;]|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_rule_for_list_strip_last" =
|
|
||||||
let source = {|[1, 2, 3, 4]|} in
|
|
||||||
let match_template = {|[:[contents]]|} in
|
|
||||||
let rewrite_template = {|[:[contents]]|} in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where rewrite :[contents] { ":[x], " -> ":[x]; " }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
|
||||||
[%expect_exact {|[1; 2; 3; 4]|}]
|
|
||||||
|
|
||||||
let%expect_test "haskell_example" =
|
|
||||||
let source = {|
|
|
||||||
(concat
|
|
||||||
[ "blah blah blah"
|
|
||||||
, "blah"
|
|
||||||
])
|
|
||||||
|} in
|
|
||||||
let match_template = {|(concat [:[contents]])|} in
|
|
||||||
let rewrite_template = {|(:[contents])|} in
|
|
||||||
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where rewrite :[contents] { "," -> "++" }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
|
||||||
[%expect_exact {|
|
|
||||||
( "blah blah blah"
|
|
||||||
++ "blah"
|
|
||||||
)
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_freeform_antecedent_pattern" =
|
|
||||||
let source = {|
|
|
||||||
(concat
|
|
||||||
[ "blah blah blah"
|
|
||||||
, "blah"
|
|
||||||
])
|
|
||||||
|} in
|
|
||||||
let match_template = {|:[contents]|} in
|
|
||||||
let rewrite_template = {|(:[contents])|} in
|
|
||||||
let rule =
|
|
||||||
{|
|
|
||||||
where rewrite :[contents] { concat [:[x]] -> "nice" }
|
|
||||||
|}
|
|
||||||
|> Language.Rule.create
|
|
||||||
|> Or_error.ok_exn
|
|
||||||
in
|
|
||||||
|
|
||||||
run_rule source match_template rewrite_template rule;
|
|
||||||
[%expect_exact {|(
|
|
||||||
(nice)
|
|
||||||
)|}]
|
|
@ -1,7 +1,9 @@
|
|||||||
|
open Matchers
|
||||||
|
|
||||||
let run input =
|
let run input =
|
||||||
let result =
|
let result =
|
||||||
match Language.Script.parse input with
|
match Script.parse input with
|
||||||
| Ok result -> Language.Script.to_string result
|
| Ok result -> Script.to_string result
|
||||||
| Error _ -> "ERROR"
|
| Error _ -> "ERROR"
|
||||||
in
|
in
|
||||||
print_string result
|
print_string result
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Match
|
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
open Comby_kernel
|
||||||
include Test_alpha
|
open Matchers
|
||||||
|
open Match
|
||||||
|
|
||||||
let %expect_test "statistics" =
|
let %expect_test "statistics" =
|
||||||
let template =
|
let template =
|
||||||
@ -28,12 +27,12 @@ let %expect_test "statistics" =
|
|||||||
let rule =
|
let rule =
|
||||||
{| where true
|
{| where true
|
||||||
|}
|
|}
|
||||||
|> Language.Rule.create
|
|> Rule.create
|
||||||
|> Or_error.ok_exn
|
|> Or_error.ok_exn
|
||||||
in
|
in
|
||||||
Go.all ~configuration ~template ~source ()
|
Alpha.Go.all ~configuration ~template ~source ()
|
||||||
|> List.filter ~f:(fun { environment; _ } ->
|
|> List.filter ~f:(fun { environment; _ } ->
|
||||||
Rule.(sat @@ apply rule environment))
|
Rule.(sat @@ apply ~match_all:(Alpha.Generic.all ~rule:[Ast.True] ~nested:false) rule environment))
|
||||||
|> fun matches ->
|
|> fun matches ->
|
||||||
let statistics =
|
let statistics =
|
||||||
Statistics.
|
Statistics.
|
||||||
|
@ -1,41 +1,78 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Rewriter
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
|
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
|
||||||
include Test_alpha
|
let all ?(configuration = configuration) (module M : Matchers.Matcher.S) template source =
|
||||||
|
M.all ~configuration ~template ~source ()
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
let rewrite_all engine template source rewrite_template =
|
||||||
C.all ~configuration ~template ~source ()
|
all engine template source
|
||||||
|
|> Rewrite.all ~source ~rewrite_template
|
||||||
|
|> (function
|
||||||
|
| Some { rewritten_source; _ } -> print_string rewritten_source
|
||||||
|
| None -> print_string "BROKEN EXPECT")
|
||||||
|
|
||||||
|
let rewrite_all_want_fail_case engine template source rewrite_template =
|
||||||
|
all engine ~configuration template source
|
||||||
|
|> Rewrite.all ~source ~rewrite_template
|
||||||
|
|> (function
|
||||||
|
| Some { rewritten_source; _ } -> print_string rewritten_source
|
||||||
|
| None -> print_string "EXPECT SUCCESS")
|
||||||
|
|
||||||
|
let rewrite_all' engine template source rewrite_template =
|
||||||
|
all engine template source
|
||||||
|
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
||||||
|
|> (fun { rewritten_source; _ } -> rewritten_source)
|
||||||
|
|> print_string
|
||||||
|
|
||||||
|
let head_match (module M : Matchers.Matcher.S) template source =
|
||||||
|
M.all ~configuration ~template ~source ()
|
||||||
|
|> function
|
||||||
|
| [] -> print_string "No matches."
|
||||||
|
| hd :: _ ->
|
||||||
|
print_string hd.matched
|
||||||
|
|
||||||
let%expect_test "comments_in_string_literals_should_not_be_treated_as_comments_by_fuzzy" =
|
let%expect_test "comments_in_string_literals_should_not_be_treated_as_comments_by_fuzzy" =
|
||||||
let source = {|"/*"(x)|} in
|
let source = {|"/*"(x)|} in
|
||||||
let template = {|(:[1])|} in
|
let template = {|(:[1])|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all template source
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all (module Alpha.C) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|"/*"x|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all (module Omega.C) template source rewrite_template;
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|"/*"x|}]
|
[%expect_exact {|"/*"x|}]
|
||||||
|
|
||||||
let%expect_test "comments_in_string_literals_should_not_be_treated_as_comments_by_fuzzy_go_raw" =
|
let%expect_test "comments_in_string_literals_should_not_be_treated_as_comments_by_fuzzy_go_raw" =
|
||||||
let source = {|`//`(x)|} in
|
let source = {|`//`(x)|} in
|
||||||
let template = {|(:[1])|} in
|
let template = {|(:[1])|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all (module Alpha.Go) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|`//`x|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all (module Omega.Go) template source rewrite_template;
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|`//`x|}]
|
[%expect_exact {|`//`x|}]
|
||||||
|
|
||||||
let%expect_test "tolerate_unbalanced_stuff_in_string_literals" =
|
let%expect_test "tolerate_unbalanced_stuff_in_string_literals" =
|
||||||
let template = {|"("|} in
|
let template = {|"("|} in
|
||||||
let source = {|"("|} in
|
let source = {|"("|} in
|
||||||
let matches = all ~configuration template source in
|
|
||||||
print_matches matches;
|
all (module Alpha.C) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
|
[%expect_exact {|[
|
||||||
|
{
|
||||||
|
"range": {
|
||||||
|
"start": { "offset": 0, "line": 1, "column": 1 },
|
||||||
|
"end": { "offset": 3, "line": 1, "column": 4 }
|
||||||
|
},
|
||||||
|
"environment": [],
|
||||||
|
"matched": "\"(\""
|
||||||
|
}
|
||||||
|
]|}];
|
||||||
|
all (module Omega.C) ~configuration template source
|
||||||
|
|> print_matches;
|
||||||
[%expect_exact {|[
|
[%expect_exact {|[
|
||||||
{
|
{
|
||||||
"range": {
|
"range": {
|
||||||
@ -47,116 +84,127 @@ let%expect_test "tolerate_unbalanced_stuff_in_string_literals" =
|
|||||||
}
|
}
|
||||||
]|}]
|
]|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
let%expect_test "base_literal_matching" =
|
||||||
let source = {|"hello"|} in
|
let source = {|"hello"|} in
|
||||||
let match_template = {|":[1]"|} in
|
let match_template = {|":[1]"|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|hello|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|hello|}]
|
[%expect_exact {|hello|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
let%expect_test "base_literal_matching" =
|
||||||
let source = {|rewrite ("hello") this string|} in
|
let source = {|rewrite ("hello") this string|} in
|
||||||
let match_template = {|rewrite (":[1]") this string|} in
|
let match_template = {|rewrite (":[1]") this string|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|hello|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|hello|}]
|
[%expect_exact {|hello|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
let%expect_test "match_string_literals" =
|
||||||
let source = {|rewrite (".") this string|} in
|
let source = {|rewrite (".") this string|} in
|
||||||
let match_template = {|rewrite (":[1]") this string|} in
|
let match_template = {|rewrite (":[1]") this string|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|.|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|.|}]
|
[%expect_exact {|.|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
let%expect_test "match_string_literals" =
|
||||||
let source = {|rewrite ("") this string|} in
|
let source = {|rewrite ("") this string|} in
|
||||||
let match_template = {|rewrite (":[1]") this string|} in
|
let match_template = {|rewrite (":[1]") this string|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {||}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {||}]
|
[%expect_exact {||}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
let%expect_test "match_string_literals" =
|
||||||
let source = {|"(" match "a""a" this "(" |} in
|
let source = {|"(" match "a""a" this "(" |} in
|
||||||
let match_template = {|match :[1] this|} in
|
let match_template = {|match :[1] this|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|"(" "a""a" "(" |}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|"(" "a""a" "(" |}]
|
[%expect_exact {|"(" "a""a" "(" |}]
|
||||||
|
|
||||||
|
|
||||||
(* this tests special functionality in non-literal hole parser
|
(* this tests special functionality in non-literal hole parser
|
||||||
but which must still ignore unbalanced delims within strings *)
|
but which must still ignore unbalanced delims within strings *)
|
||||||
let%expect_test "match_string_literals" =
|
let%expect_test "match_string_literals" =
|
||||||
let source = {|"(" match "(""(" this "(" |} in
|
let source = {|"(" match "(""(" this "(" |} in
|
||||||
let match_template = {|match :[1] this|} in
|
let match_template = {|match :[1] this|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|"(" "(""(" "(" |}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|"(" "(""(" "(" |}]
|
[%expect_exact {|"(" "(""(" "(" |}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
let%expect_test "match_string_literals" =
|
||||||
let source = {|rewrite ("") this string|} in
|
let source = {|rewrite ("") this string|} in
|
||||||
let match_template = {|rewrite (:[1]) this string|} in
|
let match_template = {|rewrite (:[1]) this string|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|""|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|""|}]
|
[%expect_exact {|""|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
let%expect_test "base_literal_matching" =
|
||||||
let source = {|"("|} in
|
let source = {|"("|} in
|
||||||
let match_template = {|":[1]"|} in
|
let match_template = {|":[1]"|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|(|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|(|}]
|
[%expect_exact {|(|}]
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|"(""("|} in
|
|
||||||
let match_template = {|":[1]"|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|((|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
let%expect_test "base_literal_matching" =
|
||||||
let source = {|"(""("|} in
|
let source = {|"(""("|} in
|
||||||
let match_template = {|":[1]"|} in
|
let match_template = {|":[1]"|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|((|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|((|}]
|
[%expect_exact {|((|}]
|
||||||
|
|
||||||
|
|
||||||
|
let%expect_test "base_literal_matching" =
|
||||||
|
let source = {|"(""("|} in
|
||||||
|
let match_template = {|":[1]"|} in
|
||||||
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|
[%expect_exact {|((|}];
|
||||||
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|
[%expect_exact {|((|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
let%expect_test "base_literal_matching" =
|
||||||
let source = {|"hello world"|} in
|
let source = {|"hello world"|} in
|
||||||
let match_template = {|":[x] :[y]"|} in
|
let match_template = {|":[x] :[y]"|} in
|
||||||
let rewrite_template = {|:[x] :[y]|} in
|
let rewrite_template = {|:[x] :[y]|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|hello world|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|hello world|}]
|
[%expect_exact {|hello world|}]
|
||||||
|
|
||||||
(* complex test: basically, we are checking that the inside of this literal is only matched by the val b part *)
|
(* complex test: basically, we are checking that the inside of this literal is only matched by the val b part *)
|
||||||
@ -164,75 +212,76 @@ let%expect_test "base_literal_matching" =
|
|||||||
let source = {|val a = "class = ${String::class}" val b = "not $a"|} in
|
let source = {|val a = "class = ${String::class}" val b = "not $a"|} in
|
||||||
let match_template = {|":[x]$:[[y]]"|} in
|
let match_template = {|":[x]$:[[y]]"|} in
|
||||||
let rewrite_template = {|(rewritten part: (:[x]) ([y]))|} in
|
let rewrite_template = {|(rewritten part: (:[x]) ([y]))|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|val a = "class = ${String::class}" val b = (rewritten part: (not ) ([y]))|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|val a = "class = ${String::class}" val b = (rewritten part: (not ) ([y]))|}]
|
[%expect_exact {|val a = "class = ${String::class}" val b = (rewritten part: (not ) ([y]))|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
let%expect_test "base_literal_matching" =
|
||||||
let source = {|get("type") rekt ("enabled", True)|} in
|
let source = {|get("type") rekt ("enabled", True)|} in
|
||||||
let match_template = {|(":[1]", :[[3]])|} in
|
let match_template = {|(":[1]", :[[3]])|} in
|
||||||
let rewrite_template = {|(rewritten part: (:[1]) (:[3]))|} in
|
let rewrite_template = {|(rewritten part: (:[1]) (:[3]))|} in
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|get("type") rekt (rewritten part: (enabled) (True))|}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
[%expect_exact {|get("type") rekt (rewritten part: (enabled) (True))|}]
|
[%expect_exact {|get("type") rekt (rewritten part: (enabled) (True))|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
let source = {|match "\"" this|} in
|
let source = {|match "\"" this|} in
|
||||||
let match_template = {|match "\"" this|} in
|
let match_template = {|match "\"" this|} in
|
||||||
let rewrite_template = "" in
|
let rewrite_template = "" in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {||}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {||}]
|
[%expect_exact {||}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
let source = {|match "\"" this|} in
|
let source = {|match "\"" this|} in
|
||||||
let match_template = {|match :[1] this|} in
|
let match_template = {|match :[1] this|} in
|
||||||
let rewrite_template = ":[1]" in
|
let rewrite_template = ":[1]" in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|"\""|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"\""|}]
|
[%expect_exact {|"\""|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
let source = {|match "\"\"" this|} in
|
let source = {|match "\"\"" this|} in
|
||||||
let match_template = {|match :[1] this|} in
|
let match_template = {|match :[1] this|} in
|
||||||
let rewrite_template = ":[1]" in
|
let rewrite_template = ":[1]" in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|"\"\""|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"\"\""|}]
|
[%expect_exact {|"\"\""|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
let source = {|match "\"(\"" "(\"" this|} in
|
let source = {|match "\"(\"" "(\"" this|} in
|
||||||
let match_template = {|match :[1] this|} in
|
let match_template = {|match :[1] this|} in
|
||||||
let rewrite_template = ":[1]" in
|
let rewrite_template = ":[1]" in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|"\"(\"" "(\""|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"\"(\"" "(\""|}]
|
[%expect_exact {|"\"(\"" "(\""|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
let source = {|match "\"(\"" "(\"" this|} in
|
let source = {|match "\"(\"" "(\"" this|} in
|
||||||
let match_template = {|match ":[1]" ":[2]" this|} in
|
let match_template = {|match ":[1]" ":[2]" this|} in
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
let rewrite_template = {|:[1] :[2]|} in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|\"(\" (\"|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|\"(\" (\"|}]
|
[%expect_exact {|\"(\" (\"|}]
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
@ -240,10 +289,9 @@ let%expect_test "rewrite_string_literals_8" =
|
|||||||
let match_template = {|:[1]|} in
|
let match_template = {|:[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|match 'sin(gle' 'quo(tes' this|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match 'sin(gle' 'quo(tes' this|}]
|
[%expect_exact {|match 'sin(gle' 'quo(tes' this|}]
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
@ -251,10 +299,9 @@ let%expect_test "rewrite_string_literals_8" =
|
|||||||
let match_template = {|:[1]|} in
|
let match_template = {|:[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|match '\''|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match '\''|}]
|
[%expect_exact {|match '\''|}]
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
@ -262,10 +309,9 @@ let%expect_test "rewrite_string_literals_8" =
|
|||||||
let match_template = {|':[1]'|} in
|
let match_template = {|':[1]'|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|match asdf|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match asdf|}]
|
[%expect_exact {|match asdf|}]
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
let%expect_test "rewrite_string_literals_8" =
|
||||||
@ -273,10 +319,9 @@ let%expect_test "rewrite_string_literals_8" =
|
|||||||
let match_template = {|':[1]'|} in
|
let match_template = {|':[1]'|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
all match_template source
|
rewrite_all' (module Alpha.C) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|match \'|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.C) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match \'|}]
|
[%expect_exact {|match \'|}]
|
||||||
|
|
||||||
|
|
||||||
@ -293,10 +338,17 @@ let%expect_test "go_raw_string_literals" =
|
|||||||
let match_template = {|`:[1]`|} in
|
let match_template = {|`:[1]`|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
Go.all ~configuration ~source ~template:match_template ()
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.Go) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|
|
||||||
|> print_string;
|
x = x
|
||||||
|
y = multi-line
|
||||||
|
raw str(ing literal
|
||||||
|
z = other multi-line
|
||||||
|
raw stri(ng literal
|
||||||
|
|}];
|
||||||
|
|
||||||
|
rewrite_all' (module Omega.Go) match_template source rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
x = x
|
x = x
|
||||||
y = multi-line
|
y = multi-line
|
||||||
@ -305,25 +357,25 @@ let%expect_test "go_raw_string_literals" =
|
|||||||
raw stri(ng literal
|
raw stri(ng literal
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "go_raw_string_literals" =
|
let%expect_test "go_raw_string_literals" =
|
||||||
let source = {|blah `(` quux|} in
|
let source = {|blah `(` quux|} in
|
||||||
let match_template = {|:[1]|} in
|
let match_template = {|:[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
Go.all ~configuration ~source ~template:match_template ()
|
rewrite_all' (module Alpha.Go) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|blah `(` quux|}];
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
rewrite_all' (module Omega.Go) match_template source rewrite_template;
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|blah `(` quux|}]
|
[%expect_exact {|blah `(` quux|}]
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
let%expect_test "match_string_literals" =
|
||||||
let source = {|`(` match `(``(` this `(` |} in
|
let source = {|`(` match `(``(` this `(` |} in
|
||||||
let match_template = {|match :[1] this|} in
|
let match_template = {|match :[1] this|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
rewrite_all' (module Alpha.Go) match_template source rewrite_template;
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
[%expect_exact {|`(` `(``(` `(` |}];
|
||||||
|> print_string;
|
rewrite_all' (module Omega.Go) match_template source rewrite_template;
|
||||||
[%expect_exact {|`(` `(``(` `(` |}]
|
[%expect_exact {|`(` `(``(` `(` |}]
|
||||||
|
|
||||||
|
|
||||||
@ -340,10 +392,16 @@ let%expect_test "go_raw_string_literals" =
|
|||||||
let match_template = {|`:[1]`|} in
|
let match_template = {|`:[1]`|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
|
|
||||||
Go.all ~configuration ~source ~template:match_template ()
|
rewrite_all' (module Alpha.Go) match_template source rewrite_template;
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
[%expect_exact {|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
x = x
|
||||||
|> print_string;
|
y = multi-line
|
||||||
|
raw "str"(ing literal
|
||||||
|
z = other multi-line
|
||||||
|
raw '"'\"\\s\\\\\tr\ni(ng literal
|
||||||
|
|}];
|
||||||
|
|
||||||
|
rewrite_all' (module Omega.Go) match_template source rewrite_template;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
x = x
|
x = x
|
||||||
y = multi-line
|
y = multi-line
|
||||||
@ -352,15 +410,15 @@ let%expect_test "go_raw_string_literals" =
|
|||||||
raw '"'\"\\s\\\\\tr\ni(ng literal
|
raw '"'\"\\s\\\\\tr\ni(ng literal
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "regression_matching_kubernetes" =
|
let%expect_test "regression_matching_kubernetes" =
|
||||||
let source = {|"\n" y = 5|} in
|
let source = {|"\n" y = 5|} in
|
||||||
let template = {|y = :[1]|} in
|
let template = {|y = :[1]|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all (module Alpha.Go) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|"\n" 5|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all (module Omega.Go) template source rewrite_template;
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|"\n" 5|}]
|
[%expect_exact {|"\n" 5|}]
|
||||||
|
|
||||||
|
|
||||||
@ -368,33 +426,30 @@ let%expect_test "match_escaped_any_char" =
|
|||||||
let source = {|printf("hello world\n");|} in
|
let source = {|printf("hello world\n");|} in
|
||||||
let template = {|printf(":[1]");|} in
|
let template = {|printf(":[1]");|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all (module Alpha.Go) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|hello world\n|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all (module Omega.Go) template source rewrite_template;
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|hello world\n|}]
|
[%expect_exact {|hello world\n|}]
|
||||||
|
|
||||||
let%expect_test "match_escaped_escaped" =
|
let%expect_test "match_escaped_escaped" =
|
||||||
let source = {|printf("hello world\n\\");|} in
|
let source = {|printf("hello world\n\\");|} in
|
||||||
let template = {|printf(":[1]");|} in
|
let template = {|printf(":[1]");|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all (module Alpha.Go) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|hello world\n\\|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all (module Omega.Go) template source rewrite_template;
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|hello world\n\\|}]
|
[%expect_exact {|hello world\n\\|}]
|
||||||
|
|
||||||
let%expect_test "match_escaped_escaped" =
|
let%expect_test "match_escaped_escaped" =
|
||||||
let source = {|printf("hello world\n\");|} in
|
let source = {|printf("hello world\n\");|} in
|
||||||
let template = {|printf(":[1]");|} in
|
let template = {|printf(":[1]");|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all_want_fail_case (module Alpha.Go) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|EXPECT SUCCESS|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all_want_fail_case (module Omega.Go) template source rewrite_template;
|
||||||
| None -> print_string "EXPECT SUCCESS");
|
|
||||||
[%expect_exact {|EXPECT SUCCESS|}]
|
[%expect_exact {|EXPECT SUCCESS|}]
|
||||||
|
|
||||||
let%expect_test "holes_in_raw_literals" =
|
let%expect_test "holes_in_raw_literals" =
|
||||||
@ -416,13 +471,17 @@ let%expect_test "holes_in_raw_literals" =
|
|||||||
)
|
)
|
||||||
|} in
|
|} in
|
||||||
let template = {|`:[1]`|} in
|
let template = {|`:[1]`|} in
|
||||||
begin
|
|
||||||
Typescript.all ~configuration ~template ~source ()
|
head_match (module Alpha.Typescript) template source;
|
||||||
|> function
|
[%expect_exact {|`
|
||||||
| [] -> print_string "No matches."
|
query ResolveRepo($repoName: String!) {
|
||||||
| hd :: _ ->
|
repository(name: $repoName) {
|
||||||
print_string hd.matched
|
url
|
||||||
end;
|
}
|
||||||
|
}
|
||||||
|
`|}];
|
||||||
|
|
||||||
|
head_match (module Omega.Typescript) template source;
|
||||||
[%expect_exact {|`
|
[%expect_exact {|`
|
||||||
query ResolveRepo($repoName: String!) {
|
query ResolveRepo($repoName: String!) {
|
||||||
repository(name: $repoName) {
|
repository(name: $repoName) {
|
||||||
@ -431,6 +490,7 @@ let%expect_test "holes_in_raw_literals" =
|
|||||||
}
|
}
|
||||||
`|}]
|
`|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "holes_in_raw_literals_partial" =
|
let%expect_test "holes_in_raw_literals_partial" =
|
||||||
let source = {|
|
let source = {|
|
||||||
return expect(
|
return expect(
|
||||||
@ -450,13 +510,19 @@ let%expect_test "holes_in_raw_literals_partial" =
|
|||||||
)
|
)
|
||||||
|} in
|
|} in
|
||||||
let template = {|` query ResolveRepo(:[1]) {:[2]} `|} in
|
let template = {|` query ResolveRepo(:[1]) {:[2]} `|} in
|
||||||
begin
|
|
||||||
Typescript.all ~configuration ~template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
head_match (module Alpha.Typescript) template source;
|
||||||
| hd :: _ ->
|
[%expect_exact {|`
|
||||||
print_string hd.matched
|
query ResolveRepo($repoName: String!) {
|
||||||
end;
|
repository(name: $repoName) {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`|}];
|
||||||
|
|
||||||
|
head_match (module Omega.Typescript) template source;
|
||||||
[%expect_exact {|`
|
[%expect_exact {|`
|
||||||
query ResolveRepo($repoName: String!) {
|
query ResolveRepo($repoName: String!) {
|
||||||
repository(name: $repoName) {
|
repository(name: $repoName) {
|
||||||
@ -465,15 +531,15 @@ let%expect_test "holes_in_raw_literals_partial" =
|
|||||||
}
|
}
|
||||||
`|}]
|
`|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "dont_detect_comments_in_strings_with_hole_matcher" =
|
let%expect_test "dont_detect_comments_in_strings_with_hole_matcher" =
|
||||||
let source = {|"// not a comment"|} in
|
let source = {|"// not a comment"|} in
|
||||||
let template = {|":[1]"|} in
|
let template = {|":[1]"|} in
|
||||||
let rewrite_template = {|:[1]|} in
|
let rewrite_template = {|:[1]|} in
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
rewrite_all (module Alpha.Go) template source rewrite_template;
|
||||||
|> (function
|
[%expect_exact {|// not a comment|}];
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
rewrite_all (module Omega.Go) template source rewrite_template;
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|// not a comment|}]
|
[%expect_exact {|// not a comment|}]
|
||||||
|
|
||||||
(* Deactivated: this will conflict with division syntax *)
|
(* Deactivated: this will conflict with division syntax *)
|
@ -1,491 +0,0 @@
|
|||||||
open Core
|
|
||||||
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
include Test_omega
|
|
||||||
|
|
||||||
let all ?(configuration = configuration) template source =
|
|
||||||
C.all ~configuration ~template ~source ()
|
|
||||||
|
|
||||||
let%expect_test "comments_in_string_literals_should_not_be_treated_as_comments_by_fuzzy" =
|
|
||||||
let source = {|"/*"(x)|} in
|
|
||||||
let template = {|(:[1])|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all template source
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|"/*"x|}]
|
|
||||||
|
|
||||||
let%expect_test "comments_in_string_literals_should_not_be_treated_as_comments_by_fuzzy_go_raw" =
|
|
||||||
let source = {|`//`(x)|} in
|
|
||||||
let template = {|(:[1])|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|`//`x|}]
|
|
||||||
|
|
||||||
let%expect_test "tolerate_unbalanced_stuff_in_string_literals" =
|
|
||||||
let template = {|"("|} in
|
|
||||||
let source = {|"("|} in
|
|
||||||
let matches = all ~configuration template source in
|
|
||||||
print_matches matches;
|
|
||||||
[%expect_exact {|[
|
|
||||||
{
|
|
||||||
"range": {
|
|
||||||
"start": { "offset": 0, "line": 1, "column": 1 },
|
|
||||||
"end": { "offset": 3, "line": 1, "column": 4 }
|
|
||||||
},
|
|
||||||
"environment": [],
|
|
||||||
"matched": "\"(\""
|
|
||||||
}
|
|
||||||
]|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|"hello"|} in
|
|
||||||
let match_template = {|":[1]"|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|hello|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|rewrite ("hello") this string|} in
|
|
||||||
let match_template = {|rewrite (":[1]") this string|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|hello|}]
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
|
||||||
let source = {|rewrite (".") this string|} in
|
|
||||||
let match_template = {|rewrite (":[1]") this string|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|.|}]
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
|
||||||
let source = {|rewrite ("") this string|} in
|
|
||||||
let match_template = {|rewrite (":[1]") this string|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {||}]
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
|
||||||
let source = {|"(" match "a""a" this "(" |} in
|
|
||||||
let match_template = {|match :[1] this|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"(" "a""a" "(" |}]
|
|
||||||
|
|
||||||
(* this tests special functionality in non-literal hole parser
|
|
||||||
but which must still ignore unbalanced delims within strings *)
|
|
||||||
let%expect_test "match_string_literals" =
|
|
||||||
let source = {|"(" match "(""(" this "(" |} in
|
|
||||||
let match_template = {|match :[1] this|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"(" "(""(" "(" |}]
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
|
||||||
let source = {|rewrite ("") this string|} in
|
|
||||||
let match_template = {|rewrite (:[1]) this string|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|""|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|"("|} in
|
|
||||||
let match_template = {|":[1]"|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|(|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|"(""("|} in
|
|
||||||
let match_template = {|":[1]"|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|((|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|"(""("|} in
|
|
||||||
let match_template = {|":[1]"|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|((|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|"hello world"|} in
|
|
||||||
let match_template = {|":[x] :[y]"|} in
|
|
||||||
let rewrite_template = {|:[x] :[y]|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|hello world|}]
|
|
||||||
|
|
||||||
(* complex test: basically, we are checking that the inside of this literal is only matched by the val b part *)
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|val a = "class = ${String::class}" val b = "not $a"|} in
|
|
||||||
let match_template = {|":[x]$:[[y]]"|} in
|
|
||||||
let rewrite_template = {|(rewritten part: (:[x]) ([y]))|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|val a = "class = ${String::class}" val b = (rewritten part: (not ) ([y]))|}]
|
|
||||||
|
|
||||||
let%expect_test "base_literal_matching" =
|
|
||||||
let source = {|get("type") rekt ("enabled", True)|} in
|
|
||||||
let match_template = {|(":[1]", :[[3]])|} in
|
|
||||||
let rewrite_template = {|(rewritten part: (:[1]) (:[3]))|} in
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|get("type") rekt (rewritten part: (enabled) (True))|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match "\"" this|} in
|
|
||||||
let match_template = {|match "\"" this|} in
|
|
||||||
let rewrite_template = "" in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {||}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match "\"" this|} in
|
|
||||||
let match_template = {|match :[1] this|} in
|
|
||||||
let rewrite_template = ":[1]" in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"\""|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match "\"\"" this|} in
|
|
||||||
let match_template = {|match :[1] this|} in
|
|
||||||
let rewrite_template = ":[1]" in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"\"\""|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match "\"(\"" "(\"" this|} in
|
|
||||||
let match_template = {|match :[1] this|} in
|
|
||||||
let rewrite_template = ":[1]" in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|"\"(\"" "(\""|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match "\"(\"" "(\"" this|} in
|
|
||||||
let match_template = {|match ":[1]" ":[2]" this|} in
|
|
||||||
let rewrite_template = {|:[1] :[2]|} in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|\"(\" (\"|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match 'sin(gle' 'quo(tes' this|} in
|
|
||||||
let match_template = {|:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match 'sin(gle' 'quo(tes' this|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match '\''|} in
|
|
||||||
let match_template = {|:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match '\''|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match 'asdf'|} in
|
|
||||||
let match_template = {|':[1]'|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match asdf|}]
|
|
||||||
|
|
||||||
let%expect_test "rewrite_string_literals_8" =
|
|
||||||
let source = {|match '\''|} in
|
|
||||||
let match_template = {|':[1]'|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
all match_template source
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|match \'|}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "go_raw_string_literals" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
x = x
|
|
||||||
y = `multi-line
|
|
||||||
raw str(ing literal`
|
|
||||||
z = `other multi-line
|
|
||||||
raw stri(ng literal`
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|`:[1]`|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
Go.all ~configuration ~source ~template:match_template ()
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|
|
|
||||||
x = x
|
|
||||||
y = multi-line
|
|
||||||
raw str(ing literal
|
|
||||||
z = other multi-line
|
|
||||||
raw stri(ng literal
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "go_raw_string_literals" =
|
|
||||||
let source = {|blah `(` quux|} in
|
|
||||||
let match_template = {|:[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
Go.all ~configuration ~source ~template:match_template ()
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|blah `(` quux|}]
|
|
||||||
|
|
||||||
let%expect_test "match_string_literals" =
|
|
||||||
let source = {|`(` match `(``(` this `(` |} in
|
|
||||||
let match_template = {|match :[1] this|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template:match_template ~source ()
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|`(` `(``(` `(` |}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "go_raw_string_literals" =
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
x = x
|
|
||||||
y = `multi-line
|
|
||||||
raw "str"(ing literal`
|
|
||||||
z = `other multi-line
|
|
||||||
raw '"'\"\\s\\\\\tr\ni(ng literal`
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|`:[1]`|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
|
|
||||||
Go.all ~configuration ~source ~template:match_template ()
|
|
||||||
|> (fun matches -> Option.value_exn (Rewrite.all ~source ~rewrite_template matches))
|
|
||||||
|> (fun { rewritten_source; _ } -> rewritten_source)
|
|
||||||
|> print_string;
|
|
||||||
[%expect_exact {|
|
|
||||||
x = x
|
|
||||||
y = multi-line
|
|
||||||
raw "str"(ing literal
|
|
||||||
z = other multi-line
|
|
||||||
raw '"'\"\\s\\\\\tr\ni(ng literal
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "regression_matching_kubernetes" =
|
|
||||||
let source = {|"\n" y = 5|} in
|
|
||||||
let template = {|y = :[1]|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|"\n" 5|}]
|
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "match_escaped_any_char" =
|
|
||||||
let source = {|printf("hello world\n");|} in
|
|
||||||
let template = {|printf(":[1]");|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|hello world\n|}]
|
|
||||||
|
|
||||||
let%expect_test "match_escaped_escaped" =
|
|
||||||
let source = {|printf("hello world\n\\");|} in
|
|
||||||
let template = {|printf(":[1]");|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|hello world\n\\|}]
|
|
||||||
|
|
||||||
let%expect_test "match_escaped_escaped" =
|
|
||||||
let source = {|printf("hello world\n\");|} in
|
|
||||||
let template = {|printf(":[1]");|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "EXPECT SUCCESS");
|
|
||||||
[%expect_exact {|EXPECT SUCCESS|}]
|
|
||||||
|
|
||||||
let%expect_test "holes_in_raw_literals" =
|
|
||||||
let source = {|
|
|
||||||
return expect(
|
|
||||||
extensionsController.executeCommand({
|
|
||||||
command: 'queryGraphQL',
|
|
||||||
arguments: [
|
|
||||||
`
|
|
||||||
query ResolveRepo($repoName: String!) {
|
|
||||||
repository(name: $repoName) {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
{ repoName: 'foo' },
|
|
||||||
],
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|} in
|
|
||||||
let template = {|`:[1]`|} in
|
|
||||||
begin
|
|
||||||
Typescript.all ~configuration ~template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
|
||||||
| hd :: _ ->
|
|
||||||
print_string hd.matched
|
|
||||||
end;
|
|
||||||
[%expect_exact {|`
|
|
||||||
query ResolveRepo($repoName: String!) {
|
|
||||||
repository(name: $repoName) {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`|}]
|
|
||||||
|
|
||||||
let%expect_test "holes_in_raw_literals_partial" =
|
|
||||||
let source = {|
|
|
||||||
return expect(
|
|
||||||
extensionsController.executeCommand({
|
|
||||||
command: 'queryGraphQL',
|
|
||||||
arguments: [
|
|
||||||
`
|
|
||||||
query ResolveRepo($repoName: String!) {
|
|
||||||
repository(name: $repoName) {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
{ repoName: 'foo' },
|
|
||||||
],
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|} in
|
|
||||||
let template = {|` query ResolveRepo(:[1]) {:[2]} `|} in
|
|
||||||
begin
|
|
||||||
Typescript.all ~configuration ~template ~source ()
|
|
||||||
|> function
|
|
||||||
| [] -> print_string "No matches."
|
|
||||||
| hd :: _ ->
|
|
||||||
print_string hd.matched
|
|
||||||
end;
|
|
||||||
[%expect_exact {|`
|
|
||||||
query ResolveRepo($repoName: String!) {
|
|
||||||
repository(name: $repoName) {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`|}]
|
|
||||||
|
|
||||||
let%expect_test "dont_detect_comments_in_strings_with_hole_matcher" =
|
|
||||||
let source = {|"// not a comment"|} in
|
|
||||||
let template = {|":[1]"|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Go.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "BROKEN EXPECT");
|
|
||||||
[%expect_exact {|// not a comment|}]
|
|
||||||
|
|
||||||
(* Deactivated: this will conflict with division syntax *)
|
|
||||||
(*
|
|
||||||
let%expect_test "match_regex_delimiters" =
|
|
||||||
let source = {|/f\/oo/ "/bar/"|} in
|
|
||||||
let template = {|/:[1]/|} in
|
|
||||||
let rewrite_template = {|:[1]|} in
|
|
||||||
Typescript.all ~configuration ~template ~source ()
|
|
||||||
|> Rewrite.all ~source ~rewrite_template
|
|
||||||
|> (function
|
|
||||||
| Some { rewritten_source; _ } -> print_string rewritten_source
|
|
||||||
| None -> print_string "EXPECT SUCCESS");
|
|
||||||
[%expect_exact {|f\/oo "/bar/"|}]
|
|
||||||
*)
|
|
@ -1,6 +1,8 @@
|
|||||||
open Core
|
open Core
|
||||||
|
|
||||||
open Match
|
open Match
|
||||||
|
|
||||||
|
open Matchers
|
||||||
open Rewriter
|
open Rewriter
|
||||||
open Rewrite_template
|
open Rewrite_template
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
open Core
|
open Core
|
||||||
open Matchers
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
|
open Comby_kernel
|
||||||
|
open Matchers
|
||||||
open Test_helpers
|
open Test_helpers
|
||||||
|
|
||||||
let create = Matchers.Alpha.create
|
let run (module E : Engine.S) user_lang source match_template rewrite_template =
|
||||||
|
let (module M) = E.create user_lang in
|
||||||
let run (module M : Matchers.Matcher.S) source match_template rewrite_template =
|
|
||||||
M.first ~configuration match_template source
|
M.first ~configuration match_template source
|
||||||
|> function
|
|> function
|
||||||
| Ok result ->
|
| Ok result ->
|
||||||
@ -18,7 +17,7 @@ let run (module M : Matchers.Matcher.S) source match_template rewrite_template =
|
|||||||
print_string rewrite_template
|
print_string rewrite_template
|
||||||
|
|
||||||
let%expect_test "user_defined_language" =
|
let%expect_test "user_defined_language" =
|
||||||
let c =
|
let user_lang =
|
||||||
Syntax.
|
Syntax.
|
||||||
{ user_defined_delimiters = [("case", "esac")]
|
{ user_defined_delimiters = [("case", "esac")]
|
||||||
; escapable_string_literals = None
|
; escapable_string_literals = None
|
||||||
@ -26,7 +25,7 @@ let%expect_test "user_defined_language" =
|
|||||||
; comments = [Multiline ("/*", "*/"); Until_newline "//"]
|
; comments = [Multiline ("/*", "*/"); Until_newline "//"]
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
let user_lang = create c in
|
|
||||||
let source =
|
let source =
|
||||||
{|
|
{|
|
||||||
case
|
case
|
||||||
@ -50,7 +49,21 @@ let%expect_test "user_defined_language" =
|
|||||||
in
|
in
|
||||||
let match_template = {|case :[1] esac|} in
|
let match_template = {|case :[1] esac|} in
|
||||||
let rewrite_template = {|case nuked blocks esac|} in
|
let rewrite_template = {|case nuked blocks esac|} in
|
||||||
run user_lang source match_template rewrite_template ;
|
|
||||||
|
run (module Alpha) user_lang source match_template rewrite_template ;
|
||||||
|
[%expect_exact {|
|
||||||
|
case nuked blocks esac
|
||||||
|
/*
|
||||||
|
case
|
||||||
|
ignore this
|
||||||
|
esac
|
||||||
|
*/
|
||||||
|
// case
|
||||||
|
// ignore this
|
||||||
|
// esac
|
||||||
|
|}];
|
||||||
|
|
||||||
|
run (module Omega) user_lang source match_template rewrite_template ;
|
||||||
[%expect_exact {|
|
[%expect_exact {|
|
||||||
case nuked blocks esac
|
case nuked blocks esac
|
||||||
/*
|
/*
|
||||||
@ -63,6 +76,7 @@ let%expect_test "user_defined_language" =
|
|||||||
// esac
|
// esac
|
||||||
|}]
|
|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "user_defined_language_from_json" =
|
let%expect_test "user_defined_language_from_json" =
|
||||||
let json =
|
let json =
|
||||||
{|{
|
{|{
|
||||||
@ -85,14 +99,17 @@ let%expect_test "user_defined_language_from_json" =
|
|||||||
Yojson.Safe.from_string json
|
Yojson.Safe.from_string json
|
||||||
|> Matchers.Syntax.of_yojson
|
|> Matchers.Syntax.of_yojson
|
||||||
|> Result.ok_or_failwith
|
|> Result.ok_or_failwith
|
||||||
|> create
|
|
||||||
in
|
in
|
||||||
let source = "" in
|
let source = "" in
|
||||||
let match_template = {|""|} in
|
let match_template = {|""|} in
|
||||||
let rewrite_template = {|""|} in
|
let rewrite_template = {|""|} in
|
||||||
run user_lang source match_template rewrite_template ;
|
|
||||||
|
run (module Alpha) user_lang source match_template rewrite_template ;
|
||||||
|
[%expect_exact {|""|}];
|
||||||
|
run (module Omega) user_lang source match_template rewrite_template ;
|
||||||
[%expect_exact {|""|}]
|
[%expect_exact {|""|}]
|
||||||
|
|
||||||
|
|
||||||
let%expect_test "user_defined_language_from_json_optional_escapable" =
|
let%expect_test "user_defined_language_from_json_optional_escapable" =
|
||||||
let json =
|
let json =
|
||||||
{|{
|
{|{
|
||||||
@ -111,10 +128,12 @@ let%expect_test "user_defined_language_from_json_optional_escapable" =
|
|||||||
Yojson.Safe.from_string json
|
Yojson.Safe.from_string json
|
||||||
|> Matchers.Syntax.of_yojson
|
|> Matchers.Syntax.of_yojson
|
||||||
|> Result.ok_or_failwith
|
|> Result.ok_or_failwith
|
||||||
|> create
|
|
||||||
in
|
in
|
||||||
let source = "" in
|
let source = "" in
|
||||||
let match_template = {|""|} in
|
let match_template = {|""|} in
|
||||||
let rewrite_template = {|""|} in
|
let rewrite_template = {|""|} in
|
||||||
run user_lang source match_template rewrite_template ;
|
|
||||||
|
run (module Alpha) user_lang source match_template rewrite_template ;
|
||||||
|
[%expect_exact {|""|}];
|
||||||
|
run (module Omega) user_lang source match_template rewrite_template ;
|
||||||
[%expect_exact {|""|}]
|
[%expect_exact {|""|}]
|
@ -1,120 +0,0 @@
|
|||||||
open Core
|
|
||||||
open Matchers
|
|
||||||
open Rewriter
|
|
||||||
|
|
||||||
open Test_helpers
|
|
||||||
|
|
||||||
let create = Matchers.Omega.create
|
|
||||||
|
|
||||||
let run (module M : Matchers.Matcher.S) source match_template rewrite_template =
|
|
||||||
M.first ~configuration match_template source
|
|
||||||
|> function
|
|
||||||
| Ok result ->
|
|
||||||
Rewrite.all ~source ~rewrite_template [result]
|
|
||||||
|> (fun x -> Option.value_exn x)
|
|
||||||
|> (fun {rewritten_source; _} -> rewritten_source)
|
|
||||||
|> print_string
|
|
||||||
| Error _ ->
|
|
||||||
print_string rewrite_template
|
|
||||||
|
|
||||||
let%expect_test "user_defined_language" =
|
|
||||||
let c =
|
|
||||||
Syntax.
|
|
||||||
{ user_defined_delimiters = [("case", "esac")]
|
|
||||||
; escapable_string_literals = None
|
|
||||||
; raw_string_literals = []
|
|
||||||
; comments = [Multiline ("/*", "*/"); Until_newline "//"]
|
|
||||||
}
|
|
||||||
in
|
|
||||||
let user_lang = create c in
|
|
||||||
let source =
|
|
||||||
{|
|
|
||||||
case
|
|
||||||
case
|
|
||||||
block 1
|
|
||||||
esac
|
|
||||||
|
|
||||||
case
|
|
||||||
block 2
|
|
||||||
esac
|
|
||||||
esac
|
|
||||||
/*
|
|
||||||
case
|
|
||||||
ignore this
|
|
||||||
esac
|
|
||||||
*/
|
|
||||||
// case
|
|
||||||
// ignore this
|
|
||||||
// esac
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let match_template = {|case :[1] esac|} in
|
|
||||||
let rewrite_template = {|case nuked blocks esac|} in
|
|
||||||
run user_lang source match_template rewrite_template ;
|
|
||||||
[%expect_exact {|
|
|
||||||
case nuked blocks esac
|
|
||||||
/*
|
|
||||||
case
|
|
||||||
ignore this
|
|
||||||
esac
|
|
||||||
*/
|
|
||||||
// case
|
|
||||||
// ignore this
|
|
||||||
// esac
|
|
||||||
|}]
|
|
||||||
|
|
||||||
let%expect_test "user_defined_language_from_json" =
|
|
||||||
let json =
|
|
||||||
{|{
|
|
||||||
"user_defined_delimiters": [
|
|
||||||
["case", "esac"]
|
|
||||||
],
|
|
||||||
"escapable_string_literals": {
|
|
||||||
"delimiters": ["\""],
|
|
||||||
"escape_character": "\\"
|
|
||||||
},
|
|
||||||
"raw_string_literals": [],
|
|
||||||
"comments": [
|
|
||||||
[ "Multiline", "/*", "*/" ],
|
|
||||||
[ "Until_newline", "//" ]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let user_lang =
|
|
||||||
Yojson.Safe.from_string json
|
|
||||||
|> Matchers.Syntax.of_yojson
|
|
||||||
|> Result.ok_or_failwith
|
|
||||||
|> create
|
|
||||||
in
|
|
||||||
let source = "" in
|
|
||||||
let match_template = {|""|} in
|
|
||||||
let rewrite_template = {|""|} in
|
|
||||||
run user_lang source match_template rewrite_template ;
|
|
||||||
[%expect_exact {|""|}]
|
|
||||||
|
|
||||||
let%expect_test "user_defined_language_from_json_optional_escapable" =
|
|
||||||
let json =
|
|
||||||
{|{
|
|
||||||
"user_defined_delimiters": [
|
|
||||||
["case", "esac"]
|
|
||||||
],
|
|
||||||
"raw_string_literals": [],
|
|
||||||
"comments": [
|
|
||||||
[ "Multiline", "/*", "*/" ],
|
|
||||||
[ "Until_newline", "//" ]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|}
|
|
||||||
in
|
|
||||||
let user_lang =
|
|
||||||
Yojson.Safe.from_string json
|
|
||||||
|> Matchers.Syntax.of_yojson
|
|
||||||
|> Result.ok_or_failwith
|
|
||||||
|> create
|
|
||||||
in
|
|
||||||
let source = "" in
|
|
||||||
let match_template = {|""|} in
|
|
||||||
let rewrite_template = {|""|} in
|
|
||||||
run user_lang source match_template rewrite_template ;
|
|
||||||
[%expect_exact {|""|}]
|
|
Loading…
Reference in New Issue
Block a user