Initial include of the J2K Converter

This commit is contained in:
Andrey Breslav
2012-01-27 17:31:05 +04:00
parent 7c55bf9315
commit e678e072f1
4 changed files with 281 additions and 268 deletions
+1
View File
@@ -12,6 +12,7 @@
<module fileurl="file://$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" filepath="$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" /> <module fileurl="file://$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" filepath="$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" />
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" /> <module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" /> <module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
<module fileurl="file://$PROJECT_DIR$/j2k/j2k.iml" filepath="$PROJECT_DIR$/j2k/j2k.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler/jet.as.java.psi/jet.as.java.psi.iml" filepath="$PROJECT_DIR$/compiler/jet.as.java.psi/jet.as.java.psi.iml" /> <module fileurl="file://$PROJECT_DIR$/compiler/jet.as.java.psi/jet.as.java.psi.iml" filepath="$PROJECT_DIR$/compiler/jet.as.java.psi/jet.as.java.psi.iml" />
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" /> <module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
<module fileurl="file://$PROJECT_DIR$/testlib/testlib.iml" filepath="$PROJECT_DIR$/testlib/testlib.iml" /> <module fileurl="file://$PROJECT_DIR$/testlib/testlib.iml" filepath="$PROJECT_DIR$/testlib/testlib.iml" />
+2 -3
View File
@@ -8,9 +8,8 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="commons-io-2.1" level="project" /> <orderEntry type="library" name="intellij-core" level="project" />
<orderEntry type="library" name="commons-cli-1.2" level="project" /> <orderEntry type="library" scope="TEST" name="idea-full" level="project" />
<orderEntry type="library" name="commons-io-2.1" level="project" />
</component> </component>
</module> </module>
+147 -147
View File
@@ -1,147 +1,147 @@
package org.jetbrains.jet.j2k; //package org.jetbrains.jet.j2k;
//
import com.intellij.psi.PsiFile; //import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile; //import com.intellij.psi.PsiJavaFile;
import org.apache.commons.cli.*; //import org.apache.commons.cli.*;
import org.jetbrains.annotations.NotNull; //import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; //import org.jetbrains.annotations.Nullable;
//
import java.io.File; //import java.io.File;
import java.io.FileNotFoundException; //import java.io.FileNotFoundException;
import java.io.IOException; //import java.io.IOException;
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.Arrays; //import java.util.Arrays;
import java.util.List; //import java.util.List;
import java.util.logging.Logger; //import java.util.logging.Logger;
import java.util.regex.Pattern; //import java.util.regex.Pattern;
//
import static org.apache.commons.io.FileUtils.readFileToString; //import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.io.FileUtils.writeStringToFile; //import static org.apache.commons.io.FileUtils.writeStringToFile;
//
/** ///**
* @author ignatov // * @author ignatov
*/ // */
@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"}) //@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"})
public class JavaToKotlinCli { //public class JavaToKotlinCli {
private static final Logger myLogger = Logger.getAnonymousLogger(); // private static final Logger myLogger = Logger.getAnonymousLogger();
//
private JavaToKotlinCli() { // private JavaToKotlinCli() {
} // }
//
public static void main(String[] args) { // public static void main(String[] args) {
CommandLineParser parser = new BasicParser(); // CommandLineParser parser = new BasicParser();
Options options = new Options() // Options options = new Options()
.addOption("h", "help", false, "Print usage information") // .addOption("h", "help", false, "Print usage information")
.addOption("f", "from", true, "Directory with Java sources") // .addOption("f", "from", true, "Directory with Java sources")
.addOption("t", "to", true, "Directory with Kotlin sources") // .addOption("t", "to", true, "Directory with Kotlin sources")
.addOption("p", "public-only", false, "Only public and protected members") // .addOption("p", "public-only", false, "Only public and protected members")
.addOption("fqn", "fqn", false, "Full qualified names") // .addOption("fqn", "fqn", false, "Full qualified names")
.addOption("d", "declarations-only", false, "Declarations only") // .addOption("d", "declarations-only", false, "Declarations only")
; // ;
//
try { // try {
CommandLine commandLine = parser.parse(options, args); // CommandLine commandLine = parser.parse(options, args);
//
if (commandLine.hasOption("help")) // if (commandLine.hasOption("help"))
showHelpAndExit(); // showHelpAndExit();
//
if (commandLine.hasOption("from") && commandLine.hasOption("to")) { // if (commandLine.hasOption("from") && commandLine.hasOption("to")) {
String from = commandLine.getOptionValue("from"); // String from = commandLine.getOptionValue("from");
String to = commandLine.getOptionValue("to"); // String to = commandLine.getOptionValue("to");
//
for (Option o : commandLine.getOptions()) { // for (Option o : commandLine.getOptions()) {
Converter.addSetting(o.getLongOpt()); // Converter.addSetting(o.getLongOpt());
} // }
//
if (!from.isEmpty() && !to.isEmpty()) // if (!from.isEmpty() && !to.isEmpty())
convertSourceTree(from, to); // convertSourceTree(from, to);
else // else
showHelpAndExit(); // showHelpAndExit();
} else // } else
showHelpAndExit(); // showHelpAndExit();
} catch (ParseException e) { // } catch (ParseException e) {
e.printStackTrace(); // e.printStackTrace();
} // }
} // }
//
@SuppressWarnings("ResultOfMethodCallIgnored") // @SuppressWarnings("ResultOfMethodCallIgnored")
private static void convertSourceTree(String javaPath, String kotlinPath) { // private static void convertSourceTree(String javaPath, String kotlinPath) {
try { // try {
File javaDir = new File(javaPath); // File javaDir = new File(javaPath);
File kotlinDir = new File(kotlinPath); // File kotlinDir = new File(kotlinPath);
//
if (kotlinDir.exists()) // if (kotlinDir.exists())
kotlinDir.delete(); // kotlinDir.delete();
//
if (!kotlinDir.exists() && !kotlinDir.mkdir()) // if (!kotlinDir.exists() && !kotlinDir.mkdir())
myLogger.warning("Creation failed: " + kotlinDir.getAbsolutePath()); // myLogger.warning("Creation failed: " + kotlinDir.getAbsolutePath());
//
for (File f : getJavaFiles(javaDir.getAbsolutePath())) { // for (File f : getJavaFiles(javaDir.getAbsolutePath())) {
String relative = javaDir.toURI().relativize(f.toURI()).getPath().replace(".java", ".kt"); // String relative = javaDir.toURI().relativize(f.toURI()).getPath().replace(".java", ".kt");
File file = new File(kotlinPath, relative); // File file = new File(kotlinPath, relative);
//
if (file.exists()) // if (file.exists())
file.delete(); // file.delete();
//
if (f.isDirectory()) // if (f.isDirectory())
if (!file.exists() && !file.mkdir()) // if (!file.exists() && !file.mkdir())
myLogger.warning("Creation failed: " + file.getAbsolutePath()); // myLogger.warning("Creation failed: " + file.getAbsolutePath());
//
if (f.isFile()) { // if (f.isFile()) {
writeStringToFile(file, fileToKotlin(f)); // writeStringToFile(file, fileToKotlin(f));
} // }
} // }
} catch (FileNotFoundException e) { // } catch (FileNotFoundException e) {
e.printStackTrace(); // e.printStackTrace();
} catch (IOException e) { // } catch (IOException e) {
e.printStackTrace(); // e.printStackTrace();
} // }
} // }
//
@NotNull // @NotNull
private static String fileToKotlin(File f) throws IOException { // private static String fileToKotlin(File f) throws IOException {
final String javaCode = readJavaFileToString(f); // final String javaCode = readJavaFileToString(f);
return generateKotlinCode(JavaToKotlinTranslator.createFile(JavaToKotlinTranslator.setUpJavaCoreEnvironment(), javaCode)); // return generateKotlinCode(JavaToKotlinTranslator.createFile(JavaToKotlinTranslator.setUpJavaCoreEnvironment(), javaCode));
} // }
//
@NotNull // @NotNull
private static String generateKotlinCode(@Nullable PsiFile file) { // private static String generateKotlinCode(@Nullable PsiFile file) {
if (file != null && file instanceof PsiJavaFile) { // if (file != null && file instanceof PsiJavaFile) {
JavaToKotlinTranslator.setClassIdentifiers(file); // JavaToKotlinTranslator.setClassIdentifiers(file);
return JavaToKotlinTranslator.prettify(Converter.fileToFile((PsiJavaFile) file).toKotlin()); // return JavaToKotlinTranslator.prettify(Converter.fileToFile((PsiJavaFile) file).toKotlin());
} // }
return ""; // return "";
} // }
//
@NotNull // @NotNull
private static String readJavaFileToString(@NotNull File javaFile) throws IOException { // private static String readJavaFileToString(@NotNull File javaFile) throws IOException {
return Pattern.compile("\\s*/\\*.*\\*/", Pattern.DOTALL).matcher(readFileToString(javaFile)).replaceAll(""); // return Pattern.compile("\\s*/\\*.*\\*/", Pattern.DOTALL).matcher(readFileToString(javaFile)).replaceAll("");
} // }
//
private static void showHelpAndExit() { // private static void showHelpAndExit() {
System.err.println("Usage: java -jar java2kotlin.jar -f <from> -t <to>"); // System.err.println("Usage: java -jar java2kotlin.jar -f <from> -t <to>");
System.exit(1); // System.exit(1);
} // }
//
static public List<File> getJavaFiles(String startDirName) throws FileNotFoundException { // static public List<File> getJavaFiles(String startDirName) throws FileNotFoundException {
return getJavaFiles(new File(startDirName)); // return getJavaFiles(new File(startDirName));
} // }
//
private static List<File> getJavaFiles(File start) throws FileNotFoundException { // private static List<File> getJavaFiles(File start) throws FileNotFoundException {
List<File> result = new ArrayList<File>(); // List<File> result = new ArrayList<File>();
//
if (start.isFile()) // if (start.isFile())
return Arrays.asList(start); // return Arrays.asList(start);
//
for (File file : Arrays.asList(start.listFiles())) { // for (File file : Arrays.asList(start.listFiles())) {
if ((file.isFile() && file.getName().endsWith(".java")) || file.isDirectory()) // if ((file.isFile() && file.getName().endsWith(".java")) || file.isDirectory())
result.add(file); // result.add(file);
//
if (file.isDirectory()) { // if (file.isDirectory()) {
List<File> deeperList = getJavaFiles(file); // List<File> deeperList = getJavaFiles(file);
result.addAll(deeperList); // result.addAll(deeperList);
} // }
} // }
return result; // return result;
} // }
} //}
@@ -1,6 +1,7 @@
package org.jetbrains.jet.j2k; package org.jetbrains.jet.j2k;
import com.intellij.core.JavaCoreEnvironment; import com.intellij.core.JavaCoreEnvironment;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile; import com.intellij.psi.PsiJavaFile;
import junit.framework.Assert; import junit.framework.Assert;
@@ -13,134 +14,146 @@ import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.io.FileUtils.writeStringToFile;
import static org.jetbrains.jet.j2k.TestCaseBuilder.getTestDataPathBase; import static org.jetbrains.jet.j2k.TestCaseBuilder.getTestDataPathBase;
/** /**
* @author ignatov * @author ignatov
*/ */
public class StandaloneJavaToKotlinConverterTest extends TestCase { public class StandaloneJavaToKotlinConverterTest extends TestCase {
private final String myDataPath; private final String myDataPath;
private final String myName; private final String myName;
@NotNull @NotNull
private final JavaCoreEnvironment myJavaCoreEnvironment; private final JavaCoreEnvironment myJavaCoreEnvironment;
public StandaloneJavaToKotlinConverterTest(String dataPath, String name) { public StandaloneJavaToKotlinConverterTest(String dataPath, String name) {
myDataPath = dataPath; myDataPath = dataPath;
myName = name; myName = name;
myJavaCoreEnvironment = JavaToKotlinTranslator.setUpJavaCoreEnvironment(); myJavaCoreEnvironment = JavaToKotlinTranslator.setUpJavaCoreEnvironment();
}
@Override
protected void runTest() throws Throwable {
String javaPath = "testData" + File.separator + getTestFilePath();
String kotlinPath = javaPath.replace(".jav", ".kt");
final File kotlinFile = new File(kotlinPath);
if (!kotlinFile.exists())
writeStringToFile(kotlinFile, "");
final String expected = readFileToString(kotlinFile);
final File javaFile = new File(javaPath);
final String javaCode = readFileToString(javaFile);
String actual = "";
if (javaFile.getParent().endsWith("/expression")) actual = expressionToKotlin(javaCode);
else if (javaFile.getParent().endsWith("/statement")) actual = statementToKotlin(javaCode);
else if (javaFile.getParent().endsWith("/method")) actual = methodToKotlin(javaCode);
else if (javaFile.getParent().endsWith("/class")) actual = fileToKotlin(javaCode);
else if (javaFile.getParent().endsWith("/file")) actual = fileToKotlin(javaCode);
else if (javaFile.getParent().endsWith("/comp")) actual = fileToFileWithCompatibilityImport(javaCode);
assert !actual.isEmpty() : "Specify what is it: file, class, method, statement or expression";
final File tmp = new File(kotlinPath + ".tmp");
if (!expected.equals(actual)) writeStringToFile(tmp, actual);
if (expected.equals(actual) && tmp.exists()) //noinspection ResultOfMethodCallIgnored
tmp.delete();
Assert.assertEquals(expected, actual);
}
@NotNull
String getTestFilePath() {
return myDataPath + File.separator + myName + ".jav";
}
@NotNull
@Override
public String getName() {
return "test_" + myName;
}
@NotNull
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(TestCaseBuilder.suiteForDirectory(getTestDataPathBase(), "/ast", new TestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name) {
return new StandaloneJavaToKotlinConverterTest(dataPath, name);
}
}));
return suite;
}
@NotNull
private static String fileToFileWithCompatibilityImport(@NotNull String text) {
return JavaToKotlinTranslator.generateKotlinCodeWithCompatibilityImport(text);
}
@NotNull
private String fileToKotlin(@NotNull String text) {
return generateKotlinCode(JavaToKotlinTranslator.createFile(myJavaCoreEnvironment, text));
}
@NotNull
private static String generateKotlinCode(@Nullable PsiFile file) {
if (file != null && file instanceof PsiJavaFile) {
JavaToKotlinTranslator.setClassIdentifiers(file);
return prettify(Converter.elementToKotlin(file));
} }
return "";
}
@NotNull @Override
private String methodToKotlin(String text) throws IOException { protected void runTest() throws Throwable {
String result = fileToKotlin("final class C {" + text + "}") String javaPath = "testData" + File.separator + getTestFilePath();
.replaceAll("class C\\(\\) \\{", ""); String kotlinPath = javaPath.replace(".jav", ".kt");
result = result.substring(0, result.lastIndexOf("}"));
return prettify(result);
}
@NotNull final File kotlinFile = new File(kotlinPath);
private String statementToKotlin(String text) throws Exception { if (!kotlinFile.exists()) {
String result = methodToKotlin("void main() {" + text + "}"); FileUtil.writeToFile(kotlinFile, "");
int pos = result.lastIndexOf("}"); }
result = result.substring(0, pos).replaceFirst("fun main\\(\\) : Unit \\{", ""); final String expected = FileUtil.loadFile(kotlinFile);
return prettify(result); final File javaFile = new File(javaPath);
} final String javaCode = FileUtil.loadFile(javaFile);
@NotNull String actual = "";
private String expressionToKotlin(String code) throws Exception { if (javaFile.getParent().endsWith("/expression")) {
String result = statementToKotlin("Object o =" + code + "}"); actual = expressionToKotlin(javaCode);
result = result.replaceFirst("var o : Any\\? =", ""); }
return prettify(result); else if (javaFile.getParent().endsWith("/statement")) {
} actual = statementToKotlin(javaCode);
}
else if (javaFile.getParent().endsWith("/method")) {
actual = methodToKotlin(javaCode);
}
else if (javaFile.getParent().endsWith("/class")) {
actual = fileToKotlin(javaCode);
}
else if (javaFile.getParent().endsWith("/file")) {
actual = fileToKotlin(javaCode);
}
else if (javaFile.getParent().endsWith("/comp")) actual = fileToFileWithCompatibilityImport(javaCode);
@NotNull assert !actual.isEmpty() : "Specify what is it: file, class, method, statement or expression";
private static String prettify(@Nullable String code) {
if (code == null) final File tmp = new File(kotlinPath + ".tmp");
return ""; if (!expected.equals(actual)) FileUtil.writeToFile(tmp, actual);
return code if (expected.equals(actual) && tmp.exists()) //noinspection ResultOfMethodCallIgnored
.trim() {
.replaceAll("\r\n", "\n") tmp.delete();
.replaceAll(" \n", "\n") }
.replaceAll("\n ", "\n")
.replaceAll("\n+", "\n") Assert.assertEquals(expected, actual);
.replaceAll(" +", " ") }
.trim()
; @NotNull
} String getTestFilePath() {
return myDataPath + File.separator + myName + ".jav";
}
@NotNull
@Override
public String getName() {
return "test_" + myName;
}
@NotNull
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(TestCaseBuilder.suiteForDirectory(getTestDataPathBase(), "/ast", new TestCaseBuilder.NamedTestFactory() {
@NotNull
@Override
public Test createTest(@NotNull String dataPath, @NotNull String name) {
return new StandaloneJavaToKotlinConverterTest(dataPath, name);
}
}));
return suite;
}
@NotNull
private static String fileToFileWithCompatibilityImport(@NotNull String text) {
return JavaToKotlinTranslator.generateKotlinCodeWithCompatibilityImport(text);
}
@NotNull
private String fileToKotlin(@NotNull String text) {
return generateKotlinCode(JavaToKotlinTranslator.createFile(myJavaCoreEnvironment, text));
}
@NotNull
private static String generateKotlinCode(@Nullable PsiFile file) {
if (file != null && file instanceof PsiJavaFile) {
JavaToKotlinTranslator.setClassIdentifiers(file);
return prettify(Converter.elementToKotlin(file));
}
return "";
}
@NotNull
private String methodToKotlin(String text) throws IOException {
String result = fileToKotlin("final class C {" + text + "}")
.replaceAll("class C\\(\\) \\{", "");
result = result.substring(0, result.lastIndexOf("}"));
return prettify(result);
}
@NotNull
private String statementToKotlin(String text) throws Exception {
String result = methodToKotlin("void main() {" + text + "}");
int pos = result.lastIndexOf("}");
result = result.substring(0, pos).replaceFirst("fun main\\(\\) : Unit \\{", "");
return prettify(result);
}
@NotNull
private String expressionToKotlin(String code) throws Exception {
String result = statementToKotlin("Object o =" + code + "}");
result = result.replaceFirst("var o : Any\\? =", "");
return prettify(result);
}
@NotNull
private static String prettify(@Nullable String code) {
if (code == null) {
return "";
}
return code
.trim()
.replaceAll("\r\n", "\n")
.replaceAll(" \n", "\n")
.replaceAll("\n ", "\n")
.replaceAll("\n+", "\n")
.replaceAll(" +", " ")
.trim()
;
}
} }