• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wurstscript / WurstScript / 228

29 Nov 2023 05:00PM UTC coverage: 62.48% (-0.09%) from 62.574%
228

push

circleci

web-flow
Show dialog for choosing game path, cleanup (#1083)

* show dialog for choosing game path

* cleanup code

* remove logs and refactor

* remove confusing mpq error, make some mpq loads readonly

17295 of 27681 relevant lines covered (62.48%)

0.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.72
de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/lua/translation/LuaTranslator.java
1
package de.peeeq.wurstscript.translation.lua.translation;
2

3
import de.peeeq.datastructures.UnionFind;
4
import de.peeeq.wurstscript.ast.Element;
5
import de.peeeq.wurstscript.ast.FuncDef;
6
import de.peeeq.wurstscript.ast.NameDef;
7
import de.peeeq.wurstscript.ast.WPackage;
8
import de.peeeq.wurstscript.jassIm.*;
9
import de.peeeq.wurstscript.luaAst.*;
10
import de.peeeq.wurstscript.translation.imtranslation.FunctionFlagEnum;
11
import de.peeeq.wurstscript.translation.imtranslation.GetAForB;
12
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;
13
import de.peeeq.wurstscript.types.TypesHelper;
14
import de.peeeq.wurstscript.utils.Lazy;
15
import de.peeeq.wurstscript.utils.Utils;
16
import org.jetbrains.annotations.NotNull;
17

18
import java.util.*;
19
import java.util.stream.Stream;
20

21
import static de.peeeq.wurstscript.translation.lua.translation.ExprTranslation.WURST_SUPERTYPES;
22

23
public class LuaTranslator {
24

25
    final ImProg prog;
26
    final LuaCompilationUnit luaModel;
27
    private final Set<String> usedNames = new HashSet<>(Arrays.asList(
1✔
28
        // reserved function names
29
        "print", "tostring", "error",
30
        // keywords:
31
        "and",
32
        "break",
33
        "do",
34
        "else",
35
        "elseif",
36
        "end",
37
        "false",
38
        "for",
39
        "function",
40
        "if",
41
        "in",
42
        "local",
43
        "nil",
44
        "not",
45
        "or",
46
        "repeat",
47
        "return",
48
        "then",
49
        "true",
50
        "until",
51
        "while"
52
    ));
53

54
    private ImProg getProg() {
55
        return prog;
1✔
56
    }
57

58
    List<ExprTranslation.TupleFunc> tupleEqualsFuncs = new ArrayList<>();
1✔
59
    List<ExprTranslation.TupleFunc> tupleCopyFuncs = new ArrayList<>();
1✔
60

61
    GetAForB<ImVar, LuaVariable> luaVar = new GetAForB<ImVar, LuaVariable>() {
1✔
62
        @Override
63
        public LuaVariable initFor(ImVar a) {
64
            String name = a.getName();
1✔
65
            if (!a.getIsBJ()) {
1✔
66
                name = uniqueName(name);
1✔
67
            }
68
            return LuaAst.LuaVariable(name, LuaAst.LuaNoExpr());
1✔
69
        }
70
    };
71

72
    GetAForB<ImFunction, LuaFunction> luaFunc = new GetAForB<ImFunction, LuaFunction>() {
1✔
73

74
        @Override
75
        public LuaFunction initFor(ImFunction a) {
76
            String name = a.getName();
1✔
77
            if (!a.isExtern() && !a.isBj() && !a.isNative()) {
1✔
78
                name = uniqueName(name);
1✔
79
            }
80

81
            LuaFunction lf = LuaAst.LuaFunction(name, LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
82
            // translate parameters
83
            for (ImVar p : a.getParameters()) {
1✔
84
                LuaVariable pv = luaVar.getFor(p);
1✔
85
                lf.getParams().add(pv);
1✔
86
            }
1✔
87
            return lf;
1✔
88
        }
89
    };
90
    public GetAForB<ImMethod, LuaMethod> luaMethod = new GetAForB<ImMethod, LuaMethod>() {
1✔
91

92
        @Override
93
        public LuaMethod initFor(ImMethod a) {
94
            LuaExpr receiver = LuaAst.LuaExprVarAccess(luaClassVar.getFor(a.attrClass()));
1✔
95
            return LuaAst.LuaMethod(receiver, a.getName(), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
96
        }
97
    };
98

99

100
    GetAForB<ImClass, LuaVariable> luaClassVar = new GetAForB<ImClass, LuaVariable>() {
1✔
101
        @Override
102
        public LuaVariable initFor(ImClass a) {
103
            return LuaAst.LuaVariable(uniqueName(a.getName()), LuaAst.LuaNoExpr());
1✔
104
        }
105
    };
106

107
    GetAForB<ImClass, LuaVariable> luaClassMetaTableVar = new GetAForB<ImClass, LuaVariable>() {
1✔
108
        @Override
109
        public LuaVariable initFor(ImClass a) {
110
            return LuaAst.LuaVariable(uniqueName(a.getName() + "_mt"), LuaAst.LuaNoExpr());
×
111
        }
112
    };
113

114
    GetAForB<ImClass, LuaMethod> luaClassInitMethod = new GetAForB<ImClass, LuaMethod>() {
1✔
115
        @Override
116
        public LuaMethod initFor(ImClass a) {
117
            LuaExprVarAccess receiver = LuaAst.LuaExprVarAccess(luaClassVar.getFor(a));
1✔
118
            return LuaAst.LuaMethod(receiver, uniqueName("create"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
119
        }
120
    };
121

122
    LuaFunction arrayInitFunction = LuaAst.LuaFunction(uniqueName("defaultArray"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
123

124
    LuaFunction stringConcatFunction = LuaAst.LuaFunction(uniqueName("stringConcat"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
125

126
    LuaFunction toIndexFunction = LuaAst.LuaFunction(uniqueName("objectToIndex"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
127

128
    LuaFunction fromIndexFunction = LuaAst.LuaFunction(uniqueName("objectFromIndex"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
129

130
    LuaFunction instanceOfFunction = LuaAst.LuaFunction(uniqueName("isInstanceOf"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
131

132
    LuaFunction ensureIntFunction = LuaAst.LuaFunction(uniqueName("intEnsure"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
133
    LuaFunction ensureStrFunction = LuaAst.LuaFunction(uniqueName("stringEnsure"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
134
    LuaFunction ensureBoolFunction = LuaAst.LuaFunction(uniqueName("boolEnsure"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
135
    LuaFunction ensureRealFunction = LuaAst.LuaFunction(uniqueName("realEnsure"), LuaAst.LuaParams(), LuaAst.LuaStatements());
1✔
136

137
    private final Lazy<LuaFunction> errorFunc = Lazy.create(() ->
1✔
138
        this.getProg().getFunctions().stream()
1✔
139
            .flatMap(f -> {
1✔
140
                Element trace = f.attrTrace();
1✔
141
                if (trace instanceof FuncDef) {
1✔
142
                    FuncDef fd = (FuncDef) trace;
1✔
143
                    if (fd.getName().equals("error")
1✔
144
                        && fd.attrNearestPackage() instanceof WPackage) {
1✔
145
                        WPackage p = (WPackage) fd.attrNearestPackage();
1✔
146
                        if (p.getName().equals("ErrorHandling")) {
1✔
147
                            return Stream.of(luaFunc.getFor(f));
1✔
148
                        }
149
                    }
150
                }
151
                return Stream.empty();
1✔
152
            })
153
            .findFirst().orElse(null));
1✔
154

155
    private final ImTranslator imTr;
156

157
    public LuaTranslator(ImProg prog, ImTranslator imTr) {
1✔
158
        this.prog = prog;
1✔
159
        this.imTr = imTr;
1✔
160
        luaModel = LuaAst.LuaCompilationUnit();
1✔
161
    }
1✔
162

163
    protected String uniqueName(String name) {
164
        int i = 0;
1✔
165
        String rname = name;
1✔
166
        while (usedNames.contains(rname)) {
1✔
167
            rname = name + ++i;
1✔
168
        }
169
        usedNames.add(rname);
1✔
170
        return rname;
1✔
171
    }
172

173
    public LuaCompilationUnit translate() {
174
        collectPredefinedNames();
1✔
175

176
        RemoveGarbage.removeGarbage(prog);
1✔
177
        prog.flatten(imTr);
1✔
178

179

180
        normalizeMethodNames();
1✔
181

182
//        NormalizeNames.normalizeNames(prog);
183

184
        createArrayInitFunction();
1✔
185
        createStringConcatFunction();
1✔
186
        createInstanceOfFunction();
1✔
187
        createObjectIndexFunctions();
1✔
188
        createEnsureTypeFunctions();
1✔
189

190
        for (ImVar v : prog.getGlobals()) {
1✔
191
            translateGlobal(v);
1✔
192
        }
1✔
193

194
        // first add class variables
195
        for (ImClass c : prog.getClasses()) {
1✔
196
            LuaVariable classVar = luaClassVar.getFor(c);
1✔
197
            luaModel.add(classVar);
1✔
198
        }
1✔
199

200
        for (ImClass c : prog.getClasses()) {
1✔
201
            translateClass(c);
1✔
202
        }
1✔
203

204
        for (ImFunction f : prog.getFunctions()) {
1✔
205
            translateFunc(f);
1✔
206
        }
1✔
207

208
        for (ImClass c : prog.getClasses()) {
1✔
209
            initClassTables(c);
1✔
210
        }
1✔
211

212
        cleanStatements();
1✔
213

214
        return luaModel;
1✔
215
    }
216

217
    private void collectPredefinedNames() {
218
        for (ImFunction function : prog.getFunctions()) {
1✔
219
            if (function.isBj() || function.isExtern() || function.isNative()) {
1✔
220
                setNameFromTrace(function);
1✔
221
                usedNames.add(function.getName());
1✔
222
            }
223
        }
1✔
224

225
        for (ImVar global : prog.getGlobals()) {
1✔
226
            if (global.getIsBJ()) {
1✔
227
                setNameFromTrace(global);
1✔
228
                usedNames.add(global.getName());
1✔
229
            }
230
        }
1✔
231
    }
1✔
232

233
    private void setNameFromTrace(JassImElementWithName named) {
234
        Element trace = named.attrTrace();
1✔
235
        if (trace instanceof NameDef) {
1✔
236
            named.setName(((NameDef) trace).getName());
1✔
237
        }
238
    }
1✔
239

240
    private void normalizeMethodNames() {
241
        // group related methods
242
        UnionFind<ImMethod> methodUnions = new UnionFind<>();
1✔
243
        for (ImClass c : prog.getClasses()) {
1✔
244
            for (ImMethod m : c.getMethods()) {
1✔
245
                methodUnions.find(m);
1✔
246
                for (ImMethod subMethod : m.getSubMethods()) {
1✔
247
                    methodUnions.union(m, subMethod);
1✔
248
                }
1✔
249
            }
1✔
250
        }
1✔
251

252
        // give all related methods the same name
253
        for (Map.Entry<ImMethod, Set<ImMethod>> entry : methodUnions.groups().entrySet()) {
1✔
254
            String name = uniqueName(entry.getKey().getName());
1✔
255
            for (ImMethod method : entry.getValue()) {
1✔
256
                method.setName(name);
1✔
257
            }
1✔
258
        }
1✔
259
    }
1✔
260

261
    private void createStringConcatFunction() {
262
        String[] code = {
1✔
263
            "if x then",
264
            "    if y then return x .. y else return x end",
265
            "else",
266
            "    return y",
267
            "end"
268
        };
269

270
        stringConcatFunction.getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
1✔
271
        stringConcatFunction.getParams().add(LuaAst.LuaVariable("y", LuaAst.LuaNoExpr()));
1✔
272
        for (String c : code) {
1✔
273
            stringConcatFunction.getBody().add(LuaAst.LuaLiteral(c));
1✔
274
        }
275
        luaModel.add(stringConcatFunction);
1✔
276
    }
1✔
277

278
    private void createInstanceOfFunction() {
279
        // x instanceof A
280

281
        // ==> x ~= nil and x.__wurst_supertypes[A]
282

283
        String[] code = {
1✔
284
            "return x ~= nil and x." + WURST_SUPERTYPES + "[A]"
285
        };
286

287
        instanceOfFunction.getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
1✔
288
        instanceOfFunction.getParams().add(LuaAst.LuaVariable("A", LuaAst.LuaNoExpr()));
1✔
289
        for (String c : code) {
1✔
290
            instanceOfFunction.getBody().add(LuaAst.LuaLiteral(c));
1✔
291
        }
292
        luaModel.add(instanceOfFunction);
1✔
293
    }
1✔
294

295
    private void createObjectIndexFunctions() {
296
        String vName = "__wurst_objectIndexMap";
1✔
297
        LuaVariable v = LuaAst.LuaVariable(vName, LuaAst.LuaTableConstructor(LuaAst.LuaTableFields(
1✔
298
            LuaAst.LuaTableNamedField("counter", LuaAst.LuaExprIntVal("0"))
1✔
299
        )));
300
        luaModel.add(v);
1✔
301

302
        LuaVariable im = LuaAst.LuaVariable("__wurst_number_wrapper_map", LuaAst.LuaTableConstructor(LuaAst.LuaTableFields(
1✔
303
            LuaAst.LuaTableNamedField("counter", LuaAst.LuaExprIntVal("0"))
1✔
304
        )));
305
        luaModel.add(im);
1✔
306

307
        {
308
            String[] code = {
1✔
309
                "if x == nil then",
310
                "    return 0",
311
                "end",
312
                // wrap numbers in special number-objects:
313
                "if type(x) == \"number\" then",
314
                "    if __wurst_number_wrapper_map[x] then",
315
                "        x = __wurst_number_wrapper_map[x]",
316
                "    else",
317
                "        local obj = {__wurst_boxed_number = x}",
318
                "        __wurst_number_wrapper_map[x] = obj",
319
                "        x = obj",
320
                "    end",
321
                "end",
322
                "if __wurst_objectIndexMap[x] then",
323
                "    return __wurst_objectIndexMap[x]",
324
                "else",
325
                "   local r = __wurst_objectIndexMap.counter + 1",
326
                "   __wurst_objectIndexMap.counter = r",
327
                "   __wurst_objectIndexMap[r] = x",
328
                "   __wurst_objectIndexMap[x] = r",
329
                "   return r",
330
                "end"
331
            };
332

333
            toIndexFunction.getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
1✔
334
            for (String c : code) {
1✔
335
                toIndexFunction.getBody().add(LuaAst.LuaLiteral(c));
1✔
336
            }
337
            luaModel.add(toIndexFunction);
1✔
338
        }
339

340
        {
341
            String[] code = {
1✔
342
                "if type(x) == \"number\" then",
343
                "    x = __wurst_objectIndexMap[x]",
344
                "end",
345
                "if type(x) == \"table\" and x.__wurst_boxed_number then",
346
                "    return x.__wurst_boxed_number",
347
                "end",
348
                "return x"
349
            };
350

351
            fromIndexFunction.getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
1✔
352
            for (String c : code) {
1✔
353
                fromIndexFunction.getBody().add(LuaAst.LuaLiteral(c));
1✔
354
            }
355
            luaModel.add(fromIndexFunction);
1✔
356
        }
357
    }
1✔
358

359
    private void createArrayInitFunction() {
360
        /*
361
        function defaultArray(d)
362
            local t = {}
363
            local mt = {__index = function (table, key)
364
                local v = d()
365
                table[key] = v
366
                return v
367
            end}
368
            setmetatable(t, mt)
369
            return t
370
        end
371
         */
372
        String[] code = {
1✔
373
            "local t = {}",
374
            "local mt = {__index = function (table, key)",
375
            "    local v = d()",
376
            "    table[key] = v",
377
            "    return v",
378
            "end}",
379
            "setmetatable(t, mt)",
380
            "return t"
381
        };
382

383
        arrayInitFunction.getParams().add(LuaAst.LuaVariable("d", LuaAst.LuaNoExpr()));
1✔
384
        for (String c : code) {
1✔
385
            arrayInitFunction.getBody().add(LuaAst.LuaLiteral(c));
1✔
386
        }
387
        luaModel.add(arrayInitFunction);
1✔
388
    }
1✔
389

390
    private void createEnsureTypeFunctions() {
391
        LuaFunction[] ensureTypeFunctions = {ensureIntFunction, ensureBoolFunction, ensureRealFunction, ensureStrFunction};
1✔
392
        String[] defaultValue = {"0", "false", "0.0", "\"\""};
1✔
393
        for(int i = 0; i < ensureTypeFunctions.length; ++i) {
1✔
394
            String[] code = {
1✔
395
                "if x == nil then",
396
                "    return " + defaultValue[i],
397
                "else",
398
                "    return x",
399
                "end"
400
            };
401

402
            ensureTypeFunctions[i].getParams().add(LuaAst.LuaVariable("x", LuaAst.LuaNoExpr()));
1✔
403
            for (String c : code) {
1✔
404
                ensureTypeFunctions[i].getBody().add(LuaAst.LuaLiteral(c));
1✔
405
            }
406
            luaModel.add(ensureTypeFunctions[i]);
1✔
407
        }
408
    }
1✔
409

410
    private void cleanStatements() {
411
        luaModel.accept(new LuaModel.DefaultVisitor() {
1✔
412
            @Override
413
            public void visit(LuaStatements stmts) {
414
                super.visit(stmts);
1✔
415
                cleanStatements(stmts);
1✔
416
            }
1✔
417

418
        });
419
    }
1✔
420

421
    private void cleanStatements(LuaStatements stmts) {
422
        ListIterator<LuaStatement> it = stmts.listIterator();
1✔
423
        while (it.hasNext()) {
1✔
424
            LuaStatement s = it.next();
1✔
425
            if (s instanceof LuaExprNull) {
1✔
426
                it.remove();
1✔
427
            } else if (s instanceof LuaExpr) {
1✔
428
                LuaExpr e = (LuaExpr) s;
1✔
429
                if (!(e instanceof LuaCallExpr || e instanceof LuaLiteral) || e instanceof LuaExprFunctionCallE) {
1✔
430
                    e.setParent(null);
×
431
                    LuaVariable exprTemp = LuaAst.LuaVariable("wurstExpr", e);
×
432
                    it.set(exprTemp);
×
433
                }
434
            }
435
        }
1✔
436
    }
1✔
437

438
    private void translateFunc(ImFunction f) {
439
        if (f.isBj()) {
1✔
440
            // do not translate blizzard functions
441
            return;
1✔
442
        }
443
        LuaFunction lf = luaFunc.getFor(f);
1✔
444
        if (f.isNative()) {
1✔
445
            LuaNatives.get(lf);
1✔
446
        } else {
447

448

449
            if (f.hasFlag(FunctionFlagEnum.IS_VARARG)) {
1✔
450
                LuaVariable lastParam = luaVar.getFor(Utils.getLast(f.getParameters()));
×
451
                lastParam.setName("...");
×
452
            }
453

454
            // translate local variables
455
            for (ImVar local : f.getLocals()) {
1✔
456
                LuaVariable luaLocal = luaVar.getFor(local);
1✔
457
                luaLocal.setInitialValue(defaultValue(local.getType()));
1✔
458
                lf.getBody().add(luaLocal);
1✔
459
            }
1✔
460

461
            // translate body:
462
            translateStatements(lf.getBody(), f.getBody());
1✔
463
        }
464

465
        if (f.isExtern() || f.isNative()) {
1✔
466
            // only add the function if it is not yet defined:
467
            String name = lf.getName();
1✔
468
            luaModel.add(LuaAst.LuaIf(
1✔
469
                LuaAst.LuaExprFuncRef(lf),
1✔
470
                LuaAst.LuaStatements(),
1✔
471
                LuaAst.LuaStatements(
1✔
472
                    LuaAst.LuaAssignment(LuaAst.LuaLiteral(name), LuaAst.LuaExprFunctionAbstraction(
1✔
473
                        lf.getParams().copy(),
1✔
474
                        lf.getBody().copy()
1✔
475
                    ))
476
                )
477
            ));
478
        } else {
1✔
479
            luaModel.add(lf);
1✔
480
        }
481
    }
1✔
482

483
    void translateStatements(List<LuaStatement> res, ImStmts stmts) {
484
        for (ImStmt s : stmts) {
1✔
485
            s.translateStmtToLua(res, this);
1✔
486
        }
1✔
487
    }
1✔
488

489
    public LuaStatements translateStatements(ImStmts stmts) {
490
        LuaStatements r = LuaAst.LuaStatements();
1✔
491
        translateStatements(r, stmts);
1✔
492
        return r;
1✔
493
    }
494

495

496
    private void translateClass(ImClass c) {
497

498
        // following the code at http://lua-users.org/wiki/InheritanceTutorial
499
        LuaVariable classVar = luaClassVar.getFor(c);
1✔
500
        LuaMethod initMethod = luaClassInitMethod.getFor(c);
1✔
501

502
        luaModel.add(initMethod);
1✔
503

504
        classVar.setInitialValue(emptyTable());
1✔
505

506
        // translate functions
507
        for (ImFunction f : c.getFunctions()) {
1✔
508
            translateFunc(f);
1✔
509
            luaFunc.getFor(f).setName(uniqueName(c.getName() + "_" + f.getName()));
1✔
510
        }
1✔
511

512
        createClassInitFunction(c, classVar, initMethod);
1✔
513
    }
1✔
514

515
    private void createClassInitFunction(ImClass c, LuaVariable classVar, LuaMethod initMethod) {
516
        // create init function:
517
        LuaStatements body = initMethod.getBody();
1✔
518
        // local new_inst = { ... }
519
        LuaTableFields initialFieldValues = LuaAst.LuaTableFields();
1✔
520
        LuaVariable newInst = LuaAst.LuaVariable("new_inst", LuaAst.LuaTableConstructor(initialFieldValues));
1✔
521
        for (ImVar field : c.getFields()) {
1✔
522
            initialFieldValues.add(
1✔
523
                LuaAst.LuaTableNamedField(field.getName(), defaultValue(field.getType()))
1✔
524
            );
525
        }
1✔
526

527

528
        body.add(newInst);
1✔
529
        // setmetatable(new_inst, {__index = classVar})
530
        body.add(LuaAst.LuaExprFunctionCallByName("setmetatable", LuaAst.LuaExprlist(
1✔
531
            LuaAst.LuaExprVarAccess(newInst),
1✔
532
            LuaAst.LuaTableConstructor(LuaAst.LuaTableFields(
1✔
533
                LuaAst.LuaTableNamedField("__index", LuaAst.LuaExprVarAccess(classVar))
1✔
534
            ))
535
        )));
536
        body.add(LuaAst.LuaReturn(LuaAst.LuaExprVarAccess(newInst)));
1✔
537
    }
1✔
538

539
    private void initClassTables(ImClass c) {
540
        LuaVariable classVar = luaClassVar.getFor(c);
1✔
541
        // create methods:
542
        Set<String> methods = new HashSet<>();
1✔
543
        createMethods(c, classVar, methods);
1✔
544

545
        // set supertype metadata:
546
        LuaTableFields superClasses = LuaAst.LuaTableFields();
1✔
547
        collectSuperClasses(superClasses, c, new HashSet<>());
1✔
548
        luaModel.add(LuaAst.LuaAssignment(LuaAst.LuaExprFieldAccess(
1✔
549
            LuaAst.LuaExprVarAccess(classVar),
1✔
550
            WURST_SUPERTYPES),
551
            LuaAst.LuaTableConstructor(superClasses)
1✔
552
        ));
553

554
        // set typeid metadata:
555
        luaModel.add(LuaAst.LuaAssignment(LuaAst.LuaExprFieldAccess(
1✔
556
            LuaAst.LuaExprVarAccess(classVar),
1✔
557
            ExprTranslation.TYPE_ID),
558
            LuaAst.LuaExprIntVal("" + prog.attrTypeId().get(c))
1✔
559
        ));
560

561

562
    }
1✔
563

564
    private void createMethods(ImClass c, LuaVariable classVar, Set<String> methods) {
565
        for (ImMethod method : c.getMethods()) {
1✔
566
            if (methods.contains(method.getName())) {
1✔
567
                continue;
1✔
568
            }
569
            methods.add(method.getName());
1✔
570
            if (method.getIsAbstract()) {
1✔
571
                continue;
1✔
572
            }
573
            luaModel.add(LuaAst.LuaAssignment(LuaAst.LuaExprFieldAccess(
1✔
574
                LuaAst.LuaExprVarAccess(classVar),
1✔
575
                method.getName()),
1✔
576
                LuaAst.LuaExprFuncRef(luaFunc.getFor(method.getImplementation()))
1✔
577
            ));
578
        }
1✔
579
        // also create links for inherited methods
580
        for (ImClassType sc : c.getSuperClasses()) {
1✔
581
            createMethods(sc.getClassDef(), classVar, methods);
1✔
582
        }
1✔
583
    }
1✔
584

585
    @NotNull
586
    private LuaTableConstructor emptyTable() {
587
        return LuaAst.LuaTableConstructor(LuaAst.LuaTableFields());
1✔
588
    }
589

590
    private void collectSuperClasses(LuaTableFields superClasses, ImClass c, Set<ImClass> visited) {
591
        if (visited.contains(c)) {
1✔
592
            return;
×
593
        }
594
        superClasses.add(LuaAst.LuaTableExprField(LuaAst.LuaExprVarAccess(luaClassVar.getFor(c)), LuaAst.LuaExprBoolVal(true)));
1✔
595
        visited.add(c);
1✔
596
        for (ImClassType sc : c.getSuperClasses()) {
1✔
597
            collectSuperClasses(superClasses, sc.getClassDef(), visited);
1✔
598
        }
1✔
599
    }
1✔
600

601

602
    private void translateGlobal(ImVar v) {
603
        if (v.getIsBJ()) {
1✔
604
            // do not translate blizzard variables
605
            return;
1✔
606
        }
607
        LuaVariable lv = luaVar.getFor(v);
1✔
608
        lv.setInitialValue(defaultValue(v.getType()));
1✔
609
        luaModel.add(lv);
1✔
610
    }
1✔
611

612
    private LuaExpr defaultValue(ImType type) {
613
        return type.match(new ImType.Matcher<LuaExpr>() {
1✔
614
            @Override
615
            public LuaExpr case_ImAnyType(ImAnyType imAnyType) {
616
                return LuaAst.LuaExprNull();
×
617
            }
618

619
            @Override
620
            public LuaExpr case_ImTupleType(ImTupleType tt) {
621
                LuaTableFields tableFields = LuaAst.LuaTableFields();
1✔
622
                for (int i = 0; i < tt.getNames().size(); i++) {
1✔
623
                    tableFields.add(LuaAst.LuaTableSingleField(defaultValue(tt.getTypes().get(i))));
1✔
624
                }
625
                return LuaAst.LuaTableConstructor(
1✔
626
                    tableFields
627
                );
628
            }
629

630
            @Override
631
            public LuaExpr case_ImVoid(ImVoid imVoid) {
632
                return LuaAst.LuaExprNull();
×
633
            }
634

635
            @Override
636
            public LuaExpr case_ImClassType(ImClassType imClassType) {
637
                return LuaAst.LuaExprNull();
1✔
638
            }
639

640
            @Override
641
            public LuaExpr case_ImArrayTypeMulti(ImArrayTypeMulti at) {
642
                ImType baseType;
643
                if (at.getArraySize().size() <= 1) {
1✔
644
                    baseType = at.getEntryType();
1✔
645
                } else {
646
                    List<Integer> arraySizes = new ArrayList<>(at.getArraySize());
×
647
                    arraySizes.remove(0);
×
648
                    baseType = JassIm.ImArrayTypeMulti(at.getEntryType(), arraySizes);
×
649
                }
650
                return LuaAst.LuaExprFunctionCall(arrayInitFunction,
1✔
651
                    LuaAst.LuaExprlist(
1✔
652
                        LuaAst.LuaExprFunctionAbstraction(LuaAst.LuaParams(),
1✔
653
                            LuaAst.LuaStatements(
1✔
654
                                LuaAst.LuaReturn(defaultValue(baseType))
1✔
655
                            )
656
                        )
657
                    ));
658
            }
659

660
            @Override
661
            public LuaExpr case_ImSimpleType(ImSimpleType st) {
662
                if (TypesHelper.isIntType(st)) {
1✔
663
                    return LuaAst.LuaExprIntVal("0");
1✔
664
                } else if (TypesHelper.isBoolType(st)) {
1✔
665
                    return LuaAst.LuaExprBoolVal(false);
1✔
666
                } else if (TypesHelper.isRealType(st)) {
1✔
667
                    return LuaAst.LuaExprRealVal("0.");
1✔
668
                }
669
                return LuaAst.LuaExprNull();
1✔
670
            }
671

672
            @Override
673
            public LuaExpr case_ImArrayType(ImArrayType imArrayType) {
674
                ImType baseType = imArrayType.getEntryType();
1✔
675
                return LuaAst.LuaExprFunctionCall(arrayInitFunction,
1✔
676
                    LuaAst.LuaExprlist(
1✔
677
                        LuaAst.LuaExprFunctionAbstraction(LuaAst.LuaParams(),
1✔
678
                            LuaAst.LuaStatements(
1✔
679
                                LuaAst.LuaReturn(defaultValue(baseType))
1✔
680
                            )
681
                        )
682
                    ));
683
            }
684

685
            @Override
686
            public LuaExpr case_ImTypeVarRef(ImTypeVarRef imTypeVarRef) {
687
                return LuaAst.LuaExprNull();
×
688
            }
689
        });
690
    }
691

692
    public LuaExprOpt translateOptional(ImExprOpt e) {
693
        if (e instanceof ImExpr) {
1✔
694
            ImExpr imExpr = (ImExpr) e;
1✔
695
            return imExpr.translateToLua(this);
1✔
696
        }
697
        return LuaAst.LuaNoExpr();
1✔
698
    }
699

700
    public LuaExprlist translateExprList(ImExprs exprs) {
701
        LuaExprlist r = LuaAst.LuaExprlist();
1✔
702
        for (ImExpr e : exprs) {
1✔
703
            r.add(e.translateToLua(this));
1✔
704
        }
1✔
705
        return r;
1✔
706
    }
707

708

709
    public int getTypeId(ImClass classDef) {
710
        return prog.attrTypeId().get(classDef);
×
711
    }
712

713

714
    public LuaFunction getErrorFunc() {
715
        return errorFunc.get();
1✔
716
    }
717
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc