============================================
Qualified type names
============================================

type a b.c

---

(source_file
  (type_declaration
    (type_spec
      name: (type_identifier)
      type: (qualified_type
        package: (package_identifier)
        name: (type_identifier)))))

============================================
Array types
============================================

type a [2+2]c

---

(source_file
  (type_declaration
    (type_spec
      name: (type_identifier)
      type: (array_type
        length: (binary_expression
          left: (int_literal)
          right: (int_literal))
        element: (type_identifier)))))

============================================
Slice types
============================================

package main

type a []c
type b [][]d

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_spec
      (type_identifier)
      (slice_type (type_identifier))))
  (type_declaration
    (type_spec
      (type_identifier)
      (slice_type (slice_type (type_identifier))))))

============================================
Struct types
============================================

package main

type s1 struct {}

type s2 struct { Person }

type s2 struct {
  f, g int
}

type s3 struct {
  // an embedded struct
  p.s1

  // a tag
  h int `json:"h"`
}

type g1 struct {
    normal Array[T]
    nested Array[Array[T]]
}

type g2[T, U any, V interface{}, W Foo[Bar[T]]] struct {}

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_spec
      (type_identifier)
      (struct_type (field_declaration_list))))
  (type_declaration
    (type_spec
      (type_identifier)
      (struct_type (field_declaration_list (field_declaration (type_identifier))))))
  (type_declaration
    (type_spec
      (type_identifier)
      (struct_type (field_declaration_list
        (field_declaration
          (field_identifier)
          (field_identifier)
          (type_identifier))))))
  (type_declaration
    (type_spec
      (type_identifier)
      (struct_type (field_declaration_list
        (comment)
        (field_declaration
          (qualified_type (package_identifier) (type_identifier)))
        (comment)
        (field_declaration
          (field_identifier)
          (type_identifier)
          (raw_string_literal))))))
  (type_declaration
    (type_spec
      (type_identifier)
      (struct_type
        (field_declaration_list
          (field_declaration
            (field_identifier)
            (generic_type
              (type_identifier)
              (type_arguments
                (type_identifier))))
          (field_declaration
            (field_identifier)
            (generic_type
              (type_identifier)
              (type_arguments
                (generic_type
                  (type_identifier)
                  (type_arguments
                    (type_identifier))))))))))
  (type_declaration
    (type_spec
      (type_identifier)
      (type_parameter_list
        (parameter_declaration
          (identifier)
          (identifier)
          (type_identifier))
        (parameter_declaration
          (identifier)
          (interface_type))
        (parameter_declaration
          (identifier)
          (generic_type
            (type_identifier)
            (type_arguments
              (generic_type
                (type_identifier)
                (type_arguments (type_identifier)))))))
      (struct_type (field_declaration_list)))))

============================================
Interface types
============================================

package main

type i1 interface {}

type i1 interface { io.Reader }

type i2 interface {
  i1
  io.Reader
  SomeMethod(s string) error
  OtherMethod(int, ...bool) bool
}

type SignedInteger interface {
  int | int8 | ~uint | ~uint8
}

---

(source_file
  (package_clause (package_identifier))
  (type_declaration (type_spec
    (type_identifier)
    (interface_type)))
  (type_declaration (type_spec
    (type_identifier)
    (interface_type (interface_type_name
      (qualified_type (package_identifier) (type_identifier))))))
  (type_declaration (type_spec
    (type_identifier)
    (interface_type
      (interface_type_name (type_identifier))
      (interface_type_name (qualified_type (package_identifier) (type_identifier)))
      (method_spec
        (field_identifier)
        (parameter_list (parameter_declaration (identifier) (type_identifier)))
        (type_identifier))
      (method_spec
        (field_identifier)
          (parameter_list
            (parameter_declaration (type_identifier))
            (variadic_parameter_declaration (type_identifier))) (type_identifier)))))
  (type_declaration (type_spec
    (type_identifier)
    (interface_type (constraint_elem
      (constraint_term (type_identifier))
      (constraint_term (type_identifier))
      (constraint_term (type_identifier))
      (constraint_term (type_identifier)))))))

============================================
Map types
============================================

package main

type m1 map[string]error

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_spec
      (type_identifier)
      (map_type (type_identifier) (type_identifier)))))

============================================
Pointer types
============================================

package main

type (
  p1 *string
  p2 **p1
)

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_spec
      (type_identifier)
      (pointer_type (type_identifier)))
    (type_spec
      (type_identifier)
      (pointer_type (pointer_type (type_identifier))))))

============================================
Channel types
============================================

package main

type (
  c1 chan<- chan int
  c2 chan<- chan<- struct{}
  c3 chan<- <-chan int
)

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_spec
      (type_identifier)
      (channel_type (channel_type (type_identifier))))
    (type_spec
      (type_identifier)
      (channel_type (channel_type (struct_type (field_declaration_list)))))
    (type_spec
      (type_identifier)
      (channel_type (channel_type (type_identifier))))))

============================================
Function types
============================================

package main

type (
  a func(int) int
  b func(int, *string) (bool, error)
  c func(int, ...*string) bool
)

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_spec
      (type_identifier)
      (function_type
        (parameter_list
          (parameter_declaration (type_identifier)))
        (type_identifier)))
    (type_spec
      (type_identifier)
      (function_type
        (parameter_list
          (parameter_declaration (type_identifier))
          (parameter_declaration (pointer_type (type_identifier))))
        (parameter_list
          (parameter_declaration (type_identifier))
          (parameter_declaration (type_identifier)))))
    (type_spec
      (type_identifier)
      (function_type
        (parameter_list
          (parameter_declaration (type_identifier))
          (variadic_parameter_declaration
            (pointer_type (type_identifier))))
        (type_identifier)))))

============================================
Type Aliases
============================================

package main

type H1 = G1
type _ = G2
type _ = struct{}
type (
	A0 = T0
	A1 = int
	A2 = struct{}
	A3 = reflect.Value
	A4 = Value
	A5 = Value
)

---

(source_file
  (package_clause (package_identifier))
  (type_declaration
    (type_alias (type_identifier) (type_identifier)))
  (type_declaration
    (type_alias (type_identifier) (type_identifier)))
  (type_declaration
    (type_alias (type_identifier) (struct_type (field_declaration_list))))
	(type_declaration
    (type_alias (type_identifier) (type_identifier))
    (type_alias (type_identifier) (type_identifier))
    (type_alias (type_identifier) (struct_type (field_declaration_list)))
    (type_alias (type_identifier) (qualified_type (package_identifier) (type_identifier)))
    (type_alias (type_identifier) (type_identifier))
    (type_alias (type_identifier) (type_identifier))))
