diff --git a/j2k.iml b/j2k.iml
index f7e0d92adb2..2b7c256c235 100644
--- a/j2k.iml
+++ b/j2k.iml
@@ -9,6 +9,8 @@
+
+
diff --git a/j2k.ipr b/j2k.ipr
index 85640093dc3..f91fa7f6738 100644
--- a/j2k.ipr
+++ b/j2k.ipr
@@ -13,6 +13,17 @@
+
+ $PROJECT_DIR$/out/artifacts/java2kotlin_jar
+
+
+
+
+
+
+
+
+
@@ -616,6 +627,13 @@
+
+
+
+
+
+
+
diff --git a/lib/commons-cli-1.2.jar b/lib/commons-cli-1.2.jar
new file mode 100644
index 00000000000..ce4b9fffe40
Binary files /dev/null and b/lib/commons-cli-1.2.jar differ
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
index 558fbaba78d..e71f8509eeb 100644
--- a/src/META-INF/MANIFEST.MF
+++ b/src/META-INF/MANIFEST.MF
@@ -1,3 +1,3 @@
-Manifest-Version: 1.0
-Main-Class: org.jetbrains.jet.j2k.JavaToKotlinTranslator
-
+Manifest-Version: 1.0
+Main-Class: org.jetbrains.jet.j2k.JavaToKotlinCli
+
diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java
index 4ed80d216c5..8d976288e52 100644
--- a/src/org/jetbrains/jet/j2k/Converter.java
+++ b/src/org/jetbrains/jet/j2k/Converter.java
@@ -6,7 +6,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.j2k.ast.*;
import org.jetbrains.jet.j2k.ast.Class;
import org.jetbrains.jet.j2k.ast.Enum;
-import org.jetbrains.jet.j2k.ast.Modifier;
import org.jetbrains.jet.j2k.util.AstUtil;
import org.jetbrains.jet.j2k.visitors.*;
@@ -35,9 +34,20 @@ public class Converter {
@Nullable
private static PsiType ourMethodReturnType = null;
+ @NotNull
+ private static Set settings = new HashSet();
+
private Converter() {
}
+ public static boolean addSetting(@NotNull String value) {
+ return settings.add(value);
+ }
+
+ public static boolean hasSetting(@NotNull String value) {
+ return settings.contains(value);
+ }
+
public static void setClassIdentifiers(@NotNull Set identifiers) {
ourClassIdentifiers = identifiers;
}
@@ -327,7 +337,7 @@ public class Converter {
final IdentifierImpl identifier = new IdentifierImpl(method.getName());
final Type returnType = typeToType(method.getReturnType(), ConverterUtil.isAnnotatedAsNotNull(method.getModifierList()));
- final Block body = blockToBlock(method.getBody(), notEmpty);
+ final Block body = hasSetting("declarations-only") ? Block.EMPTY_BLOCK : blockToBlock(method.getBody(), notEmpty); // #TODO
final Element params = createFunctionParameters(method);
final List typeParameters = elementsToElementList(method.getTypeParameters());
@@ -608,10 +618,10 @@ public class Converter {
for (PsiExpression e : arguments)
actualTypes.add(e.getType());
- assert actualTypes.size() == expectedTypes.size() : "The type list must have the same length";
-
- for (int i = 0; i < actualTypes.size(); i++)
- conversions.set(i, createConversionForExpression(arguments[i], expectedTypes.get(i)));
+ if (conversions.size() == actualTypes.size() && actualTypes.size() == expectedTypes.size()) {
+ for (int i = 0; i < actualTypes.size(); i++)
+ conversions.set(i, createConversionForExpression(arguments[i], expectedTypes.get(i)));
+ }
}
return conversions;
}
diff --git a/src/org/jetbrains/jet/j2k/JavaToKotlinCli.java b/src/org/jetbrains/jet/j2k/JavaToKotlinCli.java
new file mode 100644
index 00000000000..1f322e030ee
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/JavaToKotlinCli.java
@@ -0,0 +1,147 @@
+package org.jetbrains.jet.j2k;
+
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiJavaFile;
+import org.apache.commons.cli.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import static org.apache.commons.io.FileUtils.readFileToString;
+import static org.apache.commons.io.FileUtils.writeStringToFile;
+
+/**
+ * @author ignatov
+ */
+@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"})
+public class JavaToKotlinCli {
+ private static final Logger myLogger = Logger.getAnonymousLogger();
+
+ private JavaToKotlinCli() {
+ }
+
+ public static void main(String[] args) {
+ CommandLineParser parser = new BasicParser();
+ Options options = new Options()
+ .addOption("h", "help", false, "Print usage information")
+ .addOption("f", "from", true, "Directory with Java sources")
+ .addOption("t", "to", true, "Directory with Kotlin sources")
+ .addOption("p", "public-only", false, "Only public and protected members")
+ .addOption("fqn", "fqn", false, "Full qualified names")
+ .addOption("d", "declarations-only", false, "Declarations only")
+ ;
+
+ try {
+ CommandLine commandLine = parser.parse(options, args);
+
+ if (commandLine.hasOption("help"))
+ showHelpAndExit();
+
+ if (commandLine.hasOption("from") && commandLine.hasOption("to")) {
+ String from = commandLine.getOptionValue("from");
+ String to = commandLine.getOptionValue("to");
+
+ for (Option o : commandLine.getOptions()) {
+ Converter.addSetting(o.getLongOpt());
+ }
+
+ if (!from.isEmpty() && !to.isEmpty())
+ convertSourceTree(from, to);
+ else
+ showHelpAndExit();
+ } else
+ showHelpAndExit();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ private static void convertSourceTree(String javaPath, String kotlinPath) {
+ try {
+ File javaDir = new File(javaPath);
+ File kotlinDir = new File(kotlinPath);
+
+ if (kotlinDir.exists())
+ kotlinDir.delete();
+
+ if (!kotlinDir.exists() && !kotlinDir.mkdir())
+ myLogger.warning("Creation failed: " + kotlinDir.getAbsolutePath());
+
+ for (File f : getJavaFiles(javaDir.getAbsolutePath())) {
+ String relative = javaDir.toURI().relativize(f.toURI()).getPath().replace(".java", ".kt");
+ File file = new File(kotlinPath, relative);
+
+ if (file.exists())
+ file.delete();
+
+ if (f.isDirectory())
+ if (!file.exists() && !file.mkdir())
+ myLogger.warning("Creation failed: " + file.getAbsolutePath());
+
+ if (f.isFile()) {
+ writeStringToFile(file, fileToKotlin(f));
+ }
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @NotNull
+ private static String fileToKotlin(File f) throws IOException {
+ final String javaCode = readJavaFileToString(f);
+ return generateKotlinCode(JavaToKotlinTranslator.createFile(JavaToKotlinTranslator.setUpJavaCoreEnvironment(), javaCode));
+ }
+
+ @NotNull
+ private static String generateKotlinCode(@Nullable PsiFile file) {
+ if (file != null && file instanceof PsiJavaFile) {
+ JavaToKotlinTranslator.setClassIdentifiers(file);
+ return JavaToKotlinTranslator.prettify(Converter.fileToFile((PsiJavaFile) file).toKotlin());
+ }
+ return "";
+ }
+
+ @NotNull
+ private static String readJavaFileToString(@NotNull File javaFile) throws IOException {
+ return Pattern.compile("\\s*/\\*.*\\*/", Pattern.DOTALL).matcher(readFileToString(javaFile)).replaceAll("");
+ }
+
+ private static void showHelpAndExit() {
+ System.err.println("Usage: java -jar java2kotlin.jar -f -t ");
+ System.exit(1);
+ }
+
+ static public List getJavaFiles(String startDirName) throws FileNotFoundException {
+ return getJavaFiles(new File(startDirName));
+ }
+
+ private static List getJavaFiles(File start) throws FileNotFoundException {
+ List result = new ArrayList();
+
+ if (start.isFile())
+ return Arrays.asList(start);
+
+ for (File file : Arrays.asList(start.listFiles())) {
+ if ((file.isFile() && file.getName().endsWith(".java")) || file.isDirectory())
+ result.add(file);
+
+ if (file.isDirectory()) {
+ List deeperList = getJavaFiles(file);
+ result.addAll(deeperList);
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java b/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java
index 7698eda8c5e..f87a8952a6e 100644
--- a/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java
+++ b/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java
@@ -73,7 +73,7 @@ public class JavaToKotlinTranslator {
}
@NotNull
- private static String prettify(@Nullable String code) {
+ static String prettify(@Nullable String code) {
if (code == null)
return "";
return code
@@ -175,8 +175,8 @@ public class JavaToKotlinTranslator {
}
@NotNull
- static String generateKotlinCode(@NotNull String arg) {
- PsiFile file = createFile(arg);
+ static String generateKotlinCode(@NotNull String javaCode) {
+ PsiFile file = createFile(javaCode);
if (file != null && file instanceof PsiJavaFile) {
setClassIdentifiers(file);
return prettify(Converter.fileToFile((PsiJavaFile) file).toKotlin());
@@ -185,8 +185,8 @@ public class JavaToKotlinTranslator {
}
@NotNull
- static String generateKotlinCodeWithCompatibilityImport(@NotNull String arg) {
- PsiFile file = createFile(arg);
+ static String generateKotlinCodeWithCompatibilityImport(@NotNull String javaCode) {
+ PsiFile file = createFile(javaCode);
if (file != null && file instanceof PsiJavaFile) {
setClassIdentifiers(file);
return prettify(Converter.fileToFileWithCompatibilityImport((PsiJavaFile) file).toKotlin());
diff --git a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java
index e8a87d2b3f7..c5524a0bb91 100644
--- a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java
+++ b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java
@@ -16,7 +16,7 @@ public class AnonymousClass extends Class {
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(),
- members
+ getMembers(members)
);
}
diff --git a/src/org/jetbrains/jet/j2k/ast/Class.java b/src/org/jetbrains/jet/j2k/ast/Class.java
index 141a12699f0..87667feb136 100644
--- a/src/org/jetbrains/jet/j2k/ast/Class.java
+++ b/src/org/jetbrains/jet/j2k/ast/Class.java
@@ -2,6 +2,7 @@ package org.jetbrains.jet.j2k.ast;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.util.AstUtil;
import java.util.HashSet;
@@ -19,20 +20,34 @@ public class Class extends Member {
String TYPE = "class";
final Identifier myName;
private final List myBaseClassParams;
- private final List extends Member> myMembers;
+ private final List myMembers;
private final List myTypeParameters;
private final List myExtendsTypes;
private final List myImplementsTypes;
public Class(Identifier name, Set modifiers, List typeParameters, List extendsTypes,
- List baseClassParams, List implementsTypes, List extends Member> members) {
+ List baseClassParams, List implementsTypes, List members) {
myName = name;
myBaseClassParams = baseClassParams;
myModifiers = modifiers;
myTypeParameters = typeParameters;
myExtendsTypes = extendsTypes;
myImplementsTypes = implementsTypes;
- myMembers = members;
+ myMembers= getMembers(members);
+ }
+
+ static List getMembers(List members) {
+ List withoutPrivate = new LinkedList();
+ if (Converter.hasSetting("public-only")) {
+ for (Member m : members) {
+ if (m.accessModifier().equals("public") || m.accessModifier().equals("protected") || m.accessModifier().isEmpty()) {
+ withoutPrivate.add(m);
+ }
+ }
+ } else {
+ withoutPrivate = members;
+ }
+ return withoutPrivate;
}
diff --git a/src/org/jetbrains/jet/j2k/ast/Enum.java b/src/org/jetbrains/jet/j2k/ast/Enum.java
index 2fd28501176..cbf2cc7872c 100644
--- a/src/org/jetbrains/jet/j2k/ast/Enum.java
+++ b/src/org/jetbrains/jet/j2k/ast/Enum.java
@@ -12,7 +12,7 @@ import java.util.Set;
public class Enum extends Class {
public Enum(Identifier name, Set modifiers, List typeParameters, List extendsTypes,
List baseClassParams, List implementsTypes, List members) {
- super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
+ super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
}
String primaryConstructorSignatureToKotlin() {
diff --git a/src/org/jetbrains/jet/j2k/ast/Trait.java b/src/org/jetbrains/jet/j2k/ast/Trait.java
index 60bcd122add..aed3f075e3d 100644
--- a/src/org/jetbrains/jet/j2k/ast/Trait.java
+++ b/src/org/jetbrains/jet/j2k/ast/Trait.java
@@ -9,7 +9,7 @@ import java.util.Set;
public class Trait extends Class {
public Trait(Identifier name, Set modifiers, List typeParameters, List extendsTypes,
List baseClassParams, List implementsTypes, List members) {
- super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
+ super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
TYPE = "trait";
}
diff --git a/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java b/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java
index dc7d1814e07..4d71752d174 100644
--- a/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java
+++ b/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java
@@ -3,6 +3,7 @@ package org.jetbrains.jet.j2k.visitors;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.ast.*;
import org.jetbrains.jet.j2k.util.AstUtil;
@@ -74,6 +75,8 @@ public class TypeVisitor extends PsiTypeVisitor {
if (psiClass != null) {
String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName != null) {
+ if (!qualifiedName.equals("java.lang.Object") && Converter.hasSetting("fqn"))
+ return new IdentifierImpl(qualifiedName);
if (qualifiedName.equals(JAVA_LANG_ITERABLE))
return new IdentifierImpl(JAVA_LANG_ITERABLE);
if (qualifiedName.equals(JAVA_UTIL_ITERATOR))