From 4f9011509cc4761a4576493a1c0755c8c48a53ad Mon Sep 17 00:00:00 2001 From: ignatov Date: Mon, 26 Dec 2011 14:05:46 +0400 Subject: [PATCH] KT-871 Add main function to generated code --- src/org/jetbrains/jet/j2k/Converter.java | 15 ++-- src/org/jetbrains/jet/j2k/ConverterUtil.java | 71 +++++++++++++++++++ src/org/jetbrains/jet/j2k/ast/File.java | 6 +- testData/ast/issues/file/kt-871.jav | 7 ++ testData/ast/issues/file/kt-871.kt | 9 +++ .../ast/switch/file/comlicatedFallDown.kt | 3 +- testData/ast/switch/file/fallDown.kt | 3 +- testData/ast/switch/file/kt-539.kt | 3 +- 8 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 src/org/jetbrains/jet/j2k/ConverterUtil.java create mode 100644 testData/ast/issues/file/kt-871.jav create mode 100644 testData/ast/issues/file/kt-871.kt diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java index 6dcb560d88c..f34f43f1fc3 100644 --- a/src/org/jetbrains/jet/j2k/Converter.java +++ b/src/org/jetbrains/jet/j2k/Converter.java @@ -14,6 +14,7 @@ import org.jetbrains.jet.j2k.visitors.*; import java.util.*; +import static org.jetbrains.jet.j2k.ConverterUtil.createMainFunction; import static org.jetbrains.jet.j2k.visitors.TypeVisitor.*; /** @@ -58,17 +59,21 @@ public class Converter { @NotNull public static File fileToFile(@NotNull PsiJavaFile javaFile) { - final PsiImportList importList = javaFile.getImportList(); - List imports = importList == null ? Collections.emptyList() : importsToImportList(importList.getAllImportStatements()); - return new File(quoteKeywords(javaFile.getPackageName()), imports, classesToClassList(javaFile.getClasses())); + return fileToFile(javaFile, Collections.emptyList()); } @NotNull public static File fileToFileWithCompatibilityImport(@NotNull PsiJavaFile javaFile) { + return fileToFile(javaFile, Collections.singletonList("std.compatibility.*")); + } + + @NotNull + private static File fileToFile(PsiJavaFile javaFile, List additionalImports) { final PsiImportList importList = javaFile.getImportList(); List imports = importList == null ? Collections.emptyList() : importsToImportList(importList.getAllImportStatements()); - imports.add(new Import("std.compatibility.*")); - return new File(quoteKeywords(javaFile.getPackageName()), imports, classesToClassList(javaFile.getClasses())); + for (String i : additionalImports) + imports.add(new Import(i)); + return new File(quoteKeywords(javaFile.getPackageName()), imports, classesToClassList(javaFile.getClasses()), createMainFunction(javaFile)); } @NotNull diff --git a/src/org/jetbrains/jet/j2k/ConverterUtil.java b/src/org/jetbrains/jet/j2k/ConverterUtil.java new file mode 100644 index 00000000000..eb04032aa7b --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ConverterUtil.java @@ -0,0 +1,71 @@ +package org.jetbrains.jet.j2k; + +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.text.MessageFormat; +import java.util.LinkedList; +import java.util.List; + +/** + * @author ignatov + */ +public class ConverterUtil { + private ConverterUtil() { + } + + @NotNull + public static String createMainFunction(@NotNull PsiFile file) { + List> classNamesWithMains = new LinkedList>(); + + for (PsiClass c : ((PsiJavaFile) file).getClasses()) { + PsiMethod main = findMainMethod(c); + if (main != null) { + classNamesWithMains.add(new Pair(c.getName(), main)); + } + } + if (classNamesWithMains.size() > 0) { + String className = classNamesWithMains.get(0).getFirst(); + return MessageFormat.format("fun main(args : Array?) = {0}.main(args)", className); + } + return ""; + } + + @Nullable + private static PsiMethod findMainMethod(@NotNull PsiClass aClass) { + if (isMainClass(aClass)) { + final PsiMethod[] mainMethods = aClass.findMethodsByName("main", false); + return findMainMethod(mainMethods); + } + return null; + } + + @Nullable + private static PsiMethod findMainMethod(@NotNull PsiMethod[] mainMethods) { + for (PsiMethod mainMethod : mainMethods) { + if (isMainMethod(mainMethod)) return mainMethod; + } + return null; + } + + private static boolean isMainClass(@NotNull PsiClass psiClass) { + if (psiClass instanceof PsiAnonymousClass) return false; + if (psiClass.isInterface()) return false; + return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC); + } + + public static boolean isMainMethod(@Nullable PsiMethod method) { + if (method == null || method.getContainingClass() == null) return false; + if (PsiType.VOID != method.getReturnType()) return false; + if (!method.hasModifierProperty(PsiModifier.STATIC)) return false; + if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return false; + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 1) return false; + final PsiType type = parameters[0].getType(); + if (!(type instanceof PsiArrayType)) return false; + final PsiType componentType = ((PsiArrayType) type).getComponentType(); + return componentType.equalsToText("java.lang.String"); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/File.java b/src/org/jetbrains/jet/j2k/ast/File.java index d599ec8ab4b..0dd63fa4fd6 100644 --- a/src/org/jetbrains/jet/j2k/ast/File.java +++ b/src/org/jetbrains/jet/j2k/ast/File.java @@ -12,17 +12,19 @@ public class File extends Node { private final String myPackageName; private final List myImports; private final List myClasses; + private final String myMainFunction; - public File(String packageName, List imports, List classes) { + public File(String packageName, List imports, List classes, String mainFunction) { myPackageName = packageName; myImports = imports; myClasses = classes; + myMainFunction = mainFunction; } @NotNull @Override public String toKotlin() { - final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N; + final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N + myMainFunction; if (myPackageName.isEmpty()) return common; return "package" + SPACE + myPackageName + N + diff --git a/testData/ast/issues/file/kt-871.jav b/testData/ast/issues/file/kt-871.jav new file mode 100644 index 00000000000..b49b8041fc5 --- /dev/null +++ b/testData/ast/issues/file/kt-871.jav @@ -0,0 +1,7 @@ +package demo; + +class Program { + public static void main(String[] args) { + System.out.println("Halo!"); + } +} \ No newline at end of file diff --git a/testData/ast/issues/file/kt-871.kt b/testData/ast/issues/file/kt-871.kt new file mode 100644 index 00000000000..84fd489ca76 --- /dev/null +++ b/testData/ast/issues/file/kt-871.kt @@ -0,0 +1,9 @@ +package demo +open class Program() { +class object { +open public fun main(args : Array?) : Unit { +System.out?.println("Halo!") +} +} +} +fun main(args : Array?) = Program.main(args) \ No newline at end of file diff --git a/testData/ast/switch/file/comlicatedFallDown.kt b/testData/ast/switch/file/comlicatedFallDown.kt index b1af2ce6ffa..27edb9beab0 100644 --- a/testData/ast/switch/file/comlicatedFallDown.kt +++ b/testData/ast/switch/file/comlicatedFallDown.kt @@ -84,4 +84,5 @@ open public fun main(args : Array?) : Unit { for (i in 1..12) test(i) } } -} \ No newline at end of file +} +fun main(args : Array?) = SwitchDemo.main(args) \ No newline at end of file diff --git a/testData/ast/switch/file/fallDown.kt b/testData/ast/switch/file/fallDown.kt index a237a7ee535..29bc8f10c2b 100644 --- a/testData/ast/switch/file/fallDown.kt +++ b/testData/ast/switch/file/fallDown.kt @@ -15,4 +15,5 @@ monthString = "Invalid month" System.out?.println(monthString) } } -} \ No newline at end of file +} +fun main(args : Array?) = SwitchDemo.main(args) \ No newline at end of file diff --git a/testData/ast/switch/file/kt-539.kt b/testData/ast/switch/file/kt-539.kt index 63fd0eaf959..db23ffbaf04 100644 --- a/testData/ast/switch/file/kt-539.kt +++ b/testData/ast/switch/file/kt-539.kt @@ -48,4 +48,5 @@ monthString = "Invalid month" System.out?.println(monthString) } } -} \ No newline at end of file +} +fun main(args : Array?) = SwitchDemo.main(args) \ No newline at end of file