==================
Bare field access folds into an assignable selector
==================

void main() {
  hello.hi;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (identifier)
            (assignable_operator)
            (identifier)))))))

==================
Multi-segment field access nests left-associatively
==================

void main() {
  a.b.c;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (unconditional_assignable_selector
              (identifier)
              (assignable_operator)
              (identifier))
            (assignable_operator)
            (identifier)))))))

==================
Field access after a call folds
==================

void main() {
  obj.a().b;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (method_invocation
              (unconditional_assignable_selector
                (identifier)
                (assignable_operator)
                (identifier))
              (argument_part
                (arguments)))
            (assignable_operator)
            (identifier)))))))

==================
Non-null assertion field access folds
==================

void main() {
  directory!.path;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (identifier)
            (null_assertion_operator)
            (assignable_operator)
            (identifier)))))))

==================
Non-null assertion index access folds
==================

void main() {
  json!['data'];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (identifier)
            (null_assertion_operator)
            (index_selector
              (string_literal))))))))

==================
Chained non-null assertion index access nests left-associatively
==================

void main() {
  json!['data'][0];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (unconditional_assignable_selector
              (identifier)
              (null_assertion_operator)
              (index_selector
                (string_literal)))
            (index_selector
              (decimal_integer_literal))))))))

==================
Method call on a non-null assertion index folds
==================

void main() {
  json!['data'].trim();
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (method_invocation
            (unconditional_assignable_selector
              (unconditional_assignable_selector
                (identifier)
                (null_assertion_operator)
                (index_selector
                  (string_literal)))
              (assignable_operator)
              (identifier))
            (argument_part
              (arguments))))))))

==================
Bare index access folds into an assignable selector
==================

void main() {
  a[0];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (identifier)
            (index_selector
              (decimal_integer_literal))))))))

==================
Chained index access nests left-associatively
==================

void main() {
  a[0][1];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (unconditional_assignable_selector
            (unconditional_assignable_selector
              (identifier)
              (index_selector
                (decimal_integer_literal)))
            (index_selector
              (decimal_integer_literal))))))))

==================
Null-aware index access folds into an assignable selector
==================

void main() {
  list?[0];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (conditional_assignable_selector
            (identifier)
            (assignable_operator)
            (index_selector
              (decimal_integer_literal))))))))

==================
Chained null-aware index access nests left-associatively
==================

void main() {
  a?[0]?[1];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (conditional_assignable_selector
            (conditional_assignable_selector
              (identifier)
              (assignable_operator)
              (index_selector
                (decimal_integer_literal)))
            (assignable_operator)
            (index_selector
              (decimal_integer_literal))))))))

==================
Null-aware index access after a field access folds
==================

void main() {
  obj?.a?[0];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (conditional_assignable_selector
            (conditional_assignable_selector
              (identifier)
              (assignable_operator)
              (identifier))
            (assignable_operator)
            (index_selector
              (decimal_integer_literal))))))))

==================
Method call on a null-aware index folds
==================

void main() {
  list?[0].clear();
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (method_invocation
            (unconditional_assignable_selector
              (conditional_assignable_selector
                (identifier)
                (assignable_operator)
                (index_selector
                  (decimal_integer_literal)))
              (assignable_operator)
              (identifier))
            (argument_part
              (arguments))))))))

==================
Call on a null-aware index folds
==================

void main() {
  list?[0]();
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (method_invocation
            (conditional_assignable_selector
              (identifier)
              (assignable_operator)
              (index_selector
                (decimal_integer_literal)))
            (argument_part
              (arguments))))))))

==================
Ternary with list literals is not a null-aware index
==================

void main() {
  cond ? [1] : [2];
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (conditional_expression
            (identifier)
            (list_literal
              (decimal_integer_literal))
            (list_literal
              (decimal_integer_literal))))))))

==================
Parenthesized-cast receiver on an assignment LHS folds into the selector
==================

void main() {
  (employee as Person).firstName = 'Bob';
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (unconditional_assignable_selector
                (parenthesized_expression
                  (type_cast_expression
                    (identifier)
                    (type_cast
                      (as_operator)
                      (type_identifier))))
                (assignable_operator)
                (identifier)))
            (assignment_operator)
            (string_literal)))))))

==================
Index target with a member-access receiver folds on the assignment LHS
==================

void main() {
  req.body['password'] = x;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (unconditional_assignable_selector
                (unconditional_assignable_selector
                  (identifier)
                  (assignable_operator)
                  (identifier))
                (index_selector
                  (string_literal))))
            (assignment_operator)
            (identifier)))))))

==================
Conditional member target folds on the assignment LHS
==================

void main() {
  obj?.field = value;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (conditional_assignable_selector
                (identifier)
                (assignable_operator)
                (identifier)))
            (assignment_operator)
            (identifier)))))))

==================
Simple index target folds on the assignment LHS
==================

void main() {
  list[0] = value;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (unconditional_assignable_selector
                (identifier)
                (index_selector
                  (decimal_integer_literal))))
            (assignment_operator)
            (identifier)))))))

==================
Index-then-member target folds the index decoration into the selector
==================

void main() {
  items[0].label = value;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (unconditional_assignable_selector
                (unconditional_assignable_selector
                  (identifier)
                  (index_selector
                    (decimal_integer_literal)))
                (assignable_operator)
                (identifier)))
            (assignment_operator)
            (identifier)))))))

==================
Chained index target nests left-associatively on the assignment LHS
==================

void main() {
  grid[0][1] = value;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (unconditional_assignable_selector
                (unconditional_assignable_selector
                  (identifier)
                  (index_selector
                    (decimal_integer_literal)))
                (index_selector
                  (decimal_integer_literal))))
            (assignment_operator)
            (identifier)))))))

==================
Super-qualified member target folds on the assignment LHS
==================

class A {
  void m() {
    super.value = x;
  }
}

---

(program
  (class_definition
    (identifier)
    (class_body
      (method_declaration
        (method_signature
          (function_signature
            (void_type)
            (identifier)
            (formal_parameter_list)))
        (function_body
          (block
            (expression_statement
              (assignment_expression
                (assignable_expression
                  (unconditional_assignable_selector
                    (super)
                    (assignable_operator)
                    (identifier)))
                (assignment_operator)
                (identifier)))))))))

==================
Conditional index target folds on the assignment LHS
==================

void main() {
  list?[0] = value;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (assignment_expression
            (assignable_expression
              (conditional_assignable_selector
                (identifier)
                (assignable_operator)
                (index_selector
                  (decimal_integer_literal))))
            (assignment_operator)
            (identifier)))))))

==================
Trailing non-null assertion folds the chain
==================

void main() {
  req.url.q['a']!;
  req.headers!;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (expression_statement
          (null_assertion_expression
            (unconditional_assignable_selector
              (unconditional_assignable_selector
                (unconditional_assignable_selector
                  (identifier)
                  (assignable_operator)
                  (identifier))
                (assignable_operator)
                (identifier))
              (index_selector
                (string_literal)))
            (null_assertion_operator)))
        (expression_statement
          (null_assertion_expression
            (unconditional_assignable_selector
              (identifier)
              (assignable_operator)
              (identifier))
            (null_assertion_operator)))))))

==================
Trailing non-null assertion in an initializer
==================

void main() {
  var a = req.url.q['a']!;
  final set = {'a': 1};
  var b = set.q['a']!;
}

---

(program
  (function_declaration
    (function_signature
      (void_type)
      (identifier)
      (formal_parameter_list))
    (function_body
      (block
        (local_variable_declaration
          (initialized_variable_definition
            (inferred_type)
            (identifier)
            (null_assertion_expression
              (unconditional_assignable_selector
                (unconditional_assignable_selector
                  (unconditional_assignable_selector
                    (identifier)
                    (assignable_operator)
                    (identifier))
                  (assignable_operator)
                  (identifier))
                (index_selector
                  (string_literal)))
              (null_assertion_operator))))
        (local_variable_declaration
          (initialized_variable_definition
            (final_builtin)
            (identifier)
            (set_or_map_literal
              (pair
                (string_literal)
                (decimal_integer_literal)))))
        (local_variable_declaration
          (initialized_variable_definition
            (inferred_type)
            (identifier)
            (null_assertion_expression
              (unconditional_assignable_selector
                (unconditional_assignable_selector
                  (identifier)
                  (assignable_operator)
                  (identifier))
                (index_selector
                  (string_literal)))
              (null_assertion_operator))))))))
