Packages

sealed abstract class Purity extends IndividualProperty[Purity, VirtualMethodPurity] with PurityPropertyMetaInformation

Describes the level of the purity of a org.opalj.br.DeclaredMethod.

In general, a method is pure if its result only depends on its inputs and/or immutable global state and the execution of the method does not have any side effects; an instance method's inputs include the current object that is the receiver of the call.

The description of the purity levels is inspired by the definition found on wikipedia:

[...] a function may be considered a pure function if both of the following statements about the function hold:

  • The function always evaluates to the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change while program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices.

Hence, using true constants (e.g., Math.e) is not a problem as well as creating intermediate (mutable) data structures. More precisely, methods are pure if the values they refer to always (even across program runs) have an identical shape and the precise location in the heap is not relevant (e.g., java.lang.Object.hashCode() and ...toString() are not pure).

  • Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices. The result value need not depend on all (or any) of the argument values. However, it must depend on nothing other than the argument values. The function may return multiple result values and these conditions must apply to all returned values for the function to be considered pure. If an argument is "call-by-reference", any parameter mutation will alter the value of the argument outside the function, which will render the function impure.

Given the preceding specification, the purity of a method is described by the subclasses of this property. In the following, the prefix of the names of the purity levels are used to identify the certainty of the computation of the purity; the letters have the following meaning:

  • LB = Lower Bound; the method is at least <PURITY_LEVEL>, but can still be even more pure.
  • C = Conditional; i.e., the current purity level depends on the purity level of other entities (These states are primarily used by the analysis to record the analysis progress.)
  • D = The method is <PURITY_LEVEL> if certain Domain-specific (non-pure) operations are ignored.

ImpureByLackOfInformation methods have no constraints on their behavior. They may have side effect and depend on all accessible (global) state. Analyses can always return (LB)Impure as a safe default value - even if they are not able to prove that a method is indeed impure; however, in the latter case using ImpureByAnalysis is recommended as this enables subsequent analyses to refine the property. There are several implementations of ImpureByAnalysis which give additional reasoning why the analysis classified a method as impure.

SideEffectFree methods may depend on all accessible (and mutable) state, but may not have any side effects. In single-threaded execution, this means that the object graph of the program may not have changed between invocation of the method and its return, except for potentially additional objects allocated by the method. For multi-threaded execution, the object graph may not change due to the invocation of the method, again except allocation of new objects. Note that the object graph may change during execution of the method due to other methods executing on concurrent threads. The method must not have any effects (besides consumption of resources like memory and processor time) on methods executing concurrently, in particular it may not acquire any locks on objects that concurrent methods could also try to acquire.

Analyses may return SideEffectFree as a safe default value if they are unable to guarantee that a method is Pure, even if it is. However, to return SideEffectFree the analysis has to guarantee that the method does not have any side effects.

Pure methods must be side effect free as described above and their result may only depend on their parameters (including the receiver object) and global constants. In particular, the result of a pure method must be structurally identical each time the method is invoked with structurally identical parameters. I.e., pure methods may depend on the aliasing relation between their parameters or between their parameters and global constants. E.g., the following method is pure:

def cmp(s: String) : Boolean = {
     // Reference(!) comparison of s with the interned string "Demo":
     s eq "Demo";
}

In multi-threaded execution, pure methods can not depend on any mutable state of their parameters if that state might be mutated by concurrently executing methods.

Analyses may return Pure only if they are able to guarantee that a method fulfills these requirements.

CompileTimePure methods additionally may only use global state that is compile-time constant (i.e., deterministically initialized to the same value on every execution of the program). If their return value is of a reference type, they must return the same reference each time they are invoked with identical parameters.

ExternallySideEffectFree and ExternallyPure methods are also similar to SideEffectFree and Pure methods, respectively, but may modify their receiver object. These properties may be used to detect changes that are confined because the receiver object is under the control of the caller.

ContextuallySideEffectFree and ContextuallyPure methods may modifiy not only their receiver object but all of their parameters. Therefore, these properties can be used to detect confined changes because all parameters are under the control of the caller.

DSideEffectFree and DPure methods may perform actions that are generally considered impure (or non-deterministic in the case of DPure), but that some clients may want to treat as pure. Such actions include, e.g. logging. A Rater is used to identify such actions and the properties contain a set of reasons assigned by the Rater.

DExternallySideEffectFree and DExternallyPure methods are similar, but may again modify their receiver, while DContextuallySideEffectFree and DContextuallyPure methods may modify their parameters.

ImpureByLackOfInformation is (also) used as the fallback value if no purity information could be computed for a method (no analysis is scheduled). Conceptually, clients must treat this in the same way as ImpureByAnalysis except that a future refinement may be possible in case of ImpureByAnalysis.

Source
Purity.scala
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. Purity
  2. PurityPropertyMetaInformation
  3. IndividualProperty
  4. AggregatableValueProperty
  5. Property
  6. PropertyMetaInformation
  7. PropertyKind
  8. AnyRef
  9. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. final type Self = Purity
  2. type self = Purity

Abstract Value Members

  1. abstract val flags: Int

Concrete Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def aggregatedProperty: VirtualMethodPurity
    Definition Classes
    PurityIndividualProperty
  5. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  6. final def asOrderedProperty: OrderedProperty

    Returns this if this property inherits from OrderedProperty.

    Returns this if this property inherits from OrderedProperty.

    Used, e.g., by the framework to support debugging analyses.

    Definition Classes
    Property
  7. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... ) @native() @IntrinsicCandidate()
  8. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  9. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  10. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @IntrinsicCandidate()
  11. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native() @IntrinsicCandidate()
  12. final def id: Int

    The id uniquely identifies this property's category.

    The id uniquely identifies this property's category. All property objects of the same kind have to use the same id which is guaranteed since they share the same PropertyKey

    Definition Classes
    PropertyMetaInformationPropertyKind
  13. def isCompileTimePure: Boolean
  14. def isDeterministic: Boolean
  15. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  16. final def isOrderedProperty: Boolean

    Returns true if this property inherits from OrderedProperty.

    Returns true if this property inherits from OrderedProperty.

    Definition Classes
    Property
  17. final def key: PropertyKey[Purity]

    The globally unique key of the Purity property.

    The globally unique key of the Purity property.

    Definition Classes
    PurityPropertyMetaInformation
  18. def meet(other: Purity): Purity

    Combines this purity value with another one to represent the progress by a purity analysis in one phase.

    Combines this purity value with another one to represent the progress by a purity analysis in one phase. Conditional as well as unconditional values are combined to the purity level that expresses a weaker purity, thereby incorporating the effect of counter-examples to a stronger purity. Thus, the result of this operation is used to represent a (potentially conditional) upper bound on the possible final result of the purity analysis that performs this operation. If one of the combined purity values is conditional and the other is not, the result will be the same as if the conditional purity value was combined with the conditional value that corresponds to the unconditional value.

    Definition Classes
    PurityAggregatableValueProperty
  19. val modifiedParams: IntTrieSet
  20. def modifiesParameters: Boolean
  21. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  22. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @IntrinsicCandidate()
  23. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native() @IntrinsicCandidate()
  24. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  25. def toString(): String
    Definition Classes
    AnyRef → Any
  26. def usesDomainSpecificActions: Boolean
  27. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  28. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... ) @native()
  29. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  30. def withoutContextual: Purity

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] ) @Deprecated
    Deprecated

Inherited from Property

Inherited from PropertyMetaInformation

Inherited from PropertyKind

Inherited from AnyRef

Inherited from Any

Ungrouped