diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a318cd8..65d40aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.0.20] - 2022-03-11 + +### Fixed + +- `OverflowDB` from throwing `unable to calculate occurrenceCount` exceptions. + ## [1.0.19] - 2022-03-11 ### Added diff --git a/build.sbt b/build.sbt index 2d9acc7e..a0a1945d 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ name := "Plume" inThisBuild( List( organization := "com.github.plume-oss", - version := "1.0.19", + version := "1.0.20", scalaVersion := "2.13.7", crossScalaVersions := Seq("2.13.7", "3.1.1"), resolvers ++= Seq( diff --git a/src/main/scala/com/github/plume/oss/domain/package.scala b/src/main/scala/com/github/plume/oss/domain/package.scala index 52b4b986..f897096b 100644 --- a/src/main/scala/com/github/plume/oss/domain/package.scala +++ b/src/main/scala/com/github/plume/oss/domain/package.scala @@ -42,7 +42,7 @@ package object domain { } /** Given an object and a path, will serialize and compress the object to the given path - * using [[compress()]]. + * using [[compress]]. * @param o object to serialize. * @param p path to write serialized data to. */ @@ -63,7 +63,7 @@ package object domain { } /** Given a path, will deserialize and decompress the file at the given path - * using [[decompress()]]. + * using [[decompress]]. * @param p path to read deserialized data from. * @tparam T the type of the class to deserialize. * @return the deserialized object. diff --git a/src/main/scala/com/github/plume/oss/drivers/IDriver.scala b/src/main/scala/com/github/plume/oss/drivers/IDriver.scala index 115e418e..97eef085 100644 --- a/src/main/scala/com/github/plume/oss/drivers/IDriver.scala +++ b/src/main/scala/com/github/plume/oss/drivers/IDriver.scala @@ -63,9 +63,9 @@ trait IDriver extends AutoCloseable { } } - /** Where former list properties were serialized as strings, they will be deserialized as [[Seq]]. + /** Where former list properties were serialized as strings, they will be deserialized as Seq. * @param properties the serialized property map. - * @return a property map where comma-separated strings are made [[Seq]] objects. + * @return a property map where comma-separated strings are made Seq objects. */ protected def deserializeLists(properties: Map[String, Any]): Map[String, Any] = { properties.map { case (k, v) => diff --git a/src/main/scala/com/github/plume/oss/drivers/OverflowDbDriver.scala b/src/main/scala/com/github/plume/oss/drivers/OverflowDbDriver.scala index 4c51daab..073ce6a4 100644 --- a/src/main/scala/com/github/plume/oss/drivers/OverflowDbDriver.scala +++ b/src/main/scala/com/github/plume/oss/drivers/OverflowDbDriver.scala @@ -91,7 +91,7 @@ final case class OverflowDbDriver( case None => // Do nothing } - /** Sets the context for the data-flow engine when performing [[nodesReachableBy()]] queries. + /** Sets the context for the data-flow engine when performing [[nodesReachableBy]] queries. * * @param maxCallDepth the new method call depth. * @param methodSemantics the file containing method semantics for external methods. @@ -141,10 +141,7 @@ final case class OverflowDbDriver( ) override def clear(): Unit = { - Try(cpg.graph.nodes.asScala.foreach(_.remove())) match { - case Failure(e) => logger.error("Encountered an exception while clearing database.", e) - case Success(_) => - } + cpg.graph.nodes.asScala.foreach(safeRemove) dataFlowCacheFile match { case Some(filePath) => filePath.toFile.delete() case None => // Do nothing @@ -236,24 +233,32 @@ final case class OverflowDbDriver( val typeDecls = fileChildren.collect { case x: TypeDecl => x } val namespaceBlocks = fileChildren.collect { case x: NamespaceBlock => x } // Remove TYPE nodes - typeDecls.flatMap(_.in(EdgeTypes.REF)).foreach(n => safeRemove(n)) + typeDecls.flatMap(_.in(EdgeTypes.REF)).foreach(safeRemove) // Remove NAMESPACE_BLOCKs and their AST children (TYPE_DECL, METHOD, etc.) val nodesToDelete = mutable.Set.empty[Node] namespaceBlocks.foreach( accumNodesToDelete(_, nodesToDelete, EdgeTypes.AST, EdgeTypes.CONDITION) ) - nodesToDelete.foreach(n => safeRemove(n)) + nodesToDelete.foreach(safeRemove) // Finally remove FILE node safeRemove(f) } } - private def safeRemove(n: Node): Unit = Try(if (n != null) n.remove()) match { + private def safeRemove(n: Node): Unit = Try(if (n != null) { + n.inE().forEachRemaining(_.remove()) + n.outE().forEachRemaining(_.remove()) + n.remove() + }) match { case Failure(e) if cpg.graph.node(n.id()) != null => logger.warn( - s"Exception '${e.getMessage}' occurred while deleting node: [${n.id()}] ${n.label()}" + s"Unable to delete node due to error '${e.getMessage}': [${n.id()}] ${n.label()}" + ) + case Failure(e) => + logger.warn( + s"Exception '${e.getMessage}' occurred while attempting to delete node: [${n.id()}] ${n.label()}" ) - case Success(_) => + case _ => } override def propertyFromNodes(nodeType: String, keys: String*): List[Map[String, Any]] =