code cleanup performed (trivial cases)

This commit is contained in:
Sergey Chernov 2026-01-06 10:38:24 +01:00
parent fa4dc45f15
commit 8cd980514b
16 changed files with 86 additions and 81 deletions

View File

@ -175,8 +175,6 @@ class Compiler(
// A standalone newline not immediately following a comment resets doc buffer // A standalone newline not immediately following a comment resets doc buffer
if (!prevWasComment) clearPendingDoc() else prevWasComment = false if (!prevWasComment) clearPendingDoc() else prevWasComment = false
} }
else -> {}
} }
cc.next() cc.next()
continue continue
@ -2751,7 +2749,7 @@ class Compiler(
} }
if (extTypeName != null) { if (extTypeName != null) {
val type = context[extTypeName!!]?.value ?: context.raiseSymbolNotFound("class $extTypeName not found") val type = context[extTypeName]?.value ?: context.raiseSymbolNotFound("class $extTypeName not found")
if (type !is ObjClass) context.raiseClassCastError("$extTypeName is not the class instance") if (type !is ObjClass) context.raiseClassCastError("$extTypeName is not the class instance")
context.addExtension(type, name, ObjRecord(ObjUnset, isMutable = false, visibility = visibility, declaringClass = null, type = ObjRecord.Type.Delegated).apply { context.addExtension(type, name, ObjRecord(ObjUnset, isMutable = false, visibility = visibility, declaringClass = null, type = ObjRecord.Type.Delegated).apply {
delegate = finalDelegate delegate = finalDelegate
@ -2773,7 +2771,7 @@ class Compiler(
cls.createField(name, ObjUnset, false, visibility, null, start, declaringClass = cls, isAbstract = isAbstract, isClosed = isClosed, isOverride = isOverride, type = ObjRecord.Type.Delegated) cls.createField(name, ObjUnset, false, visibility, null, start, declaringClass = cls, isAbstract = isAbstract, isClosed = isClosed, isOverride = isOverride, type = ObjRecord.Type.Delegated)
cls.instanceInitializers += statement(start) { scp -> cls.instanceInitializers += statement(start) { scp ->
val accessType2 = scp.resolveQualifiedIdentifier("DelegateAccess.Callable") val accessType2 = scp.resolveQualifiedIdentifier("DelegateAccess.Callable")
val initValue2 = delegateExpression!!.execute(scp) val initValue2 = delegateExpression.execute(scp)
val finalDelegate2 = try { val finalDelegate2 = try {
initValue2.invokeInstanceMethod(scp, "bind", Arguments(ObjString(name), accessType2, scp.thisObj)) initValue2.invokeInstanceMethod(scp, "bind", Arguments(ObjString(name), accessType2, scp.thisObj))
} catch (e: Exception) { } catch (e: Exception) {
@ -3129,7 +3127,7 @@ class Compiler(
cc.skipWsTokens() cc.skipWsTokens()
cc.next() // consume '=' cc.next() // consume '='
val expr = parseExpression() ?: throw ScriptError(cc.current().pos, "Expected getter expression") val expr = parseExpression() ?: throw ScriptError(cc.current().pos, "Expected getter expression")
(expr as? Statement) ?: statement(expr.pos) { s -> expr.execute(s) } expr
} else { } else {
throw ScriptError(cc.current().pos, "Expected { or = after get()") throw ScriptError(cc.current().pos, "Expected { or = after get()")
} }
@ -3150,7 +3148,7 @@ class Compiler(
cc.skipWsTokens() cc.skipWsTokens()
cc.next() // consume '=' cc.next() // consume '='
val expr = parseExpression() ?: throw ScriptError(cc.current().pos, "Expected setter expression") val expr = parseExpression() ?: throw ScriptError(cc.current().pos, "Expected setter expression")
val st = (expr as? Statement) ?: statement(expr.pos) { s -> expr.execute(s) } val st = expr
statement(st.pos) { scope -> statement(st.pos) { scope ->
val value = scope.args.list.firstOrNull() ?: ObjNull val value = scope.args.list.firstOrNull() ?: ObjNull
scope.addItem(setArg.value, true, value, recordType = ObjRecord.Type.Argument) scope.addItem(setArg.value, true, value, recordType = ObjRecord.Type.Argument)
@ -3185,7 +3183,7 @@ class Compiler(
cc.current().pos, cc.current().pos,
"Expected setter expression" "Expected setter expression"
) )
val st = (expr as? Statement) ?: statement(expr.pos) { s -> expr.execute(s) } val st = expr
statement(st.pos) { scope -> statement(st.pos) { scope ->
val value = scope.args.list.firstOrNull() ?: ObjNull val value = scope.args.list.firstOrNull() ?: ObjNull
scope.addItem(setArg.value, true, value, recordType = ObjRecord.Type.Argument) scope.addItem(setArg.value, true, value, recordType = ObjRecord.Type.Argument)
@ -3388,7 +3386,7 @@ class Compiler(
prop prop
} }
} else { } else {
val isLateInitVal = !isMutable && initialExpression == null && getter == null && setter == null val isLateInitVal = !isMutable && initialExpression == null
if (declaringClassName != null && !isStatic) { if (declaringClassName != null && !isStatic) {
val storageName = "$declaringClassName::$name" val storageName = "$declaringClassName::$name"
// If we are in class scope now (defining instance field), defer initialization to instance time // If we are in class scope now (defining instance field), defer initialization to instance time

View File

@ -314,11 +314,11 @@ open class Scope(
inline fun <reified T : Obj> thisAs(): T { inline fun <reified T : Obj> thisAs(): T {
var s: Scope? = this var s: Scope? = this
do { while (s != null) {
val t = s!!.thisObj val t = s.thisObj
if (t is T) return t if (t is T) return t
s = s.parent s = s.parent
} while (s != null) }
raiseClassCastError("Cannot cast ${thisObj.objClass.className} to ${T::class.simpleName}") raiseClassCastError("Cannot cast ${thisObj.objClass.className} to ${T::class.simpleName}")
} }
@ -642,7 +642,7 @@ open class Scope(
return del.invokeInstanceMethod(scope, "invoke", Arguments(*allArgs)) return del.invokeInstanceMethod(scope, "invoke", Arguments(*allArgs))
} }
} }
})!! })
rec.value = res rec.value = res
return res return res
} }

View File

@ -40,7 +40,7 @@ class Source(val fileName: String, val text: String) {
fun extractPackageName(): String { fun extractPackageName(): String {
for ((n,line) in lines.withIndex()) { for ((n,line) in lines.withIndex()) {
if( line.isBlank() || line.isEmpty() ) if( line.isBlank() )
continue continue
if( line.startsWith("package ") ) if( line.startsWith("package ") )
return line.substring(8).trim() return line.substring(8).trim()

View File

@ -96,17 +96,15 @@ object CompletionEngineLight {
} }
// Global identifiers: params > local decls > imported > stdlib; Functions > Classes > Values; alphabetical // Global identifiers: params > local decls > imported > stdlib; Functions > Classes > Values; alphabetical
mini?.let { m -> val decls = mini.declarations
val decls = m.declarations val funs = decls.filterIsInstance<MiniFunDecl>().sortedBy { it.name.lowercase() }
val funs = decls.filterIsInstance<MiniFunDecl>().sortedBy { it.name.lowercase() } val classes = decls.filterIsInstance<MiniClassDecl>().sortedBy { it.name.lowercase() }
val classes = decls.filterIsInstance<MiniClassDecl>().sortedBy { it.name.lowercase() } val enums = decls.filterIsInstance<MiniEnumDecl>().sortedBy { it.name.lowercase() }
val enums = decls.filterIsInstance<MiniEnumDecl>().sortedBy { it.name.lowercase() } val vals = decls.filterIsInstance<MiniValDecl>().sortedBy { it.name.lowercase() }
val vals = decls.filterIsInstance<MiniValDecl>().sortedBy { it.name.lowercase() } funs.forEach { offerDeclAdd(out, prefix, it) }
funs.forEach { offerDeclAdd(out, prefix, it) } classes.forEach { offerDeclAdd(out, prefix, it) }
classes.forEach { offerDeclAdd(out, prefix, it) } enums.forEach { offerDeclAdd(out, prefix, it) }
enums.forEach { offerDeclAdd(out, prefix, it) } vals.forEach { offerDeclAdd(out, prefix, it) }
vals.forEach { offerDeclAdd(out, prefix, it) }
}
// Imported and builtin // Imported and builtin
val (nonStd, std) = imported.partition { it != "lyng.stdlib" } val (nonStd, std) = imported.partition { it != "lyng.stdlib" }
@ -192,7 +190,7 @@ object CompletionEngineLight {
val chosen = variants.asSequence() val chosen = variants.asSequence()
.filterIsInstance<MiniMemberValDecl>() .filterIsInstance<MiniMemberValDecl>()
.firstOrNull { it.type != null } ?: rep .firstOrNull { it.type != null } ?: rep
val ci = CompletionItem(name, Kind.Field, typeText = typeOf((chosen as MiniMemberValDecl).type)) val ci = CompletionItem(name, Kind.Field, typeText = typeOf(chosen.type))
if (ci.name.startsWith(prefix, true)) out += ci if (ci.name.startsWith(prefix, true)) out += ci
} }
is MiniInitDecl -> {} is MiniInitDecl -> {}

View File

@ -184,11 +184,8 @@ open class ObjClass(
val base = c3Linearize(this, mutableMapOf()) val base = c3Linearize(this, mutableMapOf())
if (this.className == "Obj" || base.any { it.className == "Obj" }) base if (this.className == "Obj" || base.any { it.className == "Obj" }) base
else { else {
// During very early bootstrap rootObjectType might not be initialized yet. val root = Obj.rootObjectType
// We use a safe check here. base + root
@Suppress("UNNECESSARY_SAFE_CALL")
val root = net.sergeych.lyng.obj.Obj.rootObjectType
if (root != null) base + root else base
} }
} }
@ -597,7 +594,7 @@ open class ObjClass(
// Fallback: property delegation // Fallback: property delegation
val propVal = del.invokeInstanceMethod(scope, "getValue", Arguments(this, ObjString(name))) val propVal = del.invokeInstanceMethod(scope, "getValue", Arguments(this, ObjString(name)))
propVal.invoke(scope, this, args, decl) propVal.invoke(scope, this, args, decl)
})!! })
} }
if (rec.type == ObjRecord.Type.Fun) { if (rec.type == ObjRecord.Type.Fun) {
return rec.value.invoke(scope, this, args, decl) return rec.value.invoke(scope, this, args, decl)

View File

@ -202,7 +202,7 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
// Fallback: property delegation // Fallback: property delegation
val propVal = del.invokeInstanceMethod(scope, "getValue", Arguments(this, ObjString(name))) val propVal = del.invokeInstanceMethod(scope, "getValue", Arguments(this, ObjString(name)))
propVal.invoke(scope, this, args, rec.declaringClass ?: cls) propVal.invoke(scope, this, args, rec.declaringClass ?: cls)
})!! })
} }
if (rec.type == ObjRecord.Type.Fun && !rec.isAbstract) { if (rec.type == ObjRecord.Type.Fun && !rec.isAbstract) {
val decl = rec.declaringClass ?: cls val decl = rec.declaringClass ?: cls
@ -211,7 +211,7 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
scope.raiseError( scope.raiseError(
ObjIllegalAccessException( ObjIllegalAccessException(
scope, scope,
"can't invoke method $name (declared in ${decl.className ?: "?"})" "can't invoke method $name (declared in ${decl.className})"
) )
) )
return rec.value.invoke( return rec.value.invoke(
@ -263,7 +263,7 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
val params = meta.params.map { readField(scope, it.name).value } val params = meta.params.map { readField(scope, it.name).value }
encoder.encodeAnyList(scope, params) encoder.encodeAnyList(scope, params)
val vars = serializingVars.values.map { it.value } val vars = serializingVars.values.map { it.value }
if (vars.isNotEmpty<Obj>()) { if (vars.isNotEmpty()) {
encoder.encodeAnyList(scope, vars) encoder.encodeAnyList(scope, vars)
} }
} }

View File

@ -115,9 +115,9 @@ class ObjRange(val start: Obj?, val end: Obj?, val isEndInclusive: Boolean) : Ob
} }
override suspend fun enumerate(scope: Scope, callback: suspend (Obj) -> Boolean) { override suspend fun enumerate(scope: Scope, callback: suspend (Obj) -> Boolean) {
if (isIntRange) { if (start is ObjInt && end is ObjInt) {
val s = (start as ObjInt).value val s = start.value
val e = (end as ObjInt).value val e = end.value
if (isEndInclusive) { if (isEndInclusive) {
for (i in s..e) { for (i in s..e) {
if (!callback(ObjInt.of(i))) break if (!callback(ObjInt.of(i))) break
@ -127,9 +127,9 @@ class ObjRange(val start: Obj?, val end: Obj?, val isEndInclusive: Boolean) : Ob
if (!callback(ObjInt.of(i))) break if (!callback(ObjInt.of(i))) break
} }
} }
} else if (isCharRange) { } else if (start is ObjChar && end is ObjChar) {
val s = (start as ObjChar).value val s = start.value
val e = (end as ObjChar).value val e = end.value
if (isEndInclusive) { if (isEndInclusive) {
for (c in s..e) { for (c in s..e) {
if (!callback(ObjChar(c))) break if (!callback(ObjChar(c))) break

View File

@ -29,14 +29,19 @@ class ObjRangeIterator(val self: ObjRange) : Obj() {
override val objClass: ObjClass = type override val objClass: ObjClass = type
fun Scope.init() { fun Scope.init() {
if (self.start == null || self.end == null) val s = self.start
raiseError("next is only available for finite ranges") val e = self.end
isCharRange = self.isCharRange if (s is ObjInt && e is ObjInt) {
lastIndex = if (self.isIntRange || self.isCharRange) { lastIndex = if (self.isEndInclusive)
if (self.isEndInclusive) (e.value - s.value + 1).toInt()
self.end.toInt() - self.start.toInt() + 1
else else
self.end.toInt() - self.start.toInt() (e.value - s.value).toInt()
} else if (s is ObjChar && e is ObjChar) {
isCharRange = true
lastIndex = if (self.isEndInclusive)
(e.value.code - s.value.code + 1)
else
(e.value.code - s.value.code)
} else { } else {
raiseError("not implemented iterator for range of $this") raiseError("not implemented iterator for range of $this")
} }
@ -46,10 +51,13 @@ class ObjRangeIterator(val self: ObjRange) : Obj() {
fun next(scope: Scope): Obj = fun next(scope: Scope): Obj =
if (nextIndex < lastIndex) { if (nextIndex < lastIndex) {
val x = if (self.isEndInclusive) val start = self.start
self.start!!.toLong() + nextIndex++ val x = if (start is ObjInt)
start.value + nextIndex++
else if (start is ObjChar)
start.value.code.toLong() + nextIndex++
else else
self.start!!.toLong() + nextIndex++ scope.raiseError("iterator error: unsupported range start")
if( isCharRange ) ObjChar(x.toInt().toChar()) else ObjInt(x) if( isCharRange ) ObjChar(x.toInt().toChar()) else ObjInt(x)
} }
else { else {

View File

@ -469,9 +469,11 @@ class FieldRef(
// Adaptive PIC (2→4) for reads/writes // Adaptive PIC (2→4) for reads/writes
private var rAccesses: Int = 0; private var rMisses: Int = 0; private var rPromotedTo4: Boolean = false private var rAccesses: Int = 0; private var rMisses: Int = 0; private var rPromotedTo4: Boolean = false
private var wAccesses: Int = 0; private var wMisses: Int = 0; private var wPromotedTo4: Boolean = false private var wAccesses: Int = 0; private var wMisses: Int = 0; private var wPromotedTo4: Boolean = false
@Suppress("NOTHING_TO_INLINE")
private inline fun size4ReadsEnabled(): Boolean = private inline fun size4ReadsEnabled(): Boolean =
PerfFlags.FIELD_PIC_SIZE_4 || PerfFlags.FIELD_PIC_SIZE_4 ||
(PerfFlags.PIC_ADAPTIVE_2_TO_4 && rPromotedTo4) (PerfFlags.PIC_ADAPTIVE_2_TO_4 && rPromotedTo4)
@Suppress("NOTHING_TO_INLINE")
private inline fun size4WritesEnabled(): Boolean = private inline fun size4WritesEnabled(): Boolean =
PerfFlags.FIELD_PIC_SIZE_4 || PerfFlags.FIELD_PIC_SIZE_4 ||
(PerfFlags.PIC_ADAPTIVE_2_TO_4 && wPromotedTo4) (PerfFlags.PIC_ADAPTIVE_2_TO_4 && wPromotedTo4)
@ -1064,6 +1066,7 @@ class MethodCallRef(
private var mFreezeWindowsLeft: Int = 0 private var mFreezeWindowsLeft: Int = 0
private var mWindowAccesses: Int = 0 private var mWindowAccesses: Int = 0
private var mWindowMisses: Int = 0 private var mWindowMisses: Int = 0
@Suppress("NOTHING_TO_INLINE")
private inline fun size4MethodsEnabled(): Boolean = private inline fun size4MethodsEnabled(): Boolean =
PerfFlags.METHOD_PIC_SIZE_4 || PerfFlags.METHOD_PIC_SIZE_4 ||
((PerfFlags.PIC_ADAPTIVE_2_TO_4 || PerfFlags.PIC_ADAPTIVE_METHODS_ONLY) && mPromotedTo4 && mFreezeWindowsLeft == 0) ((PerfFlags.PIC_ADAPTIVE_2_TO_4 || PerfFlags.PIC_ADAPTIVE_METHODS_ONLY) && mPromotedTo4 && mFreezeWindowsLeft == 0)

View File

@ -87,7 +87,7 @@ class ObjRegexMatch(val match: MatchResult) : Obj() {
// Use groupValues so that index 0 is the whole match and subsequent indices are capturing groups, // Use groupValues so that index 0 is the whole match and subsequent indices are capturing groups,
// which matches the language/tests expectation for `$~[i]`. // which matches the language/tests expectation for `$~[i]`.
ObjList( ObjList(
match.groupValues.map { ObjString(it) as Obj }.toMutableList() match.groupValues.map { ObjString(it) }.toMutableList()
) )
} }

View File

@ -47,7 +47,7 @@ class BindingHighlightTest {
val mini = sink.build() val mini = sink.build()
assertNotNull(mini, "Mini-AST must be built") assertNotNull(mini, "Mini-AST must be built")
val binding = Binder.bind(text, mini!!) val binding = Binder.bind(text, mini)
// Find the top-level symbol for counter and ensure it is mutable (Variable) // Find the top-level symbol for counter and ensure it is mutable (Variable)
val sym = binding.symbols.firstOrNull { it.name == "counter" } val sym = binding.symbols.firstOrNull { it.name == "counter" }
@ -78,7 +78,7 @@ class BindingHighlightTest {
val mini = sink.build() val mini = sink.build()
assertNotNull(mini, "Mini-AST must be built") assertNotNull(mini, "Mini-AST must be built")
val binding = Binder.bind(text, mini!!) val binding = Binder.bind(text, mini)
val sym = binding.symbols.firstOrNull { it.name == "answer" } val sym = binding.symbols.firstOrNull { it.name == "answer" }
assertNotNull(sym, "Top-level val 'answer' must be registered as a symbol") assertNotNull(sym, "Top-level val 'answer' must be registered as a symbol")
@ -114,7 +114,7 @@ class BindingHighlightTest {
val mini = sink.build() val mini = sink.build()
assertNotNull(mini, "Mini-AST must be built") assertNotNull(mini, "Mini-AST must be built")
val binding = Binder.bind(text, mini!!) val binding = Binder.bind(text, mini)
// Ensure we registered the local var/val symbol for `name` // Ensure we registered the local var/val symbol for `name`
val nameSym = binding.symbols.firstOrNull { it.name == "name" } val nameSym = binding.symbols.firstOrNull { it.name == "name" }
@ -163,7 +163,7 @@ class BindingHighlightTest {
val mini = sink.build() val mini = sink.build()
assertNotNull(mini, "Mini-AST must be built") assertNotNull(mini, "Mini-AST must be built")
val binding = Binder.bind(text, mini!!) val binding = Binder.bind(text, mini)
val nameSym = binding.symbols.firstOrNull { it.name == "name" && (it.kind == SymbolKind.Variable || it.kind == SymbolKind.Value) } val nameSym = binding.symbols.firstOrNull { it.name == "name" && (it.kind == SymbolKind.Variable || it.kind == SymbolKind.Value) }
assertNotNull(nameSym, "Local variable 'name' should be registered as a symbol") assertNotNull(nameSym, "Local variable 'name' should be registered as a symbol")

View File

@ -36,7 +36,7 @@ class BindingTest {
Compiler.compileWithMini(src, sink) Compiler.compileWithMini(src, sink)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini, "MiniScript should be built") assertNotNull(mini, "MiniScript should be built")
return Binder.bind(src, mini!!) return Binder.bind(src, mini)
} }
@Test @Test
@ -72,7 +72,7 @@ class BindingTest {
val xSym = snap.symbols.firstOrNull { it.name == "x" } val xSym = snap.symbols.firstOrNull { it.name == "x" }
assertNotNull(xSym) assertNotNull(xSym)
// One reference usage to top-level x // One reference usage to top-level x
val refs = snap.references.filter { it.symbolId == xSym!!.id } val refs = snap.references.filter { it.symbolId == xSym.id }
assertEquals(1, refs.size) assertEquals(1, refs.size)
} }
@ -111,7 +111,7 @@ class BindingTest {
val fooField = snap.symbols.firstOrNull { it.name == "foo" } val fooField = snap.symbols.firstOrNull { it.name == "foo" }
assertNotNull(fooField) assertNotNull(fooField)
// Should have at least one reference (usage in bar) // Should have at least one reference (usage in bar)
val refs = snap.references.count { it.symbolId == fooField!!.id } val refs = snap.references.count { it.symbolId == fooField.id }
assertEquals(1, refs) assertEquals(1, refs)
} }
@ -126,7 +126,7 @@ class BindingTest {
) )
val xField = snap.symbols.firstOrNull { it.name == "x" } val xField = snap.symbols.firstOrNull { it.name == "x" }
assertNotNull(xField) assertNotNull(xField)
val refs = snap.references.count { it.symbolId == xField!!.id } val refs = snap.references.count { it.symbolId == xField.id }
assertEquals(1, refs) assertEquals(1, refs)
} }
} }

View File

@ -44,7 +44,7 @@ class MiniAstTest {
val (_, sink) = compileWithMini(code) val (_, sink) = compileWithMini(code)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini) assertNotNull(mini)
val imps = mini!!.imports val imps = mini.imports
assertTrue(imps.isNotEmpty(), "imports should be captured") assertTrue(imps.isNotEmpty(), "imports should be captured")
val first = imps.first() val first = imps.first()
val segNames = first.segments.map { it.name } val segNames = first.segments.map { it.name }
@ -68,12 +68,12 @@ class MiniAstTest {
val (_, sink) = compileWithMini(code) val (_, sink) = compileWithMini(code)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini) assertNotNull(mini)
val fn = mini!!.declarations.filterIsInstance<MiniFunDecl>().firstOrNull { it.name == "foo" } val fn = mini.declarations.filterIsInstance<MiniFunDecl>().firstOrNull { it.name == "foo" }
assertNotNull(fn, "function decl should be captured") assertNotNull(fn, "function decl should be captured")
// Doc // Doc
assertNotNull(fn.doc) assertNotNull(fn.doc)
assertEquals("Summary: does foo", fn.doc!!.summary) assertEquals("Summary: does foo", fn.doc.summary)
assertTrue(fn.doc!!.raw.contains("details")) assertTrue(fn.doc.raw.contains("details"))
// Params // Params
assertEquals(2, fn.params.size) assertEquals(2, fn.params.size)
val p1 = fn.params[0] val p1 = fn.params[0]
@ -99,10 +99,10 @@ class MiniAstTest {
val (_, sink) = compileWithMini(code) val (_, sink) = compileWithMini(code)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini) assertNotNull(mini)
val vd = mini!!.declarations.filterIsInstance<net.sergeych.lyng.miniast.MiniValDecl>().firstOrNull { it.name == "x" } val vd = mini.declarations.filterIsInstance<net.sergeych.lyng.miniast.MiniValDecl>().firstOrNull { it.name == "x" }
assertNotNull(vd) assertNotNull(vd)
assertNotNull(vd.doc) assertNotNull(vd.doc)
assertEquals("docs for x", vd.doc!!.summary) assertEquals("docs for x", vd.doc.summary)
val ty = vd.type val ty = vd.type
assertNotNull(ty) assertNotNull(ty)
val gen = ty as MiniGenericType val gen = ty as MiniGenericType
@ -126,10 +126,10 @@ class MiniAstTest {
val (_, sink) = compileWithMini(code) val (_, sink) = compileWithMini(code)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini) assertNotNull(mini)
val cd = mini!!.declarations.filterIsInstance<MiniClassDecl>().firstOrNull { it.name == "C" } val cd = mini.declarations.filterIsInstance<MiniClassDecl>().firstOrNull { it.name == "C" }
assertNotNull(cd) assertNotNull(cd)
assertNotNull(cd.doc, "Class doc should be preserved even with members") assertNotNull(cd.doc, "Class doc should be preserved even with members")
assertTrue(cd.doc!!.raw.contains("Class C docs")) assertTrue(cd.doc.raw.contains("Class C docs"))
} }
@Test @Test
@ -141,10 +141,10 @@ class MiniAstTest {
val (_, sink) = compileWithMini(code) val (_, sink) = compileWithMini(code)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini) assertNotNull(mini)
val cd = mini!!.declarations.filterIsInstance<MiniClassDecl>().firstOrNull { it.name == "C" } val cd = mini.declarations.filterIsInstance<MiniClassDecl>().firstOrNull { it.name == "C" }
assertNotNull(cd) assertNotNull(cd)
assertNotNull(cd.doc) assertNotNull(cd.doc)
assertTrue(cd.doc!!.raw.contains("Class C docs")) assertTrue(cd.doc.raw.contains("Class C docs"))
// Bases captured as plain names for now // Bases captured as plain names for now
assertEquals(listOf("Base1", "Base2"), cd.bases) assertEquals(listOf("Base1", "Base2"), cd.bases)
} }
@ -162,10 +162,10 @@ class MiniAstTest {
val (_, sink) = compileWithMini(code) val (_, sink) = compileWithMini(code)
val mini = sink.build() val mini = sink.build()
assertNotNull(mini) assertNotNull(mini)
val ed = mini!!.declarations.filterIsInstance<MiniEnumDecl>().firstOrNull { it.name == "E" } val ed = mini.declarations.filterIsInstance<MiniEnumDecl>().firstOrNull { it.name == "E" }
assertNotNull(ed) assertNotNull(ed)
assertNotNull(ed.doc) assertNotNull(ed.doc)
assertTrue(ed.doc!!.raw.contains("Enum E docs")) assertTrue(ed.doc.raw.contains("Enum E docs"))
assertEquals(listOf("A", "B", "C"), ed.entries) assertEquals(listOf("A", "B", "C"), ed.entries)
assertEquals("E", ed.name) assertEquals("E", ed.name)
} }

View File

@ -39,7 +39,7 @@ class BlockReindentTest {
val open = BraceUtils.findMatchingOpenBrace(text, close) val open = BraceUtils.findMatchingOpenBrace(text, close)
assertNotNull(open) assertNotNull(open)
// The char at open must be '{' // The char at open must be '{'
assertEquals('{', text[open!!]) assertEquals('{', text[open])
} }
@Test @Test
@ -55,7 +55,7 @@ class BlockReindentTest {
val range = BraceUtils.findEnclosingBlockRange(text, close, includeTrailingNewline = true) val range = BraceUtils.findEnclosingBlockRange(text, close, includeTrailingNewline = true)
assertNotNull(range) assertNotNull(range)
// The range must start at the line start of the matching '{' and end at or after the newline after '}' // The range must start at the line start of the matching '{' and end at or after the newline after '}'
val start = range!!.first val start = range.first
val end = range.last + 1 val end = range.last + 1
val startLinePrefix = text.substring(BraceUtils.lineStart(text, start), start) val startLinePrefix = text.substring(BraceUtils.lineStart(text, start), start)
// start at column 0 of the line // start at column 0 of the line

View File

@ -34,7 +34,7 @@ class CommentEolTest {
assertTrue(cmt != null, "Expected a comment span") assertTrue(cmt != null, "Expected a comment span")
// It should start at 0 and extend exactly to the end of the line (before \n) // It should start at 0 and extend exactly to the end of the line (before \n)
val eol = text.indexOf('\n') val eol = text.indexOf('\n')
assertEquals(0, cmt!!.range.start, "Comment should start at column 0") assertEquals(0, cmt.range.start, "Comment should start at column 0")
assertEquals(eol, cmt.range.endExclusive, "Comment should extend to EOL") assertEquals(eol, cmt.range.endExclusive, "Comment should extend to EOL")
// Ensure there is no other span overlapping within the same line // Ensure there is no other span overlapping within the same line
spans.filter { it !== cmt }.forEach { spans.filter { it !== cmt }.forEach {
@ -50,7 +50,7 @@ class CommentEolTest {
assertTrue(cmt != null, "Expected a block comment span") assertTrue(cmt != null, "Expected a block comment span")
// The comment should end right after "/* block */" // The comment should end right after "/* block */"
val expectedEnd = "/* block */".length val expectedEnd = "/* block */".length
assertEquals(expectedEnd, cmt!!.range.endExclusive, "Block comment should not be extended to EOL") assertEquals(expectedEnd, cmt.range.endExclusive, "Block comment should not be extended to EOL")
} }
@Test @Test

View File

@ -3,6 +3,7 @@ package net.sergeych.lyng.miniast
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertTrue import kotlin.test.assertTrue
class CompletionEngineLightTest { class CompletionEngineLightTest {
@ -89,9 +90,9 @@ class CompletionEngineLightTest {
""".trimIndent() """.trimIndent()
val items = CompletionEngineLight.completeAtMarkerSuspend(code) val items = CompletionEngineLight.completeAtMarkerSuspend(code)
val reItem = items.firstOrNull { it.name == "re" } val reItem = items.firstOrNull { it.name == "re" }
assertTrue(reItem != null, "Expected to find 're' in String members, got: ${items.map { it.name }}") assertNotNull(reItem, "Expected to find 're' in String members, got: ${items.map { it.name }}")
// Type text should contain ": Regex" // Type text should contain ": Regex"
assertTrue(reItem!!.typeText?.contains("Regex") == true, "Expected type text to contain 'Regex', was: ${reItem.typeText}") assertTrue(reItem.typeText?.contains("Regex") == true, "Expected type text to contain 'Regex', was: ${reItem.typeText}")
} }
@Test @Test
@ -106,8 +107,8 @@ class CompletionEngineLightTest {
val names = items.map { it.name } val names = items.map { it.name }
assertTrue(names.isNotEmpty(), "Expected String members for parenthesized literal, got empty list") assertTrue(names.isNotEmpty(), "Expected String members for parenthesized literal, got empty list")
val reItem = items.firstOrNull { it.name == "re" } val reItem = items.firstOrNull { it.name == "re" }
assertTrue(reItem != null, "Expected to find 're' for parenthesized String literal, got: $names") assertNotNull(reItem, "Expected to find 're' for parenthesized String literal, got: $names")
assertTrue(reItem!!.typeText?.contains("Regex") == true, "Expected ': Regex' for re(), was: ${reItem.typeText}") assertTrue(reItem.typeText?.contains("Regex") == true, "Expected ': Regex' for re(), was: ${reItem.typeText}")
} }
@Test @Test
@ -120,8 +121,8 @@ class CompletionEngineLightTest {
val names = items.map { it.name } val names = items.map { it.name }
assertTrue(names.isNotEmpty(), "Expected String members without explicit imports, got empty list") assertTrue(names.isNotEmpty(), "Expected String members without explicit imports, got empty list")
val reItem = items.firstOrNull { it.name == "re" } val reItem = items.firstOrNull { it.name == "re" }
assertTrue(reItem != null, "Expected to find 're' without explicit imports, got: $names") assertNotNull(reItem, "Expected to find 're' without explicit imports, got: $names")
assertTrue(reItem!!.typeText?.contains("Regex") == true, "Expected ': Regex' for re() without imports, was: ${reItem.typeText}") assertTrue(reItem.typeText?.contains("Regex") == true, "Expected ': Regex' for re() without imports, was: ${reItem.typeText}")
} }
@Test @Test