Skip to content

Commit

Permalink
[ruby] Cyclic Singleton Method AST & Bracket Invocation Fix (#5189)
Browse files Browse the repository at this point in the history
* Fixed a bug where singleton methods defined on types unresolvable in scope were assigned themselves as AST parents
* Fixed a bug where bracket invocations on unresolvable types were interpreted as index accesses without an index
  • Loading branch information
DavidBakerEffendi authored Dec 18, 2024
1 parent a2eba41 commit bb9e9e9
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) {
expr
}
.getOrElse(defaultBehaviour)
case None if node.indices.isEmpty =>
astForExpression(MemberCall(node.target, ".", "[]", node.indices)(node.span))
case None => defaultBehaviour
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,14 +428,6 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th
)
val methodTypeDecl_ = typeDeclNode(node, node.methodName, fullName, relativeFileName, code(node))
val methodTypeDeclAst = Ast(methodTypeDecl_)
astParentType.orElse(scope.surroundingAstLabel).foreach { t =>
methodTypeDecl_.astParentType(t)
method.astParentType(t)
}
astParentFullName.orElse(scope.surroundingScopeFullName).foreach { fn =>
methodTypeDecl_.astParentFullName(fn)
method.astParentFullName(fn)
}

createMethodTypeBindings(method, methodTypeDecl_)

Expand Down Expand Up @@ -467,6 +459,15 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th

scope.popScope()

astParentType.orElse(scope.surroundingAstLabel).foreach { t =>
methodTypeDecl_.astParentType(t)
method.astParentType(t)
}
astParentFullName.orElse(scope.surroundingScopeFullName).foreach { fn =>
methodTypeDecl_.astParentFullName(fn)
method.astParentFullName(fn)
}

// The member for these types refers to the singleton class
val member = memberForMethod(method, Option(NodeTypes.TYPE_DECL), astParentFullName.map(x => s"$x<class>"))
diffGraph.addNode(member)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -567,4 +567,20 @@ class CallTests extends RubyCode2CpgFixture(withPostProcessing = true) {
case xs => fail(s"Expected two params, got [${xs.code.mkString(",")}]")
}
}

"A Set instantiation with a 'brackets' call" should {
val cpg = code("Set[]")

"be a call with name '[]'" in {
inside(cpg.call.nameExact("[]").l) { case bracketCall :: Nil =>
bracketCall.code shouldBe "(<tmp-0> = Set).[]()"
bracketCall.name shouldBe "[]"
inside(bracketCall.argument.l) { case (tmpBase: Identifier) :: Nil =>
tmpBase.name shouldBe "<tmp-0>"
tmpBase.code shouldBe "<tmp-0>"
tmpBase.argumentIndex shouldBe 0
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,20 @@ class MethodTests extends RubyCode2CpgFixture {
}
}

"Singleton methods binding to an unresolvable variable/type should bind to the next AST parent" in {
val cpg = code("""
|class C
| def something.foo
| end
|end
|""".stripMargin)

val foo = cpg.method.nameExact("foo").head

foo.definingTypeDecl.map(_.name) shouldBe Option("C")
foo.astParent shouldBe cpg.typeDecl("C").head
}

"A Boolean method" should {
val cpg = code("""
|def exists?
Expand Down

0 comments on commit bb9e9e9

Please sign in to comment.