fix bug with for generator variables in mixin (#297)

This commit is contained in:
Islon Scherer
2024-03-07 20:47:21 +01:00
committed by GitHub
parent 9defe868c0
commit 8dc258ef7d
4 changed files with 31 additions and 1 deletions

View File

@@ -61,6 +61,7 @@ public final class AmendFunctionNode extends PklNode {
} else {
parameterSlots = new int[0];
}
var hasForGenVars = false;
for (var i = 0; i < hostFrameDesecriptor.getNumberOfSlots(); i++) {
var slotInfo = hostFrameDesecriptor.getSlotInfo(i);
// Copy for-generator variables from the outer frame descriptor into inner lambda.
@@ -74,10 +75,22 @@ public final class AmendFunctionNode extends PklNode {
// frame (e.g. with `new Mixin { ... }` syntax), so it injects for-generator vars into the
// wrong frame.
//
// As a remedy, we simply copy outer for-generator variables into this frame.
// As a remedy, we simply copy outer variables into this frame if there are any for generator
// variables.
//
// We need to preserve the frame slot index, so we insert dummy identifiers
// for other slots that aren't for generator variables.
if (slotInfo != null && slotInfo.equals(SymbolTable.FOR_GENERATOR_VARIABLE)) {
if (!hasForGenVars) {
hasForGenVars = true;
for (var j = 0; j < i; j++) {
builder.addSlot(FrameSlotKind.Illegal, Identifier.DUMMY, null);
}
}
builder.addSlot(
hostFrameDesecriptor.getSlotKind(i), hostFrameDesecriptor.getSlotName(i), null);
} else if (hasForGenVars) {
builder.addSlot(FrameSlotKind.Illegal, Identifier.DUMMY, null);
}
}
var objectToAmendSlot = builder.addSlot(FrameSlotKind.Object, new Object(), null);

View File

@@ -152,6 +152,9 @@ public final class Identifier implements Comparable<Identifier> {
// common in lambdas etc
public static final Identifier IT = get("it");
// dummy, unrepresentable identifier
public static final Identifier DUMMY = get("`#_");
private final String name;
private Identifier(String name) {

View File

@@ -38,3 +38,13 @@ function mapEnvLiteral(_env: Dynamic) = (it) -> (it) {
}
}
}
function addElements(keys: List<String>): Mixin<Mapping<String, String>> = new {
for (key in keys) {
[key] = key
}
}
res = new Mapping<String, String> {
["base"] = "alreadyThere"
} |> addElements(List("newElement"))

View File

@@ -36,3 +36,7 @@ foo {
}
}
}
res {
["base"] = "alreadyThere"
["newElement"] = "newElement"
}