improved vairable tracking, fixed plugin to wirk with 1.0.10, fixed lambda comparison

This commit is contained in:
sergeych committed 2025-12-22 14:55:53 +01:00
1 parent 1e18a162c4
commit 0732202c80
12 files changed
+266 -28

No files matched your search

@@ -2569,7 +2569,21 @@ class Compiler(
val pattern = ListLiteralRef(entries)
// Register all names in the pattern
pattern.forEachVariable { name -> declareLocalName(name) }
pattern.forEachVariableWithPos { name, namePos ->
declareLocalName(name)
val declRange = MiniRange(namePos, namePos)
val node = MiniValDecl(
range = declRange,
name = name,
mutable = isMutable,
type = null,
initRange = null,
doc = pendingDeclDoc,
nameStart = namePos
)
miniSink?.onValDecl(node)
}
pendingDeclDoc = null
val eqToken = cc.next()
if (eqToken.type != Token.Type.ASSIGN)
@@ -1,3 +1,20 @@
/*
* Copyright 2025 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.
*
*/
/*
* Pure-Kotlin, PSI-free completion engine used for isolated tests and non-IDE harnesses.
* Mirrors the IntelliJ MVP logic: MiniAst + BuiltinDocRegistry + lenient imports.
@@ -270,6 +287,24 @@ object CompletionEngineLight {
break
}
if (hasDigits) return if (hasDot || hasExp) "Real" else "Int"
// 3) this@Type or as Type
val identRange = wordRangeAt(text, i + 1)
if (identRange != null) {
val ident = text.substring(identRange.first, identRange.second)
// if it's "as Type", we want Type
var k = prevNonWs(text, identRange.first - 1)
if (k >= 1 && text[k] == 's' && text[k - 1] == 'a' && (k - 1 == 0 || !text[k - 2].isLetterOrDigit())) {
return ident
}
// if it's "this@Type", we want Type
if (k >= 0 && text[k] == '@') {
val k2 = prevNonWs(text, k - 1)
if (k2 >= 3 && text.substring(k2 - 3, k2 + 1) == "this") {
return ident
}
}
}
}
return null
}
@@ -180,6 +180,10 @@ class ObjInt(var value: Long, override val isConst: Boolean = false) : Obj(), Nu
LynonType.IntSigned -> ObjInt(decoder.unpackSigned())
else -> scope.raiseIllegalState("illegal type code for Int: $lynonType")
}
}.apply {
addFn("toInt") {
thisObj
}
}
}
}
@@ -42,6 +42,14 @@ sealed interface ObjRef {
* Used for declaring local variables in destructuring.
*/
fun forEachVariable(block: (String) -> Unit) {}
/**
* Calls [block] for each variable name that this reference targets for writing,
* including its source position if available.
*/
fun forEachVariableWithPos(block: (String, Pos) -> Unit) {
forEachVariable { block(it, Pos.UNKNOWN) }
}
}
/** Runtime-computed read-only reference backed by a lambda. */
@@ -1225,6 +1233,10 @@ class LocalVarRef(private val name: String, private val atPos: Pos) : ObjRef {
override fun forEachVariable(block: (String) -> Unit) {
block(name)
}
override fun forEachVariableWithPos(block: (String, Pos) -> Unit) {
block(name, atPos)
}
// Per-frame slot cache to avoid repeated name lookups
private var cachedFrameId: Long = 0L
private var cachedSlot: Int = -1
@@ -1632,6 +1644,15 @@ class ListLiteralRef(private val entries: List<ListEntry>) : ObjRef {
}
}
override fun forEachVariableWithPos(block: (String, Pos) -> Unit) {
for (e in entries) {
when (e) {
is ListEntry.Element -> e.ref.forEachVariableWithPos(block)
is ListEntry.Spread -> e.ref.forEachVariableWithPos(block)
}
}
}
override suspend fun get(scope: Scope): ObjRecord {
// Heuristic capacity hint: count element entries; spreads handled opportunistically
val elemCount = entries.count { it is ListEntry.Element }
@@ -47,7 +47,8 @@ abstract class Statement(
override suspend fun compareTo(scope: Scope, other: Obj): Int {
if( other == ObjNull || other == ObjVoid ) return 1
throw UnsupportedOperationException("not comparable")
if( other === this ) return 0
return -1
}
override suspend fun callOn(scope: Scope): Obj {