Skip to content

Commit

Permalink
Merge pull request #592 from smeup/refactor/LS24003753/function-call-…
Browse files Browse the repository at this point in the history
…to-array-access-recursive
  • Loading branch information
lanarimarco authored Aug 14, 2024
2 parents 58a4998 + ab71d02 commit 1590a72
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 15 deletions.
11 changes: 5 additions & 6 deletions kolasu/src/main/kotlin/com/strumenta/kolasu/model/Processing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ fun Node.transformChildren(operation: (Node) -> Node, inPlace: Boolean = false):
}
}
var instanceToTransform = this
if (!changes.isEmpty()) {
if (changes.isNotEmpty()) {
val constructor = this.javaClass.kotlin.primaryConstructor!!
val params = HashMap<KParameter, Any?>()
constructor.parameters.forEach { param ->
Expand All @@ -206,9 +206,8 @@ fun Node.transformChildren(operation: (Node) -> Node, inPlace: Boolean = false):
return instanceToTransform
}

fun Node.replace(other: Node) {
if (this.parent == null) {
throw IllegalStateException("Parent not set")
}
this.parent!!.transformChildren(inPlace = true, operation = { if (it == this) other else it })
fun Node.replace(other: Node): Node {
return this.parent?.let {
it.transformChildren(inPlace = true, operation = { node -> if (node == this) other else node })
} ?: throw IllegalStateException("Parent not set")
}
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ data class CallStmt(

@Serializable
data class CallPStmt(
val functionCall: FunctionCall,
var functionCall: FunctionCall,
val errorIndicator: IndicatorKey? = null,
override val position: Position? = null
) : Statement(position), StatementThatCanDefineData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,35 @@ private fun Node.resolveDataRefs(cu: CompilationUnit) {
private fun Node.resolveFunctionCalls(cu: CompilationUnit) {
// replace FunctionCall with ArrayAccessExpr where it makes sense
this.specificProcess(FunctionCall::class.java) { fc ->
if (fc.args.size == 1) {
val data = cu.allDataDefinitions.firstOrNull { it.name == fc.function.name }
if (data != null) {
fc.replace(ArrayAccessExpr(
array = DataRefExpr(ReferenceByName(fc.function.name, referred = data)),
index = fc.args[0],
position = fc.position))
}
fc.tryReplaceWithArrayAccess(cu)
}
}

private fun FunctionCall.tryReplaceWithArrayAccess(cu: CompilationUnit): Optional<Node> {
// Only said FunctionCalls with 1 arg can be ArrayAccessExpr
if (this.args.size != 1) return Optional.empty()

// Replacement can only happen when there is a DataDefinition named like this 'FunctionCall'
val data = cu.allDataDefinitions.firstOrNull { it.name == this.function.name }
data ?: return Optional.empty()

// Recursively try to process inner expressions
var indexExpr = this.args.first()
if (indexExpr is FunctionCall) {
indexExpr.tryReplaceWithArrayAccess(cu).ifPresent {
// Needed for type-checking
if (it is Expression) indexExpr = it
}
}

val arrayAccessExpr = ArrayAccessExpr(
array = DataRefExpr(ReferenceByName(this.function.name, referred = data)),
index = indexExpr,
position = this.position
)

val newExpression = this.replace(arrayAccessExpr).children.first()
return Optional.of(newExpression)
}

fun MuteAnnotation.resolveAndValidate(cu: CompilationUnit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,16 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() {
assertEquals(expected, "smeup/MUDRNRAPU00243".outputOf(configuration = smeupConfig))
}

/**
* Access to an array detected as a function call recursively
* @see #LS24003753
*/
@Test
fun executeMUDRNRAPU00244() {
val expected = listOf("ok")
assertEquals(expected, "smeup/MUDRNRAPU00244".outputOf(configuration = smeupConfig))
}

/**
* Resolution of InStatement data definitions contained in CompositeStatements
* @see #LS24003769
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
* Helper declarations
D £DBG_Str S 2

* Declarations needed for test purpose
D £C6JDSO DS 512
D £C6JO_TO 2 0 DIM(10)
D $X S 5 0
D §§IMPO S 6 0
D T$AG_I S 21 6 DIM(15)

* Initializing array indices to avoid null value exception
C EVAL $X=2
C EVAL £C6JO_TO($X)=2

* Trying to access an array while accessing another array (like £C6JO_TO($X) inside T$AG_I).
* £C6JO_TO($X) should not be seen as a function call but as an array access.
* This should be true when this kind of array access is contained in any type expression.
C EVAL T$AG_I(£C6JO_TO($X))=
C T$AG_I(£C6JO_TO($X))+§§IMPO

* Test output
C EVAL £DBG_Str='ok'
C £DBG_Str DSPLY

0 comments on commit 1590a72

Please sign in to comment.