Skip to content

Commit

Permalink
feat(compiler): handle null arguments and improve error handling #16
Browse files Browse the repository at this point in the history
Enhanced the Shire compiler to handle null arguments in method calls and improved error handling for unsupported statement types and missing parameters. Also, added new test cases for pattern action functions.
  • Loading branch information
phodal committed Jun 23, 2024
1 parent 077bc89 commit 59502be
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,12 @@ object FrontmatterParser {

ShireTypes.REF_EXPR -> {
val refExpr = expr as ShireRefExpr
val methodCall = buildMethodCall(refExpr, null)
methodCall
if (refExpr.expr == null) {
Value(FrontMatterType.IDENTIFIER(refExpr.identifier.text))
} else {
val methodCall = buildMethodCall(refExpr, null)
methodCall
}
}

ShireTypes.LITERAL_EXPR -> {
Expand All @@ -202,8 +206,12 @@ object FrontmatterParser {
// fake refExpr ::= expr? '.' IDENTIFIER
ShireTypes.REF_EXPR -> {
val refExpr = expr as ShireRefExpr
val methodCall = buildMethodCall(refExpr, null)
FrontMatterType.EXPRESSION(methodCall)
if (refExpr.expr == null) {
FrontMatterType.IDENTIFIER(refExpr.identifier.text)
} else {
val methodCall = buildMethodCall(refExpr, null)
FrontMatterType.EXPRESSION(methodCall)
}
}

// callExpr ::= refExpr '(' expressionList? ')'
Expand All @@ -217,9 +225,6 @@ object FrontmatterParser {
FrontMatterType.EXPRESSION(methodCall)
}

null -> {
FrontMatterType.STRING("")
}
else -> {
logger.warn("parseRefExpr, Unknown expression type: ${expr?.elementType}")
FrontMatterType.STRING("")
Expand All @@ -229,15 +234,20 @@ object FrontmatterParser {


private fun buildMethodCall(refExpr: ShireRefExpr, expressionList: Array<PsiElement>?): MethodCall {
val left = parseRefExpr(refExpr.expr)
val left = if (refExpr.expr == null) {
FrontMatterType.IDENTIFIER(refExpr.identifier.text)
} else {
parseRefExpr(refExpr.expr)
}

val id = refExpr.expr?.nextSibling?.nextSibling
val right = FrontMatterType.IDENTIFIER(id?.text ?: "")

val args = expressionList?.map {
parseRefExpr(it)
}

return MethodCall(left, right, args ?: emptyList())
return MethodCall(left, right, args)
}

private fun parseLiteral(ref: PsiElement): FrontMatterType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ abstract class Statement {
is LogicalExpression -> "${this.left.display()} ${this.operator.display} ${this.right.display()}"
is NotExpression -> "!${this.operand.display()}"
is MethodCall -> {
val parameters = this.arguments.joinToString(", ") {
val parameters = this.arguments?.joinToString(", ") {
when (it) {
is FrontMatterType -> it.display()
else -> it.toString()
}
}
"${this.objectName.display()}.${this.methodName.display()}($parameters)"
val formattedParameters = if (parameters.isNullOrEmpty()) "" else "($parameters)"
"${this.objectName.display()}.${this.methodName.display()}$formattedParameters"
}

else -> ""
is Value -> this.value.display()
else -> throw IllegalArgumentException("Unsupported statement type: $this")
}
}
}
Expand Down Expand Up @@ -247,7 +248,7 @@ data class NotExpression(val operand: Statement) : Statement() {
data class MethodCall(
val objectName: FrontMatterType,
val methodName: FrontMatterType,
val arguments: List<Any>,
val arguments: List<Any>?,
) : Statement() {
override fun evaluate(variables: Map<String, String>): Any {
val value = when (objectName) {
Expand All @@ -256,7 +257,7 @@ data class MethodCall(
else -> null
} ?: throw IllegalArgumentException("Variable not found: ${objectName.value}")

val parameters: List<Any> = this.arguments.map {
val parameters: List<Any>? = this.arguments?.map {
when (it) {
is FrontMatterType.STRING -> it.display().removeSurrounding("\"")
is FrontMatterType.NUMBER -> it.value
Expand All @@ -270,16 +271,40 @@ data class MethodCall(
return when (method) {
ExpressionBuiltInMethod.LENGTH -> value.length
ExpressionBuiltInMethod.TRIM -> value.trim()
ExpressionBuiltInMethod.CONTAINS -> value.contains(parameters[0] as String)
ExpressionBuiltInMethod.STARTS_WITH -> value.startsWith(parameters[0] as String)
ExpressionBuiltInMethod.ENDS_WITH -> value.endsWith(parameters[0] as String)
ExpressionBuiltInMethod.CONTAINS -> {
if (parameters != null) {
value.contains(parameters[0] as String)
} else {
throw IllegalArgumentException("Missing parameter for method: $methodName")
}
}
ExpressionBuiltInMethod.STARTS_WITH -> {
if (parameters != null) {
value.startsWith(parameters[0] as String)
} else {
throw IllegalArgumentException("Missing parameter for method: $methodName")
}
}
ExpressionBuiltInMethod.ENDS_WITH -> {
if (parameters != null) {
value.endsWith(parameters[0] as String)
} else {
throw IllegalArgumentException("Missing parameter for method: $methodName")
}
}
ExpressionBuiltInMethod.LOWERCASE -> value.lowercase()
ExpressionBuiltInMethod.UPPERCASE -> value.uppercase()
ExpressionBuiltInMethod.IS_EMPTY -> value.isEmpty()
ExpressionBuiltInMethod.IS_NOT_EMPTY -> value.isNotEmpty()
ExpressionBuiltInMethod.FIRST -> value.first().toString()
ExpressionBuiltInMethod.LAST -> value.last().toString()
ExpressionBuiltInMethod.MATCHES -> value.matches((parameters[0] as String).toRegex())
ExpressionBuiltInMethod.MATCHES -> {
if (parameters != null) {
value.matches((parameters[0] as String).toRegex())
} else {
throw IllegalArgumentException("Missing parameter for method: $methodName")
}
}
else -> throw IllegalArgumentException("Unsupported method: $methodName")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ class QueryStatementProcessor(val myProject: Project, editor: Editor, hole: Hobb
when (whereStmt) {
is Comparison -> {
val operator = whereStmt.operator
val left = evaluate(whereStmt.left, variableName, elements)
val right = evaluate(whereStmt.right, variableName, elements)
val left = evaluate(whereStmt.left, elements, variableName)
val right = evaluate(whereStmt.right, elements, variableName)

when(operator.type) {
OperatorType.Equal -> {
Expand Down Expand Up @@ -93,23 +93,27 @@ class QueryStatementProcessor(val myProject: Project, editor: Editor, hole: Hobb
}
}

private fun evaluate(left: FrontMatterType, variableName: String, elements: List<PsiElement>): Any {
private fun evaluate(left: FrontMatterType, elements: List<PsiElement>, variableName: String): List<Any> {
return when (left) {
is FrontMatterType.ARRAY -> TODO()
is FrontMatterType.BOOLEAN -> TODO()
is FrontMatterType.CASE_MATCH -> TODO()
is FrontMatterType.DATE -> TODO()
is FrontMatterType.ERROR -> TODO()
is FrontMatterType.EXPRESSION -> {
// TODO
elements.map {
it.text
}
}
is FrontMatterType.IDENTIFIER -> TODO()
is FrontMatterType.NUMBER -> TODO()
is FrontMatterType.OBJECT -> TODO()
is FrontMatterType.PATTERN -> TODO()
is FrontMatterType.QUERY_STATEMENT -> TODO()
is FrontMatterType.STRING -> {
return left.display()
elements.map {
it.text
}
}
is FrontMatterType.VARIABLE -> TODO()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.phodal.shirelang

import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.jetbrains.rd.util.first
import com.phodal.shirelang.compiler.ShireCompiler
import com.phodal.shirelang.compiler.patternaction.PatternActionFunc
import com.phodal.shirelang.compiler.patternaction.PatternActionProcessor
import com.phodal.shirelang.psi.ShireFile

Expand Down Expand Up @@ -44,6 +46,14 @@ class ShireQueryExpressionTest : BasePlatformTestCase() {
val hole = compile.config!!
val editor = myFixture.editor

val patternActionFuncs = hole.variables.first().value.patternActionFuncs
val whereDisplay = (patternActionFuncs[1] as PatternActionFunc.Where).statement.display()
val selectDisplay = (patternActionFuncs[2] as PatternActionFunc.Select).variable.map { it.display() }


assertEquals(whereDisplay, "clazz.name == \"HelloWorld.txt\"")
assertEquals(selectDisplay, listOf("clazz.id", "clazz.name", "\"code\""))

val results = hole.variables.mapValues {
PatternActionProcessor(project, editor, hole).execute(it.value)
}
Expand Down

0 comments on commit 59502be

Please sign in to comment.