Skip to content

Commit 42d1bcd

Browse files
authored
Some fixes for new generics and a fully fledged ArrayList<T:> test (#1128)
1 parent 0f6321d commit 42d1bcd

9 files changed

Lines changed: 980 additions & 25 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/jassinterpreter/providers/FrameProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@ public IlConstHandle ConvertOriginFrameType(ILconstInt i) {
3535
return new IlConstHandle("frameType", i.getVal());
3636
}
3737

38+
public IlConstHandle BlzGetFrameByName(ILconstString name, ILconstInt createContext) {
39+
return new IlConstHandle("framehandle", new FrameHandle());
40+
}
41+
3842
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/interpreter/ProgramState.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public ILconstObject allocate(ImClassType clazz, Element trace) {
168168
objectIdCounter++;
169169
ILconstObject res = new ILconstObject(clazz, objectIdCounter, trace);
170170
indexToObject.put(objectIdCounter, res);
171-
System.out.println("alloc objId=" + objectIdCounter + " type=" + clazz + " trace=" + trace);
171+
WLogger.trace("alloc objId=" + objectIdCounter + " type=" + clazz + " trace=" + trace);
172172
return res;
173173
}
174174

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/EliminateGenerics.java

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import com.google.common.collect.*;
44
import de.peeeq.wurstscript.WLogger;
5+
import de.peeeq.wurstscript.ast.PackageOrGlobal;
6+
import de.peeeq.wurstscript.ast.WPackage;
57
import de.peeeq.wurstscript.attributes.CompileError;
68
import de.peeeq.wurstscript.jassIm.*;
79
import de.peeeq.wurstscript.translation.imtojass.ImAttrType;
810
import de.peeeq.wurstscript.translation.imtojass.TypeRewriteMatcher;
11+
import org.eclipse.jdt.annotation.Nullable;
912
import org.jetbrains.annotations.NotNull;
1013

1114
import java.util.*;
@@ -675,6 +678,10 @@ private ImClass specializeClass(ImClass c, GenericTypes generics) {
675678
private void createSpecializedGlobals(ImClass originalClass, GenericTypes generics, List<ImTypeVar> typeVars) {
676679
String key = gKey(generics);
677680

681+
// Collect "insert specialized init right after original init" operations per parent ImStmts
682+
// Using identity maps because IM nodes use identity semantics for parent/ownership.
683+
Map<ImStmts, IdentityHashMap<ImStmt, List<ImStmt>>> insertsByParent = new IdentityHashMap<>();
684+
678685
for (Map.Entry<ImVar, ImClass> entry : globalToClass.entrySet()) {
679686
ImVar originalGlobal = entry.getKey();
680687
ImClass owningClass = entry.getValue();
@@ -694,17 +701,89 @@ private void createSpecializedGlobals(ImClass originalClass, GenericTypes generi
694701
originalGlobal.getIsBJ()
695702
);
696703

704+
// Create + register global
705+
translator.addGlobal(specializedGlobal);
706+
specializedGlobals.put(originalGlobal, key, specializedGlobal);
707+
dbg("Created specialized global: " + specializedName + " type=" + specializedType);
708+
709+
// If original has init(s), create corresponding specialized init(s) and schedule insertion
697710
List<ImSet> originalInits = prog.getGlobalInits().get(originalGlobal);
698711
if (originalInits != null && !originalInits.isEmpty()) {
699-
ImExpr initRhs = originalInits.getFirst().getRight().copy();
700-
initRhs = specializeNullInitializer(initRhs, specializedType);
701-
translator.addGlobalWithInitalizer(specializedGlobal, initRhs);
702-
} else {
703-
translator.addGlobal(specializedGlobal);
712+
713+
ImSet firstOrig = originalInits.getFirst();
714+
if (!(firstOrig.getParent() instanceof ImStmts parentStmts)) {
715+
throw new CompileError(originalGlobal,
716+
"Initializer for global " + originalGlobal.getName() + " is not inside ImStmts.");
717+
}
718+
// ensure all original init sets share the same parent statement list
719+
for (ImSet s : originalInits) {
720+
if (s.getParent() != parentStmts) {
721+
throw new CompileError(originalGlobal,
722+
"Initializer statements for global " + originalGlobal.getName() + " are not in the same ImStmts.");
723+
}
724+
}
725+
726+
// Helper: rebuild LHS as ImLExpr for specialized global
727+
java.util.function.Function<ImLExpr, ImLExpr> specializeLhs = (ImLExpr lhs) -> {
728+
if (lhs instanceof ImVarAccess va) {
729+
if (va.getVar() == originalGlobal) {
730+
return JassIm.ImVarAccess(specializedGlobal);
731+
}
732+
return (ImLExpr) va.copy();
733+
}
734+
if (lhs instanceof ImVarArrayAccess aa) {
735+
if (aa.getVar() == originalGlobal) {
736+
return JassIm.ImVarArrayAccess(
737+
aa.getTrace(),
738+
specializedGlobal,
739+
aa.getIndexes().copy()
740+
);
741+
}
742+
return (ImLExpr) aa.copy();
743+
}
744+
throw new CompileError(originalGlobal,
745+
"Unsupported initializer LHS for global " + originalGlobal.getName() + ": " + lhs.getClass().getSimpleName());
746+
};
747+
748+
List<ImSet> specializedInitsForMap = new ArrayList<>(originalInits.size());
749+
750+
// Create specialized init sets and schedule: insert each right after its corresponding original init set
751+
for (ImSet origSet : originalInits) {
752+
ImExpr rhs = origSet.getRight().copy();
753+
rhs = specializeNullInitializer(rhs, specializedType);
754+
755+
ImLExpr newLeft = specializeLhs.apply(origSet.getLeft());
756+
ImSet specSet = JassIm.ImSet(originalGlobal.attrTrace(), newLeft, rhs);
757+
758+
// schedule insertion right after origSet in its parent ImStmts
759+
IdentityHashMap<ImStmt, List<ImStmt>> byStmt =
760+
insertsByParent.computeIfAbsent(parentStmts, k -> new IdentityHashMap<>());
761+
byStmt.computeIfAbsent(origSet, k -> new ArrayList<>(1)).add(specSet);
762+
763+
// keep prog.getGlobalInits consistent, but do NOT reuse the tree-attached node elsewhere
764+
specializedInitsForMap.add((ImSet) specSet.copy());
765+
}
766+
767+
prog.getGlobalInits().put(specializedGlobal, specializedInitsForMap);
704768
}
769+
}
705770

706-
specializedGlobals.put(originalGlobal, key, specializedGlobal);
707-
dbg("Created specialized global: " + specializedName + " type=" + specializedType);
771+
// Perform insertions after the loop (so indices/state remain stable during collection)
772+
for (Map.Entry<ImStmts, IdentityHashMap<ImStmt, List<ImStmt>>> e : insertsByParent.entrySet()) {
773+
ImStmts parent = e.getKey();
774+
IdentityHashMap<ImStmt, List<ImStmt>> toInsertAfter = e.getValue();
775+
776+
ListIterator<ImStmt> it = parent.listIterator();
777+
while (it.hasNext()) {
778+
ImStmt curr = it.next();
779+
List<ImStmt> ins = toInsertAfter.get(curr);
780+
if (ins != null) {
781+
// add in order, immediately after the original init
782+
for (ImStmt s : ins) {
783+
it.add(s);
784+
}
785+
}
786+
}
708787
}
709788
}
710789

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import static de.peeeq.wurstscript.utils.Utils.string;
1414

1515
public class BugTests extends WurstScriptTest {
16-
private static final String TEST_DIR = "./testscripts/concept/";
16+
public static final String TEST_DIR = "./testscripts/concept/";
1717

1818
@Test
1919
public void localsInOndestroy() throws IOException {

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/GenericsWithTypeclassesTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
import org.testng.annotations.Ignore;
44
import org.testng.annotations.Test;
55

6+
import java.io.File;
7+
import java.io.IOException;
8+
9+
import static tests.wurstscript.tests.BugTests.TEST_DIR;
10+
611
public class GenericsWithTypeclassesTests extends WurstScriptTest {
712

813

@@ -2013,5 +2018,10 @@ public void genericClassWithStaticMemberArray() {
20132018
);
20142019
}
20152020

2021+
@Test
2022+
public void fullArrayListTest() throws IOException {
2023+
testAssertOkFileWithStdLib(new File(TEST_DIR + "arrayList.wurst"), true);
2024+
}
2025+
20162026

20172027
}

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/StdLib.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class StdLib {
2323
/**
2424
* version to use for the tests
2525
*/
26-
private final static String version = "6107c40e64fa646a016e8c446026f2f5cf3f2a1e";
26+
private final static String version = "e6463189f754b8794e59ba9d4ac1a91977c8aaac";
2727

2828
/**
2929
* flag so that initialization in only done once

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/WurstScriptTest.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -399,15 +399,15 @@ protected WurstModel testScript(String name, boolean executeProg, String prog) {
399399
private void testWithInliningAndOptimizations(String name, boolean executeProg, boolean executeTests, WurstGui gui,
400400
WurstCompilerJassImpl compiler, WurstModel model, boolean executeProgOnlyAfterTransforms, RunArgs runArgs) throws Error {
401401
// test with inlining and local optimization
402-
currentTestEnv = "With Inlining and Optimizations";
402+
setCurrentTestEnv("With Inlining and Optimizations");
403403
compiler.setRunArgs(runArgs.with("-inline", "-localOptimizations"));
404404
translateAndTest(name + "_inlopt", executeProg, executeTests, gui, compiler, model, executeProgOnlyAfterTransforms);
405405
}
406406

407407
private void testWithInliningAndOptimizationsAndStacktraces(String name, boolean executeProg, boolean executeTests, WurstGui gui,
408408
WurstCompilerJassImpl compiler, WurstModel model, boolean executeProgOnlyAfterTransforms, RunArgs runArgs) throws Error {
409409
// test with inlining and local optimization
410-
currentTestEnv = "With Inlining, Optimizations and Stacktraces";
410+
setCurrentTestEnv("With Inlining, Optimizations and Stacktraces");
411411
compiler.setRunArgs(runArgs.with("-inline", "-localOptimizations", "-stacktraces"));
412412
translateAndTest(name + "_stacktraceinlopt", executeProg, executeTests, gui, compiler, model, executeProgOnlyAfterTransforms);
413413
}
@@ -416,15 +416,15 @@ private void testWithInlining(String name, boolean executeProg, boolean executeT
416416
, WurstCompilerJassImpl compiler, WurstModel model, boolean executeProgOnlyAfterTransforms
417417
, RunArgs runArgs) throws Error {
418418
// test with inlining
419-
currentTestEnv = "With Inlining";
419+
setCurrentTestEnv("With Inlining");
420420
compiler.setRunArgs(runArgs.with("-inline"));
421421
translateAndTest(name + "_inl", executeProg, executeTests, gui, compiler, model, executeProgOnlyAfterTransforms);
422422
}
423423

424424
private void testWithLocalOptimizations(String name, boolean executeProg, boolean executeTests, WurstGui gui,
425425
WurstCompilerJassImpl compiler, WurstModel model, boolean executeProgOnlyAfterTransforms, RunArgs runArgs) throws Error {
426426
// test with local optimization
427-
currentTestEnv = "With Local Optimizations";
427+
setCurrentTestEnv("With Local Optimizations");
428428
compiler.setRunArgs(runArgs.with("-localOptimizations"));
429429
translateAndTest(name + "_opt", executeProg, executeTests, gui, compiler, model, executeProgOnlyAfterTransforms);
430430
}
@@ -434,7 +434,7 @@ private void testWithoutInliningAndOptimization(String name, boolean executeProg
434434
throws Error {
435435
compiler.setRunArgs(runArgs);
436436
// test without inlining and optimization
437-
currentTestEnv = "No opts";
437+
setCurrentTestEnv("No opts");
438438
translateAndTest(name + "_no_opts", executeProg, executeTests, gui, compiler, model, executeProgOnlyAfterTransforms);
439439
}
440440

@@ -526,7 +526,7 @@ private void translateAndTest(String name, boolean executeProg,
526526
if (executeProg) {
527527
WLogger.info("Executing imProg before jass transformation");
528528
String currentEnv = currentTestEnv;
529-
currentTestEnv = "ImProg before jass transformation";
529+
setCurrentTestEnv("ImProg before jass transformation");
530530
executeImProg(gui, imProg);
531531
currentTestEnv = currentEnv;
532532
}
@@ -545,7 +545,7 @@ private void translateAndTest(String name, boolean executeProg,
545545
if (executeProg) {
546546
WLogger.info("Executing imProg after jass transformation");
547547
String currentEnv = currentTestEnv;
548-
currentTestEnv += "-ImProg";
548+
setCurrentTestEnv(currentTestEnv + "-ImProg");
549549
executeImProg(gui, imProg);
550550
currentTestEnv = currentEnv;
551551
}
@@ -563,7 +563,7 @@ private void translateAndTest(String name, boolean executeProg,
563563

564564
if (executeProg) {
565565
String currentEnv = currentTestEnv;
566-
currentTestEnv += "-JassProg";
566+
setCurrentTestEnv(currentTestEnv + "-JassProg");
567567
executeJassProg(prog);
568568
currentTestEnv = currentEnv;
569569
}
@@ -613,7 +613,16 @@ private void runPjass(File outputFile) throws Error {
613613
}
614614
}
615615

616-
public static String currentTestEnv = "";
616+
private static String currentTestEnv = "";
617+
618+
public static String getCurrentTestEnv() {
619+
return currentTestEnv;
620+
}
621+
622+
public static void setCurrentTestEnv(String env) {
623+
currentTestEnv = env;
624+
System.out.println("Current test environment: " + currentTestEnv);
625+
}
617626

618627
private void executeImProg(WurstGui gui, ImProg imProg) throws TestFailException {
619628
try {

0 commit comments

Comments
 (0)