    
  * 
  * Copyright ( C ) 2019 - 2022 r2c 
  * 
  * This library is free software ; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public License 
  * version 2.1 as published by the Free Software Foundation , with the 
  * special exception on linking described in file LICENSE . 
  * 
  * This library is distributed in the hope that it will be useful , but 
  * WITHOUT ANY WARRANTY ; without even the implied warranty of 
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .   See the file 
  * LICENSE for more details . 
 
 *
 * Copyright (C) 2019-2022 r2c
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation, with the
 * special exception on linking described in file LICENSE.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the file
 * LICENSE for more details.
 *)

(*****************************************************************************)
(* Prelude *)
(*****************************************************************************)

(*****************************************************************************)
(* Types *)
(*****************************************************************************)

type compiled_regexp = Regexp_engine.t [@@deriving show, eq]
type regexp_string = string [@@deriving show, eq]
  see the NOTE " Regexp " below for the need to have this type

(* used in the engine for rule->mini_rule and match_result gymnastic *)
type pattern_id = int [@@deriving show, eq]

type xpattern_kind =
  | Sem of Pattern.t * Lang.t (* language used for parsing the pattern *)
  | Spacegrep of Spacegrep.Pattern_AST.t
  | Regexp of regexp_string
* NOTE " Regexp " : 
       * We used to keep the compiled regexp of type ` Regexp_engine.t ' , but 
       * that is not a pure OCaml data structure and it can not be serialized . 
       * 
       * This had previously caused weird Semgrep crashes like 
       * 
       *      Invalid_argument " output_value : abstract value ( Custom ) " 
       * 
       * after PR # 5725 ( taint labels ) , see PA-1724 . 
       * 
       * When we use -j 2 ( or higher ) and -json , then  is used , and the result 
       * of ` Match_rules.check ' ( of type ` Report.match_result ' ) will contain some 
       * unevaluated thunks . Then  will try to marshal this value and it will 
       * crash if there is any " Custom " block involved . 
      
      * We used to keep the compiled regexp of type `Regexp_engine.t', but
      * that is not a pure OCaml data structure and it cannot be serialized.
      *
      * This had previously caused weird Semgrep crashes like
      *
      *     Invalid_argument "output_value: abstract value (Custom)"
      *
      * after PR #5725 (taint labels), see PA-1724.
      *
      * When we use -j 2 (or higher) and -json, then Parmap is used, and the result
      * of `Match_rules.check' (of type `Report.match_result') will contain some
      * unevaluated thunks. Then Parmap will try to marshal this value and it will
      * crash if there is any "Custom" block involved.
      *)
  | Comby of string
[@@deriving show, eq]

(* eXtended pattern *)
type t = {
  pat : xpattern_kind;
  Regarding @equal below , even if two patterns have different indentation , 
    * we still consider them equal in the metachecker context . 
    * We rely only on the equality on pat , which will 
    * abstract away line positions . 
    * TODO : right now we have some false positives , e.g. , in Python 
    * assert ( ... ) and assert ... are considered equal AST - wise 
    * but it might be a bug ! . 
   
   * we still consider them equal in the metachecker context.
   * We rely only on the equality on pat, which will
   * abstract away line positions.
   * TODO: right now we have some false positives, e.g., in Python
   * assert(...) and assert ... are considered equal AST-wise
   * but it might be a bug!.
   *)
  pstr : string AST_generic.wrap; [@equal fun _ _ -> true]
  Unique i d , incremented via a gensym()-like function in mk_pat ( ) . 
    * This is used to run the patterns in a formula in a batch all - at - once 
    * and remember what was the matching results for a certain pattern i d. 
   
   * This is used to run the patterns in a formula in a batch all-at-once
   * and remember what was the matching results for a certain pattern id.
   *)
  pid : pattern_id; [@equal fun _ _ -> true]
}
[@@deriving show, eq]

(*****************************************************************************)
(* Helpers *)
(*****************************************************************************)

let count = ref 0

let mk_xpat pat pstr =
  incr count;
  { pat; pstr; pid = !count }

let is_regexp xpat =
  match xpat.pat with
  | Regexp _ -> true
  | __else__ -> false

***************************************************************************
 Prelude 
***************************************************************************
***************************************************************************
 Types 
***************************************************************************
 used in the engine for rule->mini_rule and match_result gymnastic 
 language used for parsing the pattern 
 eXtended pattern 
***************************************************************************
 Helpers 
***************************************************************************
    
  * 
  * Copyright ( C ) 2019 - 2022 r2c 
  * 
  * This library is free software ; you can redistribute it and/or 
  * modify it under the terms of the GNU Lesser General Public License 
  * version 2.1 as published by the Free Software Foundation , with the 
  * special exception on linking described in file LICENSE . 
  * 
  * This library is distributed in the hope that it will be useful , but 
  * WITHOUT ANY WARRANTY ; without even the implied warranty of 
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .   See the file 
  * LICENSE for more details . 
 
 *
 * Copyright (C) 2019-2022 r2c
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation, with the
 * special exception on linking described in file LICENSE.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the file
 * LICENSE for more details.
 *)



type compiled_regexp = Regexp_engine.t [@@deriving show, eq]
type regexp_string = string [@@deriving show, eq]
  see the NOTE " Regexp " below for the need to have this type

type pattern_id = int [@@deriving show, eq]

type xpattern_kind =
  | Spacegrep of Spacegrep.Pattern_AST.t
  | Regexp of regexp_string
* NOTE " Regexp " : 
       * We used to keep the compiled regexp of type ` Regexp_engine.t ' , but 
       * that is not a pure OCaml data structure and it can not be serialized . 
       * 
       * This had previously caused weird Semgrep crashes like 
       * 
       *      Invalid_argument " output_value : abstract value ( Custom ) " 
       * 
       * after PR # 5725 ( taint labels ) , see PA-1724 . 
       * 
       * When we use -j 2 ( or higher ) and -json , then  is used , and the result 
       * of ` Match_rules.check ' ( of type ` Report.match_result ' ) will contain some 
       * unevaluated thunks . Then  will try to marshal this value and it will 
       * crash if there is any " Custom " block involved . 
      
      * We used to keep the compiled regexp of type `Regexp_engine.t', but
      * that is not a pure OCaml data structure and it cannot be serialized.
      *
      * This had previously caused weird Semgrep crashes like
      *
      *     Invalid_argument "output_value: abstract value (Custom)"
      *
      * after PR #5725 (taint labels), see PA-1724.
      *
      * When we use -j 2 (or higher) and -json, then Parmap is used, and the result
      * of `Match_rules.check' (of type `Report.match_result') will contain some
      * unevaluated thunks. Then Parmap will try to marshal this value and it will
      * crash if there is any "Custom" block involved.
      *)
  | Comby of string
[@@deriving show, eq]

type t = {
  pat : xpattern_kind;
  Regarding @equal below , even if two patterns have different indentation , 
    * we still consider them equal in the metachecker context . 
    * We rely only on the equality on pat , which will 
    * abstract away line positions . 
    * TODO : right now we have some false positives , e.g. , in Python 
    * assert ( ... ) and assert ... are considered equal AST - wise 
    * but it might be a bug ! . 
   
   * we still consider them equal in the metachecker context.
   * We rely only on the equality on pat, which will
   * abstract away line positions.
   * TODO: right now we have some false positives, e.g., in Python
   * assert(...) and assert ... are considered equal AST-wise
   * but it might be a bug!.
   *)
  pstr : string AST_generic.wrap; [@equal fun _ _ -> true]
  Unique i d , incremented via a gensym()-like function in mk_pat ( ) . 
    * This is used to run the patterns in a formula in a batch all - at - once 
    * and remember what was the matching results for a certain pattern i d. 
   
   * This is used to run the patterns in a formula in a batch all-at-once
   * and remember what was the matching results for a certain pattern id.
   *)
  pid : pattern_id; [@equal fun _ _ -> true]
}
[@@deriving show, eq]


let count = ref 0

let mk_xpat pat pstr =
  incr count;
  { pat; pstr; pid = !count }

let is_regexp xpat =
  match xpat.pat with
  | Regexp _ -> true
  | __else__ -> false
