source: java2python/src/test/java/tudelft/utilities/j2p/PyTest.java@ 359

Last change on this file since 359 was 359, checked in by wouter, 2 years ago

#110 working on new example translating code that uses ImmutableList. This part does not yet work.

File size: 6.2 KB
Line 
1package tudelft.utilities.j2p;
2
3import java.io.BufferedOutputStream;
4import java.io.BufferedReader;
5import java.io.File;
6import java.io.FileNotFoundException;
7import java.io.FileOutputStream;
8import java.io.FileWriter;
9import java.io.IOException;
10import java.io.InputStream;
11import java.io.InputStreamReader;
12import java.nio.file.Files;
13import java.nio.file.Path;
14import java.util.Arrays;
15import java.util.LinkedList;
16import java.util.List;
17
18import com.github.javaparser.JavaParser;
19import com.github.javaparser.ParseResult;
20import com.github.javaparser.ParserConfiguration;
21import com.github.javaparser.ast.CompilationUnit;
22import com.github.javaparser.symbolsolver.JavaSymbolSolver;
23import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
24import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
25
26import tudelft.utilities.j2p.formatting.Block;
27import tudelft.utilities.j2p.t.Translator;
28import tudelft.utilities.pyrunner.Call;
29import tudelft.utilities.pyrunner.PythonError;
30import tudelft.utilities.pyrunner.PythonVenv;
31
32public class PyTest {
33 private static final String TESTFILE = "test.py";
34 private static final File TESTDIR = new File("test/");
35
36 /**
37 *
38 * @param pycode the python code to run.
39 * @param fullclaspath a "package/class/path/filename.py" name containing
40 * the full filename where the file should be placed.
41 * This must be a RELATIVE name, we will prefix it with
42 * {@link #TESTDIR} as needed
43 * @return the text lines that the code printed to stdout.
44 * @throws Exception
45 */
46 public List<String> runPython(Block pycode, String fullclaspath)
47 throws Exception {
48 TESTDIR.delete();
49 File f = TESTDIR.toPath().resolve(fullclaspath).toFile();
50 f.getParentFile().mkdirs();// create dir, massaging java...
51 FileOutputStream fos = new FileOutputStream(f);
52 BufferedOutputStream bos = new BufferedOutputStream(fos);
53 // convert string to byte array
54 byte[] bytes = pycode.toString().getBytes();
55 // write byte array to file
56 bos.write(bytes);
57 bos.close();
58 fos.close();
59
60 Process process = Runtime.getRuntime().exec("python " + fullclaspath,
61 new String[0], TESTDIR);
62 List<String> errors = readAll(process.getErrorStream());
63 if (!errors.isEmpty())
64 throw new IllegalStateException("Python failed. " + errors);
65
66 return readAll(process.getInputStream());
67 }
68
69 /**
70 *
71 * @param pycode the python code to be zipped as pip-installable zip. It
72 * is assumed that the code is just 1 file.
73 * @param modulename The name of the module. It is assumed there is just 1
74 * module, and this module is also a directory in the root
75 * folder, and only 1 level deep. The main program must be
76 * in this module. FIXME should be in pycode.
77 * @return a zip {@link File} containing all the code, as a python tar.gz
78 * package that can be pip install'ed .
79 * @throws IOException
80 * @throws PythonError if python code to build tar.gz fails for
81 * some reason
82 * @throws InterruptedException
83 */
84 public File zip(Block pycode, String modulename)
85 throws IOException, InterruptedException, PythonError {
86 Path tmppath = Files.createTempDirectory("j2p");
87 System.out.println(tmppath);
88 File f = tmppath.resolve(modulename + ".py").toFile();
89 f.getParentFile().mkdirs();// create dirs
90 FileOutputStream fos = new FileOutputStream(f);
91 BufferedOutputStream bos = new BufferedOutputStream(fos);
92 // convert string to byte array
93 byte[] bytes = pycode.toString().getBytes();
94 // write byte array to file
95 bos.write(bytes);
96 bos.close();
97 fos.close();
98
99 String requirements = String.join(",\n", pycode.getInstalls());
100 // we must provide many nonsense fields like url and author to get this
101 // working...
102 String setuppy = "from setuptools import setup, find_packages\n" + "\n"
103 + "setup(\n" + " name='" + modulename + "',\n"
104 + " version=1,\n" + " author='Whatever',\n"
105 + " author_email='Whatever',\n"
106 + " url='http://nonsense'," + " py_modules=['"
107 + modulename + "'],\n" + " install_requires=[ \n"
108 + requirements + " ],\n" + "\n" + " classifiers=[\n"
109 + " 'Programming Language :: Python :: 3.8',\n"
110 + " 'Programming Language :: Python :: 3.9'\n"
111 + " ],\n" + ")\n" + "";
112
113 f = tmppath.resolve("setup.py").toFile();
114 FileWriter fw = new FileWriter(f);
115 fw.write(setuppy);
116 fw.close();
117
118 // without readme, python complains
119 f = tmppath.resolve("README").toFile();
120 fw = new FileWriter(f);
121 fw.write("");
122 fw.close();
123
124// String setuppy = "import os; chdir(" + tmppath + ");";
125
126 // call python to build the package to be sure we have a correct package
127 new Call(PythonVenv.PYTHON3, Arrays.asList("setup.py", "sdist"), 30000,
128 tmppath.toFile()).run();
129
130 // -1 is the version number added py setup.py to the file
131 return tmppath.resolve("dist/" + modulename + "-1.tar.gz").toFile();
132 }
133
134 private List<String> readAll(InputStream in) throws IOException {
135 BufferedReader Buffered_Reader = new BufferedReader(
136 new InputStreamReader(in));
137 List<String> lines = new LinkedList<>();
138
139 String line;
140 while ((line = Buffered_Reader.readLine()) != null) {
141 lines.add(line);
142 }
143 return lines;
144 }
145
146 /**
147 * @param javaFile a java file name to be translated
148 * @return a string containing python code translated from the java.
149 * @throws FileNotFoundException
150 */
151 public Block translate(String javaFile) throws FileNotFoundException {
152 ParserConfiguration conf = new ParserConfiguration();
153 CombinedTypeSolver typeSolver = new CombinedTypeSolver();
154 typeSolver.add(new ReflectionTypeSolver(false));
155 // FIXME add sources of jars source code etc
156 // typeSolver.add(new JavaParserTypeSolver(new File(SOURCE_PATH)));
157 // typeSolver.add(new JarTypeSolver(jarSourceFile));
158 JavaSymbolSolver symbolSolver = new JavaSymbolSolver(typeSolver);
159 conf.setSymbolResolver(symbolSolver);
160 JavaParser parser = new JavaParser(conf);
161
162 ParseResult<CompilationUnit> res = parser.parse(new File(javaFile));
163
164 Block translation = new Translator().translate(res.getResult().get());
165 return translation;
166 }
167
168}
Note: See TracBrowser for help on using the repository browser.