Fix apply/inc-dec handling and re-enable more ScriptTests
This commit is contained in:
parent
eaa5713eaf
commit
64fa305aa7
@ -67,24 +67,40 @@ data class ArgsDeclaration(val params: List<Item>, val endTokenType: Token.Type)
|
||||
for (i in params.indices) {
|
||||
val a = params[i]
|
||||
val value = arguments.list[i]
|
||||
scope.addItem(a.name, (a.accessType ?: defaultAccessType).isMutable,
|
||||
val recordType = if (declaringClass != null && a.accessType != null) {
|
||||
ObjRecord.Type.ConstructorField
|
||||
} else {
|
||||
ObjRecord.Type.Argument
|
||||
}
|
||||
scope.addItem(
|
||||
a.name,
|
||||
(a.accessType ?: defaultAccessType).isMutable,
|
||||
value.byValueCopy(),
|
||||
a.visibility ?: defaultVisibility,
|
||||
recordType = ObjRecord.Type.Argument,
|
||||
recordType = recordType,
|
||||
declaringClass = declaringClass,
|
||||
isTransient = a.isTransient)
|
||||
isTransient = a.isTransient
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fun assign(a: Item, value: Obj) {
|
||||
scope.addItem(a.name, (a.accessType ?: defaultAccessType).isMutable,
|
||||
val recordType = if (declaringClass != null && a.accessType != null) {
|
||||
ObjRecord.Type.ConstructorField
|
||||
} else {
|
||||
ObjRecord.Type.Argument
|
||||
}
|
||||
scope.addItem(
|
||||
a.name,
|
||||
(a.accessType ?: defaultAccessType).isMutable,
|
||||
value.byValueCopy(),
|
||||
a.visibility ?: defaultVisibility,
|
||||
recordType = ObjRecord.Type.Argument,
|
||||
recordType = recordType,
|
||||
declaringClass = declaringClass,
|
||||
isTransient = a.isTransient)
|
||||
isTransient = a.isTransient
|
||||
)
|
||||
}
|
||||
|
||||
// Prepare positional args and parameter count, handle tail-block binding
|
||||
|
||||
@ -391,7 +391,7 @@ class Compiler(
|
||||
return LocalVarRef(name, pos)
|
||||
}
|
||||
resolutionSink?.reference(name, pos)
|
||||
if (allowUnresolvedRefs) {
|
||||
if (allowUnresolvedRefs || (name.isNotEmpty() && name[0].isUpperCase())) {
|
||||
return LocalVarRef(name, pos)
|
||||
}
|
||||
throw ScriptError(pos, "unresolved name: $name")
|
||||
@ -1741,6 +1741,11 @@ class Compiler(
|
||||
|
||||
else -> null
|
||||
}
|
||||
val effectiveAccess = if (isClassDeclaration && access == null) {
|
||||
AccessType.Var
|
||||
} else {
|
||||
access
|
||||
}
|
||||
|
||||
// type information (semantic + mini syntax)
|
||||
val (typeInfo, miniType) = parseTypeDeclarationWithMini()
|
||||
@ -1757,7 +1762,7 @@ class Compiler(
|
||||
t.pos,
|
||||
isEllipsis,
|
||||
defaultValue,
|
||||
access,
|
||||
effectiveAccess,
|
||||
visibility,
|
||||
isTransient
|
||||
)
|
||||
|
||||
@ -190,6 +190,7 @@ class BytecodeCompiler(
|
||||
private fun compileRef(ref: ObjRef): CompiledValue? {
|
||||
return when (ref) {
|
||||
is ConstRef -> compileConst(ref.constValue)
|
||||
is IncDecRef -> compileIncDec(ref, true)
|
||||
is LocalSlotRef -> {
|
||||
if (ref.name == "__PACKAGE__") {
|
||||
return compileNameLookup(ref.name)
|
||||
@ -1625,6 +1626,83 @@ class BytecodeCompiler(
|
||||
}
|
||||
}
|
||||
|
||||
val thisFieldTarget = ref.target as? ThisFieldSlotRef
|
||||
if (thisFieldTarget != null) {
|
||||
val nameId = builder.addConst(BytecodeConst.StringVal(thisFieldTarget.name))
|
||||
if (nameId > 0xFFFF) return null
|
||||
val current = allocSlot()
|
||||
builder.emit(Opcode.GET_THIS_MEMBER, nameId, current)
|
||||
updateSlotType(current, SlotType.OBJ)
|
||||
val oneSlot = allocSlot()
|
||||
val oneId = builder.addConst(BytecodeConst.ObjRef(ObjInt.One))
|
||||
builder.emit(Opcode.CONST_OBJ, oneId, oneSlot)
|
||||
updateSlotType(oneSlot, SlotType.OBJ)
|
||||
val result = allocSlot()
|
||||
val op = if (ref.isIncrement) Opcode.ADD_OBJ else Opcode.SUB_OBJ
|
||||
if (wantResult && ref.isPost) {
|
||||
val old = allocSlot()
|
||||
builder.emit(Opcode.MOVE_OBJ, current, old)
|
||||
builder.emit(op, current, oneSlot, result)
|
||||
builder.emit(Opcode.SET_THIS_MEMBER, nameId, result)
|
||||
return CompiledValue(old, SlotType.OBJ)
|
||||
}
|
||||
builder.emit(op, current, oneSlot, result)
|
||||
builder.emit(Opcode.SET_THIS_MEMBER, nameId, result)
|
||||
return CompiledValue(result, SlotType.OBJ)
|
||||
}
|
||||
|
||||
val implicitTarget = ref.target as? ImplicitThisMemberRef
|
||||
if (implicitTarget != null) {
|
||||
val nameId = builder.addConst(BytecodeConst.StringVal(implicitTarget.name))
|
||||
if (nameId > 0xFFFF) return null
|
||||
val current = allocSlot()
|
||||
builder.emit(Opcode.GET_THIS_MEMBER, nameId, current)
|
||||
updateSlotType(current, SlotType.OBJ)
|
||||
val oneSlot = allocSlot()
|
||||
val oneId = builder.addConst(BytecodeConst.ObjRef(ObjInt.One))
|
||||
builder.emit(Opcode.CONST_OBJ, oneId, oneSlot)
|
||||
updateSlotType(oneSlot, SlotType.OBJ)
|
||||
val result = allocSlot()
|
||||
val op = if (ref.isIncrement) Opcode.ADD_OBJ else Opcode.SUB_OBJ
|
||||
if (wantResult && ref.isPost) {
|
||||
val old = allocSlot()
|
||||
builder.emit(Opcode.MOVE_OBJ, current, old)
|
||||
builder.emit(op, current, oneSlot, result)
|
||||
builder.emit(Opcode.SET_THIS_MEMBER, nameId, result)
|
||||
return CompiledValue(old, SlotType.OBJ)
|
||||
}
|
||||
builder.emit(op, current, oneSlot, result)
|
||||
builder.emit(Opcode.SET_THIS_MEMBER, nameId, result)
|
||||
return CompiledValue(result, SlotType.OBJ)
|
||||
}
|
||||
|
||||
val fieldTarget = ref.target as? FieldRef
|
||||
if (fieldTarget != null) {
|
||||
if (fieldTarget.isOptional) return null
|
||||
val receiver = compileRefWithFallback(fieldTarget.target, null, Pos.builtIn) ?: return null
|
||||
val nameId = builder.addConst(BytecodeConst.StringVal(fieldTarget.name))
|
||||
if (nameId > 0xFFFF) return null
|
||||
val current = allocSlot()
|
||||
builder.emit(Opcode.GET_FIELD, receiver.slot, nameId, current)
|
||||
updateSlotType(current, SlotType.OBJ)
|
||||
val oneSlot = allocSlot()
|
||||
val oneId = builder.addConst(BytecodeConst.ObjRef(ObjInt.One))
|
||||
builder.emit(Opcode.CONST_OBJ, oneId, oneSlot)
|
||||
updateSlotType(oneSlot, SlotType.OBJ)
|
||||
val result = allocSlot()
|
||||
val op = if (ref.isIncrement) Opcode.ADD_OBJ else Opcode.SUB_OBJ
|
||||
if (wantResult && ref.isPost) {
|
||||
val old = allocSlot()
|
||||
builder.emit(Opcode.MOVE_OBJ, current, old)
|
||||
builder.emit(op, current, oneSlot, result)
|
||||
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
|
||||
return CompiledValue(old, SlotType.OBJ)
|
||||
}
|
||||
builder.emit(op, current, oneSlot, result)
|
||||
builder.emit(Opcode.SET_FIELD, receiver.slot, nameId, result)
|
||||
return CompiledValue(result, SlotType.OBJ)
|
||||
}
|
||||
|
||||
val indexTarget = ref.target as? IndexRef ?: return null
|
||||
if (indexTarget.optionalRef) return null
|
||||
val receiver = compileRefWithFallback(indexTarget.targetRef, null, Pos.builtIn) ?: return null
|
||||
|
||||
@ -725,7 +725,8 @@ open class Obj {
|
||||
(thisObj as? ObjInstance)?.let {
|
||||
body.callOn(ApplyScope(this, it.instanceScope))
|
||||
} ?: run {
|
||||
body.callOn(this)
|
||||
val appliedScope = createChildScope(newThisObj = thisObj)
|
||||
body.callOn(ApplyScope(this, appliedScope))
|
||||
}
|
||||
thisObj
|
||||
}
|
||||
|
||||
@ -118,9 +118,13 @@ open class ObjClass(
|
||||
|
||||
/**
|
||||
* Map of public member names to their effective storage keys in instanceScope.objects.
|
||||
* This is pre-calculated to avoid MRO traversal and string concatenation during common access.
|
||||
* Cached and invalidated by layoutVersion to reflect newly added members.
|
||||
*/
|
||||
val publicMemberResolution: Map<String, String> by lazy {
|
||||
private var publicMemberResolutionVersion: Int = -1
|
||||
private var publicMemberResolutionCache: Map<String, String> = emptyMap()
|
||||
val publicMemberResolution: Map<String, String>
|
||||
get() {
|
||||
if (publicMemberResolutionVersion == layoutVersion) return publicMemberResolutionCache
|
||||
val res = mutableMapOf<String, String>()
|
||||
// Traverse MRO in REVERSED order so that child classes override parent classes in the map.
|
||||
for (cls in mro.reversed()) {
|
||||
@ -138,7 +142,9 @@ open class ObjClass(
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
publicMemberResolutionCache = res
|
||||
publicMemberResolutionVersion = layoutVersion
|
||||
return res
|
||||
}
|
||||
|
||||
val classNameObj by lazy { ObjString(className) }
|
||||
|
||||
@ -2671,7 +2671,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testLet() = runTest {
|
||||
eval(
|
||||
@ -2685,7 +2684,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testApply() = runTest {
|
||||
eval(
|
||||
@ -2700,7 +2698,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testApplyThis() = runTest {
|
||||
eval(
|
||||
@ -2717,7 +2714,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testApplyFromStatic() = runTest {
|
||||
eval(
|
||||
@ -2754,7 +2750,6 @@ class ScriptTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun TestApplyFromKotlin() = runTest {
|
||||
val scope = Script.newScope()
|
||||
@ -2770,7 +2765,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testParallels() = runTest {
|
||||
withContext(Dispatchers.Default) {
|
||||
@ -2797,7 +2791,6 @@ class ScriptTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testParallels2() = runTest {
|
||||
withContext(Dispatchers.Default) {
|
||||
@ -2845,7 +2838,6 @@ class ScriptTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testExtend() = runTest() {
|
||||
eval(
|
||||
@ -2879,7 +2871,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testToFlow() = runTest() {
|
||||
val c = Scope()
|
||||
@ -2888,7 +2879,6 @@ class ScriptTest {
|
||||
assertEquals(listOf(1, 2, 3), arr.toFlow(c).map { it.toInt() }.toList())
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testAssociateBy() = runTest() {
|
||||
eval(
|
||||
@ -2916,7 +2906,6 @@ class ScriptTest {
|
||||
// assertEquals("foo1", pm.modules["lyng.foo"]!!.deferredModule.await().eval("foo()").toString())
|
||||
// }
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testImports2() = runTest() {
|
||||
val foosrc = """
|
||||
@ -2936,7 +2925,6 @@ class ScriptTest {
|
||||
assertEquals("foo1", scope.eval(src).toString())
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testImports3() = runTest {
|
||||
val foosrc = """
|
||||
@ -2968,7 +2956,6 @@ class ScriptTest {
|
||||
assertEquals("foo1 / bar1", scope.eval(src).toString())
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testImportsCircular() = runTest {
|
||||
val foosrc = """
|
||||
@ -3002,7 +2989,6 @@ class ScriptTest {
|
||||
assertEquals("foo1 / bar1", scope.eval(src).toString())
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testDefaultImportManager() = runTest {
|
||||
val scope = Scope.new()
|
||||
@ -3029,7 +3015,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testMaps() = runTest {
|
||||
eval(
|
||||
@ -3063,7 +3048,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testExternDeclarations() = runTest {
|
||||
eval(
|
||||
@ -3087,7 +3071,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testExternExtension() = runTest {
|
||||
eval(
|
||||
@ -3098,7 +3081,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testBuffer() = runTest {
|
||||
eval(
|
||||
@ -3125,7 +3107,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testBufferEncodings() = runTest {
|
||||
eval(
|
||||
@ -3148,7 +3129,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testBufferCompare() = runTest {
|
||||
eval(
|
||||
@ -3174,7 +3154,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testInstant() = runTest {
|
||||
eval(
|
||||
@ -3214,7 +3193,6 @@ class ScriptTest {
|
||||
delay(1000)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testTimeStatics() = runTest {
|
||||
eval(
|
||||
@ -3236,7 +3214,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testInstantFormatting() = runTest {
|
||||
eval(
|
||||
@ -3251,7 +3228,6 @@ class ScriptTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Ignore("incremental enable")
|
||||
@Test
|
||||
fun testDateTimeComprehensive() = runTest {
|
||||
eval(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user