From 52a7c7a6f1e6bb2be90606f1f1991aafe01eb767 Mon Sep 17 00:00:00 2001 From: Francis Wang Date: Sun, 20 Feb 2022 14:24:31 -0500 Subject: [PATCH 1/6] Remove import directive checker --- verik-compiler/regression/08-class.kt | 18 ++++-- verik-compiler/regression/08-class.sv | 21 +++++-- .../check/pre/ImportDirectiveCheckerStage.kt | 56 ------------------- .../io/verik/compiler/main/StageSequencer.kt | 2 - .../io/verik/compiler/message/Messages.kt | 6 +- .../reorder/DependencyIndexerVisitor.kt | 9 ++- .../general/WrapperSerializerStage.kt | 17 +++--- .../compiler/specialize/EntryPointIndexer.kt | 5 ++ .../upper/TaskReturnTransformerStage.kt | 5 +- .../pre/ImportDirectiveCheckerStageTest.kt | 45 --------------- .../general/WrapperSerializerStageTest.kt | 16 +----- 11 files changed, 56 insertions(+), 144 deletions(-) delete mode 100644 verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStage.kt delete mode 100644 verik-compiler/src/test/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStageTest.kt diff --git a/verik-compiler/regression/08-class.kt b/verik-compiler/regression/08-class.kt index fe2749365..c7eaa5cfa 100644 --- a/verik-compiler/regression/08-class.kt +++ b/verik-compiler/regression/08-class.kt @@ -27,11 +27,12 @@ object M : Module() { val x1 = C1() val x2 = C2() val x3 = C3() + val x4 = C4(false) @Run fun f0() { - println(C0.x4) - println(C2.x5) + println(C0.x5) + println(C2.x6) } } @@ -39,7 +40,7 @@ open class C0 : Class() { companion object { - var x4 = false + var x5 = false } } @@ -49,7 +50,7 @@ class C2 : Class() { companion object { - var x5 = false + var x6 = false } } @@ -57,3 +58,12 @@ class C3: C0 { constructor(): super() } + +class C4(x7: Boolean) : Class() { + + var x8 = false + + init { + x8 = x7 + } +} diff --git a/verik-compiler/regression/08-class.sv b/verik-compiler/regression/08-class.sv index 3b3773beb..822bcc777 100644 --- a/verik-compiler/regression/08-class.sv +++ b/verik-compiler/regression/08-class.sv @@ -21,7 +21,7 @@ class C0; function new(); endfunction : new - static logic x4 = 1'b0; + static logic x5 = 1'b0; endclass : C0 @@ -35,7 +35,7 @@ endclass : C1 class C2; - static logic x5 = 1'b0; + static logic x6 = 1'b0; endclass : C2 @@ -54,16 +54,29 @@ class C3 extends C0; endclass : C3 +class C4; + + logic x8 = 1'b0; + + function new( + input logic x7 + ); + x8 = x7; + endfunction : new + +endclass : C4 + module M; C0 x0 = C0::new(); C1 x1 = C1::new(); C2_T_Int x2 = C2_T_Int::new(); C3 x3 = C3::new(); + C4 x4 = C4::new(.x7(1'b0)); initial begin : f0 - $display($sformatf("%b", C0::x4)); - $display($sformatf("%b", C2::x5)); + $display($sformatf("%b", C0::x5)); + $display($sformatf("%b", C2::x6)); end : f0 endmodule : M diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStage.kt deleted file mode 100644 index 07508e8df..000000000 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStage.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 Francis Wang - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.verik.compiler.check.pre - -import io.verik.compiler.core.common.CorePackage -import io.verik.compiler.main.ProjectContext -import io.verik.compiler.main.ProjectStage -import io.verik.compiler.message.Messages -import org.jetbrains.kotlin.psi.KtImportDirective -import org.jetbrains.kotlin.psi.KtTreeVisitorVoid - -object ImportDirectiveCheckerStage : ProjectStage() { - - override fun process(projectContext: ProjectContext) { - val packageNames = HashSet() - packageNames.add(CorePackage.VK.name) - projectContext.getKtFiles().forEach { - val packageName = it.packageFqName.asString() - if (packageName != "") - packageNames.add(packageName) - } - - val importDirectiveCheckerVisitor = ImportDirectiveCheckerVisitor(packageNames) - projectContext.getKtFiles().forEach { - it.accept(importDirectiveCheckerVisitor) - } - } - - private class ImportDirectiveCheckerVisitor(private val packageNames: Set) : KtTreeVisitorVoid() { - - override fun visitImportDirective(importDirective: KtImportDirective) { - super.visitImportDirective(importDirective) - val packageName = if (importDirective.isAllUnder) { - importDirective.importedFqName!!.toString() - } else { - importDirective.importedFqName!!.parent().toString() - } - if (packageName !in packageNames) - Messages.MISSING_PACKAGE.on(importDirective, packageName) - } - } -} diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt index 6a3afcd46..ed39bd00d 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt @@ -41,7 +41,6 @@ import io.verik.compiler.check.post.UntransformedElementCheckerStage import io.verik.compiler.check.post.UntransformedReferenceCheckerStage import io.verik.compiler.check.pre.ConfigCheckerStage import io.verik.compiler.check.pre.FileAnnotationCheckerStage -import io.verik.compiler.check.pre.ImportDirectiveCheckerStage import io.verik.compiler.check.pre.PreNameCheckerStage import io.verik.compiler.check.pre.UnsupportedElementCheckerStage import io.verik.compiler.check.pre.UnsupportedModifierCheckerStage @@ -126,7 +125,6 @@ object StageSequencer { stageSequence.add(StageType.PRE_CHECK, FileAnnotationCheckerStage) stageSequence.add(StageType.PRE_CHECK, UnsupportedElementCheckerStage) stageSequence.add(StageType.PRE_CHECK, UnsupportedModifierCheckerStage) - stageSequence.add(StageType.PRE_CHECK, ImportDirectiveCheckerStage) stageSequence.add(StageType.PRE_CHECK, PreNameCheckerStage) stageSequence.add(StageType.COMPILE, KotlinCompilerAnalyzerStage) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt index 6eac0fff0..3db270b03 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt @@ -60,10 +60,6 @@ object Messages { "Modifier $0 not supported" ) - val MISSING_PACKAGE = ErrorMessageTemplate1( - "Package not found: $0" - ) - val ILLEGAL_NAME = ErrorMessageTemplate1( "Illegal name: $0" ) @@ -253,7 +249,7 @@ object Messages { ) val UNRESOLVED_TYPE_ARGUMENT = ErrorMessageTemplate0( - "Type of type argument could not be resolved" + "Type argument should be specified explicitly" ) val CARDINAL_NEGATIVE = ErrorMessageTemplate1( diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/DependencyIndexerVisitor.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/DependencyIndexerVisitor.kt index a2fb02d38..17100e7ef 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/DependencyIndexerVisitor.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/DependencyIndexerVisitor.kt @@ -70,11 +70,14 @@ class DependencyIndexerVisitor( } private fun isValidDependency(parent: EElement, element: EElement, reference: EDeclaration): Boolean { - val elementInClass = element is ESvClass || element.getParentClassOrNull() is ESvClass - val referenceInClass = reference is ESvClass || reference.getParentClassOrNull() is ESvClass + val elementParentClass = if (element is ESvClass) element else element.getParentClassOrNull() + val referenceParentClass = if (reference is ESvClass) reference else reference.getParentClassOrNull() + val isDifferentParentClass = elementParentClass is ESvClass && + referenceParentClass is ESvClass && + elementParentClass != referenceParentClass return when { !isReorderable(parent) -> false - elementInClass && referenceInClass -> parent is EProject + isDifferentParentClass -> parent is EProject reference is EModuleInterface -> false else -> true } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStage.kt index 823a505c3..f5a0c53f7 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStage.kt @@ -31,7 +31,7 @@ object WrapperSerializerStage : ProjectStage() { override fun process(projectContext: ProjectContext) { val packageWrapperTextFiles = ArrayList() - projectContext.project.regularPackages().forEach { + projectContext.project.regularNonRootPackages.forEach { val packageWrapperTextFile = serializePackageWrapper(it, projectContext) if (packageWrapperTextFile != null) { packageWrapperTextFiles.add(packageWrapperTextFile) @@ -56,16 +56,12 @@ object WrapperSerializerStage : ProjectStage() { val builder = StringBuilder() builder.append(fileHeader) - if (!pkg.packageType.isRoot()) { - builder.appendLine() - builder.appendLine("package ${pkg.name};") - } + builder.appendLine() + builder.appendLine("package ${pkg.name};") serializeInjectedProperties(pkg.injectedProperties, builder) serializeFiles(pkg.files, projectContext, builder) - if (!pkg.packageType.isRoot()) { - builder.appendLine() - builder.appendLine("endpackage : ${pkg.name}") - } + builder.appendLine() + builder.appendLine("endpackage : ${pkg.name}") return TextFile(outputPath, builder.toString()) } @@ -91,6 +87,9 @@ object WrapperSerializerStage : ProjectStage() { } projectContext.outputContext.targetPackageTextFile?.let { serializeInclude(it.path, projectContext, builder) } packageWrapperTextFiles.forEach { serializeInclude(it.path, projectContext, builder) } + val rootPackage = projectContext.project.regularRootPackage + serializeInjectedProperties(rootPackage.injectedProperties, builder) + serializeFiles(rootPackage.files, projectContext, builder) return TextFile(outputPath, builder.toString()) } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/EntryPointIndexer.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/EntryPointIndexer.kt index 3cfa899a4..8b82bb316 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/EntryPointIndexer.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/EntryPointIndexer.kt @@ -19,6 +19,7 @@ package io.verik.compiler.specialize import io.verik.compiler.ast.common.TypeParameterized import io.verik.compiler.ast.element.declaration.common.EDeclaration import io.verik.compiler.ast.element.declaration.common.EFile +import io.verik.compiler.ast.element.declaration.common.EProperty import io.verik.compiler.ast.element.declaration.kt.ECompanionObject import io.verik.compiler.ast.element.declaration.kt.EKtClass import io.verik.compiler.ast.element.declaration.kt.ETypeAlias @@ -51,6 +52,10 @@ object EntryPointIndexer { } private fun isEntryPoint(declaration: EDeclaration): Boolean { + if (declaration.hasAnnotationEntry(AnnotationEntries.INJ) && + declaration is EProperty && + declaration.parent is EFile + ) return true return if (enableDeadCodeElimination) { if (declaration.hasAnnotationEntry(AnnotationEntries.ENTRY)) { when { diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt index 9eed3b39b..ec8ae763b 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt @@ -36,11 +36,12 @@ import io.verik.compiler.message.Messages object TaskReturnTransformerStage : ProjectStage() { override fun process(projectContext: ProjectContext) { - projectContext.project.accept(TaskReturnInternalTransformerVisitor) + val taskReturnInternalTransformerVisitor = TaskReturnInternalTransformerVisitor() + projectContext.project.accept(taskReturnInternalTransformerVisitor) projectContext.project.accept(TaskReturnExternalTransformerVisitor) } - private object TaskReturnInternalTransformerVisitor : TreeVisitor() { + private class TaskReturnInternalTransformerVisitor : TreeVisitor() { private var returnValueParameter: ESvValueParameter? = null diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStageTest.kt deleted file mode 100644 index 399d4c5d7..000000000 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/check/pre/ImportDirectiveCheckerStageTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2021 Francis Wang - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.verik.compiler.check.pre - -import io.verik.compiler.test.BaseTest -import org.junit.jupiter.api.Test - -internal class ImportDirectiveCheckerStageTest : BaseTest() { - - @Test - fun `import not found`() { - driveMessageTest( - """ - import java.time.LocalDateTime - """.trimIndent(), - true, - "Package not found: java.time" - ) - } - - @Test - fun `import not found all under`() { - driveMessageTest( - """ - import java.time.* - """.trimIndent(), - true, - "Package not found: java.time" - ) - } -} diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStageTest.kt index 5a4ae45f8..844b1b908 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/general/WrapperSerializerStageTest.kt @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test internal class WrapperSerializerStageTest : BaseTest() { @Test - fun `non root package wrapper file`() { + fun `package wrapper file`() { driveTextFileTest( """ class C : Class() @@ -39,18 +39,6 @@ internal class WrapperSerializerStageTest : BaseTest() { ) { it.packageWrapperTextFiles[0] } } - @Test - fun `root package wrapper file`() { - driveTextFileTest( - """ - class M : Module() - """.trimIndent(), - """ - `include "src/test/Test.sv" - """.trimIndent() - ) { it.packageWrapperTextFiles[0] } - } - @Test fun `project wrapper file`() { driveTextFileTest( @@ -60,7 +48,7 @@ internal class WrapperSerializerStageTest : BaseTest() { """ `timescale 1ns / 1ns - `include "src/Pkg.sv" + `include "src/test/Test.sv" """.trimIndent() ) { it.projectWrapperTextFile } } From 0a84fc8af9a40aa2ed654cac0c5b3e5ddd4388d1 Mon Sep 17 00:00:00 2001 From: Francis Wang Date: Sun, 20 Feb 2022 20:37:27 -0500 Subject: [PATCH 2/6] To string function --- CHANGELOG.md | 1 + .../io/verik/compiler/core/common/Core.kt | 8 +- .../compiler/core/declaration/kt/CoreKtAny.kt | 26 +++++++ .../core/declaration/vk/CoreVkSpecial.kt | 2 +- .../interpret/PropertyInterpreterStage.kt | 2 +- ...tringTemplateExpressionTransformerStage.kt | 25 +++---- .../upper/ToStringTransformerStage.kt | 73 ++++++++++++++----- .../interpret/PropertyInterpreterStageTest.kt | 2 +- .../source/DeclarationSerializerTest.kt | 2 +- .../upper/ToStringTransformerStageTest.kt | 20 +++-- .../src/main/kotlin/io/verik/core/Special.kt | 2 +- 11 files changed, 118 insertions(+), 45 deletions(-) create mode 100644 verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtAny.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index a252052f7..880f0b87c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - Abstract classes compile to regular classes and not virtual classes. - All classes should inherit from `Class` to get randomization functions. - Support for randomize annotation `@Rand`. +- Support `toString` function. ## [0.1.13] ### Importer diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/Core.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/Core.kt index 77504dbb9..0e913c843 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/Core.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/Core.kt @@ -20,6 +20,7 @@ package io.verik.compiler.core.common import io.verik.compiler.core.declaration.jv.CoreJvArrayList import io.verik.compiler.core.declaration.jv.CoreJvClasses +import io.verik.compiler.core.declaration.kt.CoreKtAny import io.verik.compiler.core.declaration.kt.CoreKtBoolean import io.verik.compiler.core.declaration.kt.CoreKtClasses import io.verik.compiler.core.declaration.kt.CoreKtCollections @@ -62,6 +63,11 @@ object Core { val F_assert_Boolean = CoreKtFunctions.F_assert_Boolean val F_assert_Boolean_Function = CoreKtFunctions.F_assert_Boolean_Function + object Any { + + val F_toString = CoreKtAny.F_toString + } + object Int { val F_plus_Int = CoreKtInt.F_plus_Int @@ -202,7 +208,7 @@ object Core { val F_s_String = CoreVkSpecial.F_s_String val F_s0 = CoreVkSpecial.F_s0 val F_s1 = CoreVkSpecial.F_s1 - val F_cons = CoreVkSpecial.F_cons + val F_c = CoreVkSpecial.F_c val P_unknown = CoreVkSpecial.P_unknown val P_floating = CoreVkSpecial.P_floating diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtAny.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtAny.kt new file mode 100644 index 000000000..ea5b9158e --- /dev/null +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtAny.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 Francis Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.verik.compiler.core.declaration.kt + +import io.verik.compiler.core.common.BasicCoreFunctionDeclaration +import io.verik.compiler.core.common.Core +import io.verik.compiler.core.common.CoreScope + +object CoreKtAny : CoreScope(Core.Kt.C_Any) { + + val F_toString = BasicCoreFunctionDeclaration(parent, "toString", "fun toString()", null) +} diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSpecial.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSpecial.kt index 5176f3f27..0d7ffe511 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSpecial.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSpecial.kt @@ -230,7 +230,7 @@ object CoreVkSpecial : CoreScope(CorePackage.VK) { } } - val F_cons = object : TransformableCoreFunctionDeclaration(parent, "cons", "fun cons(vararg Boolean)") { + val F_c = object : TransformableCoreFunctionDeclaration(parent, "c", "fun c(vararg Boolean)") { override fun transform(callExpression: ECallExpression): EExpression { Messages.EXPRESSION_OUT_OF_CONTEXT.on(callExpression, name) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PropertyInterpreterStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PropertyInterpreterStage.kt index 07ad17558..da6527385 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PropertyInterpreterStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PropertyInterpreterStage.kt @@ -44,7 +44,7 @@ object PropertyInterpreterStage : ProjectStage() { private fun interpretConstraint(property: EProperty): EConstraint? { val callExpression = property.initializer - if (callExpression !is ECallExpression || callExpression.reference != Core.Vk.F_cons) return null + if (callExpression !is ECallExpression || callExpression.reference != Core.Vk.F_c) return null val body = EBlockExpression( location = property.location, endLocation = property.endLocation, diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt index a89745c18..f818bbb15 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt @@ -25,7 +25,6 @@ import io.verik.compiler.ast.property.LiteralStringEntry import io.verik.compiler.common.TreeVisitor import io.verik.compiler.main.ProjectContext import io.verik.compiler.main.ProjectStage -import io.verik.compiler.message.Messages import io.verik.compiler.target.common.Target object StringTemplateExpressionTransformerStage : ProjectStage() { @@ -34,21 +33,19 @@ object StringTemplateExpressionTransformerStage : ProjectStage() { projectContext.project.accept(StringTemplateExpressionTransformerVisitor) } - private fun getFormatSpecifier(expression: EExpression): String { - val type = expression.type - return when (type.reference) { - Target.C_Boolean -> "%b" - Target.C_Int -> "%0d" - Target.C_String -> "%s" - Target.C_Ubit, Target.C_Sbit -> "%h" - Target.C_Time -> "%0t" - else -> { - Messages.INTERNAL_ERROR.on(expression, "Unable to get format specifier of type: ${expression.type}") + private object StringTemplateExpressionTransformerVisitor : TreeVisitor() { + + private fun getFormatSpecifier(expression: EExpression): String { + val type = expression.type + return when (type.reference) { + Target.C_Boolean -> "%b" + Target.C_Int -> "%0d" + Target.C_String -> "%s" + Target.C_Ubit, Target.C_Sbit -> "%h" + Target.C_Time -> "%0t" + else -> "%p" } } - } - - private object StringTemplateExpressionTransformerVisitor : TreeVisitor() { override fun visitStringTemplateExpression(stringTemplateExpression: EStringTemplateExpression) { super.visitStringTemplateExpression(stringTemplateExpression) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt index 18fcb4c91..2641a9762 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt @@ -18,12 +18,15 @@ package io.verik.compiler.transform.upper import io.verik.compiler.ast.element.declaration.common.EEnumEntry import io.verik.compiler.ast.element.declaration.sv.EEnum +import io.verik.compiler.ast.element.declaration.sv.ESvClass +import io.verik.compiler.ast.element.declaration.sv.ESvFunction import io.verik.compiler.ast.element.expression.common.ECallExpression import io.verik.compiler.ast.element.expression.common.EExpression import io.verik.compiler.ast.element.expression.common.EReferenceExpression import io.verik.compiler.ast.element.expression.kt.EStringTemplateExpression import io.verik.compiler.ast.property.ExpressionStringEntry import io.verik.compiler.ast.property.LiteralStringEntry +import io.verik.compiler.common.ExpressionCopier import io.verik.compiler.common.TreeVisitor import io.verik.compiler.core.common.Core import io.verik.compiler.main.ProjectContext @@ -39,33 +42,65 @@ object ToStringTransformerStage : ProjectStage() { private object ToStringTransformerVisitor : TreeVisitor() { private fun transform(expression: EExpression) { - if (expression.type.reference is EEnum) { - if (expression is EReferenceExpression && expression.reference is EEnumEntry) { - val stringTemplateExpression = EStringTemplateExpression( - expression.location, - listOf(LiteralStringEntry(expression.reference.name)) - ) - expression.replace(stringTemplateExpression) - } else { - val parent = expression.parentNotNull() - val callExpression = ECallExpression( - expression.location, - Core.Kt.C_String.toType(), - Target.F_name, - expression, - arrayListOf(), - arrayListOf() - ) - parent.replaceChildAsExpressionContainer(expression, callExpression) + when (val reference = expression.type.reference) { + is EEnum -> transformEnum(expression) + is ESvClass -> transformClass(expression, reference) + } + } + + private fun transformEnum(expression: EExpression) { + if (expression is EReferenceExpression && expression.reference is EEnumEntry) { + val stringTemplateExpression = EStringTemplateExpression( + expression.location, + listOf(LiteralStringEntry(expression.reference.name)) + ) + expression.replace(stringTemplateExpression) + } else { + val callExpression = ECallExpression( + expression.location, + Core.Kt.C_String.toType(), + Target.F_name, + ExpressionCopier.shallowCopy(expression), + ArrayList(), + ArrayList() + ) + expression.replace(callExpression) + } + } + + private fun transformClass(expression: EExpression, cls: ESvClass) { + val toStringFunction = findToStringFunction(cls) + if (toStringFunction != null) { + val callExpression = ECallExpression( + expression.location, + Core.Kt.C_String.toType(), + toStringFunction, + ExpressionCopier.shallowCopy(expression), + ArrayList(), + ArrayList() + ) + expression.replace(callExpression) + } + } + + private fun findToStringFunction(cls: ESvClass): ESvFunction? { + cls.declarations.forEach { + if (it is ESvFunction && it.name == "toString" && it.valueParameters.isEmpty()) { + return it } } + val superTypeReference = cls.superType.reference + return if (superTypeReference is ESvClass) { + findToStringFunction(superTypeReference) + } else null } override fun visitStringTemplateExpression(stringTemplateExpression: EStringTemplateExpression) { super.visitStringTemplateExpression(stringTemplateExpression) stringTemplateExpression.entries.forEach { - if (it is ExpressionStringEntry) + if (it is ExpressionStringEntry) { transform(it.expression) + } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PropertyInterpreterStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PropertyInterpreterStageTest.kt index 477fc1414..b238fc9c6 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PropertyInterpreterStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PropertyInterpreterStageTest.kt @@ -27,7 +27,7 @@ internal class PropertyInterpreterStageTest : BaseTest() { driveElementTest( """ @Cons - val c = cons(true) + val c = c(true) """.trimIndent(), PropertyInterpreterStage::class, "Constraint(c, BlockExpression(Unit, [ConstantExpression(*)]))" diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt index 95f06f04d..1cc9ac5ba 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt @@ -440,7 +440,7 @@ internal class DeclarationSerializerTest : BaseTest() { class C : Class(){ var x = 0 @Cons - var c = cons(x == 0) + var c = c(x == 0) } """.trimIndent(), """ diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt index 03e5b0a27..ff3a7f1fc 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt @@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test internal class ToStringTransformerStageTest : BaseTest() { @Test - fun `string template expression enum property`() { + fun `enum property`() { driveElementTest( """ enum class E { A } @@ -38,7 +38,7 @@ internal class ToStringTransformerStageTest : BaseTest() { } @Test - fun `string template expression enum entry`() { + fun `enum entry`() { driveElementTest( """ enum class E { A } @@ -52,16 +52,24 @@ internal class ToStringTransformerStageTest : BaseTest() { } @Test - fun `println enum entry`() { + fun `class to string`() { driveElementTest( """ - enum class E { A } + class C : Class() { + override fun toString(): String { return "" } + } + val c = C() fun f() { - println(E.A) + println(c) } """.trimIndent(), ToStringTransformerStage::class, - "CallExpression(Unit, println, null, [StringTemplateExpression(String, [A])], [])" + """ + CallExpression( + Unit, println, null, + [CallExpression(String, toString, ReferenceExpression(C, c, null), [], [])], [] + ) + """.trimIndent() ) { it.findExpression("f") } } } diff --git a/verik-core/src/main/kotlin/io/verik/core/Special.kt b/verik-core/src/main/kotlin/io/verik/core/Special.kt index 5aaafc653..4485ec382 100644 --- a/verik-core/src/main/kotlin/io/verik/core/Special.kt +++ b/verik-core/src/main/kotlin/io/verik/core/Special.kt @@ -211,6 +211,6 @@ fun q(value: Boolean): Sequence { /** * Construct a randomization constraint from [conditions]. */ -fun cons(vararg conditions: Boolean): Constraint { +fun c(vararg conditions: Boolean): Constraint { throw VerikException() } From 4416eda116852ec84e26be325c98e62987c49b57 Mon Sep 17 00:00:00 2001 From: Francis Wang Date: Mon, 21 Feb 2022 14:58:00 -0500 Subject: [PATCH 3/6] Prepare safe access expression --- .../expression/common/ECallExpression.kt | 1 + .../expression/common/EReceiverExpression.kt | 1 + .../expression/common/EReferenceExpression.kt | 3 +- .../verik/compiler/cast/DeclarationCaster.kt | 2 ++ .../verik/compiler/cast/ExpressionCaster.kt | 9 +++--- .../post/UntransformedElementCheckerStage.kt | 14 ++++++++ .../pre/UnsupportedElementCheckerStage.kt | 15 --------- .../verik/compiler/common/ElementPrinter.kt | 2 ++ .../verik/compiler/common/ExpressionCopier.kt | 8 +++-- .../compiler/core/common/CoreTransformUtil.kt | 3 ++ .../core/declaration/jv/CoreJvArrayList.kt | 1 + .../compiler/core/declaration/kt/CoreKtIo.kt | 2 ++ .../core/declaration/vk/CoreVkMisc.kt | 1 + .../core/declaration/vk/CoreVkRandom.kt | 2 ++ .../core/declaration/vk/CoreVkSystem.kt | 1 + .../core/declaration/vk/CoreVkUbit.kt | 2 ++ .../compiler/evaluate/ConstantPropagator.kt | 1 + .../interpret/ConstructorInterpreterStage.kt | 1 + .../PrimaryConstructorReducerStage.kt | 6 ++-- .../PropertyStatementReordererStage.kt | 2 +- .../compiler/specialize/SpecializerCopier.kt | 4 ++- .../lower/ExpressionExtractorStage.kt | 3 +- ...copeExpressionInsertionTransformerStage.kt | 6 ++-- ...tringTemplateExpressionTransformerStage.kt | 1 + .../pre/ArrayAccessExpressionReducerStage.kt | 2 ++ .../pre/BinaryExpressionReducerStage.kt | 1 + .../transform/pre/ForStatementReducerStage.kt | 1 + .../pre/UnaryExpressionReducerStage.kt | 1 + .../transform/upper/CastTransformerStage.kt | 11 +++++-- .../upper/ForStatementTransformerStage.kt | 10 ++++-- .../upper/IfAndWhenExpressionUnlifterStage.kt | 8 +++-- .../ProceduralAssignmentTransformerStage.kt | 6 ++-- .../upper/TaskReturnTransformerStage.kt | 12 +++++-- .../upper/ToStringTransformerStage.kt | 2 ++ .../compiler/cast/CallExpressionCasterTest.kt | 20 +++++++----- .../compiler/cast/DeclarationCasterTest.kt | 6 ++-- .../compiler/cast/ExpressionCasterTest.kt | 32 +++++++++---------- .../cast/SmartCastReducerStageTest.kt | 6 ++-- .../ConstantPropagatorSubstageTest.kt | 6 ++-- .../ExpressionEvaluatorSubstageTest.kt | 2 +- .../interpret/ClassInterpreterStageTest.kt | 2 +- .../ConstructorInterpreterStageTest.kt | 2 +- .../PrimaryConstructorReducerStageTest.kt | 4 +-- .../ExpressionReferenceForwarderTest.kt | 10 +++--- .../resolve/SliceResolverStageTest.kt | 2 +- .../compiler/resolve/TypeResolverStageTest.kt | 16 +++++----- .../specialize/OptionalReducerSubstageTest.kt | 2 +- .../specialize/SpecializerIndexerTest.kt | 2 +- .../specialize/SpecializerStageTest.kt | 4 +-- ...ExpressionInsertionTransformerStageTest.kt | 18 ++++++----- ...gTemplateExpressionTransformerStageTest.kt | 6 ++-- .../ArrayAccessExpressionReducerStageTest.kt | 6 ++-- .../pre/BinaryExpressionReducerStageTest.kt | 10 +++--- .../pre/ForStatementReducerStageTest.kt | 3 +- .../pre/UnaryExpressionReducerStageTest.kt | 2 +- .../CaseStatementTransformerStageTest.kt | 4 +-- .../upper/ForStatementTransformerStageTest.kt | 8 ++--- .../upper/ToStringTransformerStageTest.kt | 6 ++-- 58 files changed, 195 insertions(+), 129 deletions(-) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt index 0bbe62837..bbbcd3792 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt @@ -29,6 +29,7 @@ class ECallExpression( override var type: Type, override var reference: Declaration, override var receiver: EExpression?, + override val isSafeAccess: Boolean, val valueArguments: ArrayList, var typeArguments: ArrayList ) : EReceiverExpression() { diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt index 9ba5f1a5e..2a29c4953 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt @@ -24,6 +24,7 @@ abstract class EReceiverExpression : EExpression(), ExpressionContainer { abstract var reference: Declaration abstract var receiver: EExpression? + abstract val isSafeAccess: Boolean override fun acceptChildren(visitor: TreeVisitor) { receiver?.accept(visitor) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt index 4f0dd57dd..2472cc9e3 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt @@ -26,7 +26,8 @@ class EReferenceExpression( override val location: SourceLocation, override var type: Type, override var reference: Declaration, - override var receiver: EExpression? + override var receiver: EExpression?, + override val isSafeAccess: Boolean ) : EReceiverExpression() { override val serializationType = SerializationType.EXPRESSION diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt index 1af8d07ee..86964c358 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt @@ -373,6 +373,7 @@ object DeclarationCaster { type, declaration, null, + false, valueArguments, ArrayList(typeArguments) ) @@ -400,6 +401,7 @@ object DeclarationCaster { type, declaration, null, + false, valueArguments, typeArguments ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/ExpressionCaster.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/ExpressionCaster.kt index 1d187e9a6..0d2fa23ab 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/ExpressionCaster.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/ExpressionCaster.kt @@ -112,7 +112,7 @@ object ExpressionCaster { } else { val descriptor = castContext.sliceReferenceTarget[expression.operationReference]!! val declaration = castContext.resolveDeclaration(descriptor, expression) - ECallExpression(location, type, declaration, left, arrayListOf(right), arrayListOf()) + ECallExpression(location, type, declaration, left, false, arrayListOf(right), arrayListOf()) } } @@ -124,7 +124,7 @@ object ExpressionCaster { val descriptor = castContext.sliceReferenceTarget[expression]!! val type = castContext.castType(expression) val declaration = castContext.resolveDeclaration(descriptor, expression) - val referenceExpression = EReferenceExpression(location, type, declaration, null) + val referenceExpression = EReferenceExpression(location, type, declaration, null, false) ReferenceExpressionCaster.checkSmartCast(expression, referenceExpression, castContext) return referenceExpression } @@ -136,7 +136,7 @@ object ExpressionCaster { val declaration = castContext.resolveDeclaration(descriptor, expression) val valueArguments = CallExpressionCaster.castValueArguments(expression.calleeExpression!!, castContext) val typeArguments = CallExpressionCaster.castTypeArguments(expression, castContext) - return ECallExpression(location, type, declaration, null, valueArguments, typeArguments) + return ECallExpression(location, type, declaration, null, false, valueArguments, typeArguments) } fun castReferenceExpressionOrCallExpression( @@ -162,7 +162,7 @@ object ExpressionCaster { is KtSimpleNameExpression -> { val descriptor = castContext.sliceReferenceTarget[selector]!! val declaration = castContext.resolveDeclaration(descriptor, expression) - val referenceExpression = EReferenceExpression(location, type, declaration, receiver) + val referenceExpression = EReferenceExpression(location, type, declaration, receiver, false) ReferenceExpressionCaster.checkSmartCast(expression, referenceExpression, castContext) referenceExpression } @@ -176,6 +176,7 @@ object ExpressionCaster { type, declaration, receiver, + false, valueArguments, typeArguments ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/check/post/UntransformedElementCheckerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/check/post/UntransformedElementCheckerStage.kt index 3008cab6e..e8f093c94 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/check/post/UntransformedElementCheckerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/check/post/UntransformedElementCheckerStage.kt @@ -23,6 +23,8 @@ import io.verik.compiler.ast.element.declaration.kt.EKtFunction import io.verik.compiler.ast.element.declaration.kt.EKtValueParameter import io.verik.compiler.ast.element.declaration.kt.EPrimaryConstructor import io.verik.compiler.ast.element.declaration.kt.ESecondaryConstructor +import io.verik.compiler.ast.element.expression.common.ECallExpression +import io.verik.compiler.ast.element.expression.common.EReferenceExpression import io.verik.compiler.ast.element.expression.kt.EAsExpression import io.verik.compiler.ast.element.expression.kt.EIsExpression import io.verik.compiler.ast.element.expression.kt.EKtArrayAccessExpression @@ -85,6 +87,18 @@ object UntransformedElementCheckerStage : ProjectStage() { Messages.INTERNAL_ERROR.on(binaryExpression, "Binary expression $message") } + override fun visitReferenceExpression(referenceExpression: EReferenceExpression) { + if (referenceExpression.isSafeAccess) { + Messages.INTERNAL_ERROR.on(referenceExpression, "Reference expression $message") + } + } + + override fun visitCallExpression(callExpression: ECallExpression) { + if (callExpression.isSafeAccess) { + Messages.INTERNAL_ERROR.on(callExpression, "Call expression $message") + } + } + override fun visitStringTemplateExpression(stringTemplateExpression: EStringTemplateExpression) { Messages.INTERNAL_ERROR.on(stringTemplateExpression, "String template expression $message") } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/UnsupportedElementCheckerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/UnsupportedElementCheckerStage.kt index 0de3fe951..2b67d6227 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/UnsupportedElementCheckerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/check/pre/UnsupportedElementCheckerStage.kt @@ -20,12 +20,9 @@ import io.verik.compiler.main.ProjectContext import io.verik.compiler.main.ProjectStage import io.verik.compiler.message.Messages import org.jetbrains.kotlin.psi.KtClassLiteralExpression -import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtDoubleColonExpression -import org.jetbrains.kotlin.psi.KtImportAlias import org.jetbrains.kotlin.psi.KtObjectLiteralExpression import org.jetbrains.kotlin.psi.KtPropertyDelegate -import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression import org.jetbrains.kotlin.psi.KtThrowExpression import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.psi.KtTryExpression @@ -40,14 +37,6 @@ object UnsupportedElementCheckerStage : ProjectStage() { private object UnsupportedElementCheckerVisitor : KtTreeVisitorVoid() { - override fun visitDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration) { - Messages.UNSUPPORTED_ELEMENT.on(destructuringDeclaration, "Destructuring declaration") - } - - override fun visitImportAlias(importAlias: KtImportAlias) { - Messages.UNSUPPORTED_ELEMENT.on(importAlias, "Import alias") - } - override fun visitPropertyDelegate(delegate: KtPropertyDelegate) { Messages.UNSUPPORTED_ELEMENT.on(delegate, "Property delegate") } @@ -68,10 +57,6 @@ object UnsupportedElementCheckerStage : ProjectStage() { Messages.UNSUPPORTED_ELEMENT.on(expression, "Class literal expression") } - override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression) { - Messages.UNSUPPORTED_ELEMENT.on(expression, "Safe qualified expression") - } - override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression) { Messages.UNSUPPORTED_ELEMENT.on(expression, "Object literal expression") } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt index 749258686..9d0af6bbe 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt @@ -481,6 +481,7 @@ class ElementPrinter : Visitor() { build(referenceExpression.type.toString()) build(referenceExpression.reference.name) build(referenceExpression.receiver) + build(referenceExpression.isSafeAccess) } } @@ -489,6 +490,7 @@ class ElementPrinter : Visitor() { build(callExpression.type.toString()) build(callExpression.reference.name) build(callExpression.receiver) + build(callExpression.isSafeAccess) build(callExpression.valueArguments) build(callExpression.typeArguments.map { it.toString() }) } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ExpressionCopier.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ExpressionCopier.kt index 2b7df94a2..bba22479f 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ExpressionCopier.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ExpressionCopier.kt @@ -203,14 +203,16 @@ object ExpressionCopier { location ?: referenceExpression.location, type, referenceExpression.reference, - receiver + receiver, + referenceExpression.isSafeAccess ) } else { EReferenceExpression( location ?: referenceExpression.location, referenceExpression.type, referenceExpression.reference, - referenceExpression.receiver + referenceExpression.receiver, + referenceExpression.isSafeAccess ) } } @@ -230,6 +232,7 @@ object ExpressionCopier { type, callExpression.reference, receiver, + callExpression.isSafeAccess, ArrayList(valueArguments), ArrayList(typeArguments) ) @@ -239,6 +242,7 @@ object ExpressionCopier { callExpression.type, callExpression.reference, callExpression.receiver, + callExpression.isSafeAccess, callExpression.valueArguments, callExpression.typeArguments ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/CoreTransformUtil.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/CoreTransformUtil.kt index 59c27578e..4606553e0 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/CoreTransformUtil.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/common/CoreTransformUtil.kt @@ -30,6 +30,7 @@ object CoreTransformUtil { Core.Kt.C_Int.toType(), Core.Kt.Int.F_minus_Int, expression, + false, arrayListOf(ConstantBuilder.buildInt(expression, 1)), ArrayList() ) @@ -42,6 +43,7 @@ object CoreTransformUtil { Core.Vk.C_Sbit.toType(expression.type.getWidthAsType(expression)), Target.F_signed, null, + false, arrayListOf(expression), ArrayList() ) @@ -53,6 +55,7 @@ object CoreTransformUtil { Core.Vk.C_Ubit.toType(expression.type.getWidthAsType(expression)), Target.F_unsigned, null, + false, arrayListOf(expression), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/jv/CoreJvArrayList.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/jv/CoreJvArrayList.kt index d5dc305eb..072300fdc 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/jv/CoreJvArrayList.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/jv/CoreJvArrayList.kt @@ -41,6 +41,7 @@ object CoreJvArrayList : CoreScope(Core.Jv.Util.C_ArrayList) { referenceExpression.type, Target.ArrayList.F_size, referenceExpression.receiver, + false, arrayListOf(), arrayListOf() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtIo.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtIo.kt index c710db679..21724b39e 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtIo.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtIo.kt @@ -46,6 +46,7 @@ object CoreKtIo : CoreScope(CorePackage.KT_IO) { Core.Kt.C_Unit.toType(), Target.F_write, null, + false, arrayListOf(expression), ArrayList() ) @@ -85,6 +86,7 @@ object CoreKtIo : CoreScope(CorePackage.KT_IO) { Core.Kt.C_Unit.toType(), Target.F_display, null, + false, arrayListOf(expression), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkMisc.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkMisc.kt index a5ca4141b..9fcf42cad 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkMisc.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkMisc.kt @@ -199,6 +199,7 @@ object CoreVkMisc : CoreScope(CorePackage.VK) { Core.Kt.C_Int.toType(), Core.Kt.Int.F_shl_Int, constantExpression, + false, callExpression.valueArguments, ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkRandom.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkRandom.kt index db78ad261..ad171b832 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkRandom.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkRandom.kt @@ -41,6 +41,7 @@ object CoreVkRandom : CoreScope(CorePackage.VK) { callExpression.type, Target.F_urandom_range, null, + false, arrayListOf(expression), ArrayList() ) @@ -56,6 +57,7 @@ object CoreVkRandom : CoreScope(CorePackage.VK) { callExpression.type, Target.F_urandom_range, null, + false, arrayListOf(callExpression.valueArguments[0], expression), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSystem.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSystem.kt index 863e1260f..bc96ace86 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSystem.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkSystem.kt @@ -40,6 +40,7 @@ object CoreVkSystem : CoreScope(CorePackage.VK) { callExpression.type, Target.F_fatal, null, + false, arrayListOf( EConstantExpression(callExpression.location, Core.Kt.C_Int.toType(), "1"), callExpression.valueArguments[0] diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkUbit.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkUbit.kt index 8356c37b3..e4d326a6d 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkUbit.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkUbit.kt @@ -396,6 +396,7 @@ object CoreVkUbit : CoreScope(Core.Vk.C_Ubit) { Core.Kt.C_String.toType(), Target.F_sformatf, null, + false, arrayListOf(stringExpression, callExpression.receiver!!), ArrayList() ) @@ -411,6 +412,7 @@ object CoreVkUbit : CoreScope(Core.Vk.C_Ubit) { Core.Kt.C_String.toType(), Target.F_sformatf, null, + false, arrayListOf(stringExpression, callExpression.receiver!!), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/evaluate/ConstantPropagator.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/evaluate/ConstantPropagator.kt index 266ac3ac1..2d0bfed08 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/evaluate/ConstantPropagator.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/evaluate/ConstantPropagator.kt @@ -71,6 +71,7 @@ object ConstantPropagator { callExpression.type, callExpression.reference, receiver, + false, ArrayList(valueArguments), callExpression.typeArguments ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStage.kt index 03bbb1a04..19ccf85a8 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStage.kt @@ -83,6 +83,7 @@ object ConstructorInterpreterStage : ProjectStage() { Core.Kt.C_Unit.toType(), reference, superExpression, + false, superTypeCallExpression.valueArguments, ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt index 166b55439..80158f8e4 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt @@ -105,13 +105,15 @@ object PrimaryConstructorReducerStage : ProjectStage() { valueParameter.location, valueParameter.type.copy(), property, - thisExpression + thisExpression, + false ) val valueParameterReferenceExpression = EReferenceExpression( valueParameter.location, valueParameter.type.copy(), valueParameter, - null + null, + false ) statements.add( EKtBinaryExpression( diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/PropertyStatementReordererStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/PropertyStatementReordererStage.kt index 1996cf901..03f7b14e0 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/PropertyStatementReordererStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/reorder/PropertyStatementReordererStage.kt @@ -46,7 +46,7 @@ object PropertyStatementReordererStage : ProjectStage() { val statement = EKtBinaryExpression( it.location, Core.Kt.C_Unit.toType(), - EReferenceExpression(it.location, it.property.type.copy(), it.property, null), + EReferenceExpression(it.location, it.property.type.copy(), it.property, null, false), initializer, KtBinaryOperatorKind.EQ ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt index f5ed11afa..b88567c13 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt @@ -391,7 +391,8 @@ object SpecializerCopier { referenceExpression.location, type, referenceExpression.reference, - receiver + receiver, + referenceExpression.isSafeAccess ) } @@ -409,6 +410,7 @@ object SpecializerCopier { type, callExpression.reference, receiver, + callExpression.isSafeAccess, ArrayList(copiedValueArguments), ArrayList(copiedTypeArguments) ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt index d46a32498..c035b2d5a 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt @@ -78,7 +78,8 @@ object ExpressionExtractorStage : ProjectStage() { expression.location, property.type.copy(), property, - null + null, + false ) return Pair(propertyStatement, referenceExpression) } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStage.kt index 4c010989c..bf3c6ccf5 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStage.kt @@ -112,13 +112,15 @@ object ScopeExpressionInsertionTransformerStage : ProjectStage() { receiverExpression.location, Target.C_Void.toType(), Target.P_root, - null + null, + false ) EReferenceExpression( receiverExpression.location, module.toType(), module, - referenceExpression + referenceExpression, + false ) } else null } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt index f818bbb15..94055e76e 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStage.kt @@ -88,6 +88,7 @@ object StringTemplateExpressionTransformerStage : ProjectStage() { Target.C_String.toType(), Target.F_sformatf, null, + false, valueArguments, ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStage.kt index 0dffd00f3..7b3df19e8 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStage.kt @@ -228,6 +228,7 @@ object ArrayAccessExpressionReducerStage : ProjectStage() { binaryExpression.type, reference, left.array, + false, ArrayList(left.indices + right), arrayListOf() ) @@ -252,6 +253,7 @@ object ArrayAccessExpressionReducerStage : ProjectStage() { arrayAccessExpression.type, reference, arrayAccessExpression.array, + false, arrayAccessExpression.indices, arrayListOf() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStage.kt index 4b03854d5..221535423 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStage.kt @@ -92,6 +92,7 @@ object BinaryExpressionReducerStage : ProjectStage() { binaryExpression.type, reference, binaryExpression.left, + false, arrayListOf(binaryExpression.right), arrayListOf() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStage.kt index e5ec00cd5..7d1ba552e 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStage.kt @@ -44,6 +44,7 @@ object ForStatementReducerStage : ProjectStage() { forStatement.type, Core.Kt.Collections.F_forEach_Function, forStatement.range, + false, arrayListOf(functionLiteralExpression), arrayListOf(forStatement.valueParameter.type.copy()) ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStage.kt index d4d74044a..bf582a862 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStage.kt @@ -70,6 +70,7 @@ object UnaryExpressionReducerStage : ProjectStage() { unaryExpression.type, reference, unaryExpression.expression, + false, ArrayList(), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt index 85cb0cfd6..aee40b2eb 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt @@ -46,13 +46,15 @@ object CastTransformerStage : ProjectStage() { isExpression.location, isExpression.property.type.copy(), isExpression.property, - null + null, + false ) val callExpression = ECallExpression( isExpression.location, Core.Kt.C_Boolean.toType(), Target.F_cast, null, + false, arrayListOf(referenceExpression, isExpression.expression), ArrayList() ) @@ -63,6 +65,7 @@ object CastTransformerStage : ProjectStage() { Core.Kt.C_Boolean.toType(), Core.Kt.Boolean.F_not, callExpression, + false, ArrayList(), ArrayList() ) @@ -84,7 +87,8 @@ object CastTransformerStage : ProjectStage() { property.location, property.type.copy(), property, - null + null, + false ) val propertyStatement = EPropertyStatement(property.location, property) val castCallExpression = ECallExpression( @@ -92,6 +96,7 @@ object CastTransformerStage : ProjectStage() { Core.Kt.C_Boolean.toType(), Target.F_cast, null, + false, arrayListOf(referenceExpression, asExpression.expression), ArrayList() ) @@ -100,6 +105,7 @@ object CastTransformerStage : ProjectStage() { Core.Kt.C_Boolean.toType(), Core.Kt.Boolean.F_not, castCallExpression, + false, ArrayList(), ArrayList() ) @@ -112,6 +118,7 @@ object CastTransformerStage : ProjectStage() { Core.Kt.C_Nothing.toType(), Core.Vk.F_fatal_String, null, + false, arrayListOf(stringExpression), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt index 5d478e841..ea1fc0fba 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt @@ -89,7 +89,8 @@ object ForStatementTransformerStage : ProjectStage() { property.location, property.type.copy(), property, - null + null, + false ) val condition = EKtBinaryExpression( callExpression.location, @@ -128,13 +129,15 @@ object ForStatementTransformerStage : ProjectStage() { indexProperty.location, indexProperty.type.copy(), indexProperty, - null + null, + false ) val sizeReferenceExpression = EReferenceExpression( referenceExpression.location, Core.Kt.C_Int.toType(), Core.Jv.Util.ArrayList.P_size, - referenceExpression + referenceExpression, + false ) val condition = EKtBinaryExpression( referenceExpression.location, @@ -154,6 +157,7 @@ object ForStatementTransformerStage : ProjectStage() { valueParameter.type.copy(), Core.Jv.Util.ArrayList.F_get_Int, ExpressionCopier.deepCopy(referenceExpression), + false, arrayListOf(ExpressionCopier.deepCopy(indexReferenceExpression)), ArrayList() ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt index dff2bcacb..3200b892b 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt @@ -53,7 +53,8 @@ object IfAndWhenExpressionUnlifterStage : ProjectStage() { ifExpression.location, property.type.copy(), property, - null + null, + false ) val extractedExpressions = listOf( propertyStatement, @@ -77,7 +78,8 @@ object IfAndWhenExpressionUnlifterStage : ProjectStage() { whenExpression.location, property.type.copy(), property, - null + null, + false ) val propertyStatement = EPropertyStatement( whenExpression.location, @@ -141,7 +143,7 @@ object IfAndWhenExpressionUnlifterStage : ProjectStage() { EKtBinaryExpression( expression.location, Core.Kt.C_Unit.toType(), - EReferenceExpression(expression.location, property.type.copy(), property, null), + EReferenceExpression(expression.location, property.type.copy(), property, null, false), expression, KtBinaryOperatorKind.EQ ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt index 6f7793eed..d57af5ec3 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt @@ -76,7 +76,8 @@ object ProceduralAssignmentTransformerStage : ProjectStage() { property.location, property.type.copy(), property, - null + null, + false ) val binaryExpression = EKtBinaryExpression( property.location, @@ -112,7 +113,8 @@ object ProceduralAssignmentTransformerStage : ProjectStage() { property.location, property.type.copy(), property, - null + null, + false ) val body = initializer.valueArguments.last().cast().body if (body.isEmpty()) { diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt index ec8ae763b..ed6d3849f 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt @@ -62,10 +62,17 @@ object TaskReturnTransformerStage : ProjectStage() { val expression = returnStatement.expression if (valueParameter != null && expression != null) { val newReturnStatement = EReturnStatement(returnStatement.location, Core.Kt.C_Unit.toType(), null) + val referenceExpression = EReferenceExpression( + returnStatement.location, + valueParameter.type.copy(), + valueParameter, + null, + false + ) val binaryExpression = EKtBinaryExpression( returnStatement.location, Core.Kt.C_Unit.toType(), - EReferenceExpression(returnStatement.location, valueParameter.type.copy(), valueParameter, null), + referenceExpression, expression, KtBinaryOperatorKind.EQ ) @@ -103,7 +110,8 @@ object TaskReturnTransformerStage : ProjectStage() { callExpression.location, property.type.copy(), property, - null + null, + false ) val newCallExpression = ExpressionCopier.shallowCopy(callExpression) referenceExpression.parent = newCallExpression diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt index 2641a9762..11d302f44 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStage.kt @@ -61,6 +61,7 @@ object ToStringTransformerStage : ProjectStage() { Core.Kt.C_String.toType(), Target.F_name, ExpressionCopier.shallowCopy(expression), + false, ArrayList(), ArrayList() ) @@ -76,6 +77,7 @@ object ToStringTransformerStage : ProjectStage() { Core.Kt.C_String.toType(), toStringFunction, ExpressionCopier.shallowCopy(expression), + false, ArrayList(), ArrayList() ) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/CallExpressionCasterTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/CallExpressionCasterTest.kt index 46b827354..6cc10a3dc 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/CallExpressionCasterTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/CallExpressionCasterTest.kt @@ -29,7 +29,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x = u(0).ext<`8`>() """.trimIndent(), CasterStage::class, - "CallExpression(Ubit<`*`>, ext, *, *, [`8`])" + "CallExpression(Ubit<`*`>, ext, *, 0, *, [`8`])" ) { it.findExpression("x") } } @@ -40,7 +40,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x: Ubit<`8`> = u(0).ext() """.trimIndent(), CasterStage::class, - "CallExpression(Ubit<`*`>, ext, *, *, [`*`])" + "CallExpression(Ubit<`*`>, ext, *, 0, *, [`*`])" ) { it.findExpression("x") } } @@ -52,7 +52,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x = f(0) """.trimIndent(), CasterStage::class, - "CallExpression(Unit, f, null, [ConstantExpression(*)], [])" + "CallExpression(Unit, f, null, 0, [ConstantExpression(*)], [])" ) { it.findExpression("x") } } @@ -64,7 +64,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x = f(x = 0) """.trimIndent(), CasterStage::class, - "CallExpression(Unit, f, null, [ConstantExpression(*)], [])" + "CallExpression(Unit, f, null, 0, [ConstantExpression(*)], [])" ) { it.findExpression("x") } } @@ -76,7 +76,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x = f(y = "", x = 0) """.trimIndent(), CasterStage::class, - "CallExpression(Unit, f, null, [ConstantExpression(*), StringTemplateExpression(*)], [])" + "CallExpression(Unit, f, null, 0, [ConstantExpression(*), StringTemplateExpression(*)], [])" ) { it.findExpression("x") } } @@ -87,7 +87,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x = max(0) """.trimIndent(), CasterStage::class, - "CallExpression(Int, max, null, [ConstantExpression(*)], [])" + "CallExpression(Int, max, null, 0, [ConstantExpression(*)], [])" ) { it.findExpression("x") } } @@ -98,7 +98,11 @@ internal class CallExpressionCasterTest : BaseTest() { var x = max(0, 1, 2) """.trimIndent(), CasterStage::class, - "CallExpression(Int, max, null, [ConstantExpression(*), ConstantExpression(*), ConstantExpression(*)], [])" + """ + CallExpression( + Int, max, null, 0, [ConstantExpression(*), ConstantExpression(*), ConstantExpression(*)], [] + ) + """.trimIndent() ) { it.findExpression("x") } } @@ -110,7 +114,7 @@ internal class CallExpressionCasterTest : BaseTest() { var x = f() """.trimIndent(), CasterStage::class, - "CallExpression(Unit, f, null, [NothingExpression()], [])" + "CallExpression(Unit, f, null, 0, [NothingExpression()], [])" ) { it.findExpression("x") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt index 664a35d4a..66fab9b5e 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt @@ -150,7 +150,9 @@ internal class DeclarationCasterTest : BaseTest() { """ KtClass( C1, C1, C0, [], [], - PrimaryConstructor(C1, C1, [], CallExpression(C0, C0, null, [ConstantExpression(*)], [Int])), + PrimaryConstructor( + C1, C1, [], CallExpression(C0, C0, null, 0, [ConstantExpression(*)], [Int]) + ), 0, 0 ) """.trimIndent() @@ -187,7 +189,7 @@ internal class DeclarationCasterTest : BaseTest() { C1, C1, C0, [], [SecondaryConstructor( C1, C1, BlockExpression(*), [KtValueParameter(x, Int, null, 0, 0)], - CallExpression(C0, C0, null, [ConstantExpression(*)], [Int]) + CallExpression(C0, C0, null, 0, [ConstantExpression(*)], [Int]) )], null, 0, 0 ) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt index 89846ffe5..db691bdee 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt @@ -77,7 +77,7 @@ internal class ExpressionCasterTest : BaseTest() { var x = u(1) shl 1 """.trimIndent(), CasterStage::class, - "CallExpression(Ubit<`*`>, shl, CallExpression(*), [ConstantExpression(*)], [])" + "CallExpression(Ubit<`*`>, shl, CallExpression(*), 0, [ConstantExpression(*)], [])" ) { it.findExpression("x") } } @@ -89,7 +89,7 @@ internal class ExpressionCasterTest : BaseTest() { var y = x """.trimIndent(), CasterStage::class, - "ReferenceExpression(Int, x, null)" + "ReferenceExpression(Int, x, null, 0)" ) { it.findExpression("y") } } @@ -101,7 +101,7 @@ internal class ExpressionCasterTest : BaseTest() { var y = test.x """.trimIndent(), CasterStage::class, - "ReferenceExpression(Int, x, null)" + "ReferenceExpression(Int, x, null, 0)" ) { it.findExpression("y") } } @@ -113,7 +113,7 @@ internal class ExpressionCasterTest : BaseTest() { var x = E.A """.trimIndent(), CasterStage::class, - "ReferenceExpression(E, A, null)" + "ReferenceExpression(E, A, null, 0)" ) { it.findExpression("x") } } @@ -126,7 +126,7 @@ internal class ExpressionCasterTest : BaseTest() { } """.trimIndent(), CasterStage::class, - "CallExpression(Unit, println, null, [], [])" + "CallExpression(Unit, println, null, 0, [], [])" ) { it.findExpression("f") } } @@ -138,7 +138,7 @@ internal class ExpressionCasterTest : BaseTest() { var y = x.plus(1) """.trimIndent(), CasterStage::class, - "CallExpression(Int, plus, ReferenceExpression(*), [ConstantExpression(*)], [])" + "CallExpression(Int, plus, ReferenceExpression(*), 0, [ConstantExpression(*)], [])" ) { it.findExpression("y") } } @@ -149,7 +149,7 @@ internal class ExpressionCasterTest : BaseTest() { var x = io.verik.core.random() """.trimIndent(), CasterStage::class, - "CallExpression(Int, random, null, [], [])" + "CallExpression(Int, random, null, 0, [], [])" ) { it.findExpression("x") } } @@ -204,7 +204,7 @@ internal class ExpressionCasterTest : BaseTest() { } """.trimIndent(), CasterStage::class, - "CallExpression(Unit, f, SuperExpression(C), [], [])" + "CallExpression(Unit, f, SuperExpression(C), 0, [], [])" ) { it.findExpression("g") } } @@ -233,9 +233,7 @@ internal class ExpressionCasterTest : BaseTest() { CasterStage::class, """ CallExpression( - Unit, - forEach, - ReferenceExpression(*), + Unit, forEach, ReferenceExpression(*), 0, [FunctionLiteralExpression(Function, [KtValueParameter(y, Boolean, null, 0, 0)], *)], [Boolean] ) @@ -255,9 +253,7 @@ internal class ExpressionCasterTest : BaseTest() { CasterStage::class, """ CallExpression( - Unit, - forEach, - ReferenceExpression(*), + Unit, forEach, ReferenceExpression(*), 0, [FunctionLiteralExpression(Function, [KtValueParameter(it, Boolean, null, 0, 0)], *)], [Boolean] ) @@ -274,10 +270,12 @@ internal class ExpressionCasterTest : BaseTest() { CasterStage::class, """ CallExpression( - Boolean, oni, null, [ + Boolean, oni, null, 0, + [ CallExpression(*), FunctionLiteralExpression(Function, [], BlockExpression(Boolean, [*])) - ], [Boolean] + ], + [Boolean] ) """.trimIndent() ) { it.findExpression("x") } @@ -328,7 +326,7 @@ internal class ExpressionCasterTest : BaseTest() { """ IfExpression( Int, - ReferenceExpression(Boolean, x, null), + ReferenceExpression(Boolean, x, null, 0), BlockExpression(Int, [ConstantExpression(*)]), BlockExpression(Int, [ConstantExpression(*)]) ) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/SmartCastReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/SmartCastReducerStageTest.kt index 800f62b6c..e0c2d0790 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/SmartCastReducerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/SmartCastReducerStageTest.kt @@ -37,7 +37,7 @@ internal class SmartCastReducerStageTest : BaseTest() { } """.trimIndent(), SmartCastReducerStage::class, - "CallExpression(Boolean, f, null, [ReferenceExpression(D, , null)], [])" + "CallExpression(Boolean, f, null, 0, [ReferenceExpression(D, , null, 0)], [])" ) { it.findExpression("x") } } @@ -55,7 +55,7 @@ internal class SmartCastReducerStageTest : BaseTest() { } """.trimIndent(), SmartCastReducerStage::class, - "CallExpression(Boolean, f, ReferenceExpression(D, , null), [], [])" + "CallExpression(Boolean, f, ReferenceExpression(D, , null, 0), 0, [], [])" ) { it.findExpression("x") } } @@ -74,7 +74,7 @@ internal class SmartCastReducerStageTest : BaseTest() { } """.trimIndent(), SmartCastReducerStage::class, - "CallExpression(Boolean, f, ReferenceExpression(D, , null), [], [])" + "CallExpression(Boolean, f, ReferenceExpression(D, , null, 0), 0, [], [])" ) { it.findExpression("x") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ConstantPropagatorSubstageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ConstantPropagatorSubstageTest.kt index d219fa2e3..5c75c82f4 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ConstantPropagatorSubstageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ConstantPropagatorSubstageTest.kt @@ -33,7 +33,7 @@ internal class ConstantPropagatorSubstageTest : BaseTest() { } """.trimIndent(), SpecializerStage::class, - "CallExpression(Unit, println, null, [ConstantExpression(Int, 0)], [])" + "CallExpression(Unit, println, null, 0, [ConstantExpression(Int, 0)], [])" ) { it.findExpression("f") } } @@ -48,7 +48,7 @@ internal class ConstantPropagatorSubstageTest : BaseTest() { } """.trimIndent(), SpecializerStage::class, - "CallExpression(Unit, println, null, [ConstantExpression(Int, 0)], [])" + "CallExpression(Unit, println, null, 0, [ConstantExpression(Int, 0)], [])" ) { it.findExpression("f") } } @@ -62,7 +62,7 @@ internal class ConstantPropagatorSubstageTest : BaseTest() { } """.trimIndent(), SpecializerStage::class, - "CallExpression(Unit, println, null, [ConstantExpression(Boolean, 1'b1)], [])" + "CallExpression(Unit, println, null, 0, [ConstantExpression(Boolean, 1'b1)], [])" ) { it.findExpression("f") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ExpressionEvaluatorSubstageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ExpressionEvaluatorSubstageTest.kt index d046dd778..92ff06b37 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ExpressionEvaluatorSubstageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/evaluate/ExpressionEvaluatorSubstageTest.kt @@ -46,7 +46,7 @@ internal class ExpressionEvaluatorSubstageTest : BaseTest() { var y = x || false """.trimIndent(), SpecializerStage::class, - "ReferenceExpression(Boolean, x, null)" + "ReferenceExpression(Boolean, x, null, 0)" ) { it.findExpression("y") } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ClassInterpreterStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ClassInterpreterStageTest.kt index 66104ad55..205883af6 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ClassInterpreterStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ClassInterpreterStageTest.kt @@ -32,7 +32,7 @@ internal class ClassInterpreterStageTest : BaseTest() { """ SvClass( C, C, Class, [], - [SecondaryConstructor(C, C, BlockExpression(*), [], CallExpression(Class, Class, null, [], []))], + [SecondaryConstructor(C, C, BlockExpression(*), [], CallExpression(Class, Class, null, 0, [], []))], 0 ) """.trimIndent(), diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStageTest.kt index 514d7c90d..90ebade77 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/ConstructorInterpreterStageTest.kt @@ -51,7 +51,7 @@ internal class ConstructorInterpreterStageTest : BaseTest() { SvClass( D, D, C, [], [SvConstructor( - D, BlockExpression(Unit, [CallExpression(Unit, new, SuperExpression(C), [], [])]), [] + D, BlockExpression(Unit, [CallExpression(Unit, new, SuperExpression(C), 0, [], [])]), [] )], 0 ) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStageTest.kt index dd79daf5e..7776175bd 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStageTest.kt @@ -46,8 +46,8 @@ internal class PrimaryConstructorReducerStageTest : BaseTest() { Unit, [KtBinaryExpression( Unit, - ReferenceExpression(Int, x, ThisExpression(C)), - ReferenceExpression(Int, x, null), + ReferenceExpression(Int, x, ThisExpression(C), 0), + ReferenceExpression(Int, x, null, 0), EQ )] ) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/ExpressionReferenceForwarderTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/ExpressionReferenceForwarderTest.kt index 04d2449c2..90024002e 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/ExpressionReferenceForwarderTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/ExpressionReferenceForwarderTest.kt @@ -34,7 +34,7 @@ internal class ExpressionReferenceForwarderTest : BaseTest() { val c = C<`8`>() """.trimIndent(), TypeResolverStage::class, - "ReferenceExpression(Ubit<`8`>, x, null)" + "ReferenceExpression(Ubit<`8`>, x, null, 0)" ) { it.findExpression("y") } } @@ -52,7 +52,7 @@ internal class ExpressionReferenceForwarderTest : BaseTest() { } """.trimIndent(), TypeResolverStage::class, - "ReferenceExpression(Int, x, null)" + "ReferenceExpression(Int, x, null, 0)" ) { it.findExpression("f") } } @@ -70,7 +70,7 @@ internal class ExpressionReferenceForwarderTest : BaseTest() { } """.trimIndent(), TypeResolverStage::class, - "ReferenceExpression(Int, x, ReferenceExpression(C1, c, null))" + "ReferenceExpression(Int, x, ReferenceExpression(C1, c, null, 0), 0)" ) { it.findExpression("f") } } @@ -86,7 +86,7 @@ internal class ExpressionReferenceForwarderTest : BaseTest() { val c = C<`8`>() """.trimIndent(), TypeResolverStage::class, - "CallExpression(Boolean, f, null, [], [])" + "CallExpression(Boolean, f, null, 0, [], [])" ) { it.findExpression("x") } } @@ -101,7 +101,7 @@ internal class ExpressionReferenceForwarderTest : BaseTest() { val c = C<`8`>() """.trimIndent(), TypeResolverStage::class, - "CallExpression(D, D, null, [], [])" + "CallExpression(D, D, null, 0, [], [])" ) { it.findExpression("x") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/SliceResolverStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/SliceResolverStageTest.kt index 0afd92cc1..4a725396b 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/SliceResolverStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/SliceResolverStageTest.kt @@ -30,7 +30,7 @@ internal class SliceResolverStageTest : BaseTest() { var y = x[1, 0] """.trimIndent(), SliceResolverStage::class, - "CallExpression(Ubit<`*`>, get, ReferenceExpression(*), [*], [`2`])" + "CallExpression(Ubit<`*`>, get, ReferenceExpression(*), 0, [*], [`2`])" ) { it.findExpression("y") } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/TypeResolverStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/TypeResolverStageTest.kt index 93ce2bcc4..c2b520ee8 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/TypeResolverStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/resolve/TypeResolverStageTest.kt @@ -42,7 +42,7 @@ internal class TypeResolverStageTest : BaseTest() { var c = C<`8`>() """.trimIndent(), TypeResolverStage::class, - "Property(c, C<`8`>, CallExpression(C<`8`>, C_N_8, null, [], []), 1, 0)" + "Property(c, C<`8`>, CallExpression(C<`8`>, C_N_8, null, 0, [], []), 1, 0)" ) { it.findDeclaration("c") } } @@ -67,7 +67,7 @@ internal class TypeResolverStageTest : BaseTest() { } """.trimIndent(), TypeResolverStage::class, - "ReferenceExpression(Boolean, x, null)" + "ReferenceExpression(Boolean, x, null, 0)" ) { it.findExpression("f") } } @@ -82,7 +82,7 @@ internal class TypeResolverStageTest : BaseTest() { } """.trimIndent(), TypeResolverStage::class, - "ReferenceExpression(Ubit<`8`>, x, *)" + "ReferenceExpression(Ubit<`8`>, x, *, 0)" ) { it.findExpression("f") } } @@ -94,7 +94,7 @@ internal class TypeResolverStageTest : BaseTest() { val y = u(0x00) + x """.trimIndent(), TypeResolverStage::class, - "CallExpression(Ubit<`8`>, plus, *, *, [])" + "CallExpression(Ubit<`8`>, plus, *, 0, *, [])" ) { it.findExpression("y") } } @@ -105,7 +105,7 @@ internal class TypeResolverStageTest : BaseTest() { val x = u<`8`>() """.trimIndent(), TypeResolverStage::class, - "CallExpression(Ubit<`4`>, u, null, [], [`8`])" + "CallExpression(Ubit<`4`>, u, null, 0, [], [`8`])" ) { it.findExpression("x") } } @@ -116,7 +116,7 @@ internal class TypeResolverStageTest : BaseTest() { val x = cat(u(0), false) """.trimIndent(), TypeResolverStage::class, - "CallExpression(Ubit<`2`>, cat, null, *, [])" + "CallExpression(Ubit<`2`>, cat, null, 0, *, [])" ) { it.findExpression("x") } } @@ -128,7 +128,7 @@ internal class TypeResolverStageTest : BaseTest() { val x = f(u0()) """.trimIndent(), TypeResolverStage::class, - "CallExpression(Unit, f, null, [CallExpression(Ubit<`8`>, u0, null, [], [`8`])], [])" + "CallExpression(Unit, f, null, 0, [CallExpression(Ubit<`8`>, u0, null, 0, [], [`8`])], [])" ) { it.findExpression("x") } } @@ -141,7 +141,7 @@ internal class TypeResolverStageTest : BaseTest() { } """.trimIndent(), TypeResolverStage::class, - "ReturnStatement(Nothing, CallExpression(Ubit<`8`>, u0, null, [], [`8`]))" + "ReturnStatement(Nothing, CallExpression(Ubit<`8`>, u0, null, 0, [], [`8`]))" ) { it.findExpression("f") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/OptionalReducerSubstageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/OptionalReducerSubstageTest.kt index 4fc5658a7..fccb3acba 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/OptionalReducerSubstageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/OptionalReducerSubstageTest.kt @@ -30,7 +30,7 @@ internal class OptionalReducerSubstageTest : BaseTest() { val m = optional { M() } """.trimIndent(), SpecializerStage::class, - "Property(m, M, CallExpression(M, M, null, [], []), 0, 0)" + "Property(m, M, CallExpression(M, M, null, 0, [], []), 0, 0)" ) { it.findDeclaration("m") } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerIndexerTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerIndexerTest.kt index edf17da3a..ba99459c1 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerIndexerTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerIndexerTest.kt @@ -43,7 +43,7 @@ internal class SpecializerIndexerTest : BaseTest() { val x = C<`1`>() """.trimIndent(), SpecializerStage::class, - "CallExpression(C<`*`>, C, null, [], [`1`])" + "CallExpression(C<`*`>, C, null, 0, [], [`1`])" ) { it.findExpression("x") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerStageTest.kt index c9cd33cfe..0a2efccf9 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/specialize/SpecializerStageTest.kt @@ -111,7 +111,7 @@ internal class SpecializerStageTest : BaseTest() { val c = C<`8`>() """.trimIndent(), SpecializerStage::class, - "Property(x, Boolean, CallExpression(Boolean, f, null, [], []), 0, 0)" + "Property(x, Boolean, CallExpression(Boolean, f, null, 0, [], []), 0, 0)" ) { it.findDeclaration("x") } } @@ -126,7 +126,7 @@ internal class SpecializerStageTest : BaseTest() { val c = C1<`8`>() """.trimIndent(), SpecializerStage::class, - "Property(x, C0, CallExpression(C0, C0, null, [], []), 0, 0)" + "Property(x, C0, CallExpression(C0, C0, null, 0, [], []), 0, 0)" ) { it.findDeclaration("x") } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStageTest.kt index faaf3f231..72ee08b43 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/ScopeExpressionInsertionTransformerStageTest.kt @@ -33,11 +33,9 @@ internal class ScopeExpressionInsertionTransformerStageTest : BaseTest() { ScopeExpressionInsertionTransformerStage::class, """ CallExpression( - ArrayList, - __new, + ArrayList, __new, ScopeExpression(Void, ArrayList, []), - [], - [Boolean] + 0, [], [Boolean] ) """.trimIndent() ) { it.findExpression("f") } @@ -55,7 +53,7 @@ internal class ScopeExpressionInsertionTransformerStageTest : BaseTest() { } """.trimIndent(), ScopeExpressionInsertionTransformerStage::class, - "ReferenceExpression(Boolean, x, ScopeExpression(Void, test_pkg, []))" + "ReferenceExpression(Boolean, x, ScopeExpression(Void, test_pkg, []), 0)" ) { it.findExpression("f") } } @@ -73,7 +71,7 @@ internal class ScopeExpressionInsertionTransformerStageTest : BaseTest() { } """.trimIndent(), ScopeExpressionInsertionTransformerStage::class, - "ReferenceExpression(Boolean, x, ScopeExpression(Void, O, []))" + "ReferenceExpression(Boolean, x, ScopeExpression(Void, O, []), 0)" ) { it.findExpression("f") } } @@ -89,7 +87,7 @@ internal class ScopeExpressionInsertionTransformerStageTest : BaseTest() { } """.trimIndent(), ScopeExpressionInsertionTransformerStage::class, - "ReferenceExpression(Boolean, x, ScopeExpression(Void, O, []))" + "ReferenceExpression(Boolean, x, ScopeExpression(Void, O, []), 0)" ) { it.findExpression("f") } } @@ -107,7 +105,11 @@ internal class ScopeExpressionInsertionTransformerStageTest : BaseTest() { } """.trimIndent(), ScopeExpressionInsertionTransformerStage::class, - "ReferenceExpression(Boolean, x, ReferenceExpression(M0, M0, ReferenceExpression(Void, ${'$'}root, null)))" + """ + ReferenceExpression( + Boolean, x, ReferenceExpression(M0, M0, ReferenceExpression(Void, ${'$'}root, null, 0), 0), 0 + ) + """.trimIndent() ) { it.findExpression("f") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStageTest.kt index ded8e7686..4541c4c23 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/post/StringTemplateExpressionTransformerStageTest.kt @@ -43,8 +43,8 @@ internal class StringTemplateExpressionTransformerStageTest : BaseTest() { StringTemplateExpressionTransformerStage::class, """ CallExpression( - String, ${"$"}sformatf, null, - [StringExpression(String, %0d), ReferenceExpression(Int, x, null)], + String, ${"$"}sformatf, null, 0, + [StringExpression(String, %0d), ReferenceExpression(Int, x, null, 0)], [] ) """.trimIndent() @@ -59,7 +59,7 @@ internal class StringTemplateExpressionTransformerStageTest : BaseTest() { """.trimIndent(), StringTemplateExpressionTransformerStage::class, """ - CallExpression(String, *, null, [StringExpression(String, %0d%%), ConstantExpression(*)], []) + CallExpression(String, *, null, 0, [StringExpression(String, %0d%%), ConstantExpression(*)], []) """.trimIndent() ) { it.findExpression("x") } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStageTest.kt index b9f084a86..cc08d2b14 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ArrayAccessExpressionReducerStageTest.kt @@ -30,7 +30,7 @@ internal class ArrayAccessExpressionReducerStageTest : BaseTest() { var y = x[0] """.trimIndent(), ArrayAccessExpressionReducerStage::class, - "CallExpression(Boolean, get, *, [*], [])" + "CallExpression(Boolean, get, *, 0, [*], [])" ) { it.findExpression("y") } } @@ -42,7 +42,7 @@ internal class ArrayAccessExpressionReducerStageTest : BaseTest() { var y = x[1, 0] """.trimIndent(), ArrayAccessExpressionReducerStage::class, - "CallExpression(Ubit<`*`>, get, *, [*], [])" + "CallExpression(Ubit<`*`>, get, *, 0, [*], [])" ) { it.findExpression("y") } } @@ -56,7 +56,7 @@ internal class ArrayAccessExpressionReducerStageTest : BaseTest() { } """.trimIndent(), ArrayAccessExpressionReducerStage::class, - "CallExpression(Unit, set, *, [*, *], [])" + "CallExpression(Unit, set, *, 0, [*, *], [])" ) { it.findExpression("f") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStageTest.kt index 04394b7f1..dcb5c0648 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/BinaryExpressionReducerStageTest.kt @@ -30,7 +30,7 @@ internal class BinaryExpressionReducerStageTest : BaseTest() { var y = x + 0 """.trimIndent(), BinaryExpressionReducerStage::class, - "CallExpression(Int, plus, ReferenceExpression(*), [ConstantExpression(*)], [])" + "CallExpression(Int, plus, ReferenceExpression(*), 0, [ConstantExpression(*)], [])" ) { it.findExpression("y") } } @@ -45,11 +45,9 @@ internal class BinaryExpressionReducerStageTest : BaseTest() { BinaryExpressionReducerStage::class, """ CallExpression( - Int, - plus, - CallExpression(Int, plus, ReferenceExpression(*), [ReferenceExpression(*)], []), - [ConstantExpression(*)], - [] + Int, plus, + CallExpression(Int, plus, ReferenceExpression(*), 0, [ReferenceExpression(*)], []), + 0, [ConstantExpression(*)], [] ) """.trimIndent() ) { it.findExpression("z") } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStageTest.kt index 304e4bbbb..75e1385d9 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/ForStatementReducerStageTest.kt @@ -34,8 +34,7 @@ internal class ForStatementReducerStageTest : BaseTest() { ForStatementReducerStage::class, """ CallExpression( - Unit, forEach, - CallExpression(IntRange, until, *, [*], []), + Unit, forEach, CallExpression(IntRange, until, *, 0, [*], []), 0, [FunctionLiteralExpression(Function, [KtValueParameter(*)], BlockExpression(*))], [Int] ) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStageTest.kt index 4845debb5..89181ad41 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/pre/UnaryExpressionReducerStageTest.kt @@ -30,7 +30,7 @@ internal class UnaryExpressionReducerStageTest : BaseTest() { var y = !x """.trimIndent(), UnaryExpressionReducerStage::class, - "CallExpression(Boolean, not, ReferenceExpression(*), [], [])" + "CallExpression(Boolean, not, ReferenceExpression(*), 0, [], [])" ) { it.findExpression("y") } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/CaseStatementTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/CaseStatementTransformerStageTest.kt index baf1df854..88ee9f75f 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/CaseStatementTransformerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/CaseStatementTransformerStageTest.kt @@ -38,7 +38,7 @@ internal class CaseStatementTransformerStageTest : BaseTest() { """ CaseStatement( Unit, - ReferenceExpression(Int, x, null), + ReferenceExpression(Int, x, null, 0), [CaseEntry([ConstantExpression(Int, 0)], *), CaseEntry([], *)] ) """.trimIndent() @@ -62,7 +62,7 @@ internal class CaseStatementTransformerStageTest : BaseTest() { CaseStatement( Unit, ConstantExpression(Boolean, 1'b1), - [CaseEntry([ReferenceExpression(Boolean, x, null)], *), CaseEntry([], *)] + [CaseEntry([ReferenceExpression(Boolean, x, null, 0)], *), CaseEntry([], *)] ) """.trimIndent() ) { it.findExpression("f") } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStageTest.kt index 8855cef50..e44ad8b83 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStageTest.kt @@ -36,7 +36,7 @@ internal class ForStatementTransformerStageTest : BaseTest() { SvForStatement( Void, Property(it, Int, ConstantExpression(Int, 0), 1, 0), - KtBinaryExpression(Boolean, ReferenceExpression(Int, it, null), ConstantExpression(*), LT), + KtBinaryExpression(Boolean, ReferenceExpression(Int, it, null, 0), ConstantExpression(*), LT), KtUnaryExpression(Int, ReferenceExpression(*), POST_INC), BlockExpression(Unit, []) ) @@ -59,15 +59,15 @@ internal class ForStatementTransformerStageTest : BaseTest() { SvForStatement( Void, Property(, Int, ConstantExpression(Int, 0), 1, 0), - KtBinaryExpression(Boolean, ReferenceExpression(Int, , null), ReferenceExpression(*), LT), - KtUnaryExpression(Int, ReferenceExpression(Int, , null), POST_INC), + KtBinaryExpression(Boolean, ReferenceExpression(Int, , null, 0), ReferenceExpression(*), LT), + KtUnaryExpression(Int, ReferenceExpression(Int, , null, 0), POST_INC), BlockExpression( Unit, [PropertyStatement( Unit, Property( it, Boolean, - CallExpression(Boolean, get, ReferenceExpression(*), [ReferenceExpression(*)], []), + CallExpression(Boolean, get, ReferenceExpression(*), 0, [ReferenceExpression(*)], []), 0, 0 ) )] diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt index ff3a7f1fc..521bc9cdd 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/ToStringTransformerStageTest.kt @@ -33,7 +33,7 @@ internal class ToStringTransformerStageTest : BaseTest() { } """.trimIndent(), ToStringTransformerStage::class, - "StringTemplateExpression(String, [CallExpression(String, name, ReferenceExpression(*), [], [])])" + "StringTemplateExpression(String, [CallExpression(String, name, ReferenceExpression(*), 0, [], [])])" ) { it.findExpression("f") } } @@ -66,8 +66,8 @@ internal class ToStringTransformerStageTest : BaseTest() { ToStringTransformerStage::class, """ CallExpression( - Unit, println, null, - [CallExpression(String, toString, ReferenceExpression(C, c, null), [], [])], [] + Unit, println, null, 0, + [CallExpression(String, toString, ReferenceExpression(C, c, null, 0), 0, [], [])], [] ) """.trimIndent() ) { it.findExpression("f") } From 6e2f122bdeea344a285b643f1305a889e7e0b4f2 Mon Sep 17 00:00:00 2001 From: Francis Wang Date: Mon, 21 Feb 2022 16:22:33 -0500 Subject: [PATCH 4/6] Safe access reducer stage --- CHANGELOG.md | 1 + .../expression/common/ECallExpression.kt | 2 +- .../expression/common/EReceiverExpression.kt | 2 +- .../expression/common/EReferenceExpression.kt | 16 +++- .../io/verik/compiler/cast/CasterVisitor.kt | 4 +- .../verik/compiler/cast/ExpressionCaster.kt | 21 +++-- .../compiler/constant/ConstantBuilder.kt | 4 + .../PrimaryConstructorReducerStage.kt | 8 +- .../io/verik/compiler/main/StageSequencer.kt | 2 + .../lower/ExpressionExtractorStage.kt | 8 +- .../transform/upper/CastTransformerStage.kt | 16 +--- .../upper/ForStatementTransformerStage.kt | 16 +--- .../upper/IfAndWhenExpressionUnlifterStage.kt | 18 +--- .../ProceduralAssignmentTransformerStage.kt | 16 +--- .../transform/upper/SafeAccessReducerStage.kt | 86 +++++++++++++++++++ .../upper/TaskReturnTransformerStage.kt | 10 +-- .../compiler/cast/ExpressionCasterTest.kt | 17 ++++ .../upper/SafeAccessReducerStageTest.kt | 56 ++++++++++++ 18 files changed, 210 insertions(+), 93 deletions(-) create mode 100644 verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStage.kt create mode 100644 verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStageTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 880f0b87c..9c5f4c483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - All classes should inherit from `Class` to get randomization functions. - Support for randomize annotation `@Rand`. - Support `toString` function. +- Support for safe access operator. ## [0.1.13] ### Importer diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt index bbbcd3792..844fbce22 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/ECallExpression.kt @@ -29,7 +29,7 @@ class ECallExpression( override var type: Type, override var reference: Declaration, override var receiver: EExpression?, - override val isSafeAccess: Boolean, + override var isSafeAccess: Boolean, val valueArguments: ArrayList, var typeArguments: ArrayList ) : EReceiverExpression() { diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt index 2a29c4953..b20f07174 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReceiverExpression.kt @@ -24,7 +24,7 @@ abstract class EReceiverExpression : EExpression(), ExpressionContainer { abstract var reference: Declaration abstract var receiver: EExpression? - abstract val isSafeAccess: Boolean + abstract var isSafeAccess: Boolean override fun acceptChildren(visitor: TreeVisitor) { receiver?.accept(visitor) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt index 2472cc9e3..3be0e8232 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/common/EReferenceExpression.kt @@ -18,6 +18,7 @@ package io.verik.compiler.ast.element.expression.common import io.verik.compiler.ast.common.Declaration import io.verik.compiler.ast.common.Type +import io.verik.compiler.ast.element.declaration.common.EAbstractProperty import io.verik.compiler.ast.property.SerializationType import io.verik.compiler.common.Visitor import io.verik.compiler.message.SourceLocation @@ -27,7 +28,7 @@ class EReferenceExpression( override var type: Type, override var reference: Declaration, override var receiver: EExpression?, - override val isSafeAccess: Boolean + override var isSafeAccess: Boolean ) : EReceiverExpression() { override val serializationType = SerializationType.EXPRESSION @@ -39,4 +40,17 @@ class EReferenceExpression( override fun accept(visitor: Visitor) { visitor.visitReferenceExpression(this) } + + companion object { + + fun of(property: EAbstractProperty): EReferenceExpression { + return EReferenceExpression( + property.location, + property.type.copy(), + property, + null, + false + ) + } + } } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CasterVisitor.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CasterVisitor.kt index a478956a1..3b0db6fd7 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CasterVisitor.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CasterVisitor.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.psi.KtClassInitializer import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtConstantExpression import org.jetbrains.kotlin.psi.KtDoWhileExpression -import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.psi.KtForExpression @@ -43,6 +42,7 @@ import org.jetbrains.kotlin.psi.KtPostfixExpression import org.jetbrains.kotlin.psi.KtPrefixExpression import org.jetbrains.kotlin.psi.KtPrimaryConstructor import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtReturnExpression import org.jetbrains.kotlin.psi.KtSecondaryConstructor import org.jetbrains.kotlin.psi.KtSimpleNameExpression @@ -145,7 +145,7 @@ class CasterVisitor(private val castContext: CastContext) : KtVisitor { val descriptor = castContext.sliceReferenceTarget[selector]!! val declaration = castContext.resolveDeclaration(descriptor, expression) - val referenceExpression = EReferenceExpression(location, type, declaration, receiver, false) + val referenceExpression = EReferenceExpression(location, type, declaration, receiver, isSafeAccess) ReferenceExpressionCaster.checkSmartCast(expression, referenceExpression, castContext) referenceExpression } @@ -172,13 +175,13 @@ object ExpressionCaster { val valueArguments = CallExpressionCaster.castValueArguments(selector.calleeExpression!!, castContext) val typeArguments = CallExpressionCaster.castTypeArguments(selector, castContext) return ECallExpression( - location, - type, - declaration, - receiver, - false, - valueArguments, - typeArguments + location = location, + type = type, + reference = declaration, + receiver = receiver, + isSafeAccess = isSafeAccess, + valueArguments = valueArguments, + typeArguments = typeArguments ) } else -> Messages.INTERNAL_ERROR.on(expression, "Simple name expression or call expression expected") diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/constant/ConstantBuilder.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/constant/ConstantBuilder.kt index 98b36c920..981736107 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/constant/ConstantBuilder.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/constant/ConstantBuilder.kt @@ -23,6 +23,10 @@ import io.verik.compiler.message.SourceLocation object ConstantBuilder { + fun buildNull(location: SourceLocation): EConstantExpression { + return EConstantExpression(location, Core.Kt.C_Nothing.toType(), "null") + } + fun buildBoolean(location: SourceLocation, kind: BooleanConstantKind): EConstantExpression { return EConstantExpression( location, diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt index 80158f8e4..1db8d5cb3 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/PrimaryConstructorReducerStage.kt @@ -108,13 +108,7 @@ object PrimaryConstructorReducerStage : ProjectStage() { thisExpression, false ) - val valueParameterReferenceExpression = EReferenceExpression( - valueParameter.location, - valueParameter.type.copy(), - valueParameter, - null, - false - ) + val valueParameterReferenceExpression = EReferenceExpression.of(valueParameter) statements.add( EKtBinaryExpression( valueParameter.location, diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt index ed39bd00d..75e886a84 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt @@ -109,6 +109,7 @@ import io.verik.compiler.transform.upper.IfAndWhenExpressionUnlifterStage import io.verik.compiler.transform.upper.InjectedExpressionTransformerStage import io.verik.compiler.transform.upper.InlineIfExpressionTransformerStage import io.verik.compiler.transform.upper.ProceduralAssignmentTransformerStage +import io.verik.compiler.transform.upper.SafeAccessReducerStage import io.verik.compiler.transform.upper.TaskReturnTransformerStage import io.verik.compiler.transform.upper.ToStringTransformerStage import io.verik.compiler.transform.upper.UninitializedPropertyTransformerStage @@ -192,6 +193,7 @@ object StageSequencer { stageSequence.add(StageType.UPPER_TRANSFORM, UninitializedPropertyTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, ProceduralAssignmentTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, ForStatementTransformerStage) + stageSequence.add(StageType.UPPER_TRANSFORM, SafeAccessReducerStage) stageSequence.add(StageType.UPPER_TRANSFORM, InlineIfExpressionTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, IfAndWhenExpressionUnlifterStage) stageSequence.add(StageType.UPPER_TRANSFORM, CaseStatementTransformerStage) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt index c035b2d5a..7f5e0f7d1 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/lower/ExpressionExtractorStage.kt @@ -74,13 +74,7 @@ object ExpressionExtractorStage : ProjectStage() { expression.location, property ) - val referenceExpression = EReferenceExpression( - expression.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) return Pair(propertyStatement, referenceExpression) } } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt index aee40b2eb..ef46fca4f 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/CastTransformerStage.kt @@ -42,13 +42,7 @@ object CastTransformerStage : ProjectStage() { override fun visitIsExpression(isExpression: EIsExpression) { super.visitIsExpression(isExpression) - val referenceExpression = EReferenceExpression( - isExpression.location, - isExpression.property.type.copy(), - isExpression.property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(isExpression.property) val callExpression = ECallExpression( isExpression.location, Core.Kt.C_Boolean.toType(), @@ -83,13 +77,7 @@ object CastTransformerStage : ProjectStage() { initializer = null, isMutable = false ) - val referenceExpression = EReferenceExpression( - property.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) val propertyStatement = EPropertyStatement(property.location, property) val castCallExpression = ECallExpression( asExpression.location, diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt index ea1fc0fba..4ed189cfc 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ForStatementTransformerStage.kt @@ -85,13 +85,7 @@ object ForStatementTransformerStage : ProjectStage() { isMutable = true ) referenceUpdater.update(valueParameter, property) - val propertyReferenceExpression = EReferenceExpression( - property.location, - property.type.copy(), - property, - null, - false - ) + val propertyReferenceExpression = EReferenceExpression.of(property) val condition = EKtBinaryExpression( callExpression.location, Core.Kt.C_Boolean.toType(), @@ -125,13 +119,7 @@ object ForStatementTransformerStage : ProjectStage() { initializer = EConstantExpression(referenceExpression.location, Core.Kt.C_Int.toType(), "0"), isMutable = true ) - val indexReferenceExpression = EReferenceExpression( - indexProperty.location, - indexProperty.type.copy(), - indexProperty, - null, - false - ) + val indexReferenceExpression = EReferenceExpression.of(indexProperty) val sizeReferenceExpression = EReferenceExpression( referenceExpression.location, Core.Kt.C_Int.toType(), diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt index 3200b892b..73fc8e288 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/IfAndWhenExpressionUnlifterStage.kt @@ -49,13 +49,7 @@ object IfAndWhenExpressionUnlifterStage : ProjectStage() { ) val propertyStatement = EPropertyStatement(ifExpression.location, property) val newIfExpression = getIfExpressionReplacement(ifExpression, property) - val referenceExpression = EReferenceExpression( - ifExpression.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) val extractedExpressions = listOf( propertyStatement, newIfExpression, @@ -74,13 +68,7 @@ object IfAndWhenExpressionUnlifterStage : ProjectStage() { initializer = null, isMutable = false ) - val referenceExpression = EReferenceExpression( - whenExpression.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) val propertyStatement = EPropertyStatement( whenExpression.location, property @@ -143,7 +131,7 @@ object IfAndWhenExpressionUnlifterStage : ProjectStage() { EKtBinaryExpression( expression.location, Core.Kt.C_Unit.toType(), - EReferenceExpression(expression.location, property.type.copy(), property, null, false), + EReferenceExpression.of(property), expression, KtBinaryOperatorKind.EQ ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt index d57af5ec3..cff952845 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/ProceduralAssignmentTransformerStage.kt @@ -72,13 +72,7 @@ object ProceduralAssignmentTransformerStage : ProjectStage() { val initializer = property.initializer return if (initializer != null) { property.initializer = null - val referenceExpression = EReferenceExpression( - property.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) val binaryExpression = EKtBinaryExpression( property.location, Core.Kt.C_Unit.toType(), @@ -109,13 +103,7 @@ object ProceduralAssignmentTransformerStage : ProjectStage() { val initializer = property.initializer return if (initializer is ECallExpression && initializer.reference == Core.Vk.F_oni_Event_Event_Function) { property.initializer = null - val referenceExpression = EReferenceExpression( - property.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) val body = initializer.valueArguments.last().cast().body if (body.isEmpty()) { Messages.SEQ_ASSIGNMENT_NO_ONR_EXPRESSION.on(property) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStage.kt new file mode 100644 index 000000000..c440b6838 --- /dev/null +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStage.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Francis Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.verik.compiler.transform.upper + +import io.verik.compiler.ast.element.declaration.common.EProperty +import io.verik.compiler.ast.element.expression.common.EBlockExpression +import io.verik.compiler.ast.element.expression.common.EIfExpression +import io.verik.compiler.ast.element.expression.common.EPropertyStatement +import io.verik.compiler.ast.element.expression.common.EReceiverExpression +import io.verik.compiler.ast.element.expression.common.EReferenceExpression +import io.verik.compiler.ast.element.expression.kt.EKtBinaryExpression +import io.verik.compiler.ast.property.ExpressionType +import io.verik.compiler.ast.property.KtBinaryOperatorKind +import io.verik.compiler.common.ExpressionCopier +import io.verik.compiler.common.TreeVisitor +import io.verik.compiler.constant.ConstantBuilder +import io.verik.compiler.core.common.Core +import io.verik.compiler.main.ProjectContext +import io.verik.compiler.main.ProjectStage +import io.verik.compiler.message.Messages + +object SafeAccessReducerStage : ProjectStage() { + + override fun process(projectContext: ProjectContext) { + projectContext.project.accept(SafeAccessReducerVisitor) + } + + private object SafeAccessReducerVisitor : TreeVisitor() { + + override fun visitReceiverExpression(receiverExpression: EReceiverExpression) { + super.visitReceiverExpression(receiverExpression) + if (receiverExpression.isSafeAccess) { + val receiver = receiverExpression.receiver!! + val property = EProperty.temporary( + receiverExpression.location, + receiver.type.copy(), + ExpressionCopier.deepCopy(receiver), + false + ) + val propertyStatement = EPropertyStatement(receiverExpression.location, property) + val referenceExpression = EReferenceExpression.of(property) + val conditionBinaryExpression = EKtBinaryExpression( + receiverExpression.location, + Core.Kt.C_Boolean.toType(), + referenceExpression, + ConstantBuilder.buildNull(receiverExpression.location), + KtBinaryOperatorKind.EXCL_EQ + ) + val newReferenceExpression = ExpressionCopier.deepCopy(referenceExpression) + val newReceiverExpression = ExpressionCopier.shallowCopy(receiverExpression) + newReferenceExpression.parent = newReceiverExpression + newReceiverExpression.isSafeAccess = false + newReceiverExpression.receiver = newReferenceExpression + if (receiverExpression.getExpressionType() == ExpressionType.STATEMENT) { + val ifExpression = EIfExpression( + receiverExpression.location, + Core.Kt.C_Unit.toType(), + conditionBinaryExpression, + EBlockExpression.wrap(newReceiverExpression), + null + ) + EBlockExpression.extract( + receiverExpression, + listOf(propertyStatement, ifExpression) + ) + } else { + Messages.INTERNAL_ERROR.on(receiverExpression, "Unable to reduce smart access") + } + } + } + } +} diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt index ed6d3849f..83dd1da25 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/TaskReturnTransformerStage.kt @@ -62,7 +62,7 @@ object TaskReturnTransformerStage : ProjectStage() { val expression = returnStatement.expression if (valueParameter != null && expression != null) { val newReturnStatement = EReturnStatement(returnStatement.location, Core.Kt.C_Unit.toType(), null) - val referenceExpression = EReferenceExpression( + val referenceExpression = EReferenceExpression( returnStatement.location, valueParameter.type.copy(), valueParameter, @@ -106,13 +106,7 @@ object TaskReturnTransformerStage : ProjectStage() { isMutable = true ) val propertyStatement = EPropertyStatement(callExpression.location, property) - val referenceExpression = EReferenceExpression( - callExpression.location, - property.type.copy(), - property, - null, - false - ) + val referenceExpression = EReferenceExpression.of(property) val newCallExpression = ExpressionCopier.shallowCopy(callExpression) referenceExpression.parent = newCallExpression newCallExpression.valueArguments.add(referenceExpression) diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt index db691bdee..5cf5bf6ed 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/ExpressionCasterTest.kt @@ -153,6 +153,23 @@ internal class ExpressionCasterTest : BaseTest() { ) { it.findExpression("x") } } + @Test + fun `call expression safe access`() { + driveElementTest( + """ + class C : Class() { + fun f() {} + } + val c: C? = nc() + fun g() { + c?.f() + } + """.trimIndent(), + CasterStage::class, + "CallExpression(Unit, f, ReferenceExpression(C, c, null, 0), 1, [], [])" + ) { it.findExpression("g") } + } + @Test fun `constant expression integer`() { driveElementTest( diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStageTest.kt new file mode 100644 index 000000000..6f29f1eea --- /dev/null +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/SafeAccessReducerStageTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Francis Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.verik.compiler.transform.upper + +import io.verik.compiler.test.BaseTest +import io.verik.compiler.test.findExpression +import org.junit.jupiter.api.Test + +internal class SafeAccessReducerStageTest : BaseTest() { + + @Test + fun `transform statement`() { + driveElementTest( + """ + class C : Class() { + fun f() {} + } + val c: C? = nc() + fun g() { + c?.f() + } + """.trimIndent(), + SafeAccessReducerStage::class, + """ + BlockExpression(Unit, [ + PropertyStatement(Unit, Property(, C, ReferenceExpression(C, c, null, 0), 0, 0)), + IfExpression( + Unit, + KtBinaryExpression( + Boolean, ReferenceExpression(C, , null, 0), + ConstantExpression(Nothing, null), EXCL_EQ + ), + BlockExpression( + Unit, [CallExpression(Unit, f, ReferenceExpression(C, , null, 0), 0, [], [])] + ), + null + ) + ]) + """.trimIndent() + ) { it.findExpression("g") } + } +} From 8c8d43d81cc468fc1b0c1882e9b2aa42ea95d01e Mon Sep 17 00:00:00 2001 From: Francis Wang Date: Mon, 21 Feb 2022 22:35:11 -0500 Subject: [PATCH 5/6] Assert randomize --- .../expression/sv/EImmediateAssertStatement.kt | 4 ++-- .../io/verik/compiler/common/ElementPrinter.kt | 1 - .../core/declaration/kt/CoreKtFunctions.kt | 3 --- .../compiler/core/declaration/vk/CoreVkClass.kt | 15 +++++++++++++-- .../core/declaration/vk/CoreVkClassTest.kt | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/sv/EImmediateAssertStatement.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/sv/EImmediateAssertStatement.kt index f79be8f36..4dfa4bb52 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/sv/EImmediateAssertStatement.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/expression/sv/EImmediateAssertStatement.kt @@ -17,21 +17,21 @@ package io.verik.compiler.ast.element.expression.sv import io.verik.compiler.ast.common.ExpressionContainer -import io.verik.compiler.ast.common.Type import io.verik.compiler.ast.element.expression.common.EBlockExpression import io.verik.compiler.ast.element.expression.common.EExpression import io.verik.compiler.ast.property.SerializationType import io.verik.compiler.common.TreeVisitor import io.verik.compiler.common.Visitor import io.verik.compiler.message.SourceLocation +import io.verik.compiler.target.common.Target class EImmediateAssertStatement( override val location: SourceLocation, - override var type: Type, var condition: EExpression, var elseExpression: EBlockExpression? ) : EExpression(), ExpressionContainer { + override var type = Target.C_Void.toType() override val serializationType = SerializationType.STATEMENT init { diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt index 9d0af6bbe..c059f1f88 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt @@ -663,7 +663,6 @@ class ElementPrinter : Visitor() { override fun visitImmediateAssertStatement(immediateAssertStatement: EImmediateAssertStatement) { build("ImmediateAssertStatement") { - build(immediateAssertStatement.type.toString()) build(immediateAssertStatement.condition) build(immediateAssertStatement.elseExpression) } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtFunctions.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtFunctions.kt index d95f8f1aa..d1b267060 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtFunctions.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/kt/CoreKtFunctions.kt @@ -21,7 +21,6 @@ import io.verik.compiler.ast.element.expression.common.EExpression import io.verik.compiler.ast.element.expression.kt.EFunctionLiteralExpression import io.verik.compiler.ast.element.expression.sv.EImmediateAssertStatement import io.verik.compiler.ast.element.expression.sv.ERepeatStatement -import io.verik.compiler.core.common.Core import io.verik.compiler.core.common.CorePackage import io.verik.compiler.core.common.CoreScope import io.verik.compiler.core.common.TransformableCoreFunctionDeclaration @@ -51,7 +50,6 @@ object CoreKtFunctions : CoreScope(CorePackage.KT) { override fun transform(callExpression: ECallExpression): EExpression { return EImmediateAssertStatement( callExpression.location, - Core.Kt.C_Unit.toType(), callExpression.valueArguments[0], null ) @@ -68,7 +66,6 @@ object CoreKtFunctions : CoreScope(CorePackage.KT) { val functionLiteralExpression = callExpression.valueArguments[1].cast() return EImmediateAssertStatement( callExpression.location, - Core.Kt.C_Unit.toType(), callExpression.valueArguments[0], functionLiteralExpression.body ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClass.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClass.kt index 7f66ce31c..93bf7d674 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClass.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClass.kt @@ -16,12 +16,23 @@ package io.verik.compiler.core.declaration.vk -import io.verik.compiler.core.common.BasicCoreFunctionDeclaration +import io.verik.compiler.ast.element.expression.common.ECallExpression +import io.verik.compiler.ast.element.expression.common.EExpression +import io.verik.compiler.ast.element.expression.sv.EImmediateAssertStatement +import io.verik.compiler.common.ExpressionCopier import io.verik.compiler.core.common.Core import io.verik.compiler.core.common.CoreScope +import io.verik.compiler.core.common.TransformableCoreFunctionDeclaration import io.verik.compiler.target.common.Target object CoreVkClass : CoreScope(Core.Vk.C_Class) { - val F_randomize = BasicCoreFunctionDeclaration(parent, "randomize", "fun randomize()", Target.F_randomize) + val F_randomize = object : TransformableCoreFunctionDeclaration(parent, "randomize", "fun randomize()") { + + override fun transform(callExpression: ECallExpression): EExpression { + val copiedCallExpression = ExpressionCopier.shallowCopy(callExpression) + copiedCallExpression.reference = Target.F_randomize + return EImmediateAssertStatement(callExpression.location, copiedCallExpression, null) + } + } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClassTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClassTest.kt index c5be39c3b..d30b223c1 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClassTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/core/declaration/vk/CoreVkClassTest.kt @@ -42,7 +42,7 @@ internal class CoreVkClassTest : CoreDeclarationTest() { endclass : C function automatic void f(); - c.randomize(); + assert (c.randomize()); endfunction : f """.trimIndent() ) From f03649dff261d86bdcb1c0d636f5010e3b862e00 Mon Sep 17 00:00:00 2001 From: Francis Wang Date: Tue, 22 Feb 2022 09:15:20 -0500 Subject: [PATCH 6/6] Enum with property --- CHANGELOG.md | 1 + .../element/declaration/common/EEnumEntry.kt | 28 ++++++-- .../ast/element/declaration/sv/EEnum.kt | 10 ++- .../verik/compiler/cast/CastIndexerStage.kt | 1 + .../verik/compiler/cast/DeclarationCaster.kt | 12 +++- .../verik/compiler/common/ElementPrinter.kt | 2 + .../interpret/EnumInterpreterStage.kt | 69 +++++++++++++++---- .../io/verik/compiler/main/StageSequencer.kt | 2 + .../io/verik/compiler/message/Messages.kt | 8 +++ .../resolve/TypeConstraintCollector.kt | 18 +++++ .../serialize/source/DeclarationSerializer.kt | 14 +++- .../compiler/specialize/SpecializerCopier.kt | 2 + .../EnumPropertyReferenceTransformerStage.kt | 47 +++++++++++++ .../compiler/cast/DeclarationCasterTest.kt | 11 ++- .../interpret/EnumInterpreterStageTest.kt | 20 +++++- .../source/DeclarationSerializerTest.kt | 14 ++++ ...umPropertyReferenceTransformerStageTest.kt | 37 ++++++++++ 17 files changed, 269 insertions(+), 27 deletions(-) create mode 100644 verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStage.kt create mode 100644 verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStageTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c5f4c483..528cfdd91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Support for randomize annotation `@Rand`. - Support `toString` function. - Support for safe access operator. +- Support for enums with values. ## [0.1.13] ### Importer diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/common/EEnumEntry.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/common/EEnumEntry.kt index ab05c97d2..54f388d48 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/common/EEnumEntry.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/common/EEnumEntry.kt @@ -16,7 +16,9 @@ package io.verik.compiler.ast.element.declaration.common +import io.verik.compiler.ast.common.ExpressionContainer import io.verik.compiler.ast.common.Type +import io.verik.compiler.ast.element.expression.common.EExpression import io.verik.compiler.ast.property.AnnotationEntry import io.verik.compiler.common.TreeVisitor import io.verik.compiler.common.Visitor @@ -27,22 +29,40 @@ class EEnumEntry( override var name: String, override var type: Type, override var annotationEntries: List, - override var documentationLines: List? -) : EAbstractProperty() { + override var documentationLines: List?, + var expression: EExpression? +) : EAbstractProperty(), ExpressionContainer { + + init { + expression?.parent = this + } fun fill( type: Type, annotationEntries: List, - documentationLines: List? + documentationLines: List?, + expression: EExpression? ) { + expression?.parent = this this.type = type this.annotationEntries = annotationEntries this.documentationLines = documentationLines + this.expression = expression } override fun accept(visitor: Visitor) { visitor.visitEnumEntry(this) } - override fun acceptChildren(visitor: TreeVisitor) {} + override fun acceptChildren(visitor: TreeVisitor) { + expression?.accept(visitor) + } + + override fun replaceChild(oldExpression: EExpression, newExpression: EExpression): Boolean { + newExpression.parent = this + return if (expression == oldExpression) { + expression = newExpression + true + } else false + } } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/sv/EEnum.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/sv/EEnum.kt index fa6ded82d..8f862f33b 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/sv/EEnum.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/ast/element/declaration/sv/EEnum.kt @@ -19,6 +19,7 @@ package io.verik.compiler.ast.element.declaration.sv import io.verik.compiler.ast.common.Type import io.verik.compiler.ast.element.declaration.common.EAbstractClass import io.verik.compiler.ast.element.declaration.common.EEnumEntry +import io.verik.compiler.ast.element.declaration.common.EProperty import io.verik.compiler.ast.property.AnnotationEntry import io.verik.compiler.common.TreeVisitor import io.verik.compiler.common.Visitor @@ -33,14 +34,21 @@ class EEnum( override var type: Type, override var annotationEntries: List, override var documentationLines: List?, + val property: EProperty?, val enumEntries: List ) : EAbstractClass() { override var superType = Target.C_Void.toType() + init { + property?.parent = this + } + override fun accept(visitor: Visitor) { visitor.visitEnum(this) } - override fun acceptChildren(visitor: TreeVisitor) {} + override fun acceptChildren(visitor: TreeVisitor) { + property?.accept(visitor) + } } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CastIndexerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CastIndexerStage.kt index dd1ad57fd..00fba058a 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CastIndexerStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/CastIndexerStage.kt @@ -215,6 +215,7 @@ object CastIndexerStage : ProjectStage() { type = NullDeclaration.toType(), annotationEntries = listOf(), documentationLines = null, + expression = null ) castContext.registerDeclaration(descriptor, indexedEnumEntry) } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt index 86964c358..140679dec 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/cast/DeclarationCaster.kt @@ -264,8 +264,18 @@ object DeclarationCaster { val type = castContext.castType(descriptor.classValueType!!, enumEntry) val annotationEntries = castAnnotationEntries(enumEntry.annotationEntries, castContext) val documentationLines = castDocumentationLines(enumEntry.docComment) + val initializerList = enumEntry.initializerList + val expression = if (initializerList != null && initializerList.initializers.isNotEmpty()) { + val initializer = initializerList.initializers[0] + if (initializer is KtSuperTypeCallEntry) { + val callExpression = castSuperTypeCallExpression(initializer, castContext) + if (callExpression.valueArguments.isNotEmpty()) { + callExpression.valueArguments[0] + } else null + } else null + } else null - castedEnumEntry.fill(type, annotationEntries, documentationLines) + castedEnumEntry.fill(type, annotationEntries, documentationLines, expression) return castedEnumEntry } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt index c059f1f88..0f5dd183b 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/common/ElementPrinter.kt @@ -228,6 +228,7 @@ class ElementPrinter : Visitor() { build("Enum") { build(enum.name) build(enum.type.toString()) + build(enum.property) build(enum.enumEntries.map { it.name }) } } @@ -353,6 +354,7 @@ class ElementPrinter : Visitor() { build("EnumEntry") { build(enumEntry.name) build(enumEntry.type.toString()) + build(enumEntry.expression) } } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/EnumInterpreterStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/EnumInterpreterStage.kt index f3e04dacc..427e31924 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/EnumInterpreterStage.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/interpret/EnumInterpreterStage.kt @@ -18,10 +18,12 @@ package io.verik.compiler.interpret import io.verik.compiler.ast.common.ResizableDeclarationContainer import io.verik.compiler.ast.element.declaration.common.EEnumEntry +import io.verik.compiler.ast.element.declaration.common.EProperty import io.verik.compiler.ast.element.declaration.kt.EKtClass import io.verik.compiler.ast.element.declaration.sv.EEnum import io.verik.compiler.common.ReferenceUpdater import io.verik.compiler.common.TreeVisitor +import io.verik.compiler.core.common.Core import io.verik.compiler.main.ProjectContext import io.verik.compiler.main.ProjectStage import io.verik.compiler.message.Messages @@ -45,24 +47,61 @@ object EnumInterpreterStage : ProjectStage() { referenceUpdater.flush() } - private class EnumInterpreterVisitor(private val referenceUpdater: ReferenceUpdater) : TreeVisitor() { + private class EnumInterpreterVisitor( + private val referenceUpdater: ReferenceUpdater + ) : TreeVisitor() { + + private fun interpretEnum(cls: EKtClass): EEnum { + val property = interpretEnumProperty(cls) + val enumEntries = cls.declarations.map { it.cast() } + val enum = EEnum( + cls.location, + cls.bodyStartLocation, + cls.bodyEndLocation, + cls.name, + cls.type, + cls.annotationEntries, + cls.documentationLines, + property, + enumEntries + ) + referenceUpdater.replace(cls, enum) + return enum + } + + private fun interpretEnumProperty(cls: EKtClass): EProperty? { + val primaryConstructor = cls.primaryConstructor ?: return null + val valueParameters = primaryConstructor.valueParameters + val valueParameter = when (valueParameters.size) { + 0 -> return null + 1 -> valueParameters[0] + else -> { + valueParameters.drop(1).forEach { + Messages.ENUM_PROPERTY_ILLEGAL.on(it, it.name) + } + return null + } + } + if (valueParameter.expression != null) { + Messages.ENUM_PROPERTY_ILLEGAL.on(valueParameter, valueParameter.name) + } + if (valueParameter.type.reference !in listOf(Core.Kt.C_Int, Core.Vk.C_Ubit)) { + Messages.ENUM_PROPERTY_ILLEGAL_TYPE.on(valueParameter, valueParameter.type) + } + val property = EProperty.named( + valueParameter.location, + valueParameter.name, + valueParameter.type, + null, + false + ) + referenceUpdater.update(valueParameter, property) + return property + } override fun visitKtClass(cls: EKtClass) { super.visitKtClass(cls) - if (cls.isEnum) { - val enumEntries = cls.declarations.map { it.cast() } - val enum = EEnum( - cls.location, - cls.bodyStartLocation, - cls.bodyEndLocation, - cls.name, - cls.type, - cls.annotationEntries, - cls.documentationLines, - enumEntries - ) - referenceUpdater.replace(cls, enum) - } + if (cls.isEnum) interpretEnum(cls) } } diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt index 75e886a84..4a41c4818 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/main/StageSequencer.kt @@ -104,6 +104,7 @@ import io.verik.compiler.transform.pre.TypeAliasReducerStage import io.verik.compiler.transform.pre.UnaryExpressionReducerStage import io.verik.compiler.transform.upper.CaseStatementTransformerStage import io.verik.compiler.transform.upper.CastTransformerStage +import io.verik.compiler.transform.upper.EnumPropertyReferenceTransformerStage import io.verik.compiler.transform.upper.ForStatementTransformerStage import io.verik.compiler.transform.upper.IfAndWhenExpressionUnlifterStage import io.verik.compiler.transform.upper.InjectedExpressionTransformerStage @@ -188,6 +189,7 @@ object StageSequencer { stageSequence.add(StageType.UPPER_TRANSFORM, InjectedExpressionTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, ToStringTransformerStage) + stageSequence.add(StageType.UPPER_TRANSFORM, EnumPropertyReferenceTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, CastTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, TaskReturnTransformerStage) stageSequence.add(StageType.UPPER_TRANSFORM, UninitializedPropertyTransformerStage) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt index 3db270b03..4af7355dc 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/message/Messages.kt @@ -258,6 +258,14 @@ object Messages { // INTERPRET ///////////////////////////////////////////////////////////////////////////////////////////////////////// + val ENUM_PROPERTY_ILLEGAL = ErrorMessageTemplate1( + "Illegal enum property: $0" + ) + + val ENUM_PROPERTY_ILLEGAL_TYPE = ErrorMessageTemplate1( + "Illegal type for enum property: $0" + ) + val EXPECTED_ON_EXPRESSION = ErrorMessageTemplate0( "Expected on expression" ) diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/resolve/TypeConstraintCollector.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/resolve/TypeConstraintCollector.kt index 7b2b95bb4..8a9031957 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/resolve/TypeConstraintCollector.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/resolve/TypeConstraintCollector.kt @@ -19,8 +19,10 @@ package io.verik.compiler.resolve import io.verik.compiler.ast.element.common.EElement import io.verik.compiler.ast.element.declaration.common.EAbstractProperty import io.verik.compiler.ast.element.declaration.common.EDeclaration +import io.verik.compiler.ast.element.declaration.common.EEnumEntry import io.verik.compiler.ast.element.declaration.common.EProperty import io.verik.compiler.ast.element.declaration.kt.EKtAbstractFunction +import io.verik.compiler.ast.element.declaration.kt.EKtClass import io.verik.compiler.ast.element.declaration.kt.EKtFunction import io.verik.compiler.ast.element.declaration.kt.EKtValueParameter import io.verik.compiler.ast.element.expression.common.EBlockExpression @@ -141,6 +143,22 @@ object TypeConstraintCollector { } } + override fun visitEnumEntry(enumEntry: EEnumEntry) { + super.visitEnumEntry(enumEntry) + val expression = enumEntry.expression + val cls = enumEntry.getParentClassOrNull() as EKtClass + val valueParameter = cls.primaryConstructor?.valueParameters?.firstOrNull() + if (expression != null && valueParameter != null) { + typeConstraints.add( + TypeConstraint( + TypeConstraintKind.EQ_IN, + TypeAdapter.ofElement(expression), + TypeAdapter.ofElement(valueParameter) + ) + ) + } + } + override fun visitKtValueParameter(valueParameter: EKtValueParameter) { super.visitKtValueParameter(valueParameter) val expression = valueParameter.expression diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/source/DeclarationSerializer.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/source/DeclarationSerializer.kt index abeee5e03..742b1aba8 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/source/DeclarationSerializer.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/serialize/source/DeclarationSerializer.kt @@ -99,7 +99,14 @@ object DeclarationSerializer { } fun serializeEnum(enum: EEnum, serializeContext: SerializeContext) { - serializeContext.appendLine("typedef enum {") + serializeContext.append("typedef enum") + val property = enum.property + if (property != null) { + val serializedType = TypeSerializer.serialize(property.type, enum) + serializedType.checkNoVariableDimension(enum) + serializeContext.append(" ${serializedType.base}") + } + serializeContext.appendLine(" {") serializeContext.indent { serializeContext.serializeJoinAppendLine(enum.enumEntries) { serializeContext.serialize(it) @@ -207,6 +214,11 @@ object DeclarationSerializer { fun serializeEnumEntry(enumEntry: EEnumEntry, serializeContext: SerializeContext) { serializeContext.append(enumEntry.name) + val expression = enumEntry.expression + if (expression != null) { + serializeContext.append(" = ") + serializeContext.serializeAsExpression(expression) + } } fun serializeComponentInstantiation( diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt index b88567c13..f1a4a560e 100644 --- a/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/specialize/SpecializerCopier.kt @@ -286,12 +286,14 @@ object SpecializerCopier { specializeContext: SpecializeContext ): EEnumEntry { val type = enumEntry.type.copy() + val expression = enumEntry.expression?.let { copy(it, typeArguments, specializeContext) } val copiedEnumEntry = EEnumEntry( location = enumEntry.location, name = enumEntry.name, type = type, annotationEntries = enumEntry.annotationEntries, documentationLines = enumEntry.documentationLines, + expression = expression ) specializeContext.register(enumEntry, typeArguments, copiedEnumEntry) return copiedEnumEntry diff --git a/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStage.kt b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStage.kt new file mode 100644 index 000000000..0095ea218 --- /dev/null +++ b/verik-compiler/src/main/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStage.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Francis Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.verik.compiler.transform.upper + +import io.verik.compiler.ast.element.declaration.common.EProperty +import io.verik.compiler.ast.element.declaration.sv.EEnum +import io.verik.compiler.ast.element.expression.common.EReferenceExpression +import io.verik.compiler.common.TreeVisitor +import io.verik.compiler.main.ProjectContext +import io.verik.compiler.main.ProjectStage + +object EnumPropertyReferenceTransformerStage : ProjectStage() { + + override fun process(projectContext: ProjectContext) { + projectContext.project.accept(EnumPropertyReferenceTransformerVisitor) + } + + private object EnumPropertyReferenceTransformerVisitor : TreeVisitor() { + + override fun visitReferenceExpression(referenceExpression: EReferenceExpression) { + super.visitReferenceExpression(referenceExpression) + val reference = referenceExpression.reference + if (reference is EProperty) { + val parent = reference.parent + if (parent is EEnum) { + val receiver = referenceExpression.receiver!! + receiver.type = referenceExpression.type + referenceExpression.replace(receiver) + } + } + } + } +} diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt index 66fab9b5e..65f80d5b6 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/cast/DeclarationCasterTest.kt @@ -217,13 +217,18 @@ internal class DeclarationCasterTest : BaseTest() { } @Test - fun `enum class`() { + fun `class enum`() { driveElementTest( """ - enum class E { A } + enum class E(val value: Ubit<`4`>) { A(u(0x0)) } """.trimIndent(), CasterStage::class, - "KtClass(E, E, Enum, [], [EnumEntry(A, E)], PrimaryConstructor(E, E, [], null), 1, 0)" + """ + KtClass( + E, E, Enum, [], [EnumEntry(A, E, CallExpression(*))], + PrimaryConstructor(E, E, [KtValueParameter(value, Ubit<`4`>, null, 1, 0)], null), 1, 0 + ) + """.trimIndent() ) { it.findDeclaration("E") } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/EnumInterpreterStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/EnumInterpreterStageTest.kt index af1a7f52b..7be4bffc4 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/EnumInterpreterStageTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/interpret/EnumInterpreterStageTest.kt @@ -22,13 +22,29 @@ import org.junit.jupiter.api.Test internal class EnumInterpreterStageTest : BaseTest() { @Test - fun `interpret enum`() { + fun `interpret enum simple`() { driveElementTest( """ enum class E { A } """.trimIndent(), EnumInterpreterStage::class, - "File([Enum(E, E, [A]), EnumEntry(A, E)])" + "File([Enum(E, E, null, [A]), EnumEntry(A, E, null)])" + ) { it.files().first() } + } + + @Test + fun `interpret enum with property`() { + driveElementTest( + """ + enum class E(val value: Ubit<`4`>) { A(u(0x0)) } + """.trimIndent(), + EnumInterpreterStage::class, + """ + File([ + Enum(E, E, Property(value, Ubit<`4`>, null, 0, 0), [A]), + EnumEntry(A, E, ConstantExpression(Ubit<`4`>, 4'b0000)) + ]) + """.trimIndent() ) { it.files().first() } } } diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt index 1cc9ac5ba..cc58b452b 100644 --- a/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/serialize/source/DeclarationSerializerTest.kt @@ -152,6 +152,20 @@ internal class DeclarationSerializerTest : BaseTest() { ) { it.nonRootPackageTextFiles[0] } } + @Test + fun `enum with property`() { + driveTextFileTest( + """ + enum class E(val value: Ubit<`4`>) { A(u(0x0)) } + """.trimIndent(), + """ + typedef enum logic [3:0] { + A = 4'b0000 + } E; + """.trimIndent() + ) { it.nonRootPackageTextFiles[0] } + } + @Test fun `struct simple`() { driveTextFileTest( diff --git a/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStageTest.kt b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStageTest.kt new file mode 100644 index 000000000..7e0a3b186 --- /dev/null +++ b/verik-compiler/src/test/kotlin/io/verik/compiler/transform/upper/EnumPropertyReferenceTransformerStageTest.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Francis Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.verik.compiler.transform.upper + +import io.verik.compiler.test.BaseTest +import io.verik.compiler.test.findExpression +import org.junit.jupiter.api.Test + +internal class EnumPropertyReferenceTransformerStageTest : BaseTest() { + + @Test + fun `enum property reference`() { + driveElementTest( + """ + enum class E(val value: Ubit<`4`>) { A(u0()) } + var x = E.A + var y = x.value + """.trimIndent(), + EnumPropertyReferenceTransformerStage::class, + "ReferenceExpression(Ubit<`4`>, x, null, 0)", + ) { it.findExpression("y") } + } +}