From 3a53fdbada4049c8199209c329e0527c5528334a Mon Sep 17 00:00:00 2001 From: Andrei Dreyer Date: Thu, 1 Aug 2024 11:36:19 +0200 Subject: [PATCH] [ruby] Fixed issue where init stmts and params were missing in classDecl (#4817) --- .../rubysrc2cpg/parser/RubyNodeCreator.scala | 2 +- .../rubysrc2cpg/querying/ClassTests.scala | 44 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyNodeCreator.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyNodeCreator.scala index ab102e38ad52..d0f291cf9903 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyNodeCreator.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/parser/RubyNodeCreator.scala @@ -1083,7 +1083,7 @@ class RubyNodeCreator extends RubyParserBaseVisitor[RubyNode] { ) } - StatementList(otherTypeDeclChildren ++ updatedBodyMethod)(stmts.span) + StatementList(initMethod ++ otherTypeDeclChildren ++ updatedBodyMethod)(stmts.span) } override def visitClassDefinition(ctx: RubyParser.ClassDefinitionContext): RubyNode = { diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala index 70fa020c7f1d..758676333e53 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/ClassTests.scala @@ -6,7 +6,8 @@ import io.joern.x2cpg.Defines import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators} import io.shiftleft.codepropertygraph.generated.nodes.* import io.shiftleft.semanticcpg.language.* -import io.joern.rubysrc2cpg.passes.Defines.Main +import io.joern.rubysrc2cpg.passes.Defines.{Main, TypeDeclBody, Initialize} +import io.joern.rubysrc2cpg.passes.GlobalTypes class ClassTests extends RubyCode2CpgFixture { @@ -908,4 +909,45 @@ class ClassTests extends RubyCode2CpgFixture { cpg.method.nameExact("foo").fullName.l shouldBe List(s"Test0.rb:$Main.Foo.foo", s"Test0.rb:$Main.Foo0.foo") } + + "Class with nonAllowedTypeDeclChildren and explicit init" should { + val cpg = code(""" + |class Foo + | 1 + | def initialize(bar) + | puts bar + | end + |end + |""".stripMargin) + + "have an explicit init method" in { + inside(cpg.typeDecl.nameExact("Foo").method.l) { + case initMethod :: bodyMethod :: Nil => + bodyMethod.name shouldBe TypeDeclBody + + initMethod.name shouldBe Initialize + inside(initMethod.parameter.l) { + case selfParam :: barParam :: Nil => + selfParam.name shouldBe "self" + barParam.name shouldBe "bar" + case xs => fail(s"Expected two params, got [${xs.code.mkString(",")}]") + } + + inside(initMethod.block.astChildren.l) { + case (putsCall: Call) :: Nil => + putsCall.name shouldBe "puts" + case xs => fail(s"Expected one call, got [${xs.code.mkString(",")}]") + } + + inside(bodyMethod.block.astChildren.l) { + case (one: Literal) :: Nil => + one.code shouldBe "1" + one.typeFullName shouldBe s"${GlobalTypes.kernelPrefix}.Integer" + case xs => fail(s"Expected one literal, got [${xs.code.mkString(",")}]") + } + + case xs => fail(s"Expected body method and init method, got [${xs.code.mkString(",")}]") + } + } + } }