From 66258b8d0ba82c16e444e649994e65edf89647db Mon Sep 17 00:00:00 2001 From: Mike Barry Date: Fri, 8 Dec 2023 07:15:03 -0500 Subject: [PATCH] fix casing --- .../experimental/lua/GenerateLuaTypes.java | 30 +------- .../experimental/lua/JavaToLuaCase.java | 71 +++++++++++++++++++ .../experimental/lua/LuaConversions.java | 6 -- .../java/org/luaj/vm2/lib/jse/JavaClass.java | 13 +--- .../lua/GenerateLuaTypesTest.java | 15 ++++ .../experimental/lua/JavaToLuaCaseTest.java | 36 ++++++++++ .../experimental/lua/LuaEnvironmentTests.java | 14 ++++ 7 files changed, 139 insertions(+), 46 deletions(-) create mode 100644 planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCase.java create mode 100644 planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCaseTest.java diff --git a/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypes.java b/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypes.java index 4c65af02..b2444b27 100644 --- a/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypes.java +++ b/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypes.java @@ -1,9 +1,9 @@ package com.onthegomap.planetiler.experimental.lua; +import static com.onthegomap.planetiler.experimental.lua.JavaToLuaCase.transformMemberName; import static java.util.Map.entry; import com.google.common.base.CaseFormat; -import com.google.common.base.Converter; import com.google.common.reflect.Invokable; import com.google.common.reflect.TypeToken; import com.onthegomap.planetiler.util.Format; @@ -24,9 +24,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -81,8 +79,6 @@ public class GenerateLuaTypes { entry(Void.class, "nil"), entry(void.class, "nil") ); - private static final Converter CAMEL_TO_SNAKE_CASE = - CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_UNDERSCORE); private static final TypeToken> LIST_TYPE = new TypeToken<>() {}; private static final TypeToken> MAP_TYPE = new TypeToken<>() {}; private final Deque debugStack = new LinkedList<>(); @@ -127,30 +123,6 @@ public class GenerateLuaTypes { } } - private static String transformMemberName(String fieldName) { - if (isLowerCamelCase(fieldName)) { - fieldName = CAMEL_TO_SNAKE_CASE.convert(fieldName); - } - if (LuaConversions.LUA_KEYWORDS.contains(fieldName)) { - fieldName = Objects.requireNonNull(fieldName).toUpperCase(Locale.ROOT); - } - return fieldName; - } - - private static boolean isLowerCamelCase(String fieldName) { - var chars = fieldName.toCharArray(); - if (!Character.isLowerCase(chars[0])) { - return false; - } - boolean upper = false, lower = false, underscore = false; - for (char c : chars) { - upper |= Character.isUpperCase(c); - lower |= Character.isLowerCase(c); - underscore |= c == '_'; - } - return upper && lower && !underscore; - } - private void write(String line) { builder.append(line).append(NEWLINE); } diff --git a/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCase.java b/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCase.java new file mode 100644 index 00000000..18f445ca --- /dev/null +++ b/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCase.java @@ -0,0 +1,71 @@ +package com.onthegomap.planetiler.experimental.lua; + +import static java.lang.Character.isDigit; +import static java.lang.Character.isLowerCase; +import static java.lang.Character.isUpperCase; + +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * Converts conventional javaMemberNames to lua_member_names, and lua keywords to uppercase. + */ +public class JavaToLuaCase { + public static final Set LUA_KEYWORDS = Set.of( + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", + "repeat", "return", "then", "true", "until", "while" + ); + private static final String LOWER = "[a-z]"; + private static final String DIGIT = "\\d"; + private static final String UPPER = "[A-Z]"; + private static final String UPPER_OR_DIGIT = "[" + UPPER + DIGIT + "]"; + private static final List BOUNDARIES = List.of( + // getUTF8string -> get_utf8_string + new Boundary(DIGIT, LOWER), + // fooBar -> foo_bar + new Boundary(LOWER, UPPER), + // ASCIIString -> ascii_string, UTF8String -> utf8_string + new Boundary(UPPER_OR_DIGIT, UPPER + LOWER) + ); + private static final List BOUNDARY_PATTERNS = BOUNDARIES.stream() + .map(b -> Pattern.compile("(" + b.prev + ")(" + b.next + ")")) + .toList(); + + public static boolean isLowerCamelCase(String fieldName) { + var chars = fieldName.toCharArray(); + if (!isLowerCase(chars[0])) { + return false; + } + boolean upper = false, lower = false, underscore = false; + for (char c : chars) { + upper |= isUpperCase(c) || isDigit(c); + lower |= isLowerCase(c); + underscore |= c == '_'; + } + return upper && lower && !underscore; + } + + public static String transformMemberName(String fieldName) { + if (isLowerCamelCase(fieldName)) { + fieldName = camelToSnake(fieldName); + } + if (LUA_KEYWORDS.contains(fieldName)) { + fieldName = Objects.requireNonNull(fieldName).toUpperCase(Locale.ROOT); + } + return fieldName; + } + + private static String camelToSnake(String fieldName) { + for (Pattern pattern : BOUNDARY_PATTERNS) { + fieldName = pattern.matcher(fieldName).replaceAll("$1_$2"); + } + return fieldName.toLowerCase(); + } + + private record Boundary(String prev, String next) {} +} diff --git a/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/LuaConversions.java b/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/LuaConversions.java index 8517323a..8dd7e416 100644 --- a/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/LuaConversions.java +++ b/planetiler-experimental/src/main/java/com/onthegomap/planetiler/experimental/lua/LuaConversions.java @@ -22,12 +22,6 @@ import org.luaj.vm2.lib.jse.CoerceLuaToJava; * Helper methods to convert between lua and java types. */ public interface LuaConversions { - Set LUA_KEYWORDS = Set.of( - "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "if", - "in", "local", "nil", "not", "or", - "repeat", "return", "then", "true", "until", "while" - ); static LuaValue toLua(Object sourceFeature) { return CoerceJavaToLua.coerce(sourceFeature); diff --git a/planetiler-experimental/src/main/java/org/luaj/vm2/lib/jse/JavaClass.java b/planetiler-experimental/src/main/java/org/luaj/vm2/lib/jse/JavaClass.java index e1d5fa29..d3eeac8f 100644 --- a/planetiler-experimental/src/main/java/org/luaj/vm2/lib/jse/JavaClass.java +++ b/planetiler-experimental/src/main/java/org/luaj/vm2/lib/jse/JavaClass.java @@ -21,9 +21,7 @@ ******************************************************************************/ package org.luaj.vm2.lib.jse; -import com.google.common.base.CaseFormat; -import com.google.common.base.Converter; -import com.onthegomap.planetiler.experimental.lua.LuaConversions; +import com.onthegomap.planetiler.experimental.lua.JavaToLuaCase; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InaccessibleObjectException; @@ -57,8 +55,6 @@ import org.luaj.vm2.LuaValue; * @see CoerceLuaToJava */ public class JavaClass extends JavaInstance { - private static final Converter CAMEL_TO_SNAKE_CASE = - CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_UNDERSCORE); static final Map, JavaClass> classes = new ConcurrentHashMap<>(); @@ -174,12 +170,7 @@ public class JavaClass extends JavaInstance { private void putAliases(Map map) { for (var entry : List.copyOf(map.entrySet())) { String key = entry.getKey().tojstring(); - String key2; - if (LuaConversions.LUA_KEYWORDS.contains(key)) { - key2 = key.toUpperCase(); - } else { - key2 = CAMEL_TO_SNAKE_CASE.convert(key); - } + String key2 = JavaToLuaCase.transformMemberName(key); map.putIfAbsent(LuaValue.valueOf(key2), entry.getValue()); } } diff --git a/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypesTest.java b/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypesTest.java index 925b3657..940244d9 100644 --- a/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypesTest.java +++ b/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/GenerateLuaTypesTest.java @@ -487,6 +487,21 @@ class GenerateLuaTypesTest { UsesPath.class); } + @Test + void testAbbreviationInName() { + interface Test { + + int setSRID(Integer n); + } + assertGenerated(""" + ---@class (exact) com_onthegomap_planetiler_experimental_lua_GenerateLuaTypesTest_2Test + types.com_onthegomap_planetiler_experimental_lua_GenerateLuaTypesTest_2Test = {} + ---@param n integer + ---@return integer + function types.com_onthegomap_planetiler_experimental_lua_GenerateLuaTypesTest_2Test:set_srid(n) end + """, Test.class); + } + @Test void testGeneratedMetaFileCompiles() { String types = new GenerateLuaTypes().generatePlanetiler().toString(); diff --git a/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCaseTest.java b/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCaseTest.java new file mode 100644 index 00000000..92c53a18 --- /dev/null +++ b/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/JavaToLuaCaseTest.java @@ -0,0 +1,36 @@ +package com.onthegomap.planetiler.experimental.lua; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class JavaToLuaCaseTest { + @ParameterizedTest + @CsvSource({ + "foo, foo", + "Foo, Foo", + "fooBar, foo_bar", + "FooBar, FooBar", + "foo_bar, foo_bar", + "foo_BAR, foo_BAR", + "FOO_BAR, FOO_BAR", + "fooBAR, foo_bar", + "getISO3Code, get_iso3_code", + "utf8string, utf8_string", + "arg0, arg0", + "arg10, arg10", + "utf8String, utf8_string", + "getUTF8String, get_utf8_string", + "getUTF8string, get_utf8_string", + "getUTF8ASCIIString, get_utf8ascii_string", + "iso31661Alpha2, iso31661_alpha2", + "getUTF8At0, get_utf8_at0", + "distance3D, distance3d", + "toASCIIString, to_ascii_string", + "and, AND", + }) + void testConversions(String input, String expectedOutput) { + assertEquals(expectedOutput, JavaToLuaCase.transformMemberName(input)); + } +} diff --git a/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/LuaEnvironmentTests.java b/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/LuaEnvironmentTests.java index 60ae0da2..71d97839 100644 --- a/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/LuaEnvironmentTests.java +++ b/planetiler-experimental/src/test/java/com/onthegomap/planetiler/experimental/lua/LuaEnvironmentTests.java @@ -780,6 +780,20 @@ class LuaEnvironmentTests { assertConvertsTo(1, env.main.call()); } + @Test + void testAbbreviation() { + var env = load(""" + function main() + return obj:set_srid(1) + end + """, Map.of("obj", new Object() { + public int setSRID(int a) { + return a + 1; + } + })); + assertConvertsTo(2, env.main.call()); + } + @Test void testEnum() { enum MyEnum {