From 3512d1cc27b33fcca7da888927fc70ea2a834da1 Mon Sep 17 00:00:00 2001 From: domenico Date: Wed, 13 Nov 2024 11:52:14 +0100 Subject: [PATCH 1/6] Add test case --- .../smeup/MULANGT02ConstAndDSpecTest.kt | 10 +++++++ .../test/resources/smeup/MUDRNRAPU00270.rpgle | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt index adf3aecd4..a4ba2369a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt @@ -743,4 +743,14 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { val expected = listOf("*SCPAccesso da script 00S") assertEquals(expected, "smeup/MUDRNRAPU00154".outputOf(configuration = smeupConfig)) } + + /** + * Fields in a DS based on existing definitions + * @see #LS24004911 + */ + @Test + fun executeMUDRNRAPU00270() { + val expected = listOf("ok") + assertEquals(expected, "smeup/MUDRNRAPU00270".outputOf(configuration = smeupConfig)) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle new file mode 100644 index 000000000..8fc5970a1 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle @@ -0,0 +1,26 @@ + V* ============================================================== + V* 13/11/2024 APU002 Creation + V* ============================================================== + O * PROGRAM GOAL + O * Define a DS with fields based on existing definitions + V* ============================================================== + O * JARIKO ANOMALY + O * Before the fix, the error was about the CKEY not being resolved + V* ============================================================== + + D CKEY DS + D §OAVT1 + D §OAVP1 + D §OAVT2 + D §OAVP2 + D §OAVAT + + D §OAVT1 S 2 + D §OAVP1 S 10 + D §OAVT2 S 2 + D §OAVP2 S 10 + D §OAVAT S 15 + + C EVAL §OAVT1='ok' + C CKEY.§OAVT1 DSPLY + C SETON LR From c73c09ee14a776d328beea437f2f48692dc33e7a Mon Sep 17 00:00:00 2001 From: domenico Date: Wed, 13 Nov 2024 11:52:26 +0100 Subject: [PATCH 2/6] Remove unused line of code --- .../com/smeup/rpgparser/interpreter/internal_interpreter.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 4c4dafd90..8a8f14127 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -1110,7 +1110,6 @@ open class InternalInterpreter( is QualifiedAccessExpr -> { when (val container = eval(target.container)) { is DataStructValue -> { - container[target.field.referred!!] container.set(target.field.referred!!, coerce(value, target.field.referred!!.type)) } From 06c1bf0de637e27ddd369ec8580ce2167eb72e3d Mon Sep 17 00:00:00 2001 From: domenico Date: Wed, 13 Nov 2024 11:52:36 +0100 Subject: [PATCH 3/6] Fix DS resolution --- .../parsetreetoast/data_definitions.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt index acc03bae0..fb8de6f72 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt @@ -22,6 +22,7 @@ import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.utils.asInt import com.strumenta.kolasu.mapping.toPosition import com.strumenta.kolasu.model.Position +import com.strumenta.kolasu.model.ReferenceByName import java.math.BigDecimal import java.util.Date import kotlin.collections.HashMap @@ -890,7 +891,6 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo( } if (overlay != null) { - this.name val pos = overlay.keyword_overlay().pos val nameExpr = overlay.keyword_overlay().name val targetFieldName = nameExpr.identifier().text @@ -904,16 +904,21 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo( val hasInitValue = this.keyword().find { it.keyword_inz() != null } // compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), val varName = like?.variable?.name ?: this.name + val compileTimeLookup = { expr: Expression -> + InjectableCompileTimeInterpreter( + knownDataDefinitions = knownDataDefinitions.toList(), + delegatedCompileTimeInterpreter = conf.compileTimeInterpreter + ).evaluateTypeOf(this.rContext(), expr, conf) + } val explicitElementType: Type? = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.type ?: knownDataDefinitions.flatMap { it.fields }.firstOrNull { fe -> fe.name.equals(varName, ignoreCase = true) }?.type ?: fieldsExtname?.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.elementType - ?: like?.let { - InjectableCompileTimeInterpreter( - knownDataDefinitions = knownDataDefinitions.toList(), - delegatedCompileTimeInterpreter = conf.compileTimeInterpreter - ).evaluateTypeOf(this.rContext(), it, conf) - } + ?: like?.let { compileTimeLookup(it) } + ?: kotlin.runCatching { + val expression = DataRefExpr(ReferenceByName(varName)) + compileTimeLookup(expression) + }.getOrNull() if (hasInitValue != null) { initializationValue = if (hasInitValue.keyword_inz().simpleExpression() != null) { From c074b424eea042139e05738c3bdbb3bf1b5e02ce Mon Sep 17 00:00:00 2001 From: domenico Date: Thu, 14 Nov 2024 11:33:52 +0100 Subject: [PATCH 4/6] Update test case --- .../smeup/MULANGT02ConstAndDSpecTest.kt | 2 +- .../test/resources/smeup/MUDRNRAPU00270.rpgle | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt index a4ba2369a..0c0da55cb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt @@ -750,7 +750,7 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { */ @Test fun executeMUDRNRAPU00270() { - val expected = listOf("ok") + val expected = listOf("OK", "OK") assertEquals(expected, "smeup/MUDRNRAPU00270".outputOf(configuration = smeupConfig)) } } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle index 8fc5970a1..781b858d0 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00270.rpgle @@ -7,7 +7,6 @@ O * JARIKO ANOMALY O * Before the fix, the error was about the CKEY not being resolved V* ============================================================== - D CKEY DS D §OAVT1 D §OAVP1 @@ -15,12 +14,21 @@ D §OAVP2 D §OAVAT - D §OAVT1 S 2 - D §OAVP1 S 10 - D §OAVT2 S 2 - D §OAVP2 S 10 - D §OAVAT S 15 + D £OAVT1 S 2 + D £OAVP1 S 10 + D £OAVT2 S 2 + D £OAVP2 S 10 + D £OAVAT S 15 + + C EVAL £OAVT1='OK' + C EVAL §OAVT1='OK' + C £OAVT1 DSPLY + C §OAVT1 DSPLY + + C *LIKE DEFINE £OAVT1 §OAVT1 + C *LIKE DEFINE £OAVP1 §OAVP1 + C *LIKE DEFINE £OAVT2 §OAVT2 + C *LIKE DEFINE £OAVP2 §OAVP2 + C *LIKE DEFINE £OAVAT §OAVAT - C EVAL §OAVT1='ok' - C CKEY.§OAVT1 DSPLY - C SETON LR + C SETON LR \ No newline at end of file From b9a2a2897278aced709e669c0101015e905488c6 Mon Sep 17 00:00:00 2001 From: domenico Date: Thu, 14 Nov 2024 11:34:30 +0100 Subject: [PATCH 5/6] Fix implementation based on new test case --- .../interpreter/compile_time_interpreter.kt | 15 +++++++++++++++ .../parsing/parsetreetoast/data_definitions.kt | 18 ++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index ca38f74de..506fc8656 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -286,6 +286,21 @@ open class BaseCompileTimeInterpreter( return findType(rContext.getStatements(procedureName), declName, conf, false)!! } + /** + * Find type of declaration by specifically look for it in DEFINE statements. + */ + open fun evaluateTypeOfDefine(rContext: RContext, declName: String, conf: ToAstConfiguration, procedureName: String?): Type? { + val statements = rContext.getStatements(procedureName) + val define = statements + .mapNotNull { it.cspec_fixed() } + .mapNotNull { it.cspec_fixed_standard() } + .mapNotNull { it.csDEFINE() } + .map { it.toAst(conf) } + val match = define.firstOrNull { it.newVarName.equals(declName, ignoreCase = true) } ?: return null + + return findType(statements, match.originalName, conf) + } + private fun findType(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Type? { statements .forEach { it -> diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt index fb8de6f72..4d282cb56 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt @@ -22,7 +22,6 @@ import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.utils.asInt import com.strumenta.kolasu.mapping.toPosition import com.strumenta.kolasu.model.Position -import com.strumenta.kolasu.model.ReferenceByName import java.math.BigDecimal import java.util.Date import kotlin.collections.HashMap @@ -904,21 +903,16 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo( val hasInitValue = this.keyword().find { it.keyword_inz() != null } // compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), val varName = like?.variable?.name ?: this.name - val compileTimeLookup = { expr: Expression -> - InjectableCompileTimeInterpreter( - knownDataDefinitions = knownDataDefinitions.toList(), - delegatedCompileTimeInterpreter = conf.compileTimeInterpreter - ).evaluateTypeOf(this.rContext(), expr, conf) - } + val compileTimeInterpreter = InjectableCompileTimeInterpreter( + knownDataDefinitions = knownDataDefinitions.toList(), + delegatedCompileTimeInterpreter = conf.compileTimeInterpreter + ) val explicitElementType: Type? = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.type ?: knownDataDefinitions.flatMap { it.fields }.firstOrNull { fe -> fe.name.equals(varName, ignoreCase = true) }?.type ?: fieldsExtname?.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.elementType - ?: like?.let { compileTimeLookup(it) } - ?: kotlin.runCatching { - val expression = DataRefExpr(ReferenceByName(varName)) - compileTimeLookup(expression) - }.getOrNull() + ?: like?.let { compileTimeInterpreter.evaluateTypeOf(this.rContext(), it, conf) } + ?: compileTimeInterpreter.evaluateTypeOfDefine(this.rContext(), varName, conf, null) if (hasInitValue != null) { initializationValue = if (hasInitValue.keyword_inz().simpleExpression() != null) { From 6a2138c4c1108e885260e9114a8ae2444c33a13a Mon Sep 17 00:00:00 2001 From: domenico Date: Tue, 19 Nov 2024 11:21:53 +0100 Subject: [PATCH 6/6] Add .kotlin to .gitignore --- .gitignore | 1 + .kotlin/errors/errors-1732010706098.log | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 .kotlin/errors/errors-1732010706098.log diff --git a/.gitignore b/.gitignore index c3a04f401..cb5496040 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ bin/ .project .settings/ .idea/ +.kotlin/ **/.DS_Store rpgJavaInterpreter-core/generated-src/ rpgJavaInterpreter-core/src/main/gen/ diff --git a/.kotlin/errors/errors-1732010706098.log b/.kotlin/errors/errors-1732010706098.log deleted file mode 100644 index 7cd151b6c..000000000 --- a/.kotlin/errors/errors-1732010706098.log +++ /dev/null @@ -1,4 +0,0 @@ -kotlin version: 2.0.20 -error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output: - 1. Kotlin compile daemon is ready -