Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class LuaTranslator {
private final Set<String> usedNames = new HashSet<>(Arrays.asList(
// reserved function names
"print", "tostring", "error",
"main", "config",
// keywords:
"and",
"break",
Expand Down Expand Up @@ -74,8 +75,10 @@ public LuaVariable initFor(ImVar a) {
@Override
public LuaFunction initFor(ImFunction a) {
String name = a.getName();
if (!a.isExtern() && !a.isBj() && !a.isNative()) {
if (!a.isExtern() && !a.isBj() && !a.isNative() && !isFixedEntryPoint(a)) {
name = uniqueName(name);
} else if (isFixedEntryPoint(a)) {
usedNames.add(name);
}

LuaFunction lf = LuaAst.LuaFunction(name, LuaAst.LuaParams(), LuaAst.LuaStatements());
Expand Down Expand Up @@ -178,6 +181,7 @@ public LuaCompilationUnit translate() {


normalizeMethodNames();
normalizeFieldNames();

// NormalizeNames.normalizeNames(prog);

Expand Down Expand Up @@ -214,6 +218,10 @@ public LuaCompilationUnit translate() {
return luaModel;
}

private boolean isFixedEntryPoint(ImFunction function) {
return function == imTr.getMainFunc() || function == imTr.getConfFunc();
}

private void collectPredefinedNames() {
for (ImFunction function : prog.getFunctions()) {
if (function.isBj() || function.isExtern() || function.isNative()) {
Expand Down Expand Up @@ -258,6 +266,42 @@ private void normalizeMethodNames() {
}
}

private void normalizeFieldNames() {
for (ImClass c : prog.getClasses()) {
Set<String> methodNames = new HashSet<>();
collectMethodNames(c, methodNames, new HashSet<>());
if (methodNames.isEmpty()) {
continue;
}
Set<String> reserved = new HashSet<>(methodNames);
for (ImVar field : c.getFields()) {
if (reserved.contains(field.getName())) {
String base = field.getName() + "_field";
String candidate = base;
int i = 1;
while (reserved.contains(candidate)) {
candidate = base + i++;
}
field.setName(candidate);
}
reserved.add(field.getName());
}
}
}

private void collectMethodNames(ImClass c, Set<String> methodNames, Set<ImClass> visited) {
if (visited.contains(c)) {
return;
}
visited.add(c);
for (ImMethod method : c.getMethods()) {
methodNames.add(method.getName());
}
for (ImClassType sc : c.getSuperClasses()) {
collectMethodNames(sc.getClassDef(), methodNames, visited);
}
}

private void createStringConcatFunction() {
String[] code = {
"if x then",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ private void assertFunctionCall(String output, String functionName, String argum
private void assertFunctionBodyContains(String output, String functionName, String search, boolean mustContain) {
Pattern pattern = Pattern.compile("function\\s*" + functionName + "\\s*\\(.*\\).*\\n" + "((?:\\n|.)*?)end");
Matcher matcher = pattern.matcher(output);
boolean found = false;
while (matcher.find()) {
found = true;
String body = matcher.group(1);
if(!body.contains(search) && mustContain) {
fail("Function " + functionName + " must contain " + search + ".");
Expand All @@ -52,6 +54,7 @@ private void assertFunctionBodyContains(String output, String functionName, Stri
fail("Function " + functionName + " must not contain " + search + ".");
}
}
assertTrue("Function " + functionName + " was not found.", found);
}

@Test
Expand Down Expand Up @@ -191,6 +194,46 @@ public void stringConcatenation() throws IOException {
assertFunctionBodyContains(compiled, "test", "stringConcat", true);
}

@Test
public void methodFieldNameCollision() throws IOException {
test().testLua(true).lines(
"package Test",
"class Foo",
" int size = 3",
" function size() returns int",
" return size",
"init",
" let f = new Foo()",
" f.size()"
);
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_methodFieldNameCollision.lua"), Charsets.UTF_8);
assertFunctionBodyContains(compiled, "Foo_Foo_size", "Foo_size_field", true);
assertFunctionBodyContains(compiled, "Foo_Foo_size", "return this.Foo_size\n", false);
}

@Test
public void mainAndConfigNamesFixed() throws IOException {
test().testLua(true).lines(
"package Test",
"native takesInt(int i)",
"function helper()",
" let main = 1",
" let config = 2",
" takesInt(main)",
" takesInt(config)",
"init",
" helper()"
);
String compiled = Files.toString(new File("test-output/lua/LuaTranslationTests_mainAndConfigNamesFixed.lua"), Charsets.UTF_8);
assertFunctionBodyContains(compiled, "helper", "local main1", true);
assertFunctionBodyContains(compiled, "helper", "local config1", true);
assertTrue(compiled.contains("function main("));
assertTrue(compiled.contains("function config("));
assertFalse(compiled.contains("function main2("));
assertFalse(compiled.contains("function config2("));
}


@Test
public void intCasting() throws IOException {
// Use local variables to test if it works even when local types are eliminated.
Expand Down Expand Up @@ -234,4 +277,3 @@ public void intCasting() throws IOException {
assertFunctionBodyContains(compiled, "testClass", "cObj2 = cInt", false);
}
}

Loading