From b37bfe827affa4f085c0f904ba5f2315bbd2a420 Mon Sep 17 00:00:00 2001 From: David Baker Effendi Date: Mon, 6 Sep 2021 10:39:24 +0200 Subject: [PATCH] ReachingDefs now optional (#205) * Separating dataflow pre-calcs * Updated docs * Added default to scala tests --- CHANGELOG.md | 2 ++ .../kotlin/io/github/plume/oss/Extractor.kt | 25 +++++++++++++++---- .../plume/oss/extractor/BasicExtractorTest.kt | 3 ++- .../plume/oss/PlumeCodeToCpgSuite.scala | 2 +- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c542643..63a16f18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Upgrade ShiftLeft dependencies to 1.3.236 - Removed `Binding` vertices - Can now handle new type arguments API of domain classes +- `Extractor::project` now takes an optional boolean to disable reaching defs calculation +- `Extractor::projectReachingDefs` now calculates reaching defs separately ## [0.5.12] - 2021-07-30 diff --git a/plume/src/main/kotlin/io/github/plume/oss/Extractor.kt b/plume/src/main/kotlin/io/github/plume/oss/Extractor.kt index f84f9e14..8384374e 100644 --- a/plume/src/main/kotlin/io/github/plume/oss/Extractor.kt +++ b/plume/src/main/kotlin/io/github/plume/oss/Extractor.kt @@ -180,8 +180,11 @@ class Extractor(val driver: IDriver) { /** * Projects all loaded classes to the graph database. This expects that all application files part of the artifact * are loaded. + * + * @param includeReachingDefs if true, will include calculating REACHING_DEF chains. If false, will keep method CPGs + * in memory storage. */ - fun project(): Extractor { + fun project(includeReachingDefs: Boolean = true): Extractor { /* Load and compile files then feed them into Soot */ @@ -335,13 +338,25 @@ class Extractor(val driver: IDriver) { PlumeTimer.measure(ExtractorTimeKey.BASE_CPG_BUILDING) { buildMethods(methodsToBuild, sootUnitGraphs) } // Clear all Soot resources and storage this.clear() - /* - Method body level analysis - only done on new/updated methods - */ + if (includeReachingDefs) { + /* + Method body level analysis - only done on new/updated methods + */ + logger.info("Running data flow passes") + PlumeTimer.measure(ExtractorTimeKey.DATA_FLOW_PASS) { DataFlowPass(driver).runPass() } + PlumeStorage.methodCpgs.clear() + } + return this + } + + /** + * Runs reaching defs analysis - necessary for data-flow analysis queries i.e. reachableBy(). Will not make changes + * if [project] ran in default mode i.e. project(includeReachingDefs = true). + */ + fun projectReachingDefs() { logger.info("Running data flow passes") PlumeTimer.measure(ExtractorTimeKey.DATA_FLOW_PASS) { DataFlowPass(driver).runPass() } PlumeStorage.methodCpgs.clear() - return this } private fun earlyStopCleanUp() { diff --git a/plume/src/test/kotlin/io/github/plume/oss/extractor/BasicExtractorTest.kt b/plume/src/test/kotlin/io/github/plume/oss/extractor/BasicExtractorTest.kt index 993f0e7d..bfd44ae8 100644 --- a/plume/src/test/kotlin/io/github/plume/oss/extractor/BasicExtractorTest.kt +++ b/plume/src/test/kotlin/io/github/plume/oss/extractor/BasicExtractorTest.kt @@ -63,7 +63,8 @@ class BasicExtractorTest { @Test fun validSourceFileTest() { extractor.load(validSourceFile) - extractor.project() + extractor.project(false) + extractor.projectReachingDefs() g = driver.getWholeGraph() val ns = g.nodes().asSequence().toList() assertNotNull(ns.filterIsInstance().find { it.name() == "extractor_tests" }) diff --git a/testing/src/test/scala/io/github/plume/oss/PlumeCodeToCpgSuite.scala b/testing/src/test/scala/io/github/plume/oss/PlumeCodeToCpgSuite.scala index bc4ca168..75e1004e 100644 --- a/testing/src/test/scala/io/github/plume/oss/PlumeCodeToCpgSuite.scala +++ b/testing/src/test/scala/io/github/plume/oss/PlumeCodeToCpgSuite.scala @@ -18,7 +18,7 @@ class PlumeFrontend extends LanguageFrontend { Using(DriverFactory.invoke(GraphDatabase.OVERFLOWDB).asInstanceOf[OverflowDbDriver]) { driver => driver.storageLocation(cpgFile.getAbsolutePath) val extractor = new Extractor(driver) - extractor.load(sourceCodeFile).project() + extractor.load(sourceCodeFile).project(true) LocalCache.INSTANCE.clear() } val odbConfig = overflowdb.Config.withDefaults().withStorageLocation(cpgFile.getAbsolutePath)