• 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

92.41
de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/ModuleExpander.java
1
package de.peeeq.wurstscript;
2

3
import com.google.common.base.Preconditions;
4
import com.google.common.collect.Lists;
5
import de.peeeq.immutablecollections.ImmutableList;
6
import de.peeeq.wurstscript.ast.*;
7
import de.peeeq.wurstscript.attributes.CompileError;
8
import de.peeeq.wurstscript.parser.WPos;
9
import de.peeeq.wurstscript.types.WurstType;
10
import de.peeeq.wurstscript.utils.Pair;
11

12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.stream.Collectors;
15

16
public class ModuleExpander {
17

18
    private ModuleExpander() {
19
    }
20

21
    public static void expandModules(CompilationUnit cu) {
22
        for (WPackage t : cu.getPackages()) {
1✔
23
            expandModules(t);
1✔
24
        }
1✔
25
    }
1✔
26

27
    private static void expandModules(WPackage p) {
28
        for (WEntity e : p.getElements()) {
1✔
29
            if (e instanceof ClassOrModule) {
1✔
30
                expandModules((ClassOrModule) e);
1✔
31
            }
32
        }
1✔
33
    }
1✔
34

35
    public static ModuleInstanciations expandModules(ClassOrModule m) {
36
        return expandModules(m, new ArrayList<>());
1✔
37
    }
38

39
    private static ModuleInstanciations expandModules(ClassOrModule m, List<ClassOrModule> visited) {
40
        if (m.getP_moduleInstanciations().size() > 0 || m.getModuleUses().isEmpty()) {
1✔
41
            return m.getP_moduleInstanciations();
1✔
42
        }
43

44
        Preconditions.checkNotNull(m);
1✔
45
        if (visited.contains(m)) {
1✔
46
            throw new CompileError(m.getSource(), "Cyclic module dependencies: " +
×
47
                visited.stream().map(ClassOrModule::getName).sorted().collect(Collectors.joining(", ")));
×
48
        }
49
        visited.add(m);
1✔
50

51

52

53
        for (ModuleUse moduleUse : m.getModuleUses()) {
1✔
54
            ModuleDef usedModule = moduleUse.attrModuleDef();
1✔
55
            if (usedModule == null) {
1✔
56
                moduleUse.addError("not found");
1✔
57
                continue;
1✔
58
            }
59
            ModuleInstanciations usedModuleInst = expandModules(usedModule, visited);
1✔
60

61

62
            int numTypeArgs = moduleUse.getTypeArgs().size();
1✔
63
            if (numTypeArgs < usedModule.getTypeParameters().size()) {
1✔
64
                moduleUse.addError("Missing type arguments for module "
×
65
                        + moduleUse.getModuleName() + ".");
×
66
            } else if (numTypeArgs > usedModule.getTypeParameters().size()) {
1✔
67
                moduleUse.addError("Too many type arguments for module "
×
68
                        + moduleUse.getModuleName() + ".");
×
69
            }
70

71
            List<Pair<WurstType, WurstType>> typeReplacements = Lists.newArrayList();
1✔
72
            for (int i = 0; i < numTypeArgs; i++) {
1✔
73
                typeReplacements.add(Pair.create(usedModule.getTypeParameters().get(i).attrTyp(), moduleUse.getTypeArgs().get(i).attrTyp()));
1✔
74
            }
75

76
            WPos source = moduleUse.getSource().artificial();
1✔
77
            WPos idSource = moduleUse.getModuleNameId().getSource().artificial();
1✔
78
            ModuleInstanciation mi = Ast.ModuleInstanciation(source, Ast.Modifiers(),
1✔
79
                    Ast.Identifier(idSource, usedModule.getName()),
1✔
80
                    smartCopy(usedModule.getInnerClasses(), typeReplacements),
1✔
81
                    smartCopy(usedModule.getMethods(), typeReplacements),
1✔
82
                    smartCopy(usedModule.getVars(), typeReplacements),
1✔
83
                    smartCopy(usedModule.getConstructors(), typeReplacements),
1✔
84
                    smartCopy(usedModuleInst, typeReplacements),
1✔
85
                    smartCopy(usedModule.getModuleUses(), typeReplacements),
1✔
86
                    smartCopy(usedModule.getOnDestroy(), typeReplacements));
1✔
87

88
            if (mi.getConstructors().isEmpty()) {
1✔
89
                // add default constructor:
90
                mi.getConstructors().add(Ast.ConstructorDef(
1✔
91
                        source,
92
                        Ast.Modifiers(),
1✔
93
                        Ast.WParameters(),
1✔
94
                        Ast.NoSuperConstructorCall(),
1✔
95
                        Ast.WStatements(
1✔
96
                                Ast.StartFunctionStatement(source),
1✔
97
                                Ast.EndFunctionStatement(source)
1✔
98
                        )));
99
            }
100

101
            m.getP_moduleInstanciations().add(mi);
1✔
102

103
        }
1✔
104
        return m.getP_moduleInstanciations();
1✔
105
    }
106

107
    public static ModuleInstanciations expandModules(ModuleInstanciation mi) {
108
        return mi.getP_moduleInstanciations();
1✔
109
    }
110

111
    public static <T extends Element> T smartCopy(T e, List<Pair<WurstType, WurstType>> typeReplacements) {
112
        List<Pair<ImmutableList<Integer>, TypeExpr>> replacementsByPath = Lists.newArrayList();
1✔
113
        calcReplacementsByPath(typeReplacements, replacementsByPath, e, ImmutableList.emptyList());
1✔
114

115

116
        Element copy = e.copy();
1✔
117

118
        // Do the type replacements
119
        for (Pair<ImmutableList<Integer>, TypeExpr> rep : replacementsByPath) {
1✔
120
            doReplacement(copy, rep.getA(), rep.getB().copy());
1✔
121
        }
1✔
122

123
        @SuppressWarnings("unchecked")
124
        T t = (T) copy;
1✔
125
        return t;
1✔
126
    }
127

128
    private static void doReplacement(Element e, ImmutableList<Integer> a, TypeExpr newTypeExpr) {
129
        if (a.size() == 1) {
1✔
130
            e.set(a.head(), newTypeExpr);
1✔
131
        } else if (a.size() > 1) {
1✔
132
            doReplacement(e.get(a.head()), a.tail(), newTypeExpr);
1✔
133
        }
134
    }
1✔
135

136
    private static void calcReplacementsByPath(List<Pair<WurstType, WurstType>> typeReplacements, List<Pair<ImmutableList<Integer>, TypeExpr>> replacementsByPath, Element e, ImmutableList<Integer> pos) {
137
        if (e instanceof TypeExpr) {
1✔
138
            TypeExpr typeExpr = (TypeExpr) e;
1✔
139
            for (Pair<WurstType, WurstType> rep : typeReplacements) {
1✔
140
                if (typeExpr.attrTyp().equalsType(rep.getA(), e)) {
1✔
141
                    WPos source = typeExpr.getSource();
1✔
142
                    replacementsByPath.add(Pair.create(pos, Ast.TypeExprResolved(source, rep.getB())));
1✔
143
                }
144
            }
1✔
145
        }
146
        // children:
147
        for (int i = 0; i < e.size(); i++) {
1✔
148
            calcReplacementsByPath(typeReplacements, replacementsByPath, e.get(i), pos.appBack(i));
1✔
149
        }
150
    }
1✔
151

152
}
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