================================================================================
Simple identifiers
================================================================================

helloWorld

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

(source_file
  (simple_identifier))

================================================================================
Boolean literals
================================================================================

true
false

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

(source_file
  (boolean_literal)
  (boolean_literal))

================================================================================
String literals
================================================================================

"Hello World!"
"""
This is a "multiline"
string.
"""
"This string has a // comment (except not!)"

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

(source_file
  (line_string_literal
    (line_str_text))
  (multi_line_string_literal
    (multi_line_str_text)
    (multi_line_str_text)
    (multi_line_str_text))
  (line_string_literal
    (line_str_text)))

================================================================================
String interpolation
================================================================================

"Sample \("string.interpolation") literal"
"""
Multiline
\("""string interpolation""") literal
"""
"This is a string with // a comment in it"
"""
   And so is this! /*
   #if qwertyuiop
   And yet neither of those comments should register
""" // This comment is valid

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

(source_file
  (line_string_literal
    (line_str_text)
    (interpolated_expression
      (line_string_literal
        (line_str_text)))
    (line_str_text))
  (multi_line_string_literal
    (multi_line_str_text)
    (interpolated_expression
      (multi_line_string_literal
        (multi_line_str_text)))
    (multi_line_str_text))
  (line_string_literal
    (line_str_text))
  (multi_line_string_literal
    (multi_line_str_text))
  (comment))

================================================================================
Custom interpolation
================================================================================
"Hi, I'm \(format: age)"

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

(source_file
  (line_string_literal
    (line_str_text)
    (interpolated_expression
      (simple_identifier)
      (simple_identifier))))

================================================================================
Strings with newline escaping
================================================================================

"""
This is a string that acts as though it \
    is all on one line
"""

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

(source_file
  (multi_line_string_literal
    (multi_line_str_text)
    (str_escaped_char)
    (multi_line_str_text)))

================================================================================
Integer literals
================================================================================

0
8
23
9847
0xf00
0o774
0b01

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

(source_file
  (integer_literal)
  (integer_literal)
  (integer_literal)
  (integer_literal)
  (hex_literal)
  (oct_literal)
  (bin_literal))

================================================================================
Real literals
================================================================================

0.0
-23.434
1e-10
4.3
+53.9e-3

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

(source_file
  (real_literal)
  (prefix_expression
    (real_literal))
  (real_literal)
  (real_literal)
  (prefix_expression
    (real_literal)))

================================================================================
Collections
================================================================================

let numbers = [1, 2, 3]
let numerals = [1: "I", 4: "IV", 5: "V", 10: "X"]

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (array_literal
      (integer_literal)
      (integer_literal)
      (integer_literal)))
  (property_declaration
    (pattern
      (simple_identifier))
    (dictionary_literal
      (integer_literal)
      (line_string_literal
        (line_str_text))
      (integer_literal)
      (line_string_literal
        (line_str_text))
      (integer_literal)
      (line_string_literal
        (line_str_text))
      (integer_literal)
      (line_string_literal
        (line_str_text)))))

================================================================================
Trailing commas
================================================================================

[
    "Time": Date.now(),
    "Success": true,
]

[1, 2, 3, 4, 5,]

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

(source_file
  (dictionary_literal
    (line_string_literal
      (line_str_text))
    (call_expression
      (navigation_expression
        (simple_identifier)
        (navigation_suffix
          (simple_identifier)))
      (call_suffix
        (value_arguments)))
    (line_string_literal
      (line_str_text))
    (boolean_literal))
  (array_literal
    (integer_literal)
    (integer_literal)
    (integer_literal)
    (integer_literal)
    (integer_literal)))

================================================================================
Nil
================================================================================

let _ = nil

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

(source_file
  (property_declaration
    (pattern
      (wildcard_pattern))))

================================================================================
Raw strings
================================================================================

let _ = #"Hello, world!"#
let _ = ##"Hello, so-called "world"!"##

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

(source_file
  (property_declaration
    (pattern
      (wildcard_pattern))
    (raw_string_literal
      (raw_str_end_part)))
  (property_declaration
    (pattern
      (wildcard_pattern))
    (raw_string_literal
      (raw_str_end_part))))

================================================================================
Doesn't hang for incomplete raw strings (issue #146)
================================================================================

let _ = #"Foo"

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

(source_file
  (property_declaration
    (pattern
      (wildcard_pattern))
    (ERROR
      (UNEXPECTED '"'))
    (line_string_literal
      (line_str_text))))

================================================================================
Raw strings with interpolation
================================================================================

extension URL {
    func html(withTitle title: String) -> String {
        return #"<a href="\#(absoluteString)">\#(title)</a>"#
    }
}

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

(source_file
  (class_declaration
    (user_type
      (type_identifier))
    (class_body
      (function_declaration
        (simple_identifier)
        (parameter
          (simple_identifier)
          (simple_identifier)
          (user_type
            (type_identifier)))
        (user_type
          (type_identifier))
        (function_body
          (statements
            (control_transfer_statement
              (raw_string_literal
                (raw_str_part)
                (raw_str_interpolation
                  (raw_str_interpolation_start)
                  (interpolated_expression
                    (simple_identifier)))
                (raw_str_part)
                (raw_str_interpolation
                  (raw_str_interpolation_start)
                  (interpolated_expression
                    (simple_identifier)))
                (raw_str_end_part)))))))))

================================================================================
Raw strings interpolation edge cases
================================================================================

print(#"Hello \#(world /* commented out)"#)  */ )"#)

let _ = ##"Multiple pound signs \##(interpolated): still one part "# not done yet "##
let _ = ##"Fake \#(interpolation) and unused # pound signs "##
let _ = ##"\##(a)\#(b)\##(c)\#(d)"# ##"##
let _ = #"""
\\#(12)\#
"""#

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

(source_file
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (raw_string_literal
            (raw_str_part)
            (raw_str_interpolation
              (raw_str_interpolation_start)
              (interpolated_expression
                (simple_identifier))
              (multiline_comment))
            (raw_str_end_part))))))
  (property_declaration
    (pattern
      (wildcard_pattern))
    (raw_string_literal
      (raw_str_part)
      (raw_str_interpolation
        (raw_str_interpolation_start)
        (interpolated_expression
          (simple_identifier)))
      (raw_str_end_part)))
  (property_declaration
    (pattern
      (wildcard_pattern))
    (raw_string_literal
      (raw_str_end_part)))
  (property_declaration
    (pattern
      (wildcard_pattern))
    (raw_string_literal
      (raw_str_part)
      (raw_str_interpolation
        (raw_str_interpolation_start)
        (interpolated_expression
          (simple_identifier)))
      (raw_str_part)
      (raw_str_interpolation
        (raw_str_interpolation_start)
        (interpolated_expression
          (simple_identifier)))
      (raw_str_end_part)))
  (property_declaration
    (pattern
      (wildcard_pattern))
    (raw_string_literal
      (raw_str_part)
      (raw_str_interpolation
        (raw_str_interpolation_start)
        (interpolated_expression
          (integer_literal)))
      (raw_str_end_part))))

================================================================================
Unicode escape sequences
================================================================================

let unicodeEscaping = "\u{8}"
let anotherUnicode = "…\u{2060}"
let infinity = "\u{221E}"

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (line_string_literal
      (str_escaped_char)))
  (property_declaration
    (pattern
      (simple_identifier))
    (line_string_literal
      (line_str_text)
      (str_escaped_char)))
  (property_declaration
    (pattern
      (simple_identifier))
    (line_string_literal
      (str_escaped_char))))

================================================================================
Playground literals
================================================================================

let playgroundLiteral = #imageLiteral(resourceName: "heart")

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (simple_identifier)
    (line_string_literal
      (line_str_text))))

================================================================================
Single line regex literals
================================================================================

let regex1 = /([ab])?/
let regex2 = /([ab])|\d+/

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (regex_literal))
  (property_declaration
    (pattern
      (simple_identifier))
    (regex_literal)))

================================================================================
Multiline regex literals
================================================================================

let regex = #/
  # Match a line of the format e.g "DEBIT  03/03/2022  Totally Legit Shell Corp  $2,000,000.00"
  (?<kind>    \w+)                \s\s+
  (?<date>    \S+)                \s\s+
  (?<account> (?: (?!\s\s) . )+)  \s\s+ # Note that account names may contain spaces.
  (?<amount>  .*)
/#

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (regex_literal)))

================================================================================
Parse ambiguity in regex liteal and comment
================================================================================

/*
let regex = /[0-9]*/

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

(source_file
  (multiline_comment))

================================================================================
Regex-like custom operator not in expression position
================================================================================

infix operator /^/
func /^/ (lhs: Int, rhs: Int) -> Int { 0 }
let b = 0 /^/ 1

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

(source_file
  (operator_declaration
    (custom_operator))
  (function_declaration
    (custom_operator)
    (parameter
      (simple_identifier)
      (user_type
        (type_identifier)))
    (parameter
      (simple_identifier)
      (user_type
        (type_identifier)))
    (user_type
      (type_identifier))
    (function_body
      (statements
        (integer_literal))))
  (property_declaration
    (pattern
      (simple_identifier))
    (infix_expression
      (integer_literal)
      (custom_operator)
      (integer_literal))))

================================================================================
Unapplied `/` that is not a regex literal
================================================================================

let x = array.reduce(1, /) / 5
let y = array.reduce(1, /) + otherArray.reduce(1, /)

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (multiplicative_expression
      (call_expression
        (navigation_expression
          (simple_identifier)
          (navigation_suffix
            (simple_identifier)))
        (call_suffix
          (value_arguments
            (value_argument
              (integer_literal))
            (value_argument))))
      (integer_literal)))
  (property_declaration
    (pattern
      (simple_identifier))
    (call_expression
      (navigation_expression
        (additive_expression
          (call_expression
            (navigation_expression
              (simple_identifier)
              (navigation_suffix
                (simple_identifier)))
            (call_suffix
              (value_arguments
                (value_argument
                  (integer_literal))
                (value_argument))))
          (simple_identifier))
        (navigation_suffix
          (simple_identifier)))
      (call_suffix
        (value_arguments
          (value_argument
            (integer_literal))
          (value_argument))))))

================================================================================
Unapplied custom operators
================================================================================

baz(!/, 1) / 2
qux(/, /)
qux(/^, /)
qux(!/, /)

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

(source_file
  (multiplicative_expression
    (call_expression
      (simple_identifier)
      (call_suffix
        (value_arguments
          (value_argument
            (custom_operator))
          (value_argument
            (integer_literal)))))
    (integer_literal))
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument)
        (value_argument))))
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (custom_operator))
        (value_argument))))
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (custom_operator))
        (value_argument)))))

================================================================================
More operator not-regex edge cases
================================================================================

let d = hasSubscript[/] / 2 // Unapplied infix '/' and infix '/'
let e = !/y / .foo() // Prefix '!/' with infix '/' and operand '.foo()'

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

(source_file
  (property_declaration
    (pattern
      (simple_identifier))
    (multiplicative_expression
      (call_expression
        (simple_identifier)
        (call_suffix
          (value_arguments
            (value_argument))))
      (integer_literal)))
  (comment)
  (property_declaration
    (pattern
      (simple_identifier))
    (call_expression
      (prefix_expression
        (custom_operator)
        (multiplicative_expression
          (simple_identifier)
          (prefix_expression
            (simple_identifier))))
      (call_suffix
        (value_arguments))))
  (comment))

================================================================================
Ambiguous parse cases that now are regexes
================================================================================

foo(/a, b/) // Will become regex literal '/a, b/'
qux(/, !/)  // Will become regex literal '/, !/'
qux(/,/)    // Will become regex literal '/,/'

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

(source_file
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (regex_literal)))))
  (comment)
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (regex_literal)))))
  (comment)
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (regex_literal)))))
  (comment))

================================================================================
Unapplied division operator
================================================================================

class Operator {
    var perform: (Double, Double) -> Double {
        return (/)
    }
}

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

(source_file
  (class_declaration
    (type_identifier)
    (class_body
      (property_declaration
        (pattern
          (simple_identifier))
        (type_annotation
          (function_type
            (tuple_type
              (tuple_type_item
                (user_type
                  (type_identifier)))
              (tuple_type_item
                (user_type
                  (type_identifier))))
            (user_type
              (type_identifier))))
        (computed_property
          (statements
            (control_transfer_statement
              (tuple_expression))))))))

================================================================================
Single-line regex on multiple lines
================================================================================

doOperation(on: a, /)
/// That was fun! We ran `/`

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

(source_file
  (call_expression
    (simple_identifier)
    (call_suffix
      (value_arguments
        (value_argument
          (simple_identifier)
          (simple_identifier))
        (value_argument))))
  (comment))
