================================================================================
api/map
================================================================================

amends "../snippetTest.pkl"

local map1: Map<String, Int> = Map("one", 1, "two", 2, "three", 3)

facts {
  ["isEmpty"] {
    Map().isEmpty
    !map1.isEmpty
  }

  ["containsKey()"] {
    map1.containsKey("two")
    !Map().containsKey("two")
    !map1.containsKey("other")
  }

  ["containsValue()"] {
    map1.containsValue(3)
    !Map().containsValue(3)
    !map1.containsValue(4)
  }

  ["every()"] {
    Map().every((k, v) -> throw("unreachable code"))
    map1.every((k, v) -> v < 10)
    !map1.every((k, v) -> k.contains("o"))
  }

  ["any()"] {
    map1.any((k, v) -> k.contains("o"))
    !Map().any((k, v) -> throw("unreachable code"))
    !map1.any((k, v) -> false)
  }
}

examples {
  ["length"] {
    Map().length
    map1.length
  }

  ["getOrNull()"] {
    map1.getOrNull("one")
    map1.getOrNull("five")
  }

  ["keys"] {
    Map().keys
    map1.keys
    (Map("one", 1, "two", 2) + Map("three", 3, "four", 4)).keys
  }

  ["values"] {
    Map().values
    map1.values
    (Map("one", 1, "two", 2) + Map("three", 3, "four", 4)).values
  }

  ["remove()"] {
    Map().remove("two")
    map1.remove("two")
    map1.remove(2)
  }

  ["filter()"] {
    Map().filter((k, v) -> throw("unreachable"))
    map1.filter((k, v) -> k.contains("o"))
    map1.filter((k, v) -> v.isEven)
  }

  ["mapKeys()"] {
    Map().mapKeys((k, v) -> throw("unreachable"))
    map1.mapKeys((k, v) -> k.toUpperCase() + v.toString())
    map1.mapKeys((k, v) -> k)
  }

  ["mapValues()"] {
    Map().mapValues((k, v) -> throw("unreachable"))
    map1.mapValues((k, v) -> k.length + v * 3)
    map1.mapValues((k, v) -> v)
  }

  ["map()"] {
    Map().map((k, v) -> throw("unreachable"))
    map1.map((k, v) -> Pair(k, v * 3))
    map1.map((k, v) -> Pair(v, k))
    module.catch(() -> map1.map((k, v) -> 42))
  }

  ["flatMap()"] {
    Map().flatMap((k, v) -> throw("unreachable"))
    map1.flatMap((k, v) -> Map(v, v * 3))
    map1.flatMap((k, v) -> Map(k, k.reverse()))
    module.catch(() -> map1.flatMap((k, v) -> 42))
  }

  ["entries"] {
    Map().entries
    map1.entries
    (Map("one", 1, "two", 2) + Map("three", 3, "four", 4)).entries
  }

  ["toMap()"] {
    Map().toMap()
    map1.toMap()
  }

  ["toDynamic()"] {
    Map().toDynamic()
    map1.toDynamic()
  }

  ["toMapping()"] {
    Map().toMapping()
    map1.toMapping()
  }

  ["put()"] {
    Map().put("one", 1)
    map1.put("one", 1)
    map1.put("four", 4)
    map1.put("one", 4)
  }

  ["toTyped()"] {
    Map("name", "Pigeon", "age", 42).toTyped(Person)
    Map("age", 42, "name", "Pigeon").toTyped(Person)
    Map("age", 42).toTyped(Person).name
    Map("name", "Pigeon").toTyped(Person).hasProperty("name")
    Map("name", "Pigeon").toTyped(Person).hasProperty("age")
    Map("name", "Pigeon", "age", 42, "hobby", "surfing").toTyped(Person)
    module.catch(() -> Map("name", "Pigeon").toTyped(Person).age)
    module.catch(() -> Map().toTyped(Int))
    module.catch(() -> Map().toTyped(Abstract))
  }
}

local class Person { name: String = "Default"; age: Int }
local abstract class Abstract

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

(module
  (moduleHeader
    (extendsOrAmendsClause
      (stringConstant)))
  (classProperty
    (modifier)
    (identifier)
    (typeAnnotation
      (type
        (qualifiedIdentifier
          (identifier))
        (typeArgumentList
          (type
            (qualifiedIdentifier
              (identifier)))
          (type
            (qualifiedIdentifier
              (identifier))))))
    (methodCallExpr
      (identifier)
      (argumentList
        (slStringLiteral)
        (intLiteral)
        (slStringLiteral)
        (intLiteral)
        (slStringLiteral)
        (intLiteral))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (methodCallExpr
                  (identifier)
                  (argumentList)))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (intLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (methodCallExpr
                  (identifier)
                  (argumentList)))
              (identifier)
              (argumentList
                (intLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (intLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (binaryExpr
                    (variableExpr
                      (identifier))
                    (intLiteral))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (slStringLiteral)))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (methodCallExpr
                  (identifier)
                  (argumentList)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (falseLiteral)))))))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList
                  (binaryExpr
                    (methodCallExpr
                      (identifier)
                      (argumentList
                        (slStringLiteral)
                        (intLiteral)
                        (slStringLiteral)
                        (intLiteral)))
                    (methodCallExpr
                      (identifier)
                      (argumentList
                        (slStringLiteral)
                        (intLiteral)
                        (slStringLiteral)
                        (intLiteral))))))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList
                  (binaryExpr
                    (methodCallExpr
                      (identifier)
                      (argumentList
                        (slStringLiteral)
                        (intLiteral)
                        (slStringLiteral)
                        (intLiteral)))
                    (methodCallExpr
                      (identifier)
                      (argumentList
                        (slStringLiteral)
                        (intLiteral)
                        (slStringLiteral)
                        (intLiteral))))))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (intLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (binaryExpr
                      (methodCallExpr
                        (variableExpr
                          (identifier))
                        (identifier)
                        (argumentList))
                      (variableExpr
                        (identifier)))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (binaryExpr
                    (propertyCallExpr
                      (variableExpr
                        (identifier))
                      (identifier))
                    (binaryExpr
                      (variableExpr
                        (identifier))
                      (intLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))
                      (binaryExpr
                        (variableExpr
                          (identifier))
                        (intLiteral))))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))
                      (variableExpr
                        (identifier))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (functionLiteral
                        (parameterList
                          (typedIdentifier
                            (identifier))
                          (typedIdentifier
                            (identifier)))
                        (intLiteral))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (throwExpr
                    (parenthesizedExpr
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))
                      (binaryExpr
                        (variableExpr
                          (identifier))
                        (intLiteral))))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))
                      (methodCallExpr
                        (variableExpr
                          (identifier))
                        (identifier)
                        (argumentList))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (functionLiteral
                        (parameterList
                          (typedIdentifier
                            (identifier))
                          (typedIdentifier
                            (identifier)))
                        (intLiteral))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList
                  (binaryExpr
                    (methodCallExpr
                      (identifier)
                      (argumentList
                        (slStringLiteral)
                        (intLiteral)
                        (slStringLiteral)
                        (intLiteral)))
                    (methodCallExpr
                      (identifier)
                      (argumentList
                        (slStringLiteral)
                        (intLiteral)
                        (slStringLiteral)
                        (intLiteral))))))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList))
              (identifier)
              (argumentList
                (slStringLiteral)
                (intLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral)
                (intLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral)
                (intLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral)
                (intLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList
                  (slStringLiteral)
                  (slStringLiteral)
                  (slStringLiteral)
                  (intLiteral)))
              (identifier)
              (argumentList
                (variableExpr
                  (identifier)))))
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList
                  (slStringLiteral)
                  (intLiteral)
                  (slStringLiteral)
                  (slStringLiteral)))
              (identifier)
              (argumentList
                (variableExpr
                  (identifier)))))
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (methodCallExpr
                  (identifier)
                  (argumentList
                    (slStringLiteral)
                    (intLiteral)))
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))))
              (identifier)))
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (methodCallExpr
                  (identifier)
                  (argumentList
                    (slStringLiteral)
                    (slStringLiteral)))
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (methodCallExpr
                  (identifier)
                  (argumentList
                    (slStringLiteral)
                    (slStringLiteral)))
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (identifier)
                (argumentList
                  (slStringLiteral)
                  (slStringLiteral)
                  (slStringLiteral)
                  (intLiteral)
                  (slStringLiteral)
                  (slStringLiteral)))
              (identifier)
              (argumentList
                (variableExpr
                  (identifier)))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (propertyCallExpr
                    (methodCallExpr
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (slStringLiteral)
                          (slStringLiteral)))
                      (identifier)
                      (argumentList
                        (variableExpr
                          (identifier))))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (methodCallExpr
                      (identifier)
                      (argumentList))
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (methodCallExpr
                      (identifier)
                      (argumentList))
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))))))))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))
        (slStringLiteral))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (modifier)
    (identifier)))
