
org.opalj.br.fpcf.properties.ThrownExceptions.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
import org.opalj.fpcf.Property
import org.opalj.fpcf.PropertyKey
import org.opalj.fpcf.PropertyMetaInformation
import org.opalj.br.collection.{TypesSet => BRTypesSet}
sealed trait ThrownExceptionsPropertyMetaInformation extends PropertyMetaInformation {
final type Self = ThrownExceptions
}
/**
* The set of exceptions that are potentially thrown by a specific method.
* This includes the set of exceptions thrown by (transitively) called methods (if any).
* The property '''does not take the exceptions of methods which override the respective
* method into account'''.
* Nevertheless, in case of a method call all potential receiver methods are
* taken into consideration.
*
* Note that it may be possible to compute some meaningful upper type bound for the set of
* thrown exceptions even if methods are called for which the set of thrown exceptions is unknown.
* This is generally the case if those calls are all done in a try block but the catch/finally
* blocks only calls known methods - if any.
* An example is shown next and even if we assume that we don't know
* the exceptions potentially thrown by `Class.forName`, we could still determine that this method
* will never throw an exception.
* {{{
* object Validator {
* def isAvailable(s : String) : Boolean = {
* try { Class.forName(s); true} finally {return false;}
* }
* }
* }}}
*
* Information about `ThrownExceptions` is generally associated with `DeclaredMethods`. I.e.,
* the information is not attached to `Method` objects!
*
* Note that the top-value of the lattice is the empty set and the bottom value is the set
* of all exceptions.
*
* @author Michael Eichberg
*/
case class ThrownExceptions(
types: BRTypesSet
)
extends Property
with ThrownExceptionsPropertyMetaInformation {
final def key = ThrownExceptions.key
/**
* Returns `true` if and only if the method does not '''yet''' throw exceptions. I.e., if
* this property is still refinable then this property may still change. Otherwise,
* the analysis was able to determine that no exceptions are thrown.
*/
def throwsNoExceptions: Boolean = types.isEmpty
override def toString: String = {
if (this == ThrownExceptions.MethodIsNative)
"""ThrownExceptionsAreUnknown(reason="method is native")"""
else if (this == ThrownExceptions.UnknownExceptionIsThrown)
"""ThrownExceptionsAreUnknown(reason="the exception type is unknown")"""
else if (this == ThrownExceptions.MethodBodyIsNotAvailable)
"""ThrownExceptionsAreUnknown(reason="method body is not available")"""
else if (this == ThrownExceptions.AnalysisLimitation)
"""ThrownExceptionsAreUnknown(reason="analysis limitation")"""
else if (this == ThrownExceptions.MethodCalledThrowsUnknownExceptions)
"""ThrownExceptionsAreUnknown(reason="Method called throws unknown exception")"""
else if (this == ThrownExceptions.SomeException)
"""ThrownExceptionsAreUnknown(reason="")"""
else
s"ThrownExceptions(${types.toString})"
}
}
object ThrownExceptions extends ThrownExceptionsPropertyMetaInformation {
def apply(types: BRTypesSet): ThrownExceptions = new ThrownExceptions(types)
final val key: PropertyKey[ThrownExceptions] = {
PropertyKey.create[br.DeclaredMethod, ThrownExceptions](
"ThrownExceptions",
ThrownExceptionsFallback
)
}
final val NoExceptions: ThrownExceptions = new ThrownExceptions(BRTypesSet.empty)
//
// In the following we use specific instances to identify specific reasons...
//
final def SomeException = new ThrownExceptions(BRTypesSet.SomeException)
final val MethodIsNative = new ThrownExceptions(BRTypesSet.SomeException)
final val UnknownExceptionIsThrown = new ThrownExceptions(BRTypesSet.SomeException)
final val MethodBodyIsNotAvailable = new ThrownExceptions(BRTypesSet.SomeException)
final val AnalysisLimitation = new ThrownExceptions(BRTypesSet.SomeException)
final val MethodIsAbstract = new ThrownExceptions(BRTypesSet.SomeException)
final val MethodCalledThrowsUnknownExceptions = new ThrownExceptions(BRTypesSet.SomeException)
final val UnresolvedInvokeDynamicInstruction = new ThrownExceptions(BRTypesSet.SomeException)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy