fixed bug when some Map operations wer restricted to string keys only
This commit is contained in:
1 parent
fa91afa92b
commit
6f86e6ff97
6 files changed
+67
-37
No files matched your search
@@ -104,11 +104,14 @@ val ObjIterable by lazy {
|
||||
returns = type("lyng.Map"),
|
||||
moduleName = "lyng.stdlib"
|
||||
) {
|
||||
val result = ObjMap()
|
||||
val result = mutableMapOf<Obj, Obj>()
|
||||
thisObj.toFlow(this).collect { pair ->
|
||||
result.map[pair.getAt(this, 0)] = pair.getAt(this, 1)
|
||||
when (pair) {
|
||||
is ObjMapEntry -> result[pair.key] = pair.value
|
||||
else -> result[pair.getAt(this, 0)] = pair.getAt(this, 1)
|
||||
}
|
||||
}
|
||||
result
|
||||
ObjMap(result)
|
||||
}
|
||||
|
||||
addFnDoc(
|
||||
|
||||
@@ -174,18 +174,21 @@ class ObjMap(val map: MutableMap<Obj, Obj> = mutableMapOf()) : Obj() {
|
||||
val map = mutableMapOf<Obj, Obj>()
|
||||
if (list.isEmpty()) return map
|
||||
|
||||
val first = list.first()
|
||||
if (first.isInstanceOf(ObjArray)) {
|
||||
if (first.invokeInstanceMethod(scope, "size").toInt() != 2)
|
||||
scope.raiseIllegalArgument(
|
||||
"list to construct map entry should exactly be 2 element Array like [key,value], got $list"
|
||||
)
|
||||
} else scope.raiseIllegalArgument("first element of map list be a Collection of 2 elements; got $first")
|
||||
|
||||
|
||||
|
||||
list.forEach {
|
||||
map[it.getAt(scope, ObjInt.Zero)] = it.getAt(scope, ObjInt.One)
|
||||
when (it) {
|
||||
is ObjMapEntry -> map[it.key] = it.value
|
||||
else -> {
|
||||
if (it.isInstanceOf(ObjArray)) {
|
||||
if (it.invokeInstanceMethod(scope, "size").toInt() != 2)
|
||||
scope.raiseIllegalArgument(
|
||||
"Array to construct map entry should exactly be 2 elements [key,value], got $it"
|
||||
)
|
||||
map[it.getAt(scope, ObjInt.Zero)] = it.getAt(scope, ObjInt.One)
|
||||
} else {
|
||||
scope.raiseIllegalArgument("elements to construct map must be MapEntry or Array of 2 elements; got $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
@@ -296,13 +299,11 @@ class ObjMap(val map: MutableMap<Obj, Obj> = mutableMapOf()) : Obj() {
|
||||
is ObjMap -> {
|
||||
// Rightmost wins: copy all entries from `other` over existing ones
|
||||
for ((k, v) in other.map) {
|
||||
val key = k as? ObjString ?: scope.raiseIllegalArgument("map merge expects string keys; got $k")
|
||||
map[key] = v
|
||||
map[k] = v
|
||||
}
|
||||
}
|
||||
is ObjMapEntry -> {
|
||||
val key = other.key as? ObjString ?: scope.raiseIllegalArgument("map merge expects string keys; got ${other.key}")
|
||||
map[key] = other.value
|
||||
map[other.key] = other.value
|
||||
}
|
||||
is ObjList -> {
|
||||
// Treat as list of map entries
|
||||
@@ -311,8 +312,7 @@ class ObjMap(val map: MutableMap<Obj, Obj> = mutableMapOf()) : Obj() {
|
||||
is ObjMapEntry -> e
|
||||
else -> scope.raiseIllegalArgument("map can only be merged with MapEntry elements; got $e")
|
||||
}
|
||||
val key = entry.key as? ObjString ?: scope.raiseIllegalArgument("map merge expects string keys; got ${entry.key}")
|
||||
map[key] = entry.value
|
||||
map[entry.key] = entry.value
|
||||
}
|
||||
}
|
||||
else -> scope.raiseIllegalArgument("map can only be merged with Map, MapEntry, or List<MapEntry>")
|
||||
|
||||
@@ -1656,10 +1656,8 @@ class MapLiteralRef(private val entries: List<MapLiteralEntry>) : ObjRef {
|
||||
is MapLiteralEntry.Spread -> {
|
||||
val m = if (PerfFlags.RVAL_FASTPATH) e.ref.evalValue(scope) else e.ref.get(scope).value
|
||||
if (m !is ObjMap) scope.raiseIllegalArgument("spread element in map literal must be a Map")
|
||||
// Enforce string keys for map literals
|
||||
for ((k, v) in m.map) {
|
||||
val sKey = k as? ObjString ?: scope.raiseIllegalArgument("spread map must have string keys; got $k")
|
||||
result.map[sKey] = v
|
||||
result.map[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user