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

org.opalj.br.analyses.StringConstantsInformationKey.scala Maven / Gradle / Ivy

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

import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentLinkedQueue
import scala.jdk.CollectionConverters._
import org.opalj.br.instructions.LDCString
import org.opalj.concurrent.defaultIsInterrupted
import org.opalj.br.instructions.LDC
import org.opalj.br.instructions.LDC_W

import scala.collection.immutable.ArraySeq
import scala.collection.mutable

/**
 * The ''key'' object to get information about all string constants found in the project's code.
 *
 * @example To get the index use the [[Project]]'s `get` method and pass in `this` object.
 *
 * @author Michael Eichberg
 */
object StringConstantsInformationKey
    extends ProjectInformationKey[StringConstantsInformation, Nothing] {

    /**
     * The analysis has no special prerequisites.
     *
     * @return `Nil`.
     */
    override def requirements(project: SomeProject): Seq[ProjectInformationKey[Nothing, Nothing]] = Nil

    /**
     * Computes the field access information.
     *
     * @note  This analysis is internally parallelized. I.e., it is advantageous to run this
     *        analysis in isolation.
     */
    override def compute(project: SomeProject): mutable.Map[String, ArraySeq[PCInMethod]] = {

        val estimatedSize = project.methodsCount
        val map = new ConcurrentHashMap[String, ConcurrentLinkedQueue[PCInMethod]](estimatedSize)

        project.parForeachMethodWithBody(defaultIsInterrupted) { methodInfo =>
            val method = methodInfo.method

            method.body.get foreach { i: PCAndInstruction =>
                val pc = i.pc
                val instruction = i.instruction
                if (instruction.opcode == LDC.opcode || instruction.opcode == LDC_W.opcode) {
                    instruction match {
                        case LDCString(value) =>
                            var list: ConcurrentLinkedQueue[PCInMethod] = map.get(value)
                            if (list eq null) {
                                list = new ConcurrentLinkedQueue[PCInMethod]()
                                val previousList = map.putIfAbsent(value, list)
                                if (previousList != null) list = previousList
                            }
                            list.add(PCInMethod(method, pc))
                        case _ => /*other type of constant*/
                    }
                }
            }
        }

        val result: mutable.Map[String, ArraySeq[PCInMethod]] = mutable.Map.empty
        map.asScala foreach { kv =>
            val (name, locations) = kv
            result += ((name, ArraySeq.unsafeWrapArray(locations.asScala.toArray)))
        }
        result
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy