All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opalj.br.fpcf.properties.immutability.ClassImmutability.scala Maven / Gradle / Ivy

The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package br
package fpcf
package properties
package immutability

import scala.collection.immutable.SortedSet

import org.opalj.fpcf.Entity
import org.opalj.fpcf.OrderedProperty
import org.opalj.fpcf.PropertyKey
import org.opalj.fpcf.PropertyMetaInformation
sealed trait ClassImmutabilityPropertyMetaInformation extends PropertyMetaInformation {
    final type Self = ClassImmutability
}

/**
 * Describes the class immutability of org.opalj.br.ClassFile.
 * The immutability of the classes are represented via the lower bound of the immutability of
 * their instance fields and the immutability of its supertype.
 *
 * [[MutableClass]] The class has mutable fields.
 *
 * [[NonTransitivelyImmutableClass]] A class that's transitive state is not immutable but the values or objects representing
 * this transitive state (are not / can not be) exchanged.
 *
 * [[DependentlyImmutableClass]] A class that is at least non-transitively immutable.
 * Whether it is non-transitively or transitively immutable depends on (a) generic parameter(s).
 *
 * [[TransitivelyImmutableClass]] A class with a transitively immutable state.
 *
 * @author Tobias Roth
 */
sealed trait ClassImmutability extends OrderedProperty with ClassImmutabilityPropertyMetaInformation {

    final def key: PropertyKey[ClassImmutability] = ClassImmutability.key

    def correspondingTypeImmutability: TypeImmutability
    def isDependentlyImmutable: Boolean = false
}

object ClassImmutability extends ClassImmutabilityPropertyMetaInformation {

    /**
     * The key associated with every [[ClassImmutability]] property.
     */
    final val key: PropertyKey[ClassImmutability] = PropertyKey.create(
        "opalj.ClassImmutability",
        MutableClass
    )
}

case object TransitivelyImmutableClass extends ClassImmutability {

    override def correspondingTypeImmutability: TypeImmutability = TransitivelyImmutableType

    override def checkIsEqualOrBetterThan(e: Entity, other: Self): Unit = {}

    def meet(that: ClassImmutability): ClassImmutability = that
}

case class DependentlyImmutableClass(parameters: SortedSet[String]) extends ClassImmutability {

    override def correspondingTypeImmutability: TypeImmutability = DependentlyImmutableType(parameters)

    override def isDependentlyImmutable: Boolean = true
    def meet(that: ClassImmutability): ClassImmutability =
        if (that == MutableClass || that == NonTransitivelyImmutableClass)
            that
        else
            this

    override def checkIsEqualOrBetterThan(e: Entity, other: Self): Unit = {
        if (other == TransitivelyImmutableClass) {
            throw new IllegalArgumentException(s"$e: impossible refinement: $other => $this")
        }
    }
}

case object NonTransitivelyImmutableClass extends ClassImmutability {
    override def correspondingTypeImmutability: TypeImmutability = NonTransitivelyImmutableType

    def meet(that: ClassImmutability): ClassImmutability = {
        if (that == MutableClass)
            that
        else
            this
    }

    override def checkIsEqualOrBetterThan(e: Entity, other: Self): Unit = {
        other match {
            case TransitivelyImmutableClass | DependentlyImmutableClass(_) =>
                throw new IllegalArgumentException(s"$e: impossible refinement: $other => $this")
            case _ =>
        }
    }
}

case object MutableClass extends ClassImmutability {

    def correspondingTypeImmutability: TypeImmutability = MutableType

    def meet(other: ClassImmutability): ClassImmutability = this

    override def checkIsEqualOrBetterThan(e: Entity, other: Self): Unit = {
        if (other != MutableClass) {
            throw new IllegalArgumentException(s"$e: impossible refinement: $other => $this")
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy