diff --git a/lyng-idea/src/main/kotlin/net/sergeych/lyng/idea/actions/RunLyngScriptAction.kt b/lyng-idea/src/main/kotlin/net/sergeych/lyng/idea/actions/RunLyngScriptAction.kt index 1104024..139c519 100644 --- a/lyng-idea/src/main/kotlin/net/sergeych/lyng/idea/actions/RunLyngScriptAction.kt +++ b/lyng-idea/src/main/kotlin/net/sergeych/lyng/idea/actions/RunLyngScriptAction.kt @@ -38,6 +38,7 @@ import kotlinx.coroutines.launch import net.sergeych.lyng.ExecutionError import net.sergeych.lyng.Script import net.sergeych.lyng.Source +import net.sergeych.lyng.requireScope import net.sergeych.lyng.idea.LyngIcons import net.sergeych.lyng.obj.ObjVoid import net.sergeych.lyng.obj.getLyngExceptionMessageWithStackTrace @@ -81,7 +82,7 @@ class RunLyngScriptAction : AnAction(LyngIcons.FILE) { val sb = StringBuilder() for ((i, arg) in args.list.withIndex()) { if (i > 0) sb.append(" ") - sb.append(arg.toString(this).value) + sb.append(arg.toString(requireScope()).value) } console.print(sb.toString(), ConsoleViewContentType.NORMAL_OUTPUT) ObjVoid @@ -90,7 +91,7 @@ class RunLyngScriptAction : AnAction(LyngIcons.FILE) { val sb = StringBuilder() for ((i, arg) in args.list.withIndex()) { if (i > 0) sb.append(" ") - sb.append(arg.toString(this).value) + sb.append(arg.toString(requireScope()).value) } console.print(sb.toString() + "\n", ConsoleViewContentType.NORMAL_OUTPUT) ObjVoid diff --git a/lynglib/build.gradle.kts b/lynglib/build.gradle.kts index 84deea0..9203573 100644 --- a/lynglib/build.gradle.kts +++ b/lynglib/build.gradle.kts @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.dsl.JvmTarget group = "net.sergeych" -version = "1.3.0-SNAPSHOT" +version = "1.4.0-SNAPSHOT" // Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt index 9cf8f39..9224634 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt @@ -1192,7 +1192,9 @@ class Compiler( val found = LinkedHashMap>() collectModuleRecordMatches(module.scope, name, mutableSetOf(), found) for ((pkg, pair) in found) { - moduleMatches.putIfAbsent(pkg, ImportedModule(pair.first, module.pos) to pair.second) + if (!moduleMatches.containsKey(pkg)) { + moduleMatches[pkg] = ImportedModule(pair.first, module.pos) to pair.second + } } } if (seedRecord != null) { @@ -1241,7 +1243,9 @@ class Compiler( if (!visited.add(scope.packageName)) return val record = scope.objects[name] if (record != null && record.visibility.isPublic) { - out.putIfAbsent(scope.packageName, scope to record) + if (!out.containsKey(scope.packageName)) { + out[scope.packageName] = scope to record + } } for (child in scope.importedModules) { collectModuleRecordMatches(child, name, visited, out) diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Scope.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Scope.kt index 26933e2..2147b4f 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Scope.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Scope.kt @@ -80,23 +80,17 @@ open class Scope( extras.isEmpty() -> emptyList() else -> { try { - if (extras is MutableList<*>) { - synchronized(extras) { extras.toList() } - } else { - extras.toList() - } + extras.toList() } catch (_: Exception) { emptyList() } } } - synchronized(thisVariants) { - thisVariants.clear() - thisVariants.add(primary) - for (obj in extrasSnapshot) { - if (obj !== primary && !thisVariants.contains(obj)) { - thisVariants.add(obj) - } + thisVariants.clear() + thisVariants.add(primary) + for (obj in extrasSnapshot) { + if (obj !== primary && !thisVariants.contains(obj)) { + thisVariants.add(obj) } } } diff --git a/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt b/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt index 4400353..ab62759 100644 --- a/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt +++ b/lynglib/src/commonTest/kotlin/BytecodeRecentOpsTest.kt @@ -279,26 +279,6 @@ class BytecodeRecentOpsTest { assertTrue(disasm.contains("DECL_DELEGATED"), disasm) } - @Test - fun moduleDeclsAvoidCallableCallSlots() = runTest { - val script = """ - class A {} - fun f() { 1 } - enum E { one } - """.trimIndent() - val compiled = Compiler.compile(script.toSource(), Script.defaultImportManager) - val field = Script::class.java.getDeclaredField("moduleBytecode") - field.isAccessible = true - val moduleFn = field.get(compiled) as? CmdFunction - assertNotNull(moduleFn, "module bytecode missing") - val disasm = CmdDisassembler.disassemble(moduleFn) - assertTrue(!disasm.contains("CALL_SLOT"), disasm) - assertTrue(!disasm.contains("Callable@"), disasm) - assertTrue(disasm.contains("DECL_CLASS"), disasm) - assertTrue(disasm.contains("DECL_FUNCTION"), disasm) - assertTrue(disasm.contains("DECL_ENUM"), disasm) - } - @Test fun unionMemberDispatchSubtype() = runTest { eval( diff --git a/lynglib/src/jvmTest/kotlin/BytecodeRecentOpsJvmTest.kt b/lynglib/src/jvmTest/kotlin/BytecodeRecentOpsJvmTest.kt new file mode 100644 index 0000000..badc6e9 --- /dev/null +++ b/lynglib/src/jvmTest/kotlin/BytecodeRecentOpsJvmTest.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com + * + * 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 + * + * http://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. + * + */ + +import kotlinx.coroutines.test.runTest +import net.sergeych.lyng.Compiler +import net.sergeych.lyng.Script +import net.sergeych.lyng.toSource +import net.sergeych.lyng.bytecode.CmdDisassembler +import net.sergeych.lyng.bytecode.CmdFunction +import kotlin.test.Test +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class BytecodeRecentOpsJvmTest { + + @Test + fun moduleDeclsAvoidCallableCallSlots() = runTest { + val script = """ + class A {} + fun f() { 1 } + enum E { one } + """.trimIndent() + val compiled = Compiler.compile(script.toSource(), Script.defaultImportManager) + val field = Script::class.java.getDeclaredField("moduleBytecode") + field.isAccessible = true + val moduleFn = field.get(compiled) as? CmdFunction + assertNotNull(moduleFn, "module bytecode missing") + val disasm = CmdDisassembler.disassemble(moduleFn) + assertTrue(!disasm.contains("CALL_SLOT"), disasm) + assertTrue(!disasm.contains("Callable@"), disasm) + assertTrue(disasm.contains("DECL_CLASS"), disasm) + assertTrue(disasm.contains("DECL_FUNCTION"), disasm) + assertTrue(disasm.contains("DECL_ENUM"), disasm) + } +}