================================================================================
constant pattern
================================================================================

let x = 1

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (identifier_pattern
          (long_identifier_or_op
            (identifier))))
      (const
        (int)))))

================================================================================
tuple pattern
================================================================================

let (x,y) = (1,2)

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (paren_pattern
          (repeat_pattern
            (identifier_pattern
              (long_identifier_or_op
                (identifier)))
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))))
      (paren_expression
        (tuple_expression
          (const
            (int))
          (const
            (int)))))))

================================================================================
typed pattern
================================================================================

let name (x : int) = 1

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (function_declaration_left
        (identifier)
        (argument_patterns
          (typed_pattern
            (identifier_pattern
              (long_identifier_or_op
                (identifier)))
            (simple_type
              (long_identifier
                (identifier))))))
      (const
        (int)))))

================================================================================
typed tuple pattern
================================================================================

let name (x: int, y: string) = 1, "test"

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (function_declaration_left
        (identifier)
        (argument_patterns
          (repeat_pattern
            (typed_pattern
              (identifier_pattern
                (long_identifier_or_op
                  (identifier)))
              (simple_type
                (long_identifier
                  (identifier))))
            (typed_pattern
              (identifier_pattern
                (long_identifier_or_op
                  (identifier)))
              (simple_type
                (long_identifier
                  (identifier)))))))
      (tuple_expression
        (const
          (int))
        (const
          (string))))))

================================================================================
typed pattern with constraints
================================================================================

type A() =
  member _.B(x: 'T when 'T: equality) = ()

--------------------------------------------------------------------------------

(file
  (type_definition
    (anon_type_defn
      (type_name
        (identifier))
      (primary_constr_args)
      (type_extension_elements
        (member_defn
          (method_or_prop_defn
            (property_or_ident
              (identifier)
              (identifier))
            (paren_pattern
              (typed_pattern
                (identifier_pattern
                  (long_identifier_or_op
                    (identifier)))
                (type_argument
                  (identifier))
                (type_argument_constraints
                  (constraint
                    (type_argument
                      (identifier))))))
            (const
              (unit))))))))

================================================================================
active pattern 1
================================================================================

module A =
  let (|A|) () = ()

--------------------------------------------------------------------------------

(file
  (module_defn
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (function_declaration_left
          (active_pattern
            (active_pattern_op_name))
          (argument_patterns
            (const
              (unit))))
        (const
          (unit))))))

================================================================================
active pattern 2
================================================================================

module A =
  let (|A|B|) () = ()

--------------------------------------------------------------------------------

(file
  (module_defn
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (function_declaration_left
          (active_pattern
            (active_pattern_op_name)
            (active_pattern_op_name))
          (argument_patterns
            (const
              (unit))))
        (const
          (unit))))))

================================================================================
partial active pattern
================================================================================

module A =
  let (|A|B|_|) () = ()

--------------------------------------------------------------------------------

(file
  (module_defn
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (function_declaration_left
          (active_pattern
            (active_pattern_op_name)
            (active_pattern_op_name)
            (wildcard_active_pattern_op))
          (argument_patterns
            (const
              (unit))))
        (const
          (unit))))))

================================================================================
multiline list patterns
================================================================================

let f =
    match immutQuery with
    | CallJoin([ F(A, B)
                 G([A
                    B; C], C)]) -> ()

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (identifier_pattern
          (long_identifier_or_op
            (identifier))))
      (match_expression
        (long_identifier_or_op
          (identifier))
        (rules
          (rule
            (identifier_pattern
              (long_identifier_or_op
                (identifier))
              (paren_pattern
                (list_pattern
                  (identifier_pattern
                    (long_identifier_or_op
                      (identifier))
                    (paren_pattern
                      (repeat_pattern
                        (identifier_pattern
                          (long_identifier_or_op
                            (identifier)))
                        (identifier_pattern
                          (long_identifier_or_op
                            (identifier))))))
                  (identifier_pattern
                    (long_identifier_or_op
                      (identifier))
                    (paren_pattern
                      (repeat_pattern
                        (list_pattern
                          (identifier_pattern
                            (long_identifier_or_op
                              (identifier)))
                          (identifier_pattern
                            (long_identifier_or_op
                              (identifier)))
                          (identifier_pattern
                            (long_identifier_or_op
                              (identifier))))
                        (identifier_pattern
                          (long_identifier_or_op
                            (identifier)))))))))
            (const
              (unit))))))))

================================================================================
empty list pattern
================================================================================

let [] = []

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (list_pattern))
      (list_expression))))

================================================================================
empty array pattern
================================================================================

let [||] = [||]

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (array_pattern))
      (array_expression))))

================================================================================
Identifier pattern with negative int
================================================================================

let (Some -1) = Some -1

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (paren_pattern
          (identifier_pattern
            (long_identifier_or_op
              (identifier))
            (const
              (int)))))
      (application_expression
        (long_identifier_or_op
          (identifier))
        (const
          (int))))))

================================================================================
record pattern with single required field
================================================================================

let {F1 = v1} = {F1 = "a"}

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (record_pattern
          (field_pattern
            (long_identifier
              (identifier))
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))))
      (brace_expression
        (field_initializers
          (field_initializer
            (long_identifier
              (identifier))
            (const
              (string))))))))

================================================================================
record pattern with multiple fields
================================================================================

let {F1 = v1; F2 = v2} = {F1 = "a"; F2 = "b"}

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (record_pattern
          (field_pattern
            (long_identifier
              (identifier))
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))
          (field_pattern
            (long_identifier
              (identifier))
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))))
      (brace_expression
        (field_initializers
          (field_initializer
            (long_identifier
              (identifier))
            (const
              (string)))
          (field_initializer
            (long_identifier
              (identifier))
            (const
              (string))))))))

================================================================================
multiline record patterns
================================================================================

let f =
    match x with
    | { Field1 = 1
        Field2 = true } -> ()
    | { Field1 = 2
        Field2 = false } -> ()

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (function_or_value_defn
      (value_declaration_left
        (identifier_pattern
          (long_identifier_or_op
            (identifier))))
      (match_expression
        (long_identifier_or_op
          (identifier))
        (rules
          (rule
            (record_pattern
              (field_pattern
                (long_identifier
                  (identifier))
                (const
                  (int)))
              (field_pattern
                (long_identifier
                  (identifier))
                (const
                  (bool))))
            (const
              (unit)))
          (rule
            (record_pattern
              (field_pattern
                (long_identifier
                  (identifier))
                (const
                  (int)))
              (field_pattern
                (long_identifier
                  (identifier))
                (const
                  (bool))))
            (const
              (unit))))))))

================================================================================
named pattern
================================================================================

type T =
    | T of a: bool

    member x.F =
        match x with
        | T(a = true) -> true

--------------------------------------------------------------------------------

(file
  (type_definition
    (union_type_defn
      (type_name
        (identifier))
      (union_type_cases
        (union_type_case
          (identifier)
          (union_type_fields
            (union_type_field
              (identifier)
              (simple_type
                (long_identifier
                  (identifier)))))))
      (type_extension_elements
        (member_defn
          (method_or_prop_defn
            (property_or_ident
              (identifier)
              (identifier))
            (match_expression
              (long_identifier_or_op
                (identifier))
              (rules
                (rule
                  (identifier_pattern
                    (long_identifier_or_op
                      (identifier))
                    (named_field_pattern
                      (named_field
                        (identifier)
                        (const
                          (bool)))))
                  (const
                    (bool)))))))))))

================================================================================
multiple named pattern
================================================================================

type T =
    | T of a: bool

    member x.F =
        match x with
        | T(a = true; b = false) -> true

--------------------------------------------------------------------------------

(file
  (type_definition
    (union_type_defn
      (type_name
        (identifier))
      (union_type_cases
        (union_type_case
          (identifier)
          (union_type_fields
            (union_type_field
              (identifier)
              (simple_type
                (long_identifier
                  (identifier)))))))
      (type_extension_elements
        (member_defn
          (method_or_prop_defn
            (property_or_ident
              (identifier)
              (identifier))
            (match_expression
              (long_identifier_or_op
                (identifier))
              (rules
                (rule
                  (identifier_pattern
                    (long_identifier_or_op
                      (identifier))
                    (named_field_pattern
                      (named_field
                        (identifier)
                        (const
                          (bool)))
                      (named_field
                        (identifier)
                        (const
                          (bool)))))
                  (const
                    (bool)))))))))))

================================================================================
parameterized pattern
================================================================================

do
    match x with
    | Parse (TextConversions.AsFloat [||] false) _ -> ()

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (do
      (match_expression
        (long_identifier_or_op
          (identifier))
        (rules
          (rule
            (identifier_pattern
              (long_identifier_or_op
                (identifier))
              (paren_pattern
                (identifier_pattern
                  (long_identifier_or_op
                    (long_identifier
                      (identifier)
                      (identifier)))
                  (array_pattern)
                  (const
                    (bool))))
              (wildcard_pattern))
            (const
              (unit))))))))

================================================================================
type test pattern
================================================================================

do
  match x with
  | :? string -> true
  | :? int as i -> false

--------------------------------------------------------------------------------

(file
  (declaration_expression
    (do
      (match_expression
        (long_identifier_or_op
          (identifier))
        (rules
          (rule
            (type_check_pattern
              (atomic_type
                (long_identifier
                  (identifier))))
            (const
              (bool)))
          (rule
            (type_check_pattern
              (atomic_type
                (long_identifier
                  (identifier)))
              (identifier))
            (const
              (bool))))))))

================================================================================
record pattern with qualified identifiers and union case field values
================================================================================

match x with
| { Bar = A.B } -> 1
| { Foo.Bar = Some y } -> y
| { Bar = Foo.Baz y } -> y

--------------------------------------------------------------------------------

(file
  (match_expression
    (long_identifier_or_op
      (identifier))
    (rules
      (rule
        (record_pattern
          (field_pattern
            (long_identifier
              (identifier))
            (identifier_pattern
              (long_identifier_or_op
                (long_identifier
                  (identifier)
                  (identifier))))))
        (const
          (int)))
      (rule
        (record_pattern
          (field_pattern
            (long_identifier
              (identifier)
              (identifier))
            (identifier_pattern
              (long_identifier_or_op
                (identifier))
              (identifier_pattern
                (long_identifier_or_op
                  (identifier))))))
        (long_identifier_or_op
          (identifier)))
      (rule
        (record_pattern
          (field_pattern
            (long_identifier
              (identifier))
            (identifier_pattern
              (long_identifier_or_op
                (long_identifier
                  (identifier)
                  (identifier)))
              (identifier_pattern
                (long_identifier_or_op
                  (identifier))))))
        (long_identifier_or_op
          (long_identifier
            (identifier)))))))
