Skip to content

Commit 71efc54

Browse files
authored
[semanticcpg] Add better exception for .method on annotations. (#5762)
* [semanticcpg] Add better exception for `.method` on annotations. * Add `methodOption` step for Annotation and AnnotationLiteral nodes. This step is now referenced in `method` step on CFG nodes exception.
1 parent a30dec7 commit 71efc54

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.shiftleft.semanticcpg.language.nodemethods
2+
3+
import io.shiftleft.codepropertygraph.generated.nodes.{AnnotationLiteral, Method}
4+
import io.shiftleft.semanticcpg.NodeExtension
5+
import io.shiftleft.semanticcpg.language.*
6+
7+
class AnnotationLiteralNodeMethods(val node: AnnotationLiteral) extends AnyVal with NodeExtension {
8+
def methodOption: Option[Method] = {
9+
node.inAst.collectAll[Method].headOption
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.shiftleft.semanticcpg.language.nodemethods
2+
3+
import io.shiftleft.codepropertygraph.generated.nodes.{Annotation, Method}
4+
import io.shiftleft.semanticcpg.NodeExtension
5+
import io.shiftleft.semanticcpg.language.*
6+
7+
class AnnotationNodeMethods(val node: Annotation) extends AnyVal with NodeExtension {
8+
def methodOption: Option[Method] = {
9+
node.inAst.collectAll[Method].headOption
10+
}
11+
}

semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/nodemethods/CfgNodeMethods.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,20 @@ class CfgNodeMethods(val node: CfgNode) extends AnyVal with NodeExtension {
106106
case _: MethodParameterIn | _: MethodParameterOut | _: MethodReturn =>
107107
walkUpAst(node)
108108
case _: CallRepr if !node.isInstanceOf[Call] => walkUpAst(node)
109-
case _: Annotation | _: AnnotationLiteral => node.inAst.collectAll[Method].head
110-
case _: Expression | _: JumpTarget => walkUpContains(node)
109+
case _: Annotation | _: AnnotationLiteral =>
110+
node.inAst.collectAll[Method].headOption match {
111+
case Some(method) =>
112+
method
113+
case _ =>
114+
throw new RuntimeException(s"""|This method cannot be used on ANNOTATION or ANNOTATION_LITERAL nodes as they
115+
|do not necessarily belong to a METHOD. This problem is caused by annotations
116+
|invalidly implementing the CFG trait which we sadly cannot easily fix.
117+
|As workaround you can use the `methodOption` extension on the annotation
118+
|nodes, manually walk the AST or test a CONTAINS edge expansion to check if
119+
|an annotation is part of a method or not.
120+
|""".stripMargin)
121+
}
122+
case _: Expression | _: JumpTarget => walkUpContains(node)
111123
}
112124

113125
/** Obtain hexadecimal string representation of lineNumber field.

semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/package.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,10 @@ trait LowPrioImplicits {
293293
implicit def iterOnceToAstNodeDot[A <: AstNode](a: IterableOnce[A]): AstNodeDot[A] =
294294
new AstNodeDot(a.iterator)
295295

296+
implicit def toAnnotationNodeMethods(node: Annotation): AnnotationNodeMethods = new AnnotationNodeMethods(node)
297+
implicit def toAnnotationLiteralNodeMethods(node: AnnotationLiteral): AnnotationLiteralNodeMethods =
298+
new AnnotationLiteralNodeMethods(node)
299+
296300
implicit def toCfgNodeMethods(node: CfgNode): CfgNodeMethods = new CfgNodeMethods(node)
297301

298302
implicit def iterOnceToCfgNodeTraversal[A <: CfgNode](a: IterableOnce[A]): CfgNodeTraversal[A] =

0 commit comments

Comments
 (0)