Skip to content

Commit

Permalink
[ruby] Add commandTernaryExpression to command (#4864)
Browse files Browse the repository at this point in the history
* [ruby] Added operatorExpression to commandArgument

* [ruby] removed operatorExpression, added only ternaryExpression to command
  • Loading branch information
AndreiDreyer authored Aug 21, 2024
1 parent 9fdc4ca commit caf75bc
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ methodInvocationWithoutParentheses
;

command
: primary NL? (AMPDOT | DOT | COLON2) methodName commandArgument
: operatorExpression QMARK NL* operatorExpression NL* COLON NL* operatorExpression
# commandTernaryOperatorExpression
| primary NL? (AMPDOT | DOT | COLON2) methodName commandArgument
# memberAccessCommand
| methodIdentifier commandArgument
# simpleCommand
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,18 @@ class RubyNodeCreator extends RubyParserBaseVisitor[RubyNode] {
Unknown()(ctx.toTextSpan)
}

override def visitCommandTernaryOperatorExpression(ctx: CommandTernaryOperatorExpressionContext): RubyNode = {
val condition = visit(ctx.operatorExpression(0))
val thenBody = visit(ctx.operatorExpression(1))
val elseBody = visit(ctx.operatorExpression(2))
IfExpression(
condition,
thenBody,
List.empty,
Option(ElseClause(StatementList(elseBody :: Nil)(elseBody.span))(elseBody.span))
)(ctx.toTextSpan)
}

override def visitTernaryOperatorExpression(ctx: RubyParser.TernaryOperatorExpressionContext): RubyNode = {
val condition = visit(ctx.operatorExpression(0))
val thenBody = visit(ctx.operatorExpression(1))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,4 +578,38 @@ class ControlStructureTests extends RubyCode2CpgFixture {
}
}

"Ternary if" in {
val cpg = code("""
|class Api::V1::UsersController < ApplicationController
| def index
| respond_with @user.admin ? User.all : @user
| end
|end
|""".stripMargin)

inside(cpg.method.name("index").l) {
case indexMethod :: Nil =>
inside(indexMethod.call.name(Operators.conditional).l) {
case ternary :: Nil =>
ternary.code shouldBe "@user.admin ? User.all : @user"

inside(ternary.argument.l) {
case condition :: (leftOpt: Block) :: (rightOpt: Block) :: Nil =>
condition.code shouldBe "@user.admin"
condition.ast.isFieldIdentifier.code.l shouldBe List("@user", "admin")

leftOpt.ast.fieldAccess.code.head shouldBe "User.all"
leftOpt.ast.isFieldIdentifier.code.l shouldBe List("User", "all")

rightOpt.ast.fieldAccess.code.head shouldBe "self.@user"
rightOpt.ast.isFieldIdentifier.code.head shouldBe "@user"

case xs => fail(s"Expected two arguments, got ${xs.code.mkString(",")}")
}
case xs => fail(s"Expected one call for ternary, got ${xs.code.mkString(",")}")
}
case xs => fail(s"Expected one method, got ${xs.name.mkString(",")}")
}
}

}

0 comments on commit caf75bc

Please sign in to comment.