Skip to content

Commit cfe62f4

Browse files
[pysrc2cpg] Represent imports as static calls (#6249)
* [pysrc2cpg] Represent imports as static calls * Rename to "<operator * Bump Version
1 parent b0b102b commit cfe62f4

9 files changed

Lines changed: 36 additions & 29 deletions

File tree

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module(name = "joern")
33
bazel_dep(name = "rules_scala", version = "7.2.5")
44
bazel_dep(name = "codepropertygraph")
55

6-
CODEPROPERTYGRAPH_VERSION = "bd34f991c710fb616d8c26e3d9385043bb22820f"
6+
CODEPROPERTYGRAPH_VERSION = "e7b6e8da670e4b58a64ba153d197041c25fd798a"
77

88
BAZEL_TOOLING_VERSION = "4bcf42cc81b574b91699d696b504637677640871"
99

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name := "joern"
22
ThisBuild / organization := "io.joern"
33
ThisBuild / scalaVersion := "3.8.3"
44

5-
val cpgVersion = "1.7.70"
5+
val cpgVersion = "1.7.74"
66

77
lazy val joerncli = Projects.joerncli
88
lazy val querydb = Projects.querydb

joern-cli/frontends/pysrc2cpg/src/main/scala/io/joern/pysrc2cpg/PythonAstVisitorHelpers.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,13 @@ trait PythonAstVisitorHelpers(implicit withSchemaValidation: ValidationMode) { t
113113
case None => Seq()
114114
})
115115

116-
val importCallNode =
117-
createCall(
118-
createIdentifierNode("import", Load, lineAndCol),
119-
"import",
120-
lineAndCol,
121-
arguments,
122-
Nil,
123-
Some(importAstNode)
124-
)
116+
val importCallNode = nodeBuilder.callNode(
117+
new AstPrinter("").print(importAstNode),
118+
Operators.importCall,
119+
DispatchTypes.STATIC_DISPATCH,
120+
lineAndCol
121+
)
122+
addAstChildrenAsArguments(importCallNode, 1, arguments)
125123

126124
val assignNode = createAssignment(importAssignLhsIdentifierNode, importCallNode, lineAndCol)
127125
assignNode
@@ -529,7 +527,7 @@ trait PythonAstVisitorHelpers(implicit withSchemaValidation: ValidationMode) { t
529527
addAstChildrenAsArguments(callNode, 1, lhsNode, rhsNode)
530528
// Do not include imports or function pointers
531529
val isImportCall = rhsNode match {
532-
case c: NewCall => c.name == "import"
530+
case c: NewCall => c.name == Operators.importCall
533531
case _ => false
534532
}
535533
if (!isImportCall && codeOf(rhsNode) != s"def ${codeOf(lhsNode)}(...)") {

joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/cpg/ImportCpgTests.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.joern.pysrc2cpg.cpg
22

3-
import io.shiftleft.codepropertygraph.generated.Operators
3+
import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators}
44
import io.shiftleft.semanticcpg.language.*
55
import org.scalatest.freespec.AnyFreeSpec
66
import org.scalatest.matchers.should.Matchers
@@ -15,10 +15,16 @@ class ImportCpgTests extends PySrc2CpgFixture with Matchers {
1515
val lhsIdentifier = assignment.argument(1).isIdentifier.head
1616
lhsIdentifier.code shouldBe "a"
1717

18-
val fromLiteral = assignment.argument(2).isCall.argument(1).head
18+
val importCall = assignment.argument(2).isCall.head
19+
importCall.name shouldBe Operators.importCall
20+
importCall.methodFullName shouldBe Operators.importCall
21+
importCall.dispatchType shouldBe DispatchTypes.STATIC_DISPATCH
22+
importCall.receiver.l shouldBe empty
23+
24+
val fromLiteral = importCall.argument(1)
1925
fromLiteral.code shouldBe ""
2026

21-
val importedEntity = assignment.argument(2).isCall.argument(2).head
27+
val importedEntity = importCall.argument(2)
2228
importedEntity.code shouldBe "a"
2329
}
2430

joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/passes/ImportsPassTests.scala

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
package io.joern.pysrc2cpg.passes
22

33
import io.joern.pysrc2cpg.testfixtures.PySrc2CpgFixture
4+
import io.shiftleft.codepropertygraph.generated.Operators
45
import io.shiftleft.semanticcpg.language.*
56

67
class ImportsPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
78

89
"For a simple import statement, there" should {
910
lazy val cpg = code("import foo", "app.py")
1011
"be a create a call to `import`" in {
11-
val List(callToImport) = cpg.call("import").l
12+
val List(callToImport) = cpg.call(Operators.importCall).l
1213
callToImport.code shouldBe "import foo"
1314
val List(where, what) = callToImport.argument.l
1415
where.code shouldBe ""
1516
what.code shouldBe "foo"
1617
}
1718
"create an assignment with the import on the right-hand-side" in {
18-
val List(assignment) = cpg.call("import").inAssignment.l
19+
val List(assignment) = cpg.call(Operators.importCall).inAssignment.l
1920
assignment.target.code shouldBe "foo"
2021
assignment.source.code shouldBe "import foo"
2122
}
@@ -60,15 +61,15 @@ class ImportsPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
6061
"For an import of the form `from... import`, it" should {
6162
lazy val cpg = code("from foo import Bar")
6263
"create a call to `import`" in {
63-
val List(callToImport) = cpg.call("import").l
64+
val List(callToImport) = cpg.call(Operators.importCall).l
6465
callToImport.code shouldBe "from foo import Bar"
6566
val List(where, what) = callToImport.argument.l
6667
where.code shouldBe "foo"
6768
what.code shouldBe "Bar"
6869
}
6970

7071
"create an assignment with the import on the right-hand-side" in {
71-
val List(assignment) = cpg.call("import").inAssignment.l
72+
val List(assignment) = cpg.call(Operators.importCall).inAssignment.l
7273
assignment.target.code shouldBe "Bar"
7374
assignment.source.code shouldBe "from foo import Bar"
7475
}
@@ -84,7 +85,7 @@ class ImportsPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
8485
"For an import of a module with alias, it" should {
8586
lazy val cpg = code("import foo as bar")
8687
"create a call to `import`" in {
87-
val List(callToImport) = cpg.call("import").l
88+
val List(callToImport) = cpg.call(Operators.importCall).l
8889
callToImport.code shouldBe "import foo as bar"
8990
val List(where, what, as) = callToImport.argument.l
9091
where.code shouldBe ""
@@ -93,7 +94,7 @@ class ImportsPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
9394
}
9495

9596
"create an assignment with the import on the right-hand-side" in {
96-
val List(assignment) = cpg.call("import").inAssignment.l
97+
val List(assignment) = cpg.call(Operators.importCall).inAssignment.l
9798
assignment.target.code shouldBe "bar"
9899
assignment.source.code shouldBe "import foo as bar"
99100
}
@@ -109,7 +110,7 @@ class ImportsPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
109110
"For an import of a class by alias, it" should {
110111
lazy val cpg = code("from foo import Bar as Woo")
111112
"create a call to `import`" in {
112-
val List(callToImport) = cpg.call("import").l
113+
val List(callToImport) = cpg.call(Operators.importCall).l
113114
callToImport.code shouldBe "from foo import Bar as Woo"
114115
val List(where, what, as) = callToImport.argument.l
115116
where.code shouldBe "foo"
@@ -118,7 +119,7 @@ class ImportsPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
118119
}
119120

120121
"create an assignment with the import on the right-hand-side" in {
121-
val List(assignment) = cpg.call("import").inAssignment.l
122+
val List(assignment) = cpg.call(Operators.importCall).inAssignment.l
122123
assignment.target.code shouldBe "Woo"
123124
assignment.source.code shouldBe "from foo import Bar as Woo"
124125
}

joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/passes/TypeRecoveryPassTests.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.joern.pysrc2cpg.passes
22

33
import io.joern.pysrc2cpg.testfixtures.PySrc2CpgFixture
44
import io.joern.x2cpg.passes.frontend.XTypeHintCallLinker
5+
import io.shiftleft.codepropertygraph.generated.Operators
56
import io.shiftleft.codepropertygraph.generated.nodes.{Call, Identifier}
67
import io.shiftleft.semanticcpg.language.*
78
import io.shiftleft.semanticcpg.language.importresolver.*
@@ -1325,7 +1326,8 @@ class TypeRecoveryPassTests extends PySrc2CpgFixture(withOssDataflow = false) {
13251326
.l
13261327
val appIncludeRouterCalls = variables.invokingCalls.nameExact("include_router")
13271328
val includedRouters = appIncludeRouterCalls.argument.argumentIndexGte(1).moduleVariables
1328-
val definitionsOfRouters = includedRouters.definitions.whereNot(_.source.isCall.nameExact("import"))
1329+
val definitionsOfRouters =
1330+
includedRouters.definitions.whereNot(_.source.isCall.nameExact(Operators.importCall))
13291331
val List(adminRouter, normalRouter, itemsRouter) =
13301332
definitionsOfRouters.map(x => (x.code, x.method.fullName)).sortBy(_._1).l: @unchecked
13311333

joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/frontendspecific/pysrc2cpg/ImportsPass.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package io.joern.x2cpg.frontendspecific.pysrc2cpg
22

33
import io.joern.x2cpg.passes.frontend.XImportsPass
4-
import io.shiftleft.codepropertygraph.generated.Cpg
4+
import io.shiftleft.codepropertygraph.generated.{Cpg, Operators}
55
import io.shiftleft.codepropertygraph.generated.nodes.*
66
import io.shiftleft.semanticcpg.language.*
77
import io.shiftleft.semanticcpg.language.operatorextension.OpNodes.Assignment
88

99
class ImportsPass(cpg: Cpg) extends XImportsPass(cpg) {
1010

11-
override protected val importCallName: String = "import"
11+
override protected val importCallName: String = Operators.importCall
1212

1313
override protected def importCallToPart(x: Call): Iterator[(Call, Assignment)] = x.inAssignment.map(y => (x, y))
1414

joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/frontendspecific/pysrc2cpg/PythonTypeRecovery.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ private class RecoverForPythonFile(cpg: Cpg, cu: File, builder: DiffGraphBuilder
115115
}
116116

117117
override def visitIdentifierAssignedToCall(i: Identifier, c: Call): Set[String] = {
118-
// Ignore legacy import representation
119-
if (c.name.equals("import")) Set.empty
118+
// Ignore the import call representation
119+
if (c.name.equals(Operators.importCall)) Set.empty
120120
// Stop custom annotation representation from hitting superclass
121121
else if (c.name.isBlank) Set.empty
122122
else super.visitIdentifierAssignedToCall(i, c)

joern-cli/src/universal/schema-extender/build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name := "schema-extender"
22

3-
ThisBuild / scalaVersion := "3.7.4"
3+
ThisBuild / scalaVersion := "3.8.3"
44

55
val cpgVersion = IO.read(file("cpg-version"))
66

0 commit comments

Comments
 (0)