package decompsource.net.minecraftforge.gradle.extrastuff; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import immibis.bon.com.immibis.json.JsonReader; public class GLConstantFixer { private static final String[] PACKAGES = { "GL11", "GL12", "GL13", "GL14", "GL15", "GL20", "GL21", "ARBMultitexture", "ARBOcclusionQuery", "ARBVertexBufferObject", "ARBShaderObjects" }; private static final String join(String[] a, String delim) { StringBuilder sb = new StringBuilder(); for(int k = 0; k < a.length; k++) { if(k > 0) sb.append(delim); sb.append(a[k]); } return sb.toString(); } private final Object json; public static final Pattern CALL_REGEX = Pattern.compile("(" + join(PACKAGES,"|") + ")\\.([\\w]+)\\(.+\\)"); public static final Pattern CONSTANT_REGEX = Pattern.compile("(?<![-.\\w])\\d+(?![.\\w])"); private static final String ADD_AFTER = "org.lwjgl.opengl.GL11"; private static final String CHECK = "org.lwjgl.opengl."; private static final String IMPORT_CHECK = "import " + CHECK; private static final String IMPORT_REPLACE = "import " + ADD_AFTER + ";"; public GLConstantFixer() { try { try (Reader r = new InputStreamReader(GLConstantFixer.class.getResourceAsStream("gl.json"), StandardCharsets.UTF_8)) { json = JsonReader.readJSON(r); } } catch(IOException e) { throw new RuntimeException(e); } } public String fixOGL(String text) { // if it never uses openGL, ignore it. if (!text.contains(IMPORT_CHECK)) { return text; } text = annotateConstants(text); for (String pack : PACKAGES) { if (text.contains(pack + ".")) { text = updateImports(text, CHECK + pack); } } return text; } private String annotateConstants(String text) { Matcher rootMatch = CALL_REGEX.matcher(text); String pack, method, fullCall; StringBuffer out = new StringBuffer(text.length()); StringBuffer innerOut; // search with regex. while (rootMatch.find()) { // helper variables fullCall = rootMatch.group(); pack = rootMatch.group(1); method = rootMatch.group(2); Matcher constantMatcher = CONSTANT_REGEX.matcher(fullCall); innerOut = new StringBuffer(fullCall.length()); Map listNode; // search for hardcoded numbers while (constantMatcher.find()) { // helper variables and return variable. String constant = constantMatcher.group(); String answer = null; // iterrate over the JSON for (Object group : (List)json) { // the list part object listNode = (Map)((List)group).get(0); // ensure that the package and method are defined if (listNode.containsKey(pack) && jsonArrayContains((List)listNode.get(pack), method)) { // now the map part object listNode = (Map)((List)group).get(1); // itterrate through the map. for (Map.Entry<String, Map> entry : (Set<Map.Entry<String, Map>>)listNode.entrySet()) { // find the actual constant for the number from the regex if (entry.getValue().containsKey(constant)) { // construct the final line answer = entry.getKey() + "." + entry.getValue().get(constant); } } } } // replace the final line. if (answer != null) { constantMatcher.appendReplacement(innerOut, Matcher.quoteReplacement(answer)); } } constantMatcher.appendTail(innerOut); // replace the final line. if (fullCall != null) { rootMatch.appendReplacement(out, Matcher.quoteReplacement(innerOut.toString())); } } rootMatch.appendTail(out); return out.toString(); } private boolean jsonArrayContains(List nodes, String str) { boolean hasMethod = false; for (Object testMethod : nodes) { hasMethod = testMethod.equals(str); if (hasMethod) { return hasMethod; } } return false; } private String updateImports(String text, String imp) { if (!text.contains("import " + imp + ";")) { text = text.replace(IMPORT_REPLACE, IMPORT_REPLACE + "\nimport " + imp + ";"); } return text; } }