================================================================================
api/typed
================================================================================

amends "../snippetTest.pkl"

local class Empty

local open class Animal {
  species: String
  age: Int
  numberOfFeet: Int = 2
}

local class Dinosaur extends Animal {
  isExtinct: Boolean = true
}

local dino = new Dinosaur {
  numberOfFeet = 4
}

local pigeon = new Animal {
  local n = "Pigeon"
  species = n
  age = 5
}

examples {
  ["getProperty()"] {
    pigeon.getProperty("species")
    pigeon.getProperty("spe" + "cies")
    pigeon.getProperty("age")
    module.catch(() -> pigeon.getProperty("other"))
  }

  ["getPropertyOrNull()"] {
    pigeon.getPropertyOrNull("species")
    pigeon.getPropertyOrNull("speci" + "es")
    pigeon.getPropertyOrNull("age")
    pigeon.getPropertyOrNull("other")
  }

  ["hasProperty()"] {
    pigeon.hasProperty("species")
    pigeon.hasProperty("specie" + "s")
    pigeon.hasProperty("age")
    pigeon.hasProperty("other")

    pigeon.hasProperty("numberOfFeet")
    dino.hasProperty("numberOfFeet")
    dino.hasProperty("isAlive")
  }

  ["toDynamic()"] {
    local dynPigeon = pigeon.toDynamic()
    dynPigeon
    dynPigeon.getClass().simpleName
    (dynPigeon) {
      age = "age" // change type
      ["isExtinct"] = false // add new property
    }
    (new Animal { species = "Pigeon"; age = species.length }.toDynamic()) {
      species = "Pigeon" // no dynamic binding
    }
  }

  ["toMap()"] {
    local mapPigeon = pigeon.toMap()
    mapPigeon
    mapPigeon.getClass().simpleName
    new Empty {}.toMap()
    pigeon.toDynamic().toMap()
    new Dynamic { species = "Pigeon"; age = species.length }.toMap() + Map(
        "species", "Pigeon"
      )
  }
}

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

(module
  (moduleHeader
    (extendsOrAmendsClause
      (stringConstant)))
  (clazz
    (modifier)
    (identifier))
  (clazz
    (modifier)
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))
        (intLiteral))))
  (clazz
    (modifier)
    (identifier)
    (classExtendsClause
      (qualifiedIdentifier
        (identifier)))
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))
        (trueLiteral))))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody
        (objectProperty
          (identifier)
          (intLiteral)))))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody
        (objectProperty
          (modifier)
          (identifier)
          (slStringLiteral))
        (objectProperty
          (identifier)
          (variableExpr
            (identifier)))
        (objectProperty
          (identifier)
          (intLiteral)))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (binaryExpr
                  (slStringLiteral)
                  (slStringLiteral)))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (slStringLiteral)))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (binaryExpr
                  (slStringLiteral)
                  (slStringLiteral)))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (binaryExpr
                  (slStringLiteral)
                  (slStringLiteral)))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectProperty
            (modifier)
            (identifier)
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (variableExpr
              (identifier)))
          (objectElement
            (objectLiteral
              (methodCallExpr
                (methodCallExpr
                  (variableExpr
                    (identifier))
                  (identifier)
                  (argumentList))
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral))
                (lineComment)
                (objectEntry
                  (slStringLiteral)
                  (falseLiteral))
                (lineComment))))
          (objectElement
            (objectLiteral
              (parenthesizedExpr
                (methodCallExpr
                  (newExpr
                    (type
                      (qualifiedIdentifier
                        (identifier)))
                    (objectBody
                      (objectProperty
                        (identifier)
                        (slStringLiteral))
                      (objectProperty
                        (identifier)
                        (propertyCallExpr
                          (variableExpr
                            (identifier))
                          (identifier)))))
                  (identifier)
                  (argumentList)))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral))
                (lineComment))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectProperty
            (modifier)
            (identifier)
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (variableExpr
              (identifier)))
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList))
              (identifier)))
          (objectElement
            (methodCallExpr
              (newExpr
                (type
                  (qualifiedIdentifier
                    (identifier)))
                (objectBody))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList))
              (identifier)
              (argumentList)))
          (objectElement
            (binaryExpr
              (methodCallExpr
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (slStringLiteral))
                    (objectProperty
                      (identifier)
                      (propertyCallExpr
                        (variableExpr
                          (identifier))
                        (identifier)))))
                (identifier)
                (argumentList))
              (methodCallExpr
                (identifier)
                (argumentList
                  (slStringLiteral)
                  (slStringLiteral))))))))))
