================================================================================
top-level module attribute
================================================================================

[<AutoOpen>]
module test =
 let x = 4

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

(file
  (module_defn
    (attributes
      (attribute
        (simple_type
          (long_identifier
            (identifier)))))
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (value_declaration_left
          (identifier_pattern
            (long_identifier_or_op
              (identifier))))
        (const
          (int))))))

================================================================================
top-level module attributes repeated
================================================================================

[<A;B;C>]
module test =
 let x = 4

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

(file
  (module_defn
    (attributes
      (attribute
        (simple_type
          (long_identifier
            (identifier))))
      (attribute
        (simple_type
          (long_identifier
            (identifier))))
      (attribute
        (simple_type
          (long_identifier
            (identifier)))))
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (value_declaration_left
          (identifier_pattern
            (long_identifier_or_op
              (identifier))))
        (const
          (int))))))

================================================================================
top-level module attributes separate
================================================================================

[<A>]
[<B;C>]
module test =
 let x = 4

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

(file
  (module_defn
    (attributes
      (attribute
        (simple_type
          (long_identifier
            (identifier))))
      (attribute
        (simple_type
          (long_identifier
            (identifier))))
      (attribute
        (simple_type
          (long_identifier
            (identifier)))))
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (value_declaration_left
          (identifier_pattern
            (long_identifier_or_op
              (identifier))))
        (const
          (int))))))

================================================================================
top-level class attribute
================================================================================

[<Route("test")>]
type A() =
 do ()

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

(file
  (type_definition
    (attributes
      (attribute
        (simple_type
          (long_identifier
            (identifier)))
        (paren_expression
          (const
            (string)))))
    (anon_type_defn
      (type_name
        (identifier))
      (primary_constr_args)
      (type_extension_elements
        (const
          (unit))))))

================================================================================
attribute on let binding
================================================================================

[<AutoOpen>]
module Constants =
  [<Literal>]
  let A = "A"

  [<Literal>]
  let B = "B"

module Impl =
  let v = A + B

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

(file
  (module_defn
    (attributes
      (attribute
        (simple_type
          (long_identifier
            (identifier)))))
    (identifier)
    (declaration_expression
      (attributes
        (attribute
          (simple_type
            (long_identifier
              (identifier)))))
      (function_or_value_defn
        (value_declaration_left
          (identifier_pattern
            (long_identifier_or_op
              (identifier))))
        (const
          (string))))
    (declaration_expression
      (attributes
        (attribute
          (simple_type
            (long_identifier
              (identifier)))))
      (function_or_value_defn
        (value_declaration_left
          (identifier_pattern
            (long_identifier_or_op
              (identifier))))
        (const
          (string)))))
  (module_defn
    (identifier)
    (declaration_expression
      (function_or_value_defn
        (value_declaration_left
          (identifier_pattern
            (long_identifier_or_op
              (identifier))))
        (infix_expression
          (long_identifier_or_op
            (identifier))
          (infix_op)
          (long_identifier_or_op
            (long_identifier
              (identifier))))))))

================================================================================
attribute on let binding in namespace
================================================================================
namespace Com.Test

[<AutoOpen>]
module Constants =
  [<Literal>]
  let A = "A"

  [<Literal>]
  let B = "B"

module Impl =
  let x = A + B

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

(file
  (namespace
    (long_identifier
      (identifier)
      (identifier))
    (module_defn
      (attributes
        (attribute
          (simple_type
            (long_identifier
              (identifier)))))
      (identifier)
      (declaration_expression
        (attributes
          (attribute
            (simple_type
              (long_identifier
                (identifier)))))
        (function_or_value_defn
          (value_declaration_left
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))
          (const
            (string))))
      (declaration_expression
        (attributes
          (attribute
            (simple_type
              (long_identifier
                (identifier)))))
        (function_or_value_defn
          (value_declaration_left
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))
          (const
            (string)))))
    (module_defn
      (identifier)
      (declaration_expression
        (function_or_value_defn
          (value_declaration_left
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))
          (infix_expression
            (long_identifier_or_op
              (identifier))
            (infix_op)
            (long_identifier_or_op
              (long_identifier
                (identifier)))))))))

================================================================================
assembly attribute with expression
================================================================================

namespace FSharp.Finance.Personal

[<assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Tests")>]
()

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

(file
  (namespace
    (long_identifier
      (identifier)
      (identifier)
      (identifier))
    (declaration_expression
      (attributes
        (attribute
          (identifier)
          (simple_type
            (long_identifier
              (identifier)
              (identifier)
              (identifier)
              (identifier)))
          (paren_expression
            (const
              (string)))))
      (const
        (unit)))))

================================================================================
And attribute on its own line
================================================================================

type ExpressionShape =
    | Unit
    | Record of RecordShape
    with
            member x.ClrType =
                match x with
                | Unit -> typeof<Unit>
                | Record r -> r.ClrType
    and
        [<NoComparison>]
        RecordShape = {
            ClrType : Type
        }

type AfterShapes = { X : int }

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

(file
  (type_definition
    (union_type_defn
      (type_name
        (identifier))
      (union_type_cases
        (union_type_case
          (identifier))
        (union_type_case
          (identifier)
          (union_type_fields
            (union_type_field
              (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)))
                  (typed_expression
                    (long_identifier_or_op
                      (identifier))
                    (types
                      (simple_type
                        (long_identifier
                          (identifier))))))
                (rule
                  (identifier_pattern
                    (long_identifier_or_op
                      (identifier))
                    (identifier_pattern
                      (long_identifier_or_op
                        (identifier))))
                  (long_identifier_or_op
                    (long_identifier
                      (identifier)
                      (identifier))))))))))
    (attributes
      (attribute
        (simple_type
          (long_identifier
            (identifier)))))
    (record_type_defn
      (type_name
        (identifier))
      (record_fields
        (record_field
          (identifier)
          (simple_type
            (long_identifier
              (identifier)))))))
  (type_definition
    (record_type_defn
      (type_name
        (identifier))
      (record_fields
        (record_field
          (identifier)
          (simple_type
            (long_identifier
              (identifier))))))))


================================================================================
Attribute between a type and a name
================================================================================

module M =

    type First = | A of int
    with
        override x.ToString() = ""

    and [<NoComparison>]
    Second = { B : int }

    type After = { C: int }

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

(file
  (module_defn
    (identifier)
    (type_definition
      (union_type_defn
        (type_name
          (identifier))
        (union_type_cases
          (union_type_case
            (identifier)
            (union_type_fields
              (union_type_field
                (simple_type
                  (long_identifier
                    (identifier)))))))
        (type_extension_elements
          (member_defn
            (method_or_prop_defn
              (property_or_ident
                (identifier)
                (identifier))
              (const
                (unit))
              (const
                (string))))))
      (attributes
        (attribute
          (simple_type
            (long_identifier
              (identifier)))))
      (record_type_defn
        (type_name
          (identifier))
        (record_fields
          (record_field
            (identifier)
            (simple_type
              (long_identifier
                (identifier)))))))
    (type_definition
      (record_type_defn
        (type_name
          (identifier))
        (record_fields
          (record_field
            (identifier)
            (simple_type
              (long_identifier
                (identifier)))))))))
================================================================================
attribute on a property setter accessor
================================================================================

type T() =
    let mutable v = 0
    member this.P
        with get () = v
        and [<System.Obsolete>] set x = v <- x

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

(file
  (type_definition
    (anon_type_defn
      (type_name
        type_name: (identifier))
      (primary_constr_args)
      block: (type_extension_elements
        (function_or_value_defn
          (value_declaration_left
            (identifier_pattern
              (long_identifier_or_op
                (identifier))))
          body: (const
            (int))))
      block: (type_extension_elements
        (member_defn
          (method_or_prop_defn
            name: (property_or_ident
              instance: (identifier)
              method: (identifier))
            block: (property_accessor
              (argument_patterns
                (const
                  (unit)))
              (long_identifier_or_op
                (identifier)))
            block: (property_accessor
              (attributes
                (attribute
                  (simple_type
                    (long_identifier
                      (identifier)
                      (identifier)))))
              (argument_patterns
                (long_identifier
                  (identifier)))
              (mutate_expression
                assignee: (long_identifier_or_op
                  (identifier))
                value: (long_identifier_or_op
                  (long_identifier
                    (identifier)))))))))))

================================================================================
attributes on a return type
================================================================================

open System
let f(x) : [<Obsolete>] int = x + 1

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

(file
  (import_decl
    (long_identifier
      (identifier)))
  (declaration_expression
    (function_or_value_defn
      (function_declaration_left
        (identifier)
        (argument_patterns
          (identifier_pattern
            (long_identifier_or_op
              (identifier)))))
      (attributes
        (attribute
          (simple_type
            (long_identifier
              (identifier)))))
      (simple_type
        (long_identifier
          (identifier)))
      body: (infix_expression
        (long_identifier_or_op
          (identifier))
        (infix_op)
        (const
          (int))))))
