================================================================================
objects/hashCode
================================================================================

amends "../snippetTest.pkl"

local class Person { name: String }

local open class Person2 { name: String; hidden age: Int }

local class Teenager extends Person2 { age = 15 }

facts {
  local set: Set<Int> = IntSeq(1, 100).fold(Set(), (res, n) -> res.add(n))
  
  ["local members aren't included in hash code - Dynamic"] {
    local obj1 = new Dynamic { name = "Pigeon" }
    local obj2 = new Dynamic { name = x; local x = "Pigeon" }
    local obj3 = new Dynamic { name = x; local x = "Pigeon" } { name = y; local y = "Pigeon" }
    
    set.add(obj1).contains(obj2)
    set.add(obj2).contains(obj3)
    set.add(obj3).contains(obj2)
    set.add(obj1).add(obj2).add(obj3).length == 101
  }

  ["local members aren't included in hash code - Typed"] {
    local obj1 = new Person { name = "Pigeon" }
    local obj2 = new Person { name = x; local x = "Pigeon" }
    local obj3 = new Person { name = x; local x = "Pigeon" } { name = y; local y = "Pigeon" }

    set.add(obj1).contains(obj2)
    set.add(obj2).contains(obj3)
    set.add(obj3).contains(obj2)
    set.add(obj1).add(obj2).add(obj3).length == 101
  }

  ["hidden members aren't included in hash code - Dynamic"] {
    local obj1 = new Dynamic { name = "Pigeon" }
    local obj2 = new Dynamic { name = "Pigeon"; default = (_) -> 42 }

    set.add(obj1).contains(obj2)
    set.add(obj2).contains(obj1)
    set.add(obj1).add(obj2).length == 101
  }

  ["hidden members aren't included in hash code - Typed"] {
    local obj1 = new Person2 { name = "Pigeon" }
    local obj2 = new Person2 { name = "Pigeon"; age = 42 }

    set.add(obj1).contains(obj2)
    set.add(obj2).contains(obj1)
    set.add(obj1).add(obj2).length == 101
  }

  ["hidden members of superclass aren't included in hash code - Typed"] {
    local obj = new Teenager { name = "Jojo" }
    set.add(obj).length == 101
  }
}

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

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