fixed few bugs in compiler and plugin
This commit is contained in:
parent
37d093817e
commit
e447c778ed
@ -88,9 +88,11 @@ class LyngExternalAnnotator : ExternalAnnotator<LyngExternalAnnotator.Input, Lyn
|
||||
// Imports: each segment as namespace/path
|
||||
mini?.imports?.forEach { imp ->
|
||||
imp.segments.forEach { seg ->
|
||||
val start = analysis.source.offsetOf(seg.range.start)
|
||||
val end = analysis.source.offsetOf(seg.range.end)
|
||||
putRange(start, end, LyngHighlighterColors.NAMESPACE)
|
||||
if (seg.range.start.source === analysis.source && seg.range.end.source === analysis.source) {
|
||||
val start = analysis.source.offsetOf(seg.range.start)
|
||||
val end = analysis.source.offsetOf(seg.range.end)
|
||||
putRange(start, end, LyngHighlighterColors.NAMESPACE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ class LyngLexer : LexerBase() {
|
||||
"fun", "val", "var", "class", "interface", "type", "import", "as",
|
||||
"abstract", "closed", "override", "static", "extern", "open", "private", "protected",
|
||||
"if", "else", "for", "while", "return", "true", "false", "null",
|
||||
"when", "in", "is", "break", "continue", "try", "catch", "finally",
|
||||
"when", "in", "is", "break", "continue", "try", "catch", "finally", "void",
|
||||
"get", "set", "object", "enum", "init", "by", "step", "property", "constructor"
|
||||
)
|
||||
|
||||
|
||||
@ -26,23 +26,16 @@ import com.intellij.psi.search.FilenameIndex
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.sergeych.lyng.binding.BindingSnapshot
|
||||
import net.sergeych.lyng.miniast.BuiltinDocRegistry
|
||||
import net.sergeych.lyng.miniast.DocLookupUtils
|
||||
import net.sergeych.lyng.miniast.MiniEnumDecl
|
||||
import net.sergeych.lyng.miniast.MiniRange
|
||||
import net.sergeych.lyng.miniast.MiniScript
|
||||
import net.sergeych.lyng.tools.IdeLenientImportProvider
|
||||
import net.sergeych.lyng.tools.LyngAnalysisRequest
|
||||
import net.sergeych.lyng.tools.LyngAnalysisResult
|
||||
import net.sergeych.lyng.tools.LyngDiagnostic
|
||||
import net.sergeych.lyng.tools.LyngLanguageTools
|
||||
import net.sergeych.lyng.idea.LyngFileType
|
||||
import net.sergeych.lyng.miniast.*
|
||||
import net.sergeych.lyng.tools.*
|
||||
|
||||
object LyngAstManager {
|
||||
private val MINI_KEY = Key.create<MiniScript>("lyng.mini.cache")
|
||||
private val BINDING_KEY = Key.create<BindingSnapshot>("lyng.binding.cache")
|
||||
private val STAMP_KEY = Key.create<Long>("lyng.mini.cache.stamp")
|
||||
private val ANALYSIS_KEY = Key.create<LyngAnalysisResult>("lyng.analysis.cache")
|
||||
private val implicitBuiltinNames = setOf("void")
|
||||
|
||||
fun getMiniAst(file: PsiFile): MiniScript? = runReadAction {
|
||||
getAnalysis(file)?.mini
|
||||
@ -217,7 +210,7 @@ object LyngAstManager {
|
||||
val msg = diag.message
|
||||
if (msg.startsWith("unresolved name: ")) {
|
||||
val name = msg.removePrefix("unresolved name: ").trim()
|
||||
name in declaredTopLevel || name in builtinTopLevel
|
||||
name in declaredTopLevel || name in builtinTopLevel || name in implicitBuiltinNames
|
||||
} else if (msg.startsWith("unresolved member: ")) {
|
||||
val name = msg.removePrefix("unresolved member: ").trim()
|
||||
val range = diag.range
|
||||
|
||||
@ -124,4 +124,16 @@ class LyngDefinitionFilesTest : BasePlatformTestCase() {
|
||||
assertTrue("Should not report unresolved name for Declared", messages.none { it.contains("unresolved name: Declared") })
|
||||
assertTrue("Should not report unresolved member for greet", messages.none { it.contains("unresolved member: greet") })
|
||||
}
|
||||
|
||||
fun test_DiagnosticsDoNotReportVoidAsUnresolvedName() {
|
||||
val code = """
|
||||
fun f(): void {
|
||||
return void
|
||||
}
|
||||
""".trimIndent()
|
||||
myFixture.configureByText("main.lyng", code)
|
||||
val analysis = LyngAstManager.getAnalysis(myFixture.file)
|
||||
val messages = analysis?.diagnostics?.map { it.message } ?: emptyList()
|
||||
assertTrue("Should not report unresolved name for void, got=$messages", messages.none { it.contains("unresolved name: void") })
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,6 +176,8 @@ class Compiler(
|
||||
private val lambdaCaptureEntriesByRef: MutableMap<ValueFnRef, List<net.sergeych.lyng.bytecode.LambdaCaptureEntry>> =
|
||||
mutableMapOf()
|
||||
private val classFieldTypesByName: MutableMap<String, MutableMap<String, ObjClass>> = mutableMapOf()
|
||||
private val classMethodReturnTypeByName: MutableMap<String, MutableMap<String, ObjClass>> = mutableMapOf()
|
||||
private val classMethodReturnTypeDeclByName: MutableMap<String, MutableMap<String, TypeDecl>> = mutableMapOf()
|
||||
private val classScopeMembersByClassName: MutableMap<String, MutableSet<String>> = mutableMapOf()
|
||||
private val classScopeCallableMembersByClassName: MutableMap<String, MutableSet<String>> = mutableMapOf()
|
||||
private val encodedPayloadTypeByScopeId: MutableMap<Int, MutableMap<Int, ObjClass>> = mutableMapOf()
|
||||
@ -2614,7 +2616,34 @@ class Compiler(
|
||||
}
|
||||
|
||||
Token.Type.NOT -> {
|
||||
if (operand != null) throw ScriptError(t.pos, "unexpected operator not '!' ")
|
||||
if (operand != null) {
|
||||
val save = cc.savePos()
|
||||
val next = cc.next()
|
||||
if (next.type == Token.Type.NOT) {
|
||||
val operandRef = operand
|
||||
val receiverClass = resolveReceiverClassForMember(operandRef)
|
||||
val inferredType = resolveReceiverTypeDecl(operandRef)
|
||||
?: receiverClass?.let { TypeDecl.Simple(it.className, false) }
|
||||
if (inferredType == null) {
|
||||
operand = operandRef
|
||||
continue
|
||||
}
|
||||
if (inferredType == TypeDecl.TypeAny || inferredType == TypeDecl.TypeNullableAny) {
|
||||
operand = operandRef
|
||||
continue
|
||||
}
|
||||
val nonNullType = makeTypeDeclNonNullable(inferredType)
|
||||
operand = CastRef(
|
||||
operandRef,
|
||||
TypeDeclRef(nonNullType, t.pos),
|
||||
isNullable = false,
|
||||
atPos = t.pos
|
||||
)
|
||||
continue
|
||||
}
|
||||
cc.restorePos(save)
|
||||
throw ScriptError(t.pos, "unexpected operator not '!' ")
|
||||
}
|
||||
val op = parseTerm() ?: throw ScriptError(t.pos, "Expecting expression")
|
||||
operand = UnaryOpRef(UnaryOp.NOT, op)
|
||||
}
|
||||
@ -3821,6 +3850,21 @@ class Compiler(
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeTypeDeclNonNullable(type: TypeDecl): TypeDecl {
|
||||
if (!type.isNullable) return type
|
||||
return when (type) {
|
||||
TypeDecl.TypeAny -> type
|
||||
TypeDecl.TypeNullableAny -> TypeDecl.TypeAny
|
||||
is TypeDecl.Function -> type.copy(nullable = false)
|
||||
is TypeDecl.Ellipsis -> type.copy(nullable = false)
|
||||
is TypeDecl.TypeVar -> type.copy(nullable = false)
|
||||
is TypeDecl.Union -> type.copy(nullable = false)
|
||||
is TypeDecl.Intersection -> type.copy(nullable = false)
|
||||
is TypeDecl.Simple -> TypeDecl.Simple(type.name, false)
|
||||
is TypeDecl.Generic -> TypeDecl.Generic(type.name, type.args, false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeMiniTypeNullable(type: MiniTypeRef): MiniTypeRef {
|
||||
return when (type) {
|
||||
is MiniTypeName -> type.copy(nullable = true)
|
||||
@ -4491,6 +4535,48 @@ class Compiler(
|
||||
is TypeDecl.Intersection -> "I:${type.options.joinToString("&") { typeDeclKey(it) }}"
|
||||
}
|
||||
|
||||
private fun classMethodReturnTypeDecl(targetClass: ObjClass?, name: String): TypeDecl? {
|
||||
if (targetClass == null) return null
|
||||
if (targetClass == ObjDynamic.type) return TypeDecl.TypeAny
|
||||
val member = targetClass.getInstanceMemberOrNull(name, includeAbstract = true)
|
||||
val declaringName = member?.declaringClass?.className
|
||||
if (declaringName != null) {
|
||||
classMethodReturnTypeDeclByName[declaringName]?.get(name)?.let { return it }
|
||||
classMethodReturnTypeByName[declaringName]?.get(name)?.let {
|
||||
return TypeDecl.Simple(it.className, false)
|
||||
}
|
||||
}
|
||||
classMethodReturnTypeDeclByName[targetClass.className]?.get(name)?.let { return it }
|
||||
classMethodReturnTypeByName[targetClass.className]?.get(name)?.let {
|
||||
return TypeDecl.Simple(it.className, false)
|
||||
}
|
||||
member?.typeDecl?.let { declaredType ->
|
||||
if (declaredType is TypeDecl.Function) return declaredType.returnType
|
||||
return declaredType
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun classMethodReturnClass(targetClass: ObjClass?, name: String): ObjClass? {
|
||||
if (targetClass == null) return null
|
||||
if (targetClass == ObjDynamic.type) return ObjDynamic.type
|
||||
classMethodReturnTypeDecl(targetClass, name)?.let { declared ->
|
||||
resolveTypeDeclObjClass(declared)?.let { return it }
|
||||
if (declared is TypeDecl.TypeVar) return Obj.rootObjectType
|
||||
}
|
||||
val member = targetClass.getInstanceMemberOrNull(name, includeAbstract = true)
|
||||
val declaringName = member?.declaringClass?.className
|
||||
if (declaringName != null) {
|
||||
classMethodReturnTypeByName[declaringName]?.get(name)?.let { return it }
|
||||
}
|
||||
classMethodReturnTypeByName[targetClass.className]?.get(name)?.let { return it }
|
||||
val declaredType = member?.typeDecl
|
||||
if (declaredType is TypeDecl.Function) {
|
||||
resolveTypeDeclObjClass(declaredType.returnType)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun inferObjClassFromRef(ref: ObjRef): ObjClass? = when (ref) {
|
||||
is ConstRef -> ref.constValue as? ObjClass ?: ref.constValue.objClass
|
||||
is LocalVarRef -> nameObjClass[ref.name] ?: resolveClassByName(ref.name)
|
||||
@ -4511,6 +4597,11 @@ class Compiler(
|
||||
is RangeRef -> ObjRange.type
|
||||
is ClassOperatorRef -> ObjClassType
|
||||
is CastRef -> resolveTypeRefClass(ref.castTypeRef())
|
||||
is IndexRef -> {
|
||||
val targetClass = resolveReceiverClassForMember(ref.targetRef)
|
||||
classMethodReturnClass(targetClass, "getAt")
|
||||
?: inferFieldReturnClass(targetClass, "getAt")
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
@ -4547,6 +4638,12 @@ class Compiler(
|
||||
else -> TypeDecl.TypeVar("${typeDeclName(targetDecl)}.${ref.name}", false)
|
||||
}
|
||||
}
|
||||
is IndexRef -> {
|
||||
val targetDecl = resolveReceiverTypeDecl(ref.targetRef)
|
||||
inferMethodCallReturnTypeDecl("getAt", targetDecl)?.let { return it }
|
||||
val targetClass = resolveReceiverClassForMember(ref.targetRef)
|
||||
classMethodReturnTypeDecl(targetClass, "getAt")
|
||||
}
|
||||
is MethodCallRef -> methodReturnTypeDeclByRef[ref]
|
||||
is CallRef -> callReturnTypeDeclByRef[ref]
|
||||
is StatementRef -> (ref.statement as? ExpressionStatement)?.let { resolveReceiverTypeDecl(it.ref) }
|
||||
@ -4616,6 +4713,12 @@ class Compiler(
|
||||
val targetClass = resolveReceiverClassForMember(ref.target)
|
||||
inferFieldReturnClass(targetClass, ref.name)
|
||||
}
|
||||
is IndexRef -> {
|
||||
val targetClass = resolveReceiverClassForMember(ref.targetRef)
|
||||
classMethodReturnClass(targetClass, "getAt")
|
||||
?: inferFieldReturnClass(targetClass, "getAt")
|
||||
?: inferMethodCallReturnClass("getAt")
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@ -5102,6 +5205,7 @@ class Compiler(
|
||||
}
|
||||
|
||||
private fun resolveTypeRefClass(ref: ObjRef): ObjClass? = when (ref) {
|
||||
is TypeDeclRef -> resolveTypeDeclObjClass(ref.decl())
|
||||
is ConstRef -> ref.constValue as? ObjClass
|
||||
is LocalSlotRef -> resolveTypeDeclObjClass(TypeDecl.Simple(ref.name, false)) ?: nameObjClass[ref.name]
|
||||
is LocalVarRef -> resolveTypeDeclObjClass(TypeDecl.Simple(ref.name, false)) ?: nameObjClass[ref.name]
|
||||
@ -7885,6 +7989,23 @@ class Compiler(
|
||||
val rawFnStatements = parsedFnStatements?.let { unwrapBytecodeDeep(it) }
|
||||
val inferredReturnClass = returnTypeDecl?.let { resolveTypeDeclObjClass(it) }
|
||||
?: inferReturnClassFromStatement(rawFnStatements)
|
||||
if (declKind == SymbolKind.MEMBER && extTypeName == null) {
|
||||
val ownerClassName = (parentContext as? CodeContext.ClassBody)?.name
|
||||
if (ownerClassName != null) {
|
||||
val returnDecl = returnTypeDecl
|
||||
?: inferredReturnClass?.let { TypeDecl.Simple(it.className, false) }
|
||||
if (returnDecl != null) {
|
||||
classMethodReturnTypeDeclByName
|
||||
.getOrPut(ownerClassName) { mutableMapOf() }[name] = returnDecl
|
||||
resolveTypeDeclObjClass(returnDecl)?.let { returnClass ->
|
||||
classMethodReturnTypeByName
|
||||
.getOrPut(ownerClassName) { mutableMapOf() }[name] = returnClass
|
||||
classFieldTypesByName
|
||||
.getOrPut(ownerClassName) { mutableMapOf() }[name] = returnClass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (declKind != SymbolKind.MEMBER && inferredReturnClass != null) {
|
||||
callableReturnTypeByName[name] = inferredReturnClass
|
||||
val slotLoc = lookupSlotLocation(name, includeModule = true)
|
||||
|
||||
@ -46,7 +46,7 @@ private val fallbackKeywordIds = setOf(
|
||||
"private", "protected", "static", "open", "extern", "init", "get", "set", "by", "step",
|
||||
// control flow and misc
|
||||
"if", "else", "when", "while", "do", "for", "try", "catch", "finally",
|
||||
"throw", "return", "break", "continue", "this", "null", "true", "false", "unset"
|
||||
"throw", "return", "break", "continue", "this", "null", "true", "false", "unset", "void"
|
||||
)
|
||||
|
||||
/** Maps lexer token type (and sometimes value) to a [HighlightKind]. */
|
||||
|
||||
@ -179,6 +179,7 @@ object LyngLanguageTools {
|
||||
val source = analysis.source
|
||||
val out = ArrayList<LyngSemanticSpan>(128)
|
||||
val covered = HashSet<Pair<Int, Int>>()
|
||||
fun isCurrentSource(pos: Pos): Boolean = pos.source === source
|
||||
|
||||
fun addRange(start: Int, end: Int, kind: LyngSemanticKind) {
|
||||
if (start < 0 || end <= start || end > analysis.text.length) return
|
||||
@ -187,6 +188,7 @@ object LyngLanguageTools {
|
||||
}
|
||||
|
||||
fun addName(pos: Pos, name: String, kind: LyngSemanticKind) {
|
||||
if (!isCurrentSource(pos)) return
|
||||
val s = source.offsetOf(pos)
|
||||
addRange(s, s + name.length, kind)
|
||||
}
|
||||
@ -206,7 +208,9 @@ object LyngLanguageTools {
|
||||
addTypeSegments(t.returnType)
|
||||
}
|
||||
is MiniTypeVar -> {
|
||||
addRange(source.offsetOf(t.range.start), source.offsetOf(t.range.end), LyngSemanticKind.TypeRef)
|
||||
if (isCurrentSource(t.range.start) && isCurrentSource(t.range.end)) {
|
||||
addRange(source.offsetOf(t.range.start), source.offsetOf(t.range.end), LyngSemanticKind.TypeRef)
|
||||
}
|
||||
}
|
||||
is MiniTypeUnion -> {
|
||||
t.options.forEach { addTypeSegments(it) }
|
||||
@ -262,7 +266,9 @@ object LyngLanguageTools {
|
||||
|
||||
mini.imports.forEach { imp ->
|
||||
imp.segments.forEach { seg ->
|
||||
addRange(source.offsetOf(seg.range.start), source.offsetOf(seg.range.end), LyngSemanticKind.TypeRef)
|
||||
if (isCurrentSource(seg.range.start) && isCurrentSource(seg.range.end)) {
|
||||
addRange(source.offsetOf(seg.range.start), source.offsetOf(seg.range.end), LyngSemanticKind.TypeRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -565,19 +565,6 @@ class TypesTest {
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
// @Test
|
||||
// fun testNullableGenericTypes() = runTest {
|
||||
// eval("""
|
||||
// fun t<T>(): String =
|
||||
// when(T) {
|
||||
// is Object -> "%s is Object"(T::class.name)
|
||||
// else -> throw "It should not happen"
|
||||
// }
|
||||
// assert( Int is Object)
|
||||
// assertEquals( t<Int>(), "Class is Object")
|
||||
// """.trimIndent())
|
||||
// }
|
||||
|
||||
@Test fun testIndexer() = runTest {
|
||||
eval("""
|
||||
class Greeter {
|
||||
@ -596,6 +583,38 @@ class TypesTest {
|
||||
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test fun testIndexer2() = runTest {
|
||||
eval("""
|
||||
class Foo(bar)
|
||||
|
||||
class Greeter {
|
||||
override fun getAt(name): Foo = Foo("Hello, %s!"(name))
|
||||
}
|
||||
assertEquals("Hello, Bob!",Greeter()["Bob"].bar)
|
||||
val g = Greeter()
|
||||
assertEquals("Hello, Bob!",g["Bob"].bar)
|
||||
|
||||
// it should work with objects too:
|
||||
object Polite {
|
||||
override fun getAt(name): Foo? = Foo("How do you do, %s?"(name))
|
||||
}
|
||||
|
||||
assertEquals("How do you do, Bob?",Polite["Bob"].bar)
|
||||
assertEquals("How do you do, Bob?",Polite["Bob"]?.bar)
|
||||
assertEquals("How do you do, Bob?",Polite["Bob"]!!.bar)
|
||||
|
||||
class Greeter2 {
|
||||
override fun getAt(name): Foo? = Foo("How do you do, %s?"(name))
|
||||
}
|
||||
val g2 = Greeter2()
|
||||
assertEquals("How do you do, Bob?",g2["Bob"]?.bar)
|
||||
val g2v: Foo = g2["Bob"]!!
|
||||
assertEquals("How do you do, Bob?",g2v.bar)
|
||||
assertEquals("How do you do, Bob?",Greeter2()["Bob"].bar)
|
||||
|
||||
""".trimIndent())
|
||||
}
|
||||
// @Test fun nonTrivialOperatorsTest() = runTest {
|
||||
// val s = Script.newScope()
|
||||
// s.eval("""
|
||||
|
||||
@ -18,8 +18,9 @@
|
||||
package net.sergeych.lyng.tools
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import net.sergeych.lyng.miniast.MiniClassDecl
|
||||
import net.sergeych.lyng.miniast.MiniMemberTypeAliasDecl
|
||||
import net.sergeych.lyng.Pos
|
||||
import net.sergeych.lyng.Source
|
||||
import net.sergeych.lyng.miniast.*
|
||||
import net.sergeych.lyng.stdlib_included.rootLyng
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -127,4 +128,48 @@ class LyngLanguageToolsTest {
|
||||
val dis = LyngLanguageTools.disassembleSymbol(code, "add")
|
||||
assertTrue(!dis.contains("not a compiled body"), "Disassembly should be produced, got: $dis")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun languageTools_semanticHighlights_ignore_foreign_sources() {
|
||||
val localSource = Source("local.lyng", "val x = 1")
|
||||
val foreignSource = Source("defs.lyng.d", "val y = 2")
|
||||
val localStart = Pos(localSource, 0, 0)
|
||||
val foreignStart = Pos(foreignSource, 0, 0)
|
||||
|
||||
val mini = MiniScript(
|
||||
range = MiniRange(localStart, localStart),
|
||||
declarations = mutableListOf(
|
||||
MiniValDecl(
|
||||
range = MiniRange(foreignStart, foreignStart),
|
||||
name = "y",
|
||||
mutable = false,
|
||||
type = null,
|
||||
initRange = null,
|
||||
doc = null,
|
||||
nameStart = foreignStart
|
||||
)
|
||||
),
|
||||
imports = mutableListOf(
|
||||
MiniImport(
|
||||
range = MiniRange(foreignStart, foreignStart),
|
||||
segments = listOf(
|
||||
MiniImport.Segment("defs", MiniRange(foreignStart, foreignStart))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
val analysis = LyngAnalysisResult(
|
||||
source = localSource,
|
||||
text = localSource.text,
|
||||
mini = mini,
|
||||
binding = null,
|
||||
resolution = null,
|
||||
importedModules = emptyList(),
|
||||
diagnostics = emptyList(),
|
||||
lexicalHighlights = emptyList()
|
||||
)
|
||||
|
||||
val spans = LyngLanguageTools.semanticHighlights(analysis)
|
||||
assertTrue(spans.isEmpty(), "Semantic spans should ignore positions from foreign sources, got $spans")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package lyng.stdlib
|
||||
|
||||
extern fun flow(builder: FlowBuilder.()->Void): Flow
|
||||
extern fun flow(builder: FlowBuilder.()->void): Flow
|
||||
|
||||
/* Built-in exception type. */
|
||||
extern class Exception
|
||||
@ -9,7 +9,7 @@ extern class NotImplementedException
|
||||
extern class Delegate
|
||||
extern class Iterable<T> {
|
||||
fun iterator(): Iterator<T>
|
||||
fun forEach(action: (T)->Void): Void
|
||||
fun forEach(action: (T)->void): void
|
||||
fun map<R>(transform: (T)->R): List<R>
|
||||
fun toList(): List<T>
|
||||
fun toImmutableList(): ImmutableList<T>
|
||||
@ -22,7 +22,7 @@ extern class Iterable<T> {
|
||||
extern class Iterator<T> {
|
||||
fun hasNext(): Bool
|
||||
fun next(): T
|
||||
fun cancelIteration(): Void
|
||||
fun cancelIteration(): void
|
||||
fun toList(): List<T>
|
||||
}
|
||||
|
||||
@ -44,14 +44,14 @@ extern class ImmutableList<T> : Array<T> {
|
||||
}
|
||||
|
||||
extern class List<T> : Array<T> {
|
||||
fun add(value: T, more...): Void
|
||||
fun add(value: T, more...): void
|
||||
fun toImmutable(): ImmutableList<T>
|
||||
}
|
||||
|
||||
extern class RingBuffer<T> : Iterable<T> {
|
||||
val size: Int
|
||||
fun first(): T
|
||||
fun add(value: T): Void
|
||||
fun add(value: T): void
|
||||
}
|
||||
|
||||
extern class Set<T> : Collection<T> {
|
||||
@ -337,17 +337,17 @@ override fun List<T>.toString() {
|
||||
}
|
||||
|
||||
/* Sort list in-place by key selector. */
|
||||
fun List<T>.sortBy<R>(predicate: (T)->R): Void {
|
||||
fun List<T>.sortBy<R>(predicate: (T)->R): void {
|
||||
sortWith { a, b -> predicate(a) <=> predicate(b) }
|
||||
}
|
||||
|
||||
/* Sort list in-place by natural order. */
|
||||
fun List<T>.sort(): Void {
|
||||
fun List<T>.sort(): void {
|
||||
sortWith { a, b -> a <=> b }
|
||||
}
|
||||
|
||||
/* Print this exception and its stack trace to standard output. */
|
||||
fun Exception.printStackTrace(): Void {
|
||||
fun Exception.printStackTrace(): void {
|
||||
println(this)
|
||||
for( entry in stackTrace ) {
|
||||
println("\tat "+entry.toString())
|
||||
@ -357,7 +357,7 @@ fun Exception.printStackTrace(): Void {
|
||||
/* Compile this string into a regular expression. */
|
||||
val String.re: Regex get() = Regex(this)
|
||||
|
||||
fun TODO(message: Object?=null): Void {
|
||||
fun TODO(message: Object?=null): void {
|
||||
throw "not implemented"
|
||||
}
|
||||
|
||||
@ -376,12 +376,12 @@ enum DelegateAccess {
|
||||
Implementing this interface is optional as Lyng uses dynamic dispatch,
|
||||
but it is recommended for documentation and clarity.
|
||||
*/
|
||||
interface Delegate<T,ThisRefType=Void> {
|
||||
interface Delegate<T,ThisRefType=void> {
|
||||
/* Called when a delegated 'val' or 'var' is read. */
|
||||
fun getValue(thisRef: ThisRefType, name: String): T = TODO("delegate getter is not implemented")
|
||||
|
||||
/* Called when a delegated 'var' is written. */
|
||||
fun setValue(thisRef: ThisRefType, name: String, newValue: T): Void = TODO("delegate setter is not implemented")
|
||||
fun setValue(thisRef: ThisRefType, name: String, newValue: T): void = TODO("delegate setter is not implemented")
|
||||
|
||||
/* Called when a delegated function is invoked. */
|
||||
fun invoke(thisRef: ThisRefType, name: String, args...): Object = TODO("delegate invoke is not implemented")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user