Skip to content

Commit

Permalink
[ruby] public in a Method body is lowered to SimpleCall (#5122)
Browse files Browse the repository at this point in the history
* Fixed warning on calling function that shadows a reserved keyword

* Moved lowering to AstCreator
  • Loading branch information
AndreiDreyer authored Nov 20, 2024
1 parent 2df0318 commit 62b3767
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import io.joern.rubysrc2cpg.datastructures.BlockScope
import io.joern.rubysrc2cpg.parser.RubyJsonHelpers
import io.joern.rubysrc2cpg.passes.Defines
import io.joern.rubysrc2cpg.passes.Defines.getBuiltInType
import io.joern.x2cpg.datastructures.MethodLike
import io.joern.x2cpg.{Ast, ValidationMode}
import io.shiftleft.codepropertygraph.generated.nodes.{NewBlock, NewControlStructure}
import io.shiftleft.codepropertygraph.generated.{ControlStructureTypes, ModifierTypes}
import io.shiftleft.codepropertygraph.generated.{ControlStructureTypes, ModifierTypes, NodeTypes}

trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { this: AstCreator =>

Expand All @@ -22,7 +23,7 @@ trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { t
case node: AnonymousTypeDeclaration => astForAnonymousTypeDeclaration(node) :: Nil
case node: TypeDeclaration => astForClassDeclaration(node)
case node: FieldsDeclaration => astsForFieldDeclarations(node)
case node: AccessModifier => registerAccessModifier(node)
case node: AccessModifier => astForAccessModifier(node)
case node: MethodDeclaration => astForMethodDeclaration(node)
case node: MethodAccessModifier => astForMethodAccessModifier(node)
case node: SingletonMethodDeclaration => astForSingletonMethodDeclaration(node)
Expand Down Expand Up @@ -73,6 +74,16 @@ trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { t
controlStructureAst(ifNode, Some(conditionAst), thenAst +: elseAsts) :: Nil
}

private def astForAccessModifier(node: AccessModifier): Seq[Ast] = {
scope.surroundingAstLabel match {
case Some(x) if x == NodeTypes.METHOD =>
val simpleIdent = node.toSimpleIdentifier
astForSimpleCall(SimpleCall(simpleIdent, List.empty)(simpleIdent.span)) :: Nil
case _ =>
registerAccessModifier(node)
}
}

/** Registers the currently set access modifier for the current type (until it is reset later).
*/
private def registerAccessModifier(node: AccessModifier): Seq[Ast] = {
Expand Down Expand Up @@ -224,6 +235,10 @@ trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { t
stmts.map(astForExpression) ++ astsForImplicitReturnStatement(nilReturnLiteral)
case x: RangeExpression =>
astForReturnRangeExpression(x) :: Nil
case node: AccessModifier =>
val simpleIdent = node.toSimpleIdentifier
val simpleCall = SimpleCall(simpleIdent, List.empty)(simpleIdent.span)
astForReturnExpression(ReturnExpression(List(simpleCall))(node.span)) :: Nil
case node =>
logger.warn(s" not supported yet: ${node.text} (${node.getClass.getSimpleName}), only generating statement")
astsForStatement(node).toList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1064,4 +1064,38 @@ class MethodTests extends RubyCode2CpgFixture {
case xs => fail(s"Expected one return, got [${xs.code.mkString(",")}]")
}
}

"Method call with same name as reserved keyword" in {
val cpg = code("""
| def public
| list.sort_by(&:position).filter_map { |category| category.slug if category.visible_to_public? }
| end
|
| def notifiable
| public
| end
|
| def not_notifiable
| public
| puts 1
| puts 2
| end
|""".stripMargin)

inside(cpg.method.name("notifiable").body.astChildren.isReturn.astChildren.isCall.name("public").l) {
case publicCall :: Nil =>
publicCall.code shouldBe "public"

val List(selfArg) = publicCall.argument.l
case xs => fail(s"Expected one call, got ${xs.code.mkString(",")}")
}

inside(cpg.method.name("not_notifiable").body.astChildren.isCall.name("public").l) {
case publicCall :: Nil =>
publicCall.code shouldBe "public"

val List(selfArg) = publicCall.argument.l
case xs => fail(s"Expected one call, got ${xs.code.mkString(",")}")
}
}
}

0 comments on commit 62b3767

Please sign in to comment.