
org.opalj.br.analyses.VirtualFormalParametersKey.scala Maven / Gradle / Ivy
The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj
package br
package analyses
import scala.collection.immutable.ArraySeq
import scala.collection.mutable
/**
* The set of all explicit and implicit virtual formal method parameters in a project.
* The set also contains virtual formal parameters of library methods.
*
* @param data Contains for each virtual method the array with the virtual formal parameters. The
* value with index 0 contains the implicit `this` reference, the array elements with
* the indexes [1..method.descriptor.parametersCount] contain the respective
* [[VirtualFormalParameter]] objects for the corresponding method parameters.
* @author Florian Kuebler
*/
class VirtualFormalParameters private[analyses] (
val data: scala.collection.Map[DeclaredMethod, ArraySeq[VirtualFormalParameter]]
) {
/**
* Returns the virtual formal parameters array for the given method. If the method is not known,
* `null` is returned. If the method is known a non-null (but potentially empty)
* [[scala.collection.immutable.ArraySeq]] is returned.
*/
def apply(m: DeclaredMethod): ArraySeq[VirtualFormalParameter] = data.getOrElse(m, null)
def virtualFormalParameters: Iterable[VirtualFormalParameter] = {
// todo Why should it ever be null?
data.values.flatten.filter(_ ne null)
}
}
/**
* The ''key'' object to get information about all virtual formal parameters.
*
* @note See [[org.opalj.br.analyses.VirtualFormalParameter]] and [[VirtualFormalParameters]]
* for further details.
* @example To get the index use the [[org.opalj.br.analyses.Project]]'s `get` method and pass in
* `this` object.
* @author Florian Kuebler
*/
object VirtualFormalParametersKey extends ProjectInformationKey[VirtualFormalParameters, Nothing] {
/**
* The key uses the `VirtualForwardingMethodsKey`.
*/
override def requirements(project: SomeProject): ProjectInformationKeys = List(DeclaredMethodsKey)
/**
* Collects all virtual formal parameters.
*
* @note This analysis is internally parallelized. I.e., it is advantageous to run this
* analysis in isolation.
*/
override def compute(p: SomeProject): VirtualFormalParameters = {
val sites = mutable.HashMap.empty[DeclaredMethod, ArraySeq[VirtualFormalParameter]]
for {
dm <- p.get(DeclaredMethodsKey).declaredMethods
if (dm.hasSingleDefinedMethod)
} {
val md = dm.descriptor
val parametersCount = md.parametersCount
val formalParameters = new Array[VirtualFormalParameter](parametersCount + 1)
if (dm.hasSingleDefinedMethod && !dm.definedMethod.isStatic)
formalParameters(0) = new VirtualFormalParameter(dm, -1)
var p = 1
while (p <= parametersCount) {
formalParameters(p) = new VirtualFormalParameter(dm, -p - 1)
p += 1
}
sites += (dm -> ArraySeq.unsafeWrapArray(formalParameters))
}
new VirtualFormalParameters(sites)
}
//
// HELPER FUNCTION TO MAKE IT EASILY POSSIBLE TO ADD VIRTUAL FORMAL PARAMETERS TO A
// PROPERTYSTORE AND TO ENSURE THAT VIRTUAL FORMAL PARAMETERS AND THE PROPERTYSTORE CONTAIN THE SAME
// OBJECTS!
//
final val entityDerivationFunction: (SomeProject) => (Iterable[AnyRef], VirtualFormalParameters) = {
(p: SomeProject) =>
{
// this will collect the formal parameters of the project if not yet collected...
val formalParameters = p.get(VirtualFormalParametersKey)
(formalParameters.virtualFormalParameters, formalParameters)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy