JavaToKotlinCli added

This commit is contained in:
Sergey Ignatov
2012-01-17 16:42:32 +04:00
parent 0ed16b5c9c
commit b93b25d002
12 changed files with 215 additions and 20 deletions
+2
View File
@@ -9,6 +9,8 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="commons-io-2.1" level="project" />
<orderEntry type="library" name="commons-cli-1.2" level="project" />
<orderEntry type="library" name="commons-io-2.1" level="project" />
</component>
</module>
+18
View File
@@ -13,6 +13,17 @@
<element id="module-output" name="j2k" />
</root>
</artifact>
<artifact type="jar" build-on-make="true" name="java2kotlin:jar">
<output-path>$PROJECT_DIR$/out/artifacts/java2kotlin_jar</output-path>
<root id="archive" name="java2kotlin.jar">
<element id="directory" name="META-INF">
<element id="file-copy" path="$PROJECT_DIR$/src/META-INF/MANIFEST.MF" />
</element>
<element id="module-output" name="j2k" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-cli-1.2.jar" path-in-jar="/" />
</root>
</artifact>
</component>
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
@@ -616,6 +627,13 @@
</component>
<component name="WebServicesPlugin" addRequiredLibraries="true" />
<component name="libraryTable">
<library name="commons-cli-1.2">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/commons-cli-1.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
<library name="commons-io-2.1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/commons-io-2.1.jar!/" />
Binary file not shown.
+3 -3
View File
@@ -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
+16 -6
View File
@@ -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<String> settings = new HashSet<String>();
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<String> 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<Element> 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;
}
@@ -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 <from> -t <to>");
System.exit(1);
}
static public List<File> getJavaFiles(String startDirName) throws FileNotFoundException {
return getJavaFiles(new File(startDirName));
}
private static List<File> getJavaFiles(File start) throws FileNotFoundException {
List<File> result = new ArrayList<File>();
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<File> deeperList = getJavaFiles(file);
result.addAll(deeperList);
}
}
return result;
}
}
@@ -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());
@@ -16,7 +16,7 @@ public class AnonymousClass extends Class {
Collections.<Type>emptyList(),
Collections.<Expression>emptyList(),
Collections.<Type>emptyList(),
members
getMembers(members)
);
}
+18 -3
View File
@@ -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<Expression> myBaseClassParams;
private final List<? extends Member> myMembers;
private final List<Member> myMembers;
private final List<Element> myTypeParameters;
private final List<Type> myExtendsTypes;
private final List<Type> myImplementsTypes;
public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
List<Expression> baseClassParams, List<Type> implementsTypes, List<? extends Member> members) {
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
myName = name;
myBaseClassParams = baseClassParams;
myModifiers = modifiers;
myTypeParameters = typeParameters;
myExtendsTypes = extendsTypes;
myImplementsTypes = implementsTypes;
myMembers = members;
myMembers= getMembers(members);
}
static List<Member> getMembers(List<Member> members) {
List<Member> withoutPrivate = new LinkedList<Member>();
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;
}
+1 -1
View File
@@ -12,7 +12,7 @@ import java.util.Set;
public class Enum extends Class {
public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
}
String primaryConstructorSignatureToKotlin() {
+1 -1
View File
@@ -9,7 +9,7 @@ import java.util.Set;
public class Trait extends Class {
public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
TYPE = "trait";
}
@@ -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<Type> {
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))