Skip to content

Commit 5b9ffa6

Browse files
committed
fix callees in specialized functions
1 parent dc2f094 commit 5b9ffa6

2 files changed

Lines changed: 52 additions & 8 deletions

File tree

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,49 @@ private void eliminateGenericUses() {
223223
}
224224
}
225225

226+
private void fixCalleesInSpecializedFunction(ImFunction newF, GenericTypes generics) {
227+
newF.accept(new Element.DefaultVisitor() {
228+
229+
@Override
230+
public void visit(ImFunctionCall fc) {
231+
super.visit(fc);
232+
233+
ImFunction callee = fc.getFunc();
234+
if (callee == null) return;
235+
236+
// Only interesting if callee itself is generic
237+
if (callee.getTypeVariables().isEmpty()) {
238+
return;
239+
}
240+
241+
// Determine which generics to use for the callee
242+
GenericTypes calleeGenerics;
243+
244+
if (!fc.getTypeArguments().isEmpty()) {
245+
// Call carries explicit type args → honor them
246+
calleeGenerics = new GenericTypes(specializeTypeArgs(fc.getTypeArguments()));
247+
} else {
248+
// No explicit type args → use the same generics context as the enclosing function.
249+
// This matches the pattern: destroyArrayList<T>(this: ArrayList<T>) calls ArrayList_onDestroy<T>(this)
250+
calleeGenerics = generics;
251+
}
252+
253+
if (calleeGenerics.containsTypeVariable()) {
254+
// Still not concrete → let the normal pipeline handle it later or fail explicitly if needed
255+
return;
256+
}
257+
258+
ImFunction specializedCallee = specializedFunctions.get(callee, calleeGenerics);
259+
if (specializedCallee == null) {
260+
specializedCallee = specializeFunction(callee, calleeGenerics);
261+
}
262+
263+
fc.setFunc(specializedCallee);
264+
fc.getTypeArguments().removeAll();
265+
}
266+
});
267+
}
268+
226269
/**
227270
* creates a specialized version of this function
228271
*/
@@ -246,7 +289,13 @@ private ImFunction specializeFunction(ImFunction f, GenericTypes generics) {
246289

247290
newF.setName(f.getName() + "⟪" + generics.makeName() + "⟫");
248291
rewriteGenerics(newF, generics, typeVars);
292+
293+
// fix calls inside this specialized function so they also point to specialized callees
294+
fixCalleesInSpecializedFunction(newF, generics);
295+
296+
// Then collect further generic uses inside the now-specialized body
249297
collectGenericUsages(newF);
298+
250299
return newF;
251300
}
252301

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,11 +1616,9 @@ public void inheritedField_lazyClosure_uses_enclosing_receiver() {
16161616

16171617
@Test
16181618
public void arrayListInClosure() {
1619-
testAssertOkLinesWithStdLib(true,
1619+
testAssertOkLines(true,
16201620
"package Hello",
16211621
"import NoWurst",
1622-
"import Integer",
1623-
"import Printing",
16241622
"",
16251623
"native testSuccess()",
16261624
"",
@@ -1659,11 +1657,10 @@ public void arrayListInClosure() {
16591657
" freeSectionCount--",
16601658
" return",
16611659
"",
1662-
" if nextFreeIndex + cap > JASS_MAX_ARRAY_SIZE",
1660+
" if nextFreeIndex + cap > 10000",
16631661
" compactFreeList()",
16641662
"",
1665-
" if nextFreeIndex + cap > JASS_MAX_ARRAY_SIZE",
1666-
" print(\"ArrayList: WARNING - Memory store exhausted, wrapping around!\")",
1663+
" if nextFreeIndex + cap > 10000",
16671664
" nextFreeIndex = 0",
16681665
"",
16691666
" startIndex = nextFreeIndex",
@@ -1761,13 +1758,11 @@ public void arrayListInClosure() {
17611758
" /** Returns the element at the specified index (O(1)) */",
17621759
" function get(int index) returns T",
17631760
" if index < 0 or index >= size",
1764-
" print(\"ArrayList: Index out of bounds: \" + index.toString())",
17651761
" return store[startIndex + index]",
17661762
"",
17671763
" /** Removes the element at the given index and returns it (O(n) - shifts elements) */",
17681764
" function removeAt(int index) returns T",
17691765
" if index < 0 or index >= size",
1770-
" print(\"ArrayList: Index out of bounds: \" + index.toString())",
17711766
"",
17721767
" let elem = store[startIndex + index]",
17731768
"",

0 commit comments

Comments
 (0)