Skip to content

Commit e76d739

Browse files
committed
Merge branch 'lua'
2 parents 77e4994 + cd29808 commit e76d739

File tree

22 files changed

+1418
-821
lines changed

22 files changed

+1418
-821
lines changed

de.peeeq.wurstscript/parserspec/jass_im.parseq

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ ImType =
2727
| ImVoid()
2828
| ImClassType(ref ImClass classDef, ImTypeArguments typeArguments)
2929
| ImTypeVarRef(ref ImTypeVar typeVariable)
30+
| ImAnyType()
3031

3132
ImTypeVars * ImTypeVar
3233

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/ConfigProvider.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.peeeq.wurstio.languageserver;
22

33
import com.google.gson.JsonElement;
4+
import com.google.gson.JsonNull;
45
import com.google.gson.JsonObject;
56
import de.peeeq.wurstscript.WLogger;
67
import org.eclipse.lsp4j.ConfigurationItem;
@@ -16,7 +17,7 @@
1617
*
1718
*/
1819
public class ConfigProvider {
19-
private final LanguageClient languageClient;
20+
private final LanguageClient languageClient;
2021

2122
public ConfigProvider(LanguageClient languageClient) {
2223
this.languageClient = languageClient;
@@ -32,7 +33,9 @@ public String getConfig(String key, String defaultValue) {
3233
if (c instanceof JsonObject) {
3334
JsonObject cfg = (JsonObject) c;
3435
JsonElement result = cfg.get(key);
35-
if (result != null) {
36+
if (result instanceof JsonNull) {
37+
return null;
38+
} else if (result != null) {
3639
return result.getAsString();
3740
}
3841
}
@@ -46,6 +49,13 @@ public String getConfig(String key, String defaultValue) {
4649
public String getJhcrExe() {
4750
return getConfig("jhcrExe", "jhcr.exe");
4851
}
52+
53+
/**
54+
* The path where to put maps before running them
55+
*/
56+
public String getMapDocumentPath() {
57+
return getConfig("mapDocumentPath", null);
58+
}
4959
}
5060

5161

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/MapRequest.java

Lines changed: 83 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import de.peeeq.wurstscript.gui.WurstGui;
2121
import de.peeeq.wurstscript.jassAst.JassProg;
2222
import de.peeeq.wurstscript.jassprinter.JassPrinter;
23+
import de.peeeq.wurstscript.luaAst.LuaCompilationUnit;
2324
import de.peeeq.wurstscript.parser.WPos;
25+
import de.peeeq.wurstscript.translation.lua.printing.LuaPrinter;
2426
import de.peeeq.wurstscript.utils.LineOffsets;
2527
import de.peeeq.wurstscript.utils.Utils;
2628
import org.eclipse.lsp4j.MessageParams;
@@ -45,7 +47,8 @@
4547

4648
public abstract class MapRequest extends UserRequest<Object> {
4749
protected final ConfigProvider configProvider;
48-
protected final @Nullable File map;
50+
protected final @Nullable
51+
File map;
4952
protected final List<String> compileArgs;
5053
protected final WFile workspaceRoot;
5154
protected final RunArgs runArgs;
@@ -88,23 +91,35 @@ protected void processMapScript(RunArgs runArgs, WurstGui gui, ModelManager mode
8891
return;
8992
} else {
9093
throw new CompileError(new WPos("", new LineOffsets(), 0, 0),
91-
"RunArg noExtractMapScript is set but no mapscript is provided inside the wurst folder");
94+
"RunArg noExtractMapScript is set but no mapscript is provided inside the wurst folder");
9295
}
9396
}
9497
WLogger.info("extracting mapscript");
95-
byte[] extractedScript;
98+
byte[] extractedScript = null;
9699
try (MpqEditor mpqEditor = MpqEditorFactory.getEditor(mapCopy)) {
97-
extractedScript = mpqEditor.extractFile("war3map.j");
100+
if (mpqEditor.hasFile("war3map.j")) {
101+
extractedScript = mpqEditor.extractFile("war3map.j");
102+
}
98103
}
99-
if (new String(extractedScript, StandardCharsets.UTF_8).startsWith(JassPrinter.WURST_COMMENT_RAW)) {
104+
if (extractedScript == null) {
105+
if (existingScript.exists()) {
106+
String msg = "No war3map.j in map file, using old extracted file";
107+
WLogger.info(msg);
108+
} else {
109+
CompileError err = new CompileError(new WPos(mapCopy.toString(), new LineOffsets(), 0, 0),
110+
"No war3map.j found in map file.");
111+
gui.showInfoMessage(err.getMessage());
112+
WLogger.severe(err);
113+
}
114+
} else if (new String(extractedScript, StandardCharsets.UTF_8).startsWith(JassPrinter.WURST_COMMENT_RAW)) {
100115
WLogger.info("map has already been compiled with wurst");
101116
// file generated by wurst, do not use
102117
if (existingScript.exists()) {
103-
WLogger.info(
104-
"Cannot use war3map.j from map file, because it already was compiled with wurst. " + "Using war3map.j from Wurst directory instead.");
118+
String msg = "Cannot use war3map.j from map file, because it already was compiled with wurst. " + "Using war3map.j from Wurst directory instead.";
119+
WLogger.info(msg);
105120
} else {
106121
CompileError err = new CompileError(new WPos(mapCopy.toString(), new LineOffsets(), 0, 0),
107-
"Cannot use war3map.j from map file, because it already was compiled with wurst. " + "Please add war3map.j to the wurst directory.");
122+
"Cannot use war3map.j from map file, because it already was compiled with wurst. " + "Please add war3map.j to the wurst directory.");
108123
gui.showInfoMessage(err.getMessage());
109124
WLogger.severe(err);
110125
}
@@ -124,7 +139,7 @@ protected File compileMap(File projectFolder, WurstGui gui, File mapCopy, RunArg
124139
//WurstGui gui = new WurstGuiLogger();
125140
if (mpqEditor != null && !mpqEditor.canWrite()) {
126141
WLogger.severe("The supplied map is invalid/corrupted/protected and Wurst cannot write to it.\n" +
127-
"Please supply a valid .w3x input map that can be opened in the world editor.");
142+
"Please supply a valid .w3x input map that can be opened in the world editor.");
128143
throw new NonWritableChannelException();
129144
}
130145
WurstCompilerJassImpl compiler = new WurstCompilerJassImpl(projectFolder, gui, mpqEditor, runArgs);
@@ -148,39 +163,60 @@ protected File compileMap(File projectFolder, WurstGui gui, File mapCopy, RunArg
148163

149164
compiler.runCompiletime();
150165

151-
print("translating program to jass ... ");
152-
compiler.transformProgToJass();
166+
if (runArgs.isLua()) {
167+
print("translating program to Lua ... ");
168+
LuaCompilationUnit luaCode = compiler.transformProgToLua();
153169

154-
JassProg jassProg = compiler.getProg();
155-
if (jassProg == null) {
156-
print("Could not compile project\n");
157-
throw new RuntimeException("Could not compile project (error in JASS translation)");
158-
}
170+
if (luaCode == null) {
171+
print("Could not compile project\n");
172+
throw new RuntimeException("Could not compile project (error in LUA translation)");
173+
}
174+
175+
StringBuilder sb = new StringBuilder();
176+
luaCode.print(sb, 0);
159177

160-
gui.sendProgress("Printing program");
161-
JassPrinter printer = new JassPrinter(!runArgs.isOptimize(), jassProg);
162-
String compiledMapScript = printer.printProg();
163-
164-
File buildDir = getBuildDir();
165-
File outFile = new File(buildDir, "compiled.j.txt");
166-
Files.write(compiledMapScript.getBytes(Charsets.UTF_8), outFile);
167-
168-
if (!runArgs.isDisablePjass()) {
169-
gui.sendProgress("Running PJass");
170-
Pjass.Result pJassResult = Pjass.runPjass(outFile);
171-
WLogger.info(pJassResult.getMessage());
172-
if (!pJassResult.isOk()) {
173-
for (CompileError err : pJassResult.getErrors()) {
174-
gui.sendError(err);
178+
String compiledMapScript = sb.toString();
179+
File buildDir = getBuildDir();
180+
File outFile = new File(buildDir, "compiled.lua");
181+
Files.write(compiledMapScript.getBytes(Charsets.UTF_8), outFile);
182+
return outFile;
183+
184+
} else {
185+
print("translating program to jass ... ");
186+
compiler.transformProgToJass();
187+
188+
JassProg jassProg = compiler.getProg();
189+
if (jassProg == null) {
190+
print("Could not compile project\n");
191+
throw new RuntimeException("Could not compile project (error in JASS translation)");
192+
}
193+
194+
gui.sendProgress("Printing program");
195+
JassPrinter printer = new JassPrinter(!runArgs.isOptimize(), jassProg);
196+
String compiledMapScript = printer.printProg();
197+
File buildDir = getBuildDir();
198+
File outFile = new File(buildDir, "compiled.j.txt");
199+
Files.write(compiledMapScript.getBytes(Charsets.UTF_8), outFile);
200+
201+
if (!runArgs.isDisablePjass()) {
202+
gui.sendProgress("Running PJass");
203+
Pjass.Result pJassResult = Pjass.runPjass(outFile);
204+
WLogger.info(pJassResult.getMessage());
205+
if (!pJassResult.isOk()) {
206+
for (CompileError err : pJassResult.getErrors()) {
207+
gui.sendError(err);
208+
}
209+
return null;
175210
}
176-
return null;
177211
}
212+
213+
if (runArgs.isHotStartmap()) {
214+
gui.sendProgress("Running JHCR");
215+
return runJassHotCodeReload(outFile);
216+
}
217+
return outFile;
178218
}
179-
if (runArgs.isHotStartmap()) {
180-
gui.sendProgress("Running JHCR");
181-
return runJassHotCodeReload(outFile);
182-
}
183-
return outFile;
219+
184220
} catch (Exception e) {
185221
throw new RuntimeException(e);
186222
}
@@ -214,7 +250,7 @@ private File runJassHotCodeReload(File mapScript) throws IOException, Interrupte
214250
private void purgeUnimportedFiles(WurstModel model) {
215251

216252
Set<CompilationUnit> imported = model.stream()
217-
.filter(cu -> isInWurstFolder(cu.getCuInfo().getFile()) || cu.getCuInfo().getFile().endsWith(".j")).distinct().collect(Collectors.toSet());
253+
.filter(cu -> isInWurstFolder(cu.getCuInfo().getFile()) || cu.getCuInfo().getFile().endsWith(".j")).distinct().collect(Collectors.toSet());
218254
addImports(imported, imported);
219255

220256
model.removeIf(cu -> !imported.contains(cu));
@@ -229,8 +265,8 @@ private boolean isInWurstFolder(String file) {
229265
return false;
230266
}
231267
return p.startsWith(w)
232-
&& java.nio.file.Files.exists(p)
233-
&& Utils.isWurstFile(file);
268+
&& java.nio.file.Files.exists(p)
269+
&& Utils.isWurstFile(file);
234270
}
235271

236272
protected File getBuildDir() {
@@ -248,13 +284,13 @@ protected File getBuildDir() {
248284

249285
private void addImports(Set<CompilationUnit> result, Set<CompilationUnit> toAdd) {
250286
Set<CompilationUnit> imported =
251-
toAdd.stream()
252-
.flatMap((CompilationUnit cu) -> cu.getPackages().stream())
253-
.flatMap((WPackage p) -> p.getImports().stream())
254-
.map(WImport::attrImportedPackage)
255-
.filter(Objects::nonNull)
256-
.map(WPackage::attrCompilationUnit)
257-
.collect(Collectors.toSet());
287+
toAdd.stream()
288+
.flatMap((CompilationUnit cu) -> cu.getPackages().stream())
289+
.flatMap((WPackage p) -> p.getImports().stream())
290+
.map(WImport::attrImportedPackage)
291+
.filter(Objects::nonNull)
292+
.map(WPackage::attrCompilationUnit)
293+
.collect(Collectors.toSet());
258294
boolean changed = result.addAll(imported);
259295
if (changed) {
260296
// recursive call terminates, as there are only finitely many compilation units

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/languageserver/requests/RunMap.java

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@
99
import de.peeeq.wurstio.mpq.MpqEditor;
1010
import de.peeeq.wurstio.mpq.MpqEditorFactory;
1111
import de.peeeq.wurstio.utils.W3Utils;
12-
import de.peeeq.wurstscript.RunArgs;
1312
import de.peeeq.wurstscript.WLogger;
14-
import de.peeeq.wurstscript.ast.CompilationUnit;
15-
import de.peeeq.wurstscript.ast.WurstModel;
1613
import de.peeeq.wurstscript.attributes.CompileError;
1714
import de.peeeq.wurstscript.gui.WurstGui;
1815
import de.peeeq.wurstscript.utils.Utils;
19-
import de.peeeq.wurstscript.utils.WinRegistry;
2016
import net.moonlightflower.wc3libs.bin.GameExe;
2117
import org.eclipse.lsp4j.MessageType;
2218
import org.jetbrains.annotations.NotNull;
@@ -84,10 +80,7 @@ public Object execute(ModelManager modelManager) {
8480
// call jhcr update
8581
gui.sendProgress("Calling JHCR update");
8682
callJhcrUpdate(compiledScript);
87-
}
88-
8983

90-
if (runArgs.isHotReload()) {
9184
// if we are just reloading the mapscript with JHCR, we are done here
9285
gui.sendProgress("update complete");
9386
return "ok";
@@ -100,8 +93,16 @@ public Object execute(ModelManager modelManager) {
10093
// then inject the script into the map
10194
gui.sendProgress("Injecting mapscript");
10295
try (MpqEditor mpqEditor = MpqEditorFactory.getEditor(testMap)) {
96+
String mapScriptName;
97+
if (runArgs.isLua()) {
98+
mapScriptName = "war3map.lua";
99+
} else {
100+
mapScriptName = "war3map.j";
101+
}
102+
// delete both original mapscripts, just to be sure:
103103
mpqEditor.deleteFile("war3map.j");
104-
mpqEditor.insertFile("war3map.j", compiledScript);
104+
mpqEditor.deleteFile("war3map.lua");
105+
mpqEditor.insertFile(mapScriptName, compiledScript);
105106
}
106107

107108

@@ -122,7 +123,7 @@ public Object execute(ModelManager modelManager) {
122123
if (W3Utils.getWc3PatchVersion() == null) {
123124
throw new RequestFailedException(MessageType.Error, wc3Path + " does not exist.");
124125
}
125-
List<String> cmd = Lists.newArrayList(gameExe.getAbsolutePath(), "-window", "-loadfile", path);
126+
List<String> cmd = Lists.newArrayList(gameExe.getAbsolutePath(), "-loadfile", path);
126127

127128
if (!System.getProperty("os.name").startsWith("Windows")) {
128129
// run with wine
@@ -235,32 +236,9 @@ private File copyToWarcraftMapDir(File testMap) throws IOException {
235236
}
236237
}
237238
}
238-
File myDocumentsFolder = FileSystemView.getFileSystemView().getDefaultDirectory();
239-
String documentPath = myDocumentsFolder.getAbsolutePath() + File.separator + "Warcraft III";
240-
if (!new File(documentPath).exists()) {
241-
WLogger.info("Warcraft folder " + documentPath + " does not exist.");
242-
// Try wine default:
243-
documentPath = System.getProperty("user.home")
244-
+ "/.wine/drive_c/users/" + System.getProperty("user.name") + "/My Documents/Warcraft III";
245-
if (!new File(documentPath).exists()) {
246-
WLogger.severe("Severe: Wine Warcraft folder " + documentPath + " does not exist.");
247-
}
248-
}
249239

250-
251-
if (W3Utils.getWc3PatchVersion().compareTo(new GameExe.Version("1.27.9")) <= 0) {
252-
// 1.27 and lower compat
253-
WLogger.info("Version 1.27 or lower detected, changing file location");
254-
documentPath = wc3Path;
255-
} else {
256-
// For 1.28+ the wc3/maps/test folder must not contain a map of the same name
257-
File oldFile = new File(wc3Path, "Maps" + File.separator + "Test" + File.separator + testMapName);
258-
if (oldFile.exists()) {
259-
if (!oldFile.delete()) {
260-
WLogger.severe("Cannot delete old Wurst Test Map");
261-
}
262-
}
263-
}
240+
File myDocumentsFolder = FileSystemView.getFileSystemView().getDefaultDirectory();
241+
String documentPath = findMapDocumentPath(testMapName, myDocumentsFolder);
264242

265243
// copy the map to the appropriate directory
266244
File testFolder = new File(documentPath, "Maps" + File.separator + "Test");
@@ -274,5 +252,37 @@ private File copyToWarcraftMapDir(File testMap) throws IOException {
274252
return null;
275253
}
276254

255+
private String findMapDocumentPath(String testMapName, File myDocumentsFolder) {
256+
String documentPath = configProvider.getMapDocumentPath();
257+
if (documentPath == null) {
258+
documentPath = myDocumentsFolder.getAbsolutePath() + File.separator + "Warcraft III";
259+
if (!new File(documentPath).exists()) {
260+
WLogger.info("Warcraft folder " + documentPath + " does not exist.");
261+
// Try wine default:
262+
documentPath = System.getProperty("user.home")
263+
+ "/.wine/drive_c/users/" + System.getProperty("user.name") + "/My Documents/Warcraft III";
264+
if (!new File(documentPath).exists()) {
265+
WLogger.severe("Severe: Wine Warcraft folder " + documentPath + " does not exist.");
266+
}
267+
}
268+
269+
270+
if (W3Utils.getWc3PatchVersion().compareTo(new GameExe.Version("1.27.9")) <= 0) {
271+
// 1.27 and lower compat
272+
WLogger.info("Version 1.27 or lower detected, changing file location");
273+
documentPath = wc3Path;
274+
} else {
275+
// For 1.28+ the wc3/maps/test folder must not contain a map of the same name
276+
File oldFile = new File(wc3Path, "Maps" + File.separator + "Test" + File.separator + testMapName);
277+
if (oldFile.exists()) {
278+
if (!oldFile.delete()) {
279+
WLogger.severe("Cannot delete old Wurst Test Map");
280+
}
281+
}
282+
}
283+
}
284+
return documentPath;
285+
}
286+
277287

278288
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtojass/DefaultValue.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,8 @@ public static ILconst get(ImTypeVarRef e) {
5454
public static ILconst get(ImClassType ct) {
5555
return new ILconstInt(0);
5656
}
57+
58+
public static ILconst get(ImAnyType imAnyType) {
59+
return ILconstNull.instance();
60+
}
5761
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtojass/ImAttributes.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,8 @@ public static String translateType(ImTypeVarRef t) {
125125
public static String translateType(ImClassType imClassType) {
126126
return "integer";
127127
}
128+
129+
public static String translateType(ImAnyType at) {
130+
return "integer";
131+
}
128132
}

0 commit comments

Comments
 (0)