See More

package co.deepblue.java2cpp; import co.deepblue.java2cpp.io.BufferedStringWriter; import co.deepblue.java2cpp.processor.*; import co.deepblue.java2cpp.symbol.SymbolTreeParser; import co.deepblue.java2cpp.util.PathUtils; import co.deepblue.java2cpp.type.TypeConverter; import co.deepblue.java2cpp.util.FileUtils; import co.deepblue.java2cpp.util.StringConstants; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.EnumDeclaration; import com.github.javaparser.ast.body.TypeDeclaration; import java.io.BufferedWriter; import java.io.File; import java.io.FileFilter; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; /** * Created by levin on 17-5-6. */ public class Java2CppMemory { String projNamespace; String shortestPackage; String javaDir; String cppRootPath; String cppProjectDirName; Parser parser; HashMap cuMap; ArrayList cuList = new ArrayList<>(); ArrayList typeSizeList = new ArrayList<>(); BufferedWriter cmakeListWriter; public Java2CppMemory(String shortestPackage, String srcDir, String dstDir, String namespace) { this.shortestPackage = shortestPackage; this.javaDir = srcDir; this.cppRootPath = dstDir; this.projNamespace = namespace; parser = new Parser(); cuMap = new HashMap<>(); } void cleanDstDir() { try { FileUtils.deleteDirectory(new File(cppRootPath)); } catch (Exception e) { e.printStackTrace(); } } public void startParse() { cleanDstDir(); parseDir(javaDir); preprocessCompilationUnits(); SymbolTreeParser.createInstance("projectName", cuMap, cuList); SymbolTreeParser.getInstance().scanSymbols(); //int total = symbolTreeParser.getTotalNumberOfSymbols(); try { cppProjectDirName = Paths.get(cppRootPath).getFileName().toString(); cmakeListWriter = FileUtils.createWriter(Paths.get(cppRootPath).getParent(), "CMakeLists.txt"); cmakeListWriter.write("#\n"); cmakeListWriter.write("#autogenerated\n"); cmakeListWriter.write("#\n"); cmakeListWriter.write("cmake_minimum_required (VERSION 3.2.3)\n\n"); cmakeListWriter.write("project (projectName)\n\n"); cmakeListWriter.write("SET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wall -std=c++11\")\n\n"); cmakeListWriter.write("set (WORLD_INCLUDE_DIRS src)\n"); cmakeListWriter.write("include_directories (${WORLD_INCLUDE_DIRS})\n\n"); cmakeListWriter.write("add_executable(projectName\n"); copyPredefinedCppFiles(); convertToCpp(); cmakeListWriter.write(")"); cmakeListWriter.close(); } catch (Exception e) { e.printStackTrace(); } } String predefinedCppDir = ""; void copyPredefinedCppFiles() { predefinedCppDir = Paths.get(shortestPackage.replace(".", File.separator), "cpptemplate").toString(); Path dst = Paths.get(cppRootPath, predefinedCppDir); FileUtils.copyDirectory("/media/levin/842aef23-8664-4811-be6b-e3124f37cc64/levin/games/java_parser/cpp", dst.toString()); File f = dst.toFile(); File[] children = f.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.getName().endsWith(".h"); } }); if (children != null) { for (File child : children) { String name = Paths.get(predefinedCppDir, child.getName()).toString(); name = name.substring(0, name.indexOf(".h")); name = name.replace(File.separator, "."); String typeName = child.getName().substring(0, child.getName().indexOf(".h")); SymbolTreeParser.getInstance().registerPredefinedInclude(typeName, name); } } } public void parseDir(String dir) { File srcFile = new File(dir); if (srcFile.isDirectory()) { File[] fileList = srcFile.listFiles(); if (fileList != null) { for (File file : fileList) { parseDir(file.getAbsolutePath()); } } } else if (srcFile.getName().endsWith(".java")){ try { CompilationUnit cu = parser.parseToCompilationUnit(srcFile.getAbsolutePath()); String packageName = ""; String className = PathUtils.removeExtension(srcFile.getName(), ".java"); String key = ""; if (cu.getPackageDeclaration().isPresent()) { packageName = cu.getPackageDeclaration().get().getNameAsString(); key = packageName + "." + className; } else { String path = srcFile.getAbsolutePath().replace(File.separator, "."); packageName = path.substring(path.indexOf(shortestPackage)); packageName = PathUtils.removeExtension(packageName, ".java"); key = packageName.substring(0, packageName.lastIndexOf(".")) + "." + className; } cu.setData(AstNodeHelper.FilenameDatakey, key); cuMap.put(key, cu); if (cu.getTypes() != null) typeSizeList.add(cu.getTypes().size()); else typeSizeList.add(0); cuList.add(cu); } catch (Exception e) { e.printStackTrace(); } } } public void preprocessCompilationUnits() { for (CompilationUnit cu : cuList) { if (cu.getPackageDeclaration().isPresent()) { String packageName = cu.getPackageDeclaration().get().getName().asString(); NodeList> types = cu.getTypes(); if (types.size() > 0) { TypeDeclaration typeDeclaration = types.get(0); if (typeDeclaration instanceof ClassOrInterfaceDeclaration) { } else if (typeDeclaration instanceof EnumDeclaration) { EnumDeclaration ed = (EnumDeclaration) typeDeclaration; if (ed.getMembers().size() <= 0) { TypeConverter.getInstance().addSimpleEnumType(ed.getNameAsString(), packageName); } } } } } } public void convertToCpp() { for (CompilationUnit cu : cuList) { if (cu == SymbolTreeParser.getInstance().getMainCU()) { writeMainEntrance(cu); } else processCompilationUnit(cu); } } public void writeHeaderDeclaration(BufferedStringWriter writer) throws Exception { writer.insertAtBegin("/*\nGenerate by Java2Cpp\n*/\n\n"); } public void writeBasicIncludes(BufferedStringWriter writer) throws Exception { writer.insert("\n", 0); writer.insertAtBegin("#include \n"); writer.insertAtBegin("#include \n"); } void writeIncludes(CompilationUnit unit, BufferedStringWriter writer) { writer.insertAtBegin("\n"); String key = unit.getData(AstNodeHelper.FilenameDatakey); Set includes = SymbolTreeParser.getInstance().getInclude(key); if (includes != null) { for (String include : includes) { include = include.replace(".", File.separator); if (!include.startsWith("<")) include = "<" + include; if (!include.endsWith(">")) include = include + ".h>"; writer.insertAtBegin("#include " + include + "\n"); } } } void writeUsingNamespace(CompilationUnit unit, BufferedStringWriter writer, boolean isMainUnit) { writer.insertAtBegin("\n"); String key = unit.getData(AstNodeHelper.FilenameDatakey); Set namespaceSet = SymbolTreeParser.getInstance().getNamespace(key); if (namespaceSet != null) { for (String ns : namespaceSet) { writer.insertAtBegin("using namespace " + ns + ";\n"); } } if (isMainUnit) writer.insertAtBegin("using namespace " + projNamespace + ";\n"); } public void writeMainEntrance(CompilationUnit mainCU) { String packageName = mainCU.getPackageDeclaration().get().getName().asString(); String pkgDir = PathUtils.packageName2Path(packageName); Path fileDir = Paths.get(cppRootPath, pkgDir); TypeDeclaration typeDeclaration = mainCU.getTypes().get(0); String className = typeDeclaration.getNameAsString(); try { cmakeListWriter.write(StringConstants.TAB + StringConstants.TAB + Paths.get(cppProjectDirName, pkgDir, className + ".cpp").toString() + "\n"); BufferedWriter implWriter = FileUtils.createWriter(fileDir, className + ".cpp"); BufferedStringWriter writer = new BufferedStringWriter(); MainClassProcessor.process((ClassOrInterfaceDeclaration) typeDeclaration, writer, ""); writeUsingNamespace(mainCU, writer, true); writeIncludes(mainCU, writer); implWriter.write(writer.getString()); implWriter.close(); } catch (Exception e) { e.printStackTrace(); } } public void processCompilationUnit(CompilationUnit cu) { if (cu.getPackageDeclaration().isPresent()) { String packageName = cu.getPackageDeclaration().get().getName().asString(); String pkgDir = PathUtils.packageName2Path(packageName); Path fileDir = Paths.get(cppRootPath, pkgDir); NodeList> types = cu.getTypes(); if (types.size() > 0) { boolean res = fileDir.toFile().mkdirs(); try { TypeDeclaration typeDeclaration = types.get(0); String className = typeDeclaration.getNameAsString(); BufferedWriter headerFileWriter = FileUtils.createWriter(fileDir, className + ".h"); BufferedStringWriter headerWriter = new BufferedStringWriter(); //writeIncludes(headerWriter, cu); headerWriter.write("namespace " + projNamespace + "\n"); headerWriter.write("{\n\n"); boolean isSimpleEnum = false; if (typeDeclaration instanceof EnumDeclaration) { EnumDeclaration ed = (EnumDeclaration) typeDeclaration; if (ed.getMembers().size() <= 0) { SimpleEnumCreator.create(ed, headerWriter, ""); isSimpleEnum = true; } } if (!isSimpleEnum) { BufferedWriter implFileWriter = FileUtils.createWriter(fileDir, className + ".cpp"); BufferedStringWriter implWriter = new BufferedStringWriter(); implWriter.write("#include \"" + className + ".h\"\n\n"); implWriter.write("namespace " + projNamespace + "\n"); implWriter.write("{\n\n"); if (typeDeclaration instanceof ClassOrInterfaceDeclaration) { ClassOrInterfaceProcessor.process((ClassOrInterfaceDeclaration) typeDeclaration, headerWriter, implWriter, ""); } else if (typeDeclaration instanceof EnumDeclaration) { EnumDeclaration ed = (EnumDeclaration) typeDeclaration; ComplexEnumProcessor.process(ed, headerWriter, implWriter, ""); } implWriter.write("\n\n}"); implWriter.close(); writeIncludes(cu, implWriter); implFileWriter.write(implWriter.getString()); implFileWriter.close(); cmakeListWriter.write(StringConstants.TAB + StringConstants.TAB + Paths.get(cppProjectDirName, pkgDir, className + ".cpp").toString() + "\n"); } writeUsingNamespace(cu, headerWriter, false); writeBasicIncludes(headerWriter); writeIncludes(cu, headerWriter); headerWriter.insert("#pragma once\n\n", 0); writeHeaderDeclaration(headerWriter); headerWriter.write("\n\n}"); headerWriter.close(); headerFileWriter.write(headerWriter.getString()); headerFileWriter.close(); } catch (Exception e) { e.printStackTrace(); } } } } public ArrayList getCompilationUnitList() { return cuList; } public int countNumberOfUnitTypesLargerThanOne() { int counter = 0; for (int i = 0; i < typeSizeList.size(); i++) { if (typeSizeList.get(i) > 1) counter++; } return counter; } public ArrayList getTypeSizeList() { return typeSizeList; } public HashMap getCompilationUnitMap() { return cuMap; } }