Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions OPAL/ba/src/test/scala/org/opalj/ba/FieldBuilderTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package org.opalj
package ba

import scala.language.postfixOps
import scala.reflect.classTag
import scala.reflect.runtime.universe.*

import java.io.ByteArrayInputStream

Expand Down Expand Up @@ -88,8 +86,8 @@ class FieldBuilderTest extends AnyFlatSpec {
this.getClass.getClassLoader
)

val fieldInstance = loader.loadClass(javaClassName).getDeclaredConstructor().newInstance()
val mirror = runtimeMirror(loader).reflect(fieldInstance)(using classTag[AnyRef])
val clazz = loader.loadClass(javaClassName)
val fieldInstance = clazz.getDeclaredConstructor().newInstance()

val brClassFile = Java8Framework.ClassFile(() => new ByteArrayInputStream(rawClassFile)).head

Expand All @@ -101,13 +99,14 @@ class FieldBuilderTest extends AnyFlatSpec {
}

"the field `FieldClass.privateField`" should "be initialized as true" in {
val field = mirror.symbol.typeSignature.member(TermName("privateField")).asTerm
assert(mirror.reflectField(field).get == true)
val field = clazz.getDeclaredField("privateField")
field.setAccessible(true)
assert(field.get(fieldInstance) == true)
}

"FieldClass.publicField" should "be initialized as 3" in {
val field = mirror.symbol.typeSignature.member(TermName("publicField")).asTerm
assert(mirror.reflectField(field).get == 3)
val field = clazz.getDeclaredField("publicField")
assert(field.get(fieldInstance) == 3)
}

}
13 changes: 5 additions & 8 deletions OPAL/ba/src/test/scala/org/opalj/ba/JumpLabelsTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package org.opalj
package ba

import scala.language.postfixOps
import scala.reflect.classTag
import scala.reflect.runtime.universe.*

import java.io.ByteArrayInputStream

Expand Down Expand Up @@ -83,13 +81,12 @@ class JumpLabelsTest extends AnyFlatSpec {
def testClass(clazz: Class[?]): Unit = {
val testJumpInstance = clazz.getDeclaredConstructor().newInstance()

val mirror = runtimeMirror(loader).reflect(testJumpInstance)(using classTag[AnyRef])
val method = mirror.symbol.typeSignature.member(TermName("returnInt")).asMethod
val method = clazz.getMethod("returnInt", classOf[Int])

assert(mirror.reflectMethod(method)(0) == 0)
assert(mirror.reflectMethod(method)(1) == 1)
assert(mirror.reflectMethod(method)(2) == 2)
assert(mirror.reflectMethod(method)(10) == 10)
assert(method.invoke(testJumpInstance, 0) == 0)
assert(method.invoke(testJumpInstance, 1) == 1)
assert(method.invoke(testJumpInstance, 2) == 2)
assert(method.invoke(testJumpInstance, 10) == 10)
}

testClass(loader.loadClass("TestJumpJava5"))
Expand Down
16 changes: 6 additions & 10 deletions OPAL/ba/src/test/scala/org/opalj/ba/MethodBuilderTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package org.opalj
package ba

import scala.language.postfixOps
import scala.reflect.classTag
import scala.reflect.runtime.universe.*

import java.io.ByteArrayInputStream
import scala.collection.immutable.ArraySeq
Expand Down Expand Up @@ -59,10 +57,9 @@ class MethodBuilderTest extends AnyFlatSpec {

val simpleMethodClazz = loader.loadClass("SimpleMethodClass")
val simpleMethodInstance = simpleMethodClazz.getDeclaredConstructor().newInstance()
val mirror = runtimeMirror(loader).reflect(simpleMethodInstance)(using classTag[AnyRef])
val method = mirror.symbol.typeSignature.member(TermName("testMethod")).asMethod
val method = simpleMethodClazz.getMethod("testMethod", classOf[String])

assert(mirror.reflectMethod(method)("test") == null)
assert(method.invoke(simpleMethodInstance, "test") == null)
}

val brClassFile = J8ClassFile(() => new java.io.ByteArrayInputStream(rawClassFile)).head
Expand Down Expand Up @@ -205,11 +202,10 @@ class MethodBuilderTest extends AnyFlatSpec {
try {
val attributeMethodClass = loader.loadClass("AttributeMethodClass")
val attributeTestInstance = attributeMethodClass.getDeclaredConstructor().newInstance()
val mirror = runtimeMirror(loader).reflect(attributeTestInstance)(using classTag[AnyRef])
val method = mirror.symbol.typeSignature.member(TermName("tryCatchFinallyTest")).asMethod
assert(mirror.reflectMethod(method)(-1) == 0)
assert(mirror.reflectMethod(method)(0) == 1)
assert(mirror.reflectMethod(method)(1) == 2)
val method = attributeMethodClass.getDeclaredMethod("tryCatchFinallyTest", classOf[Int])
assert(method.invoke(attributeTestInstance, -1) == 0)
assert(method.invoke(attributeTestInstance, 0) == 1)
assert(method.invoke(attributeTestInstance, 1) == 2)
} catch {
case t: Throwable =>
info(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package fpcf
package cli

import scala.language.postfixOps
import scala.reflect.internal.util.NoPosition.showError

import java.io.File
import java.net.URL
Expand Down Expand Up @@ -102,7 +101,7 @@ trait ProjectBasedCommandLineConfig extends OPALCommandLineConfig {

val cpFiles = resolveDirToCP(get(ProjectDirectoryArg), cp, cp)
if (cpFiles.isEmpty) {
showError("Nothing to analyze.")
error("fatal", "Nothing to analyze.")
printHelp()
sys.exit(1)
}
Expand Down
25 changes: 19 additions & 6 deletions OPAL/common/src/main/scala/org/opalj/util/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,27 @@ package object util {
def getObjectReflectively[A](fqn: String, source: AnyRef, category: String = "configuration")(implicit
logContext: LogContext = GlobalLogContext
): Option[A] = {
import scala.reflect.runtime.universe._
// Ensure fully qualified name of singleton object ends with dollar symbol
val fqnObject = if (fqn.endsWith("$")) fqn else fqn + "$"

try {
val mirror = runtimeMirror(source.getClass.getClassLoader)
val module = mirror.staticModule(fqn)
Some(mirror.reflectModule(module).instance.asInstanceOf[A])
// Get the class loader from the source object
val classLoader = source.getClass.getClassLoader

// Get class from class loader
val clazz = Class.forName(fqnObject, true, classLoader)

// Access the singleton instance field
val moduleField = clazz.getField("MODULE$")

// Read the static field (passing null because it is a static field)
Some(moduleField.get(null).asInstanceOf[A])
} catch {
case sre: ScalaReflectionException =>
error(category, s"Cannot find object $fqn", sre)
case sre: ClassNotFoundException =>
error(category, s"Cannot find object $fqnObject", sre)
None
case nsfe: NoSuchFieldException =>
error(category, "Singleton instance field not found", nsfe)
None
case cce: ClassCastException =>
error(category, "Reflected object is invalid", cce)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,17 @@ trait ConfigurationBasedConstructorEscapeAnalysis extends AbstractEscapeAnalysis
*/
private val predefinedConstructors: Map[ClassType, EscapeProperty] = {
ConfigSource.fromConfig(project.config).at(ConfigKey).loadOrThrow[Seq[PredefinedResult]].map { r =>
import scala.reflect.runtime.*
val rootMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = rootMirror.staticModule(r.escapeOfThis)
val property = rootMirror.reflectModule(module).instance.asInstanceOf[EscapeProperty]
// 1. Get the ClassLoader
val classLoader = this.getClass.getClassLoader

// 2. Load the companion object or module class
// Note: Scala modules (object) compiled to Java have a '$' suffix
val moduleClass = classLoader.loadClass(r.escapeOfThis + "$")

// 3. Access the singleton instance via the MODULE$ field
val moduleField = moduleClass.getField("MODULE$")
val property = moduleField.get(null).asInstanceOf[EscapeProperty]

(ClassType(r.classType), property)
}.toMap
}
Expand Down
4 changes: 1 addition & 3 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ object Dependencies {
case _ => throw new Exception("Unknown platform!")
}

def reflect(scalaVersion: String): ModuleID = "org.scala-lang" % "scala-reflect" % "2.13.16" // scalaVersion No scala-reflect available for Scala 3

val scalaxml = "org.scala-lang.modules" %% "scala-xml" % version.scalaxml
val scalaparallelcollections =
"org.scala-lang.modules" %% "scala-parallel-collections" % version.scalaparallelcollections
Expand Down Expand Up @@ -72,7 +70,7 @@ object Dependencies {
val testlibs: Seq[ModuleID] = Seq(junit, scalatest, scalatestjunit, scalacheck)

def common(scalaVersion: String) =
Seq(reflect(scalaVersion), scalaparallelcollections, scalaxml, playjson, ficus, pureconfig, fastutil, scallop)
Seq(scalaparallelcollections, scalaxml, playjson, ficus, pureconfig, fastutil, scallop)

val si = Seq(scalagraphcore, scalagraphdot)
val bi = Seq(commonstext)
Expand Down