Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name := "joern"
ThisBuild / organization := "io.joern"
ThisBuild / scalaVersion := "3.6.4"

val cpgVersion = "1.7.43"
val cpgVersion = "1.7.45"

lazy val joerncli = Projects.joerncli
lazy val querydb = Projects.querydb
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ trait AstForCallExpressionsCreator { this: AstCreator =>
.toList
}

val receiverType = scopeAsts.rootType.filter(_ != TypeConstants.Any).orElse(receiverTypeOption)
val receiverType = scopeAsts.rootType.filter(_ != TypeConstants.Any).orElse(receiverTypeOption)
val staticReceiver = Option.when(dispatchType == DispatchTypes.STATIC_DISPATCH)(receiverType).flatten

val argumentsCode = getArgumentCodeString(call.getArguments)
val codePrefix = scopeAsts.headOption
Expand All @@ -103,6 +104,7 @@ trait AstForCallExpressionsCreator { this: AstCreator =>
.lineNumber(line(call))
.columnNumber(column(call))
.typeFullName(expressionTypeFullName.getOrElse(defaultTypeFallback()))
.staticReceiver(staticReceiver)

callAst(callRoot, argumentAsts, scopeAsts.headOption)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ class NewCallTests extends JavaSrcCode2CpgFixture {
|
|""".stripMargin)

cpg.call.name("valueOf").methodFullName.l shouldBe List("java.lang.String.valueOf:java.lang.String(boolean)")
inside(cpg.call.name("valueOf").l) { case List(valueOfCall) =>
valueOfCall.methodFullName shouldBe "java.lang.String.valueOf:java.lang.String(boolean)"
valueOfCall.staticReceiver shouldBe Some("java.lang.String")
}
}

"they are instance methods imported from java.lang.* should be resolved" in {
Expand Down Expand Up @@ -131,7 +134,132 @@ class NewCallTests extends JavaSrcCode2CpgFixture {
|}
|""".stripMargin)

cpg.call.name("foo").methodFullName.l shouldBe List("foo.Foo.foo:java.lang.String()")
inside(cpg.call.name("foo").l) { case List(fooCall) =>
fooCall.methodFullName shouldBe "foo.Foo.foo:java.lang.String()"
fooCall.staticReceiver shouldBe Some("foo.Foo")
}
}

"calls to inherited static methods" should {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a test where the static method is called on an instance and not directly via the class name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do! I didn't know that was a thing in Java as well.

val cpg = code("""
|package foo;
|
|class Foo {
| public static String foo() {
| return "FOO";
| }
|}
|""".stripMargin)
.moreCode("""
|package bar;
|
|import foo.Foo;
|
|class Bar extends Foo { }
|""".stripMargin)
.moreCode("""
|package baz;
|
|import bar.Bar;
|
|class Baz {
| void test() {
| Bar.foo();
| }
|}
|""".stripMargin)

"have the correct staticReceiver set" in {
inside(cpg.call.name("foo").l) { case List(fooCall) =>
fooCall.methodFullName shouldBe "bar.Bar.foo:java.lang.String()"
fooCall.staticReceiver shouldBe Some("bar.Bar")
}
}
}

"calls to inherited static methods via an instance" should {
val cpg = code("""
|package foo;
|
|class Foo {
| public static String foo() {
| return "FOO";
| }
|}
|""".stripMargin)
.moreCode("""
|package bar;
|
|import foo.Foo;
|
|class Bar extends Foo {
| public static String foo() {
| return "BAR";
| }
|}
|""".stripMargin)
.moreCode("""
|package baz;
|
|import bar.Bar;
|
|class Baz {
| void test(Bar b) {
| b.foo();
| }
|}
|""".stripMargin)

"have the correct staticReceiver set" in {
inside(cpg.call.name("foo").l) { case List(fooCall) =>
fooCall.dispatchType shouldBe DispatchTypes.STATIC_DISPATCH
fooCall.methodFullName shouldBe "bar.Bar.foo:java.lang.String()"
fooCall.staticReceiver shouldBe Some("bar.Bar")
}
}
}

"calls to overridden static methods via an instance" should {
val cpg = code("""
|package foo;
|
|class Foo {
| public static String foo() {
| return "FOO";
| }
|}
|""".stripMargin)
.moreCode("""
|package bar;
|
|import foo.Foo;
|
|class Bar extends Foo {
| public static String foo() {
| return "BAR";
| }
|}
|""".stripMargin)
.moreCode("""
|package baz;
|
|import bar.Bar;
|import foo.Foo;
|
|class Baz {
| void test(Foo f) {
| f.foo();
| }
|}
|""".stripMargin)

"have the correct staticReceiver set" in {
inside(cpg.call.name("foo").l) { case List(fooCall) =>
fooCall.dispatchType shouldBe DispatchTypes.STATIC_DISPATCH
fooCall.methodFullName shouldBe "foo.Foo.foo:java.lang.String()"
fooCall.staticReceiver shouldBe Some("foo.Foo")
}
}
}

"calls with unresolved receivers should have the correct fullnames" in {
Expand Down
Loading