Reformat code to use 4 spaces indent
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -16,101 +16,103 @@ import static org.jetbrains.jet.j2k.Converter.NOT_NULL_ANNOTATIONS;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ConverterUtil {
|
public class ConverterUtil {
|
||||||
private ConverterUtil() {
|
private ConverterUtil() {
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String createMainFunction(@NotNull PsiFile file) {
|
|
||||||
List<Pair<String, PsiMethod>> classNamesWithMains = new LinkedList<Pair<String, PsiMethod>>();
|
|
||||||
|
|
||||||
for (PsiClass c : ((PsiJavaFile) file).getClasses()) {
|
|
||||||
PsiMethod main = findMainMethod(c);
|
|
||||||
if (main != null) {
|
|
||||||
classNamesWithMains.add(new Pair<String, PsiMethod>(c.getName(), main));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (classNamesWithMains.size() > 0) {
|
|
||||||
String className = classNamesWithMains.get(0).getFirst();
|
|
||||||
return MessageFormat.format("fun main(args : Array<String?>?) = {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");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int countWritingAccesses(@Nullable PsiElement element, @Nullable PsiElement container) {
|
|
||||||
int counter = 0;
|
|
||||||
if (container != null) {
|
|
||||||
ReferenceCollector visitor = new ReferenceCollector();
|
|
||||||
container.accept(visitor);
|
|
||||||
for (PsiReferenceExpression e : visitor.getCollectedReferences())
|
|
||||||
if (e.isReferenceTo(element) && PsiUtil.isAccessedForWriting(e))
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isReadOnly(PsiElement element, PsiElement container) {
|
|
||||||
return countWritingAccesses(element, container) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAnnotatedAsNotNull(@Nullable PsiModifierList modifierList) {
|
|
||||||
if (modifierList != null) {
|
|
||||||
PsiAnnotation[] annotations = modifierList.getAnnotations();
|
|
||||||
for (PsiAnnotation a : annotations) {
|
|
||||||
String qualifiedName = a.getQualifiedName();
|
|
||||||
if (qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ReferenceCollector extends JavaRecursiveElementVisitor {
|
|
||||||
public List<PsiReferenceExpression> getCollectedReferences() {
|
|
||||||
return myCollectedReferences;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PsiReferenceExpression> myCollectedReferences = new LinkedList<PsiReferenceExpression>();
|
@NotNull
|
||||||
|
public static String createMainFunction(@NotNull PsiFile file) {
|
||||||
|
List<Pair<String, PsiMethod>> classNamesWithMains = new LinkedList<Pair<String, PsiMethod>>();
|
||||||
|
|
||||||
@Override
|
for (PsiClass c : ((PsiJavaFile) file).getClasses()) {
|
||||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
PsiMethod main = findMainMethod(c);
|
||||||
super.visitReferenceExpression(expression);
|
if (main != null) {
|
||||||
myCollectedReferences.add(expression);
|
classNamesWithMains.add(new Pair<String, PsiMethod>(c.getName(), main));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (classNamesWithMains.size() > 0) {
|
||||||
|
String className = classNamesWithMains.get(0).getFirst();
|
||||||
|
return MessageFormat.format("fun main(args : Array<String?>?) = {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");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countWritingAccesses(@Nullable PsiElement element, @Nullable PsiElement container) {
|
||||||
|
int counter = 0;
|
||||||
|
if (container != null) {
|
||||||
|
ReferenceCollector visitor = new ReferenceCollector();
|
||||||
|
container.accept(visitor);
|
||||||
|
for (PsiReferenceExpression e : visitor.getCollectedReferences())
|
||||||
|
if (e.isReferenceTo(element) && PsiUtil.isAccessedForWriting(e)) {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isReadOnly(PsiElement element, PsiElement container) {
|
||||||
|
return countWritingAccesses(element, container) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAnnotatedAsNotNull(@Nullable PsiModifierList modifierList) {
|
||||||
|
if (modifierList != null) {
|
||||||
|
PsiAnnotation[] annotations = modifierList.getAnnotations();
|
||||||
|
for (PsiAnnotation a : annotations) {
|
||||||
|
String qualifiedName = a.getQualifiedName();
|
||||||
|
if (qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ReferenceCollector extends JavaRecursiveElementVisitor {
|
||||||
|
public List<PsiReferenceExpression> getCollectedReferences() {
|
||||||
|
return myCollectedReferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PsiReferenceExpression> myCollectedReferences = new LinkedList<PsiReferenceExpression>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||||
|
super.visitReferenceExpression(expression);
|
||||||
|
myCollectedReferences.add(expression);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,178 +38,185 @@ import java.net.URLClassLoader;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class JavaToKotlinTranslator {
|
public class JavaToKotlinTranslator {
|
||||||
private JavaToKotlinTranslator() {
|
private JavaToKotlinTranslator() {
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static PsiFile createFile(@NotNull String text) {
|
|
||||||
JavaCoreEnvironment javaCoreEnvironment = setUpJavaCoreEnvironment();
|
|
||||||
return PsiFileFactory.getInstance(javaCoreEnvironment.getProject()).createFileFromText(
|
|
||||||
"test.java", JavaLanguage.INSTANCE, text
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
static PsiFile createFile(@NotNull JavaCoreEnvironment javaCoreEnvironment, @NotNull String text) {
|
|
||||||
return PsiFileFactory.getInstance(javaCoreEnvironment.getProject()).createFileFromText(
|
|
||||||
"test.java", JavaLanguage.INSTANCE, text
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static JavaCoreEnvironment setUpJavaCoreEnvironment() {
|
|
||||||
JavaCoreEnvironment javaCoreEnvironment = new JavaCoreEnvironment(new Disposable() {
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
javaCoreEnvironment.addToClasspath(findRtJar());
|
|
||||||
File annotations = findAnnotations();
|
|
||||||
if (annotations != null && annotations.exists()) {
|
|
||||||
javaCoreEnvironment.addToClasspath(annotations);
|
|
||||||
}
|
|
||||||
return javaCoreEnvironment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
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()
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static File findRtJar() {
|
|
||||||
String javaHome = System.getenv("JAVA_HOME");
|
|
||||||
File rtJar;
|
|
||||||
if (javaHome == null) {
|
|
||||||
rtJar = findActiveRtJar(true);
|
|
||||||
|
|
||||||
if (rtJar == null) {
|
|
||||||
throw new SetupJavaCoreEnvironmentException("JAVA_HOME environment variable needs to be defined");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rtJar = findRtJar(javaHome);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtJar == null || !rtJar.exists()) {
|
@Nullable
|
||||||
rtJar = findActiveRtJar(true);
|
private static PsiFile createFile(@NotNull String text) {
|
||||||
|
JavaCoreEnvironment javaCoreEnvironment = setUpJavaCoreEnvironment();
|
||||||
if ((rtJar == null || !rtJar.exists())) {
|
return PsiFileFactory.getInstance(javaCoreEnvironment.getProject()).createFileFromText(
|
||||||
throw new SetupJavaCoreEnvironmentException("No rt.jar found under JAVA_HOME=" + javaHome);
|
"test.java", JavaLanguage.INSTANCE, text
|
||||||
}
|
);
|
||||||
}
|
|
||||||
return rtJar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static File findRtJar(String javaHome) {
|
|
||||||
File rtJar = new File(javaHome, "jre/lib/rt.jar");
|
|
||||||
if (rtJar.exists()) {
|
|
||||||
return rtJar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
File classesJar = new File(new File(javaHome).getParentFile().getAbsolutePath(), "Classes/classes.jar");
|
@Nullable
|
||||||
if (classesJar.exists()) {
|
static PsiFile createFile(@NotNull JavaCoreEnvironment javaCoreEnvironment, @NotNull String text) {
|
||||||
return classesJar;
|
return PsiFileFactory.getInstance(javaCoreEnvironment.getProject()).createFileFromText(
|
||||||
|
"test.java", JavaLanguage.INSTANCE, text
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@NotNull
|
||||||
private static File findAnnotations() {
|
static JavaCoreEnvironment setUpJavaCoreEnvironment() {
|
||||||
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
JavaCoreEnvironment javaCoreEnvironment = new JavaCoreEnvironment(new Disposable() {
|
||||||
if (systemClassLoader instanceof URLClassLoader) {
|
@Override
|
||||||
URLClassLoader loader = (URLClassLoader) systemClassLoader;
|
public void dispose() {
|
||||||
for (URL url : loader.getURLs())
|
}
|
||||||
if ("file".equals(url.getProtocol()) && url.getFile().endsWith("/annotations.jar"))
|
});
|
||||||
return new File(url.getFile());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
javaCoreEnvironment.addToClasspath(findRtJar());
|
||||||
private static File findActiveRtJar(boolean failOnError) {
|
File annotations = findAnnotations();
|
||||||
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
if (annotations != null && annotations.exists()) {
|
||||||
if (systemClassLoader instanceof URLClassLoader) {
|
javaCoreEnvironment.addToClasspath(annotations);
|
||||||
URLClassLoader loader = (URLClassLoader) systemClassLoader;
|
|
||||||
for (URL url : loader.getURLs()) {
|
|
||||||
if ("file".equals(url.getProtocol())) {
|
|
||||||
if (url.getFile().endsWith("/lib/rt.jar")) {
|
|
||||||
return new File(url.getFile());
|
|
||||||
}
|
|
||||||
if (url.getFile().endsWith("/Classes/classes.jar")) {
|
|
||||||
return new File(url.getFile()).getAbsoluteFile();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
return javaCoreEnvironment;
|
||||||
if (failOnError) {
|
|
||||||
throw new SetupJavaCoreEnvironmentException("Could not find rt.jar in system class loader: " + StringUtil.join(loader.getURLs(), new Function<URL, String>() {
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String fun(@NotNull URL url) {
|
|
||||||
return url.toString() + "\n";
|
|
||||||
}
|
|
||||||
}, ", "));
|
|
||||||
}
|
|
||||||
} else if (failOnError) {
|
|
||||||
throw new SetupJavaCoreEnvironmentException("System class loader is not an URLClassLoader: " + systemClassLoader);
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setClassIdentifiers(@NotNull PsiElement psiFile) {
|
@NotNull
|
||||||
ClassVisitor c = new ClassVisitor();
|
static String prettify(@Nullable String code) {
|
||||||
psiFile.accept(c);
|
if (code == null) {
|
||||||
Converter.clearClassIdentifiers();
|
return "";
|
||||||
Converter.setClassIdentifiers(c.getClassIdentifiers());
|
}
|
||||||
}
|
return code
|
||||||
|
.trim()
|
||||||
@NotNull
|
.replaceAll("\r\n", "\n")
|
||||||
static String generateKotlinCode(@NotNull String javaCode) {
|
.replaceAll(" \n", "\n")
|
||||||
PsiFile file = createFile(javaCode);
|
.replaceAll("\n ", "\n")
|
||||||
if (file != null && file instanceof PsiJavaFile) {
|
.replaceAll("\n+", "\n")
|
||||||
setClassIdentifiers(file);
|
.replaceAll(" +", " ")
|
||||||
return prettify(Converter.fileToFile((PsiJavaFile) file).toKotlin());
|
.trim()
|
||||||
|
;
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@Nullable
|
||||||
static String generateKotlinCodeWithCompatibilityImport(@NotNull String javaCode) {
|
private static File findRtJar() {
|
||||||
PsiFile file = createFile(javaCode);
|
String javaHome = System.getenv("JAVA_HOME");
|
||||||
if (file != null && file instanceof PsiJavaFile) {
|
File rtJar;
|
||||||
setClassIdentifiers(file);
|
if (javaHome == null) {
|
||||||
return prettify(Converter.fileToFileWithCompatibilityImport((PsiJavaFile) file).toKotlin());
|
rtJar = findActiveRtJar(true);
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(@NotNull String[] args) throws IOException {
|
if (rtJar == null) {
|
||||||
//noinspection UseOfSystemOutOrSystemErr
|
throw new SetupJavaCoreEnvironmentException("JAVA_HOME environment variable needs to be defined");
|
||||||
final PrintStream out = System.out;
|
}
|
||||||
if (args.length == 1) {
|
}
|
||||||
String kotlinCode = "";
|
else {
|
||||||
try {
|
rtJar = findRtJar(javaHome);
|
||||||
kotlinCode = generateKotlinCode(args[0]);
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
out.println("EXCEPTION: " + e.getMessage());
|
if (rtJar == null || !rtJar.exists()) {
|
||||||
}
|
rtJar = findActiveRtJar(true);
|
||||||
if (kotlinCode.isEmpty())
|
|
||||||
out.println("EXCEPTION: generated code is empty.");
|
if ((rtJar == null || !rtJar.exists())) {
|
||||||
else
|
throw new SetupJavaCoreEnvironmentException("No rt.jar found under JAVA_HOME=" + javaHome);
|
||||||
out.println(kotlinCode);
|
}
|
||||||
} else {
|
}
|
||||||
out.println("EXCEPTION: wrong number of arguments (should be 1).");
|
return rtJar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static File findRtJar(String javaHome) {
|
||||||
|
File rtJar = new File(javaHome, "jre/lib/rt.jar");
|
||||||
|
if (rtJar.exists()) {
|
||||||
|
return rtJar;
|
||||||
|
}
|
||||||
|
|
||||||
|
File classesJar = new File(new File(javaHome).getParentFile().getAbsolutePath(), "Classes/classes.jar");
|
||||||
|
if (classesJar.exists()) {
|
||||||
|
return classesJar;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static File findAnnotations() {
|
||||||
|
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
if (systemClassLoader instanceof URLClassLoader) {
|
||||||
|
URLClassLoader loader = (URLClassLoader) systemClassLoader;
|
||||||
|
for (URL url : loader.getURLs())
|
||||||
|
if ("file".equals(url.getProtocol()) && url.getFile().endsWith("/annotations.jar")) {
|
||||||
|
return new File(url.getFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static File findActiveRtJar(boolean failOnError) {
|
||||||
|
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
if (systemClassLoader instanceof URLClassLoader) {
|
||||||
|
URLClassLoader loader = (URLClassLoader) systemClassLoader;
|
||||||
|
for (URL url : loader.getURLs()) {
|
||||||
|
if ("file".equals(url.getProtocol())) {
|
||||||
|
if (url.getFile().endsWith("/lib/rt.jar")) {
|
||||||
|
return new File(url.getFile());
|
||||||
|
}
|
||||||
|
if (url.getFile().endsWith("/Classes/classes.jar")) {
|
||||||
|
return new File(url.getFile()).getAbsoluteFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failOnError) {
|
||||||
|
throw new SetupJavaCoreEnvironmentException("Could not find rt.jar in system class loader: " + StringUtil.join(loader.getURLs(), new Function<URL, String>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String fun(@NotNull URL url) {
|
||||||
|
return url.toString() + "\n";
|
||||||
|
}
|
||||||
|
}, ", "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (failOnError) {
|
||||||
|
throw new SetupJavaCoreEnvironmentException("System class loader is not an URLClassLoader: " + systemClassLoader);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setClassIdentifiers(@NotNull PsiElement psiFile) {
|
||||||
|
ClassVisitor c = new ClassVisitor();
|
||||||
|
psiFile.accept(c);
|
||||||
|
Converter.clearClassIdentifiers();
|
||||||
|
Converter.setClassIdentifiers(c.getClassIdentifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(@NotNull String[] args) throws IOException {
|
||||||
|
//noinspection UseOfSystemOutOrSystemErr
|
||||||
|
final PrintStream out = System.out;
|
||||||
|
if (args.length == 1) {
|
||||||
|
String kotlinCode = "";
|
||||||
|
try {
|
||||||
|
kotlinCode = generateKotlinCode(args[0]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
out.println("EXCEPTION: " + e.getMessage());
|
||||||
|
}
|
||||||
|
if (kotlinCode.isEmpty()) {
|
||||||
|
out.println("EXCEPTION: generated code is empty.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.println(kotlinCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.println("EXCEPTION: wrong number of arguments (should be 1).");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ package org.jetbrains.jet.j2k;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SetupJavaCoreEnvironmentException extends RuntimeException {
|
public class SetupJavaCoreEnvironmentException extends RuntimeException {
|
||||||
public SetupJavaCoreEnvironmentException(String s) {
|
public SetupJavaCoreEnvironmentException(String s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,20 +9,20 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class AnonymousClass extends Class {
|
public class AnonymousClass extends Class {
|
||||||
public AnonymousClass(List<Member> members) {
|
public AnonymousClass(List<Member> members) {
|
||||||
super(new IdentifierImpl("anonClass"),
|
super(new IdentifierImpl("anonClass"),
|
||||||
Collections.<String>emptySet(),
|
Collections.<String>emptySet(),
|
||||||
Collections.<Element>emptyList(),
|
Collections.<Element>emptyList(),
|
||||||
Collections.<Type>emptyList(),
|
Collections.<Type>emptyList(),
|
||||||
Collections.<Expression>emptyList(),
|
Collections.<Expression>emptyList(),
|
||||||
Collections.<Type>emptyList(),
|
Collections.<Type>emptyList(),
|
||||||
getMembers(members)
|
getMembers(members)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return bodyToKotlin();
|
return bodyToKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ArrayAccessExpression extends Expression {
|
public class ArrayAccessExpression extends Expression {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final Expression myIndex;
|
private final Expression myIndex;
|
||||||
|
|
||||||
public ArrayAccessExpression(Expression expression, Expression index) {
|
public ArrayAccessExpression(Expression expression, Expression index) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myIndex = index;
|
myIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myExpression.toKotlin() + "[" + myIndex.toKotlin() + "]";
|
return myExpression.toKotlin() + "[" + myIndex.toKotlin() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,62 +9,64 @@ import java.util.*;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ArrayInitializerExpression extends Expression {
|
public class ArrayInitializerExpression extends Expression {
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
private final List<Expression> myInitializers;
|
private final List<Expression> myInitializers;
|
||||||
|
|
||||||
public ArrayInitializerExpression(final Type type, List<Expression> initializers) {
|
public ArrayInitializerExpression(final Type type, List<Expression> initializers) {
|
||||||
myType = type;
|
myType = type;
|
||||||
myInitializers = initializers;
|
myInitializers = initializers;
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String createArrayFunction(@NotNull final Type type) {
|
|
||||||
String sType = innerTypeStr(type);
|
|
||||||
if (PRIMITIVE_TYPES.contains(sType))
|
|
||||||
return sType + "Array"; // intArray
|
|
||||||
return AstUtil.lowerFirstCharacter(type.convertedToNotNull().toKotlin()); // array<Foo?>
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String innerTypeStr(@NotNull final Type type) {
|
|
||||||
return type.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String createInitializers(@NotNull final Type type, @NotNull final List<Expression> initializers) {
|
|
||||||
List<String> arguments = new LinkedList<String>();
|
|
||||||
for (Expression i : initializers)
|
|
||||||
arguments.add(explicitConvertIfNeeded(type, i));
|
|
||||||
return AstUtil.join(arguments, COMMA_WITH_SPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String explicitConvertIfNeeded(@NotNull final Type type, @NotNull final Expression i) {
|
|
||||||
Set<String> doubleOrFloatTypes = new HashSet<String>(
|
|
||||||
Arrays.asList("double", "float", "java.lang.double", "java.lang.float")
|
|
||||||
);
|
|
||||||
String afterReplace = innerTypeStr(type).replace(">", "").replace("<", "").replace("?", "");
|
|
||||||
if (doubleOrFloatTypes.contains(afterReplace)) {
|
|
||||||
if (i.getKind() == Kind.LITERAL) {
|
|
||||||
if (i.toKotlin().contains("."))
|
|
||||||
return i.toKotlin();
|
|
||||||
return i.toKotlin() + DOT + ZERO;
|
|
||||||
}
|
|
||||||
return "(" + i.toKotlin() + ")" + getConversion(afterReplace);
|
|
||||||
}
|
}
|
||||||
return i.toKotlin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String getConversion(@NotNull final String afterReplace) {
|
private static String createArrayFunction(@NotNull final Type type) {
|
||||||
if (afterReplace.contains("double")) return DOT + "dbl";
|
String sType = innerTypeStr(type);
|
||||||
if (afterReplace.contains("float")) return DOT + "flt";
|
if (PRIMITIVE_TYPES.contains(sType)) {
|
||||||
return "";
|
return sType + "Array"; // intArray
|
||||||
}
|
}
|
||||||
|
return AstUtil.lowerFirstCharacter(type.convertedToNotNull().toKotlin()); // array<Foo?>
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
private static String innerTypeStr(@NotNull final Type type) {
|
||||||
public String toKotlin() {
|
return type.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase();
|
||||||
return createArrayFunction(myType) + "(" + createInitializers(myType, myInitializers) + ")";
|
}
|
||||||
}
|
|
||||||
|
@NotNull
|
||||||
|
private static String createInitializers(@NotNull final Type type, @NotNull final List<Expression> initializers) {
|
||||||
|
List<String> arguments = new LinkedList<String>();
|
||||||
|
for (Expression i : initializers)
|
||||||
|
arguments.add(explicitConvertIfNeeded(type, i));
|
||||||
|
return AstUtil.join(arguments, COMMA_WITH_SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String explicitConvertIfNeeded(@NotNull final Type type, @NotNull final Expression i) {
|
||||||
|
Set<String> doubleOrFloatTypes = new HashSet<String>(
|
||||||
|
Arrays.asList("double", "float", "java.lang.double", "java.lang.float")
|
||||||
|
);
|
||||||
|
String afterReplace = innerTypeStr(type).replace(">", "").replace("<", "").replace("?", "");
|
||||||
|
if (doubleOrFloatTypes.contains(afterReplace)) {
|
||||||
|
if (i.getKind() == Kind.LITERAL) {
|
||||||
|
if (i.toKotlin().contains(".")) {
|
||||||
|
return i.toKotlin();
|
||||||
|
}
|
||||||
|
return i.toKotlin() + DOT + ZERO;
|
||||||
|
}
|
||||||
|
return "(" + i.toKotlin() + ")" + getConversion(afterReplace);
|
||||||
|
}
|
||||||
|
return i.toKotlin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getConversion(@NotNull final String afterReplace) {
|
||||||
|
if (afterReplace.contains("double")) return DOT + "dbl";
|
||||||
|
if (afterReplace.contains("float")) return DOT + "flt";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return createArrayFunction(myType) + "(" + createInitializers(myType, myInitializers) + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,27 +6,28 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ArrayType extends Type {
|
public class ArrayType extends Type {
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
|
|
||||||
public ArrayType(Type type) {
|
public ArrayType(Type type) {
|
||||||
myType = type;
|
myType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getInnerType() {
|
public Type getInnerType() {
|
||||||
return myType;
|
return myType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.ARRAY_TYPE;
|
return Kind.ARRAY_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (PRIMITIVE_TYPES.contains(myType.toKotlin().toLowerCase()))
|
if (PRIMITIVE_TYPES.contains(myType.toKotlin().toLowerCase())) {
|
||||||
return myType.toKotlin() + "Array" + isNullableStr(); // returns IntArray, BooleanArray, etc.
|
return myType.toKotlin() + "Array" + isNullableStr(); // returns IntArray, BooleanArray, etc.
|
||||||
return "Array" + "<" + myType.toKotlin() + ">" + isNullableStr();
|
}
|
||||||
}
|
return "Array" + "<" + myType.toKotlin() + ">" + isNullableStr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,45 +9,48 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ArrayWithoutInitializationExpression extends Expression {
|
public class ArrayWithoutInitializationExpression extends Expression {
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
private final List<Expression> myExpressions;
|
private final List<Expression> myExpressions;
|
||||||
|
|
||||||
public ArrayWithoutInitializationExpression(Type type, List<Expression> expressions) {
|
public ArrayWithoutInitializationExpression(Type type, List<Expression> expressions) {
|
||||||
myType = type;
|
myType = type;
|
||||||
myExpressions = expressions;
|
myExpressions = expressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myType.getKind() == Kind.ARRAY_TYPE)
|
if (myType.getKind() == Kind.ARRAY_TYPE) {
|
||||||
return constructInnerType((ArrayType) myType, myExpressions);
|
return constructInnerType((ArrayType) myType, myExpressions);
|
||||||
return getConstructorName(myType);
|
}
|
||||||
}
|
return getConstructorName(myType);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String constructInnerType(@NotNull ArrayType hostType, @NotNull List<Expression> expressions) {
|
private static String constructInnerType(@NotNull ArrayType hostType, @NotNull List<Expression> expressions) {
|
||||||
if (expressions.size() == 1)
|
if (expressions.size() == 1) {
|
||||||
return oneDim(hostType, expressions.get(0));
|
return oneDim(hostType, expressions.get(0));
|
||||||
Type innerType = hostType.getInnerType();
|
}
|
||||||
if (expressions.size() > 1 && innerType.getKind() == Kind.ARRAY_TYPE)
|
Type innerType = hostType.getInnerType();
|
||||||
return oneDim(hostType, expressions.get(0), "{" + constructInnerType((ArrayType) innerType, expressions.subList(1, expressions.size())) + "}");
|
if (expressions.size() > 1 && innerType.getKind() == Kind.ARRAY_TYPE) {
|
||||||
return getConstructorName(hostType);
|
return oneDim(hostType, expressions.get(0), "{" + constructInnerType((ArrayType) innerType, expressions.subList(1, expressions.size())) + "}");
|
||||||
}
|
}
|
||||||
|
return getConstructorName(hostType);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String oneDim(@NotNull Type type, @NotNull Expression size) {
|
private static String oneDim(@NotNull Type type, @NotNull Expression size) {
|
||||||
return oneDim(type, size, EMPTY);
|
return oneDim(type, size, EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String oneDim(@NotNull Type type, @NotNull Expression size, @NotNull String init) {
|
private static String oneDim(@NotNull Type type, @NotNull Expression size, @NotNull String init) {
|
||||||
String commaWithInit = init.isEmpty() ? EMPTY : COMMA_WITH_SPACE + init;
|
String commaWithInit = init.isEmpty() ? EMPTY : COMMA_WITH_SPACE + init;
|
||||||
return getConstructorName(type) + "(" + size.toKotlin() + commaWithInit + ")";
|
return getConstructorName(type) + "(" + size.toKotlin() + commaWithInit + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String getConstructorName(@NotNull Type type) {
|
private static String getConstructorName(@NotNull Type type) {
|
||||||
return AstUtil.replaceLastQuest(type.toKotlin());
|
return AstUtil.replaceLastQuest(type.toKotlin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class AssertStatement extends Statement {
|
public class AssertStatement extends Statement {
|
||||||
private final Expression myCondition;
|
private final Expression myCondition;
|
||||||
private final Expression myDetail;
|
private final Expression myDetail;
|
||||||
|
|
||||||
public AssertStatement(Expression condition, Expression detail) {
|
public AssertStatement(Expression condition, Expression detail) {
|
||||||
myCondition = condition;
|
myCondition = condition;
|
||||||
myDetail = detail;
|
myDetail = detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
String detail = myDetail != Expression.EMPTY_EXPRESSION ? "(" + myDetail.toKotlin() + ")" : EMPTY;
|
String detail = myDetail != Expression.EMPTY_EXPRESSION ? "(" + myDetail.toKotlin() + ")" : EMPTY;
|
||||||
return "assert" + detail + SPACE + "{" + myCondition.toKotlin() + "}";
|
return "assert" + detail + SPACE + "{" + myCondition.toKotlin() + "}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,33 +6,33 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class AssignmentExpression extends Expression {
|
public class AssignmentExpression extends Expression {
|
||||||
private final Expression myLeft;
|
private final Expression myLeft;
|
||||||
private final Expression myRight;
|
private final Expression myRight;
|
||||||
private final String myOp;
|
private final String myOp;
|
||||||
|
|
||||||
public Expression getLeft() {
|
public Expression getLeft() {
|
||||||
return myLeft;
|
return myLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression getRight() {
|
public Expression getRight() {
|
||||||
return myRight;
|
return myRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssignmentExpression(Expression left, Expression right, String op) {
|
public AssignmentExpression(Expression left, Expression right, String op) {
|
||||||
myLeft = left;
|
myLeft = left;
|
||||||
myRight = right;
|
myRight = right;
|
||||||
myOp = op;
|
myOp = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myLeft.toKotlin() + SPACE + myOp + SPACE + myRight.toKotlin();
|
return myLeft.toKotlin() + SPACE + myOp + SPACE + myRight.toKotlin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.ASSIGNMENT_EXPRESSION;
|
return Kind.ASSIGNMENT_EXPRESSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,26 +10,26 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class BinaryExpression extends Expression {
|
public class BinaryExpression extends Expression {
|
||||||
private final Expression myLeft;
|
private final Expression myLeft;
|
||||||
private final Expression myRight;
|
private final Expression myRight;
|
||||||
private final String myOp;
|
private final String myOp;
|
||||||
private final List<String> myConversions;
|
private final List<String> myConversions;
|
||||||
|
|
||||||
public BinaryExpression(Expression left, Expression right, String op) {
|
public BinaryExpression(Expression left, Expression right, String op) {
|
||||||
this(left, right, op, Arrays.asList("", ""));
|
this(left, right, op, Arrays.asList("", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryExpression(Expression left, Expression right, String op, List<String> conversions) {
|
public BinaryExpression(Expression left, Expression right, String op, List<String> conversions) {
|
||||||
myLeft = left;
|
myLeft = left;
|
||||||
myRight = right;
|
myRight = right;
|
||||||
myOp = op;
|
myOp = op;
|
||||||
myConversions = conversions;
|
myConversions = conversions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
List<String> expressionsWithConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(Arrays.asList(myLeft, myRight)), myConversions);
|
List<String> expressionsWithConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(Arrays.asList(myLeft, myRight)), myConversions);
|
||||||
return AstUtil.join(expressionsWithConversions, SPACE + myOp + SPACE);
|
return AstUtil.join(expressionsWithConversions, SPACE + myOp + SPACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,42 +10,43 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Block extends Statement {
|
public class Block extends Statement {
|
||||||
@NotNull
|
@NotNull
|
||||||
public final static Block EMPTY_BLOCK = new Block();
|
public final static Block EMPTY_BLOCK = new Block();
|
||||||
|
|
||||||
private List<Statement> myStatements;
|
private List<Statement> myStatements;
|
||||||
private boolean myNotEmpty = false;
|
private boolean myNotEmpty = false;
|
||||||
|
|
||||||
private Block() {
|
private Block() {
|
||||||
myStatements = new LinkedList<Statement>();
|
myStatements = new LinkedList<Statement>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block(List<Statement> statements) {
|
public Block(List<Statement> statements) {
|
||||||
myStatements = new LinkedList<Statement>();
|
myStatements = new LinkedList<Statement>();
|
||||||
myStatements = statements;
|
myStatements = statements;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block(List<Statement> statements, boolean notEmpty) {
|
public Block(List<Statement> statements, boolean notEmpty) {
|
||||||
myStatements = new LinkedList<Statement>();
|
myStatements = new LinkedList<Statement>();
|
||||||
myStatements = statements;
|
myStatements = statements;
|
||||||
myNotEmpty = notEmpty;
|
myNotEmpty = notEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return !myNotEmpty && myStatements.size() == 0;
|
return !myNotEmpty && myStatements.size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Statement> getStatements() {
|
public List<Statement> getStatements() {
|
||||||
return myStatements;
|
return myStatements;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (!isEmpty())
|
if (!isEmpty()) {
|
||||||
return "{" + N +
|
return "{" + N +
|
||||||
AstUtil.joinNodes(myStatements, N) + N +
|
AstUtil.joinNodes(myStatements, N) + N +
|
||||||
"}";
|
"}";
|
||||||
return EMPTY;
|
}
|
||||||
}
|
return EMPTY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,27 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class BreakStatement extends Statement {
|
public class BreakStatement extends Statement {
|
||||||
private Identifier myLabel = Identifier.EMPTY_IDENTIFIER;
|
private Identifier myLabel = Identifier.EMPTY_IDENTIFIER;
|
||||||
|
|
||||||
public BreakStatement(Identifier label) {
|
public BreakStatement(Identifier label) {
|
||||||
myLabel = label;
|
myLabel = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BreakStatement() {
|
public BreakStatement() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.BREAK;
|
return Kind.BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myLabel.isEmpty())
|
if (myLabel.isEmpty()) {
|
||||||
return "break";
|
return "break";
|
||||||
return "break" + AT + myLabel.toKotlin();
|
}
|
||||||
}
|
return "break" + AT + myLabel.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,37 +6,40 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class CallChainExpression extends Expression {
|
public class CallChainExpression extends Expression {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final Expression myIdentifier;
|
private final Expression myIdentifier;
|
||||||
|
|
||||||
public Expression getIdentifier() {
|
public Expression getIdentifier() {
|
||||||
return myIdentifier;
|
return myIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.CALL_CHAIN;
|
return Kind.CALL_CHAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CallChainExpression(Expression expression, Expression identifier) {
|
public CallChainExpression(Expression expression, Expression identifier) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return myIdentifier.isNullable();
|
return myIdentifier.isNullable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (!myExpression.isEmpty())
|
if (!myExpression.isEmpty()) {
|
||||||
if (myExpression.isNullable())
|
if (myExpression.isNullable()) {
|
||||||
return myExpression.toKotlin() + QUESTDOT + myIdentifier.toKotlin();
|
return myExpression.toKotlin() + QUESTDOT + myIdentifier.toKotlin();
|
||||||
else
|
}
|
||||||
return myExpression.toKotlin() + DOT + myIdentifier.toKotlin();
|
else {
|
||||||
return myIdentifier.toKotlin();
|
return myExpression.toKotlin() + DOT + myIdentifier.toKotlin();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return myIdentifier.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,21 +10,22 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class CaseContainer extends Statement {
|
public class CaseContainer extends Statement {
|
||||||
private final List<Statement> myCaseStatement;
|
private final List<Statement> myCaseStatement;
|
||||||
private final Block myBlock;
|
private final Block myBlock;
|
||||||
|
|
||||||
public CaseContainer(final List<Statement> caseStatement, @NotNull final List<Statement> statements) {
|
public CaseContainer(final List<Statement> caseStatement, @NotNull final List<Statement> statements) {
|
||||||
myCaseStatement = caseStatement;
|
myCaseStatement = caseStatement;
|
||||||
List<Statement> newStatements = new LinkedList<Statement>();
|
List<Statement> newStatements = new LinkedList<Statement>();
|
||||||
for (Statement s : statements)
|
for (Statement s : statements)
|
||||||
if (s.getKind() != Kind.BREAK && s.getKind() != Kind.CONTINUE)
|
if (s.getKind() != Kind.BREAK && s.getKind() != Kind.CONTINUE) {
|
||||||
newStatements.add(s);
|
newStatements.add(s);
|
||||||
myBlock = new Block(newStatements);
|
}
|
||||||
}
|
myBlock = new Block(newStatements);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return AstUtil.joinNodes(myCaseStatement, COMMA_WITH_SPACE) + SPACE + "->" + SPACE + myBlock.toKotlin();
|
return AstUtil.joinNodes(myCaseStatement, COMMA_WITH_SPACE) + SPACE + "->" + SPACE + myBlock.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class CatchStatement extends Statement {
|
public class CatchStatement extends Statement {
|
||||||
private final Parameter myVariable;
|
private final Parameter myVariable;
|
||||||
private final Block myBlock;
|
private final Block myBlock;
|
||||||
|
|
||||||
public CatchStatement(Parameter variable, Block block) {
|
public CatchStatement(Parameter variable, Block block) {
|
||||||
myVariable = variable;
|
myVariable = variable;
|
||||||
myBlock = block;
|
myBlock = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "catch" + SPACE + "(" + myVariable.toKotlin() + ")" + SPACE + myBlock.toKotlin();
|
return "catch" + SPACE + "(" + myVariable.toKotlin() + ")" + SPACE + myBlock.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,221 +16,237 @@ import static org.jetbrains.jet.j2k.util.AstUtil.*;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Class extends Member {
|
public class Class extends Member {
|
||||||
@NotNull
|
@NotNull
|
||||||
String TYPE = "class";
|
String TYPE = "class";
|
||||||
final Identifier myName;
|
final Identifier myName;
|
||||||
private final List<Expression> myBaseClassParams;
|
private final List<Expression> myBaseClassParams;
|
||||||
private final List<Member> myMembers;
|
private final List<Member> myMembers;
|
||||||
private final List<Element> myTypeParameters;
|
private final List<Element> myTypeParameters;
|
||||||
private final List<Type> myExtendsTypes;
|
private final List<Type> myExtendsTypes;
|
||||||
private final List<Type> myImplementsTypes;
|
private final List<Type> myImplementsTypes;
|
||||||
|
|
||||||
public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
|
public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
|
||||||
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
|
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
|
||||||
myName = name;
|
myName = name;
|
||||||
myBaseClassParams = baseClassParams;
|
myBaseClassParams = baseClassParams;
|
||||||
myModifiers = modifiers;
|
myModifiers = modifiers;
|
||||||
myTypeParameters = typeParameters;
|
myTypeParameters = typeParameters;
|
||||||
myExtendsTypes = extendsTypes;
|
myExtendsTypes = extendsTypes;
|
||||||
myImplementsTypes = implementsTypes;
|
myImplementsTypes = implementsTypes;
|
||||||
myMembers= getMembers(members);
|
myMembers = getMembers(members);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Member> getMembers(List<Member> members) {
|
static List<Member> getMembers(List<Member> members) {
|
||||||
List<Member> withoutPrivate = new LinkedList<Member>();
|
List<Member> withoutPrivate = new LinkedList<Member>();
|
||||||
if (Converter.hasSetting("public-only")) {
|
if (Converter.hasSetting("public-only")) {
|
||||||
for (Member m : members) {
|
for (Member m : members) {
|
||||||
if (m.accessModifier().equals("public") || m.accessModifier().equals("protected")) {
|
if (m.accessModifier().equals("public") || m.accessModifier().equals("protected")) {
|
||||||
withoutPrivate.add(m);
|
withoutPrivate.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
withoutPrivate = members;
|
|
||||||
}
|
|
||||||
return withoutPrivate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Constructor getPrimaryConstructor() {
|
|
||||||
for (Member m : myMembers)
|
|
||||||
if (m.getKind() == Kind.CONSTRUCTOR)
|
|
||||||
if (((Constructor) m).isPrimary())
|
|
||||||
return (Constructor) m;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String primaryConstructorSignatureToKotlin() {
|
|
||||||
Constructor maybeConstructor = getPrimaryConstructor();
|
|
||||||
if (maybeConstructor != null)
|
|
||||||
return maybeConstructor.primarySignatureToKotlin();
|
|
||||||
return "(" + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
String primaryConstructorBodyToKotlin() {
|
|
||||||
Constructor maybeConstructor = getPrimaryConstructor();
|
|
||||||
if (maybeConstructor != null && !maybeConstructor.getBlock().isEmpty())
|
|
||||||
return maybeConstructor.primaryBodyToKotlin();
|
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasWhere() {
|
|
||||||
for (Element t : myTypeParameters)
|
|
||||||
if (t instanceof TypeParameter && ((TypeParameter) t).hasWhere())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
String typeParameterWhereToKotlin() {
|
|
||||||
if (hasWhere()) {
|
|
||||||
List<String> wheres = new LinkedList<String>();
|
|
||||||
for (Element t : myTypeParameters)
|
|
||||||
if (t instanceof TypeParameter)
|
|
||||||
wheres.add(((TypeParameter) t).getWhereToKotlin());
|
|
||||||
return SPACE + "where" + SPACE + join(wheres, COMMA_WITH_SPACE) + SPACE;
|
|
||||||
}
|
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
LinkedList<Member> membersExceptConstructors() {
|
|
||||||
final LinkedList<Member> result = new LinkedList<Member>();
|
|
||||||
for (Member m : myMembers)
|
|
||||||
if (m.getKind() != Kind.CONSTRUCTOR)
|
|
||||||
result.add(m);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
List<Function> secondaryConstructorsAsStaticInitFunction() {
|
|
||||||
final LinkedList<Function> result = new LinkedList<Function>();
|
|
||||||
for (Member m : myMembers)
|
|
||||||
if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) {
|
|
||||||
Function f = (Function) m;
|
|
||||||
Set<String> modifiers = new HashSet<String>(m.myModifiers);
|
|
||||||
modifiers.add(Modifier.STATIC);
|
|
||||||
|
|
||||||
final List<Statement> statements = f.getBlock().getStatements();
|
|
||||||
statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages
|
|
||||||
final Block block = new Block(statements);
|
|
||||||
|
|
||||||
final List<Element> typeParameters = new LinkedList<Element>();
|
|
||||||
if (f.getTypeParameters().size() == 0)
|
|
||||||
typeParameters.addAll(myTypeParameters);
|
|
||||||
else {
|
else {
|
||||||
typeParameters.addAll(myTypeParameters);
|
withoutPrivate = members;
|
||||||
typeParameters.addAll(f.getTypeParameters());
|
}
|
||||||
|
return withoutPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Constructor getPrimaryConstructor() {
|
||||||
|
for (Member m : myMembers)
|
||||||
|
if (m.getKind() == Kind.CONSTRUCTOR) {
|
||||||
|
if (((Constructor) m).isPrimary()) {
|
||||||
|
return (Constructor) m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String primaryConstructorSignatureToKotlin() {
|
||||||
|
Constructor maybeConstructor = getPrimaryConstructor();
|
||||||
|
if (maybeConstructor != null) {
|
||||||
|
return maybeConstructor.primarySignatureToKotlin();
|
||||||
|
}
|
||||||
|
return "(" + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
String primaryConstructorBodyToKotlin() {
|
||||||
|
Constructor maybeConstructor = getPrimaryConstructor();
|
||||||
|
if (maybeConstructor != null && !maybeConstructor.getBlock().isEmpty()) {
|
||||||
|
return maybeConstructor.primaryBodyToKotlin();
|
||||||
|
}
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasWhere() {
|
||||||
|
for (Element t : myTypeParameters)
|
||||||
|
if (t instanceof TypeParameter && ((TypeParameter) t).hasWhere()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String typeParameterWhereToKotlin() {
|
||||||
|
if (hasWhere()) {
|
||||||
|
List<String> wheres = new LinkedList<String>();
|
||||||
|
for (Element t : myTypeParameters)
|
||||||
|
if (t instanceof TypeParameter) {
|
||||||
|
wheres.add(((TypeParameter) t).getWhereToKotlin());
|
||||||
|
}
|
||||||
|
return SPACE + "where" + SPACE + join(wheres, COMMA_WITH_SPACE) + SPACE;
|
||||||
|
}
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
LinkedList<Member> membersExceptConstructors() {
|
||||||
|
final LinkedList<Member> result = new LinkedList<Member>();
|
||||||
|
for (Member m : myMembers)
|
||||||
|
if (m.getKind() != Kind.CONSTRUCTOR) {
|
||||||
|
result.add(m);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<Function> secondaryConstructorsAsStaticInitFunction() {
|
||||||
|
final LinkedList<Function> result = new LinkedList<Function>();
|
||||||
|
for (Member m : myMembers)
|
||||||
|
if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) {
|
||||||
|
Function f = (Function) m;
|
||||||
|
Set<String> modifiers = new HashSet<String>(m.myModifiers);
|
||||||
|
modifiers.add(Modifier.STATIC);
|
||||||
|
|
||||||
|
final List<Statement> statements = f.getBlock().getStatements();
|
||||||
|
statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages
|
||||||
|
final Block block = new Block(statements);
|
||||||
|
|
||||||
|
final List<Element> typeParameters = new LinkedList<Element>();
|
||||||
|
if (f.getTypeParameters().size() == 0) {
|
||||||
|
typeParameters.addAll(myTypeParameters);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
typeParameters.addAll(myTypeParameters);
|
||||||
|
typeParameters.addAll(f.getTypeParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(new Function(
|
||||||
|
new IdentifierImpl("init"),
|
||||||
|
modifiers,
|
||||||
|
new ClassType(myName, typeParameters, false),
|
||||||
|
typeParameters,
|
||||||
|
f.getParams(),
|
||||||
|
block
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String typeParametersToKotlin() {
|
||||||
|
return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> baseClassSignatureWithParams() {
|
||||||
|
if (TYPE.equals("class") && myExtendsTypes.size() == 1) {
|
||||||
|
LinkedList<String> result = new LinkedList<String>();
|
||||||
|
result.add(myExtendsTypes.get(0).toKotlin() + "(" + joinNodes(myBaseClassParams, COMMA_WITH_SPACE) + ")");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nodesToKotlin(myExtendsTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String implementTypesToKotlin() {
|
||||||
|
List<String> allTypes = new LinkedList<String>() {
|
||||||
|
{
|
||||||
|
addAll(baseClassSignatureWithParams());
|
||||||
|
addAll(nodesToKotlin(myImplementsTypes));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return allTypes.size() == 0 ? EMPTY : SPACE + COLON + SPACE + join(allTypes, COMMA_WITH_SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String modifiersToKotlin() {
|
||||||
|
List<String> modifierList = new LinkedList<String>();
|
||||||
|
|
||||||
|
if (needAbstractModifier()) {
|
||||||
|
modifierList.add(Modifier.ABSTRACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.add(new Function(
|
modifierList.add(accessModifier());
|
||||||
new IdentifierImpl("init"),
|
|
||||||
modifiers,
|
|
||||||
new ClassType(myName, typeParameters, false),
|
|
||||||
typeParameters,
|
|
||||||
f.getParams(),
|
|
||||||
block
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
if (needOpenModifier()) {
|
||||||
String typeParametersToKotlin() {
|
modifierList.add(Modifier.OPEN);
|
||||||
return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
List<String> baseClassSignatureWithParams() {
|
if (modifierList.size() > 0) {
|
||||||
if (TYPE.equals("class") && myExtendsTypes.size() == 1) {
|
return join(modifierList, SPACE) + SPACE;
|
||||||
LinkedList<String> result = new LinkedList<String>();
|
}
|
||||||
result.add(myExtendsTypes.get(0).toKotlin() + "(" + joinNodes(myBaseClassParams, COMMA_WITH_SPACE) + ")");
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
return nodesToKotlin(myExtendsTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
return EMPTY;
|
||||||
String implementTypesToKotlin() {
|
|
||||||
List<String> allTypes = new LinkedList<String>() {
|
|
||||||
{
|
|
||||||
addAll(baseClassSignatureWithParams());
|
|
||||||
addAll(nodesToKotlin(myImplementsTypes));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return allTypes.size() == 0 ? EMPTY : SPACE + COLON + SPACE + join(allTypes, COMMA_WITH_SPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
String modifiersToKotlin() {
|
|
||||||
List<String> modifierList = new LinkedList<String>();
|
|
||||||
|
|
||||||
if (needAbstractModifier())
|
|
||||||
modifierList.add(Modifier.ABSTRACT);
|
|
||||||
|
|
||||||
modifierList.add(accessModifier());
|
|
||||||
|
|
||||||
if (needOpenModifier())
|
|
||||||
modifierList.add(Modifier.OPEN);
|
|
||||||
|
|
||||||
if (modifierList.size() > 0)
|
|
||||||
return join(modifierList, SPACE) + SPACE;
|
|
||||||
|
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean needOpenModifier() {
|
|
||||||
return !myModifiers.contains(Modifier.FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean needAbstractModifier() {
|
|
||||||
return isAbstract();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
String bodyToKotlin() {
|
|
||||||
return SPACE + "{" + N +
|
|
||||||
AstUtil.joinNodes(getNonStatic(membersExceptConstructors()), N) + N +
|
|
||||||
primaryConstructorBodyToKotlin() + N +
|
|
||||||
classObjectToKotlin() + N +
|
|
||||||
"}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<Member> getStatic(@NotNull List<? extends Member> members) {
|
|
||||||
List<Member> result = new LinkedList<Member>();
|
|
||||||
for (Member m : members)
|
|
||||||
if (m.isStatic())
|
|
||||||
result.add(m);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<Member> getNonStatic(@NotNull List<? extends Member> members) {
|
|
||||||
List<Member> result = new LinkedList<Member>();
|
|
||||||
for (Member m : members)
|
|
||||||
if (!m.isStatic())
|
|
||||||
result.add(m);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private String classObjectToKotlin() {
|
|
||||||
final List<Member> staticMembers = new LinkedList<Member>(secondaryConstructorsAsStaticInitFunction());
|
|
||||||
staticMembers.addAll(getStatic(membersExceptConstructors()));
|
|
||||||
if (staticMembers.size() > 0) {
|
|
||||||
return "class" + SPACE + "object" + SPACE + "{" + N +
|
|
||||||
AstUtil.joinNodes(staticMembers, N) + N +
|
|
||||||
"}";
|
|
||||||
}
|
}
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
boolean needOpenModifier() {
|
||||||
@Override
|
return !myModifiers.contains(Modifier.FINAL);
|
||||||
public String toKotlin() {
|
}
|
||||||
return modifiersToKotlin() + TYPE + SPACE + myName.toKotlin() + typeParametersToKotlin() + primaryConstructorSignatureToKotlin() +
|
|
||||||
implementTypesToKotlin() +
|
boolean needAbstractModifier() {
|
||||||
typeParameterWhereToKotlin() +
|
return isAbstract();
|
||||||
bodyToKotlin();
|
}
|
||||||
}
|
|
||||||
|
@NotNull
|
||||||
|
String bodyToKotlin() {
|
||||||
|
return SPACE + "{" + N +
|
||||||
|
AstUtil.joinNodes(getNonStatic(membersExceptConstructors()), N) + N +
|
||||||
|
primaryConstructorBodyToKotlin() + N +
|
||||||
|
classObjectToKotlin() + N +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<Member> getStatic(@NotNull List<? extends Member> members) {
|
||||||
|
List<Member> result = new LinkedList<Member>();
|
||||||
|
for (Member m : members)
|
||||||
|
if (m.isStatic()) {
|
||||||
|
result.add(m);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<Member> getNonStatic(@NotNull List<? extends Member> members) {
|
||||||
|
List<Member> result = new LinkedList<Member>();
|
||||||
|
for (Member m : members)
|
||||||
|
if (!m.isStatic()) {
|
||||||
|
result.add(m);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String classObjectToKotlin() {
|
||||||
|
final List<Member> staticMembers = new LinkedList<Member>(secondaryConstructorsAsStaticInitFunction());
|
||||||
|
staticMembers.addAll(getStatic(membersExceptConstructors()));
|
||||||
|
if (staticMembers.size() > 0) {
|
||||||
|
return "class" + SPACE + "object" + SPACE + "{" + N +
|
||||||
|
AstUtil.joinNodes(staticMembers, N) + N +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return modifiersToKotlin() + TYPE + SPACE + myName.toKotlin() + typeParametersToKotlin() + primaryConstructorSignatureToKotlin() +
|
||||||
|
implementTypesToKotlin() +
|
||||||
|
typeParameterWhereToKotlin() +
|
||||||
|
bodyToKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ClassObjectAccessExpression extends Expression {
|
public class ClassObjectAccessExpression extends Expression {
|
||||||
private final Element myTypeElement;
|
private final Element myTypeElement;
|
||||||
|
|
||||||
public ClassObjectAccessExpression(Element typeElement) {
|
public ClassObjectAccessExpression(Element typeElement) {
|
||||||
myTypeElement = typeElement;
|
myTypeElement = typeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "getJavaClass" + "<" + myTypeElement.toKotlin() + ">";
|
return "getJavaClass" + "<" + myTypeElement.toKotlin() + ">";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,30 +10,32 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ClassType extends Type {
|
public class ClassType extends Type {
|
||||||
private final Identifier myType;
|
private final Identifier myType;
|
||||||
private final List<? extends Element> myParameters;
|
private final List<? extends Element> myParameters;
|
||||||
|
|
||||||
public ClassType(Identifier type, List<? extends Element> parameters, boolean nullable) {
|
public ClassType(Identifier type, List<? extends Element> parameters, boolean nullable) {
|
||||||
myType = type;
|
myType = type;
|
||||||
myParameters = parameters;
|
myParameters = parameters;
|
||||||
myNullable = nullable;
|
myNullable = nullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassType(Identifier type, List<? extends Element> parameters) {
|
public ClassType(Identifier type, List<? extends Element> parameters) {
|
||||||
myType = type;
|
myType = type;
|
||||||
myParameters = parameters;
|
myParameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassType(Identifier type) {
|
public ClassType(Identifier type) {
|
||||||
myType = type;
|
myType = type;
|
||||||
myNullable = false;
|
myNullable = false;
|
||||||
myParameters = Collections.emptyList();
|
myParameters = Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
String params = myParameters.size() == 0 ? EMPTY : "<" + AstUtil.joinNodes(myParameters, COMMA_WITH_SPACE) + ">";
|
String params = myParameters.size() == 0
|
||||||
return myType.toKotlin() + params + isNullableStr();
|
? EMPTY
|
||||||
}
|
: "<" + AstUtil.joinNodes(myParameters, COMMA_WITH_SPACE) + ">";
|
||||||
|
return myType.toKotlin() + params + isNullableStr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,30 +9,30 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Constructor extends Function {
|
public class Constructor extends Function {
|
||||||
private final boolean myIsPrimary;
|
private final boolean myIsPrimary;
|
||||||
|
|
||||||
public Constructor(Identifier identifier, Set<String> modifiers, Type type, List<Element> typeParameters, Element params, Block block, boolean isPrimary) {
|
public Constructor(Identifier identifier, Set<String> modifiers, Type type, List<Element> typeParameters, Element params, Block block, boolean isPrimary) {
|
||||||
super(identifier, modifiers, type, typeParameters, params, block);
|
super(identifier, modifiers, type, typeParameters, params, block);
|
||||||
myIsPrimary = isPrimary;
|
myIsPrimary = isPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String primarySignatureToKotlin() {
|
public String primarySignatureToKotlin() {
|
||||||
return "(" + myParams.toKotlin() + ")";
|
return "(" + myParams.toKotlin() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String primaryBodyToKotlin() {
|
public String primaryBodyToKotlin() {
|
||||||
return myBlock.toKotlin();
|
return myBlock.toKotlin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPrimary() {
|
public boolean isPrimary() {
|
||||||
return myIsPrimary;
|
return myIsPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.CONSTRUCTOR;
|
return Kind.CONSTRUCTOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,26 +6,27 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ContinueStatement extends Statement {
|
public class ContinueStatement extends Statement {
|
||||||
private Identifier myLabel = Identifier.EMPTY_IDENTIFIER;
|
private Identifier myLabel = Identifier.EMPTY_IDENTIFIER;
|
||||||
|
|
||||||
public ContinueStatement(Identifier label) {
|
public ContinueStatement(Identifier label) {
|
||||||
myLabel = label;
|
myLabel = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContinueStatement() {
|
public ContinueStatement() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.CONTINUE;
|
return Kind.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myLabel.isEmpty())
|
if (myLabel.isEmpty()) {
|
||||||
return "continue";
|
return "continue";
|
||||||
return "continue" + AT + myLabel.toKotlin();
|
}
|
||||||
}
|
return "continue" + AT + myLabel.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,31 +10,31 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class DeclarationStatement extends Statement {
|
public class DeclarationStatement extends Statement {
|
||||||
private final List<Element> myElements;
|
private final List<Element> myElements;
|
||||||
|
|
||||||
public DeclarationStatement(List<Element> elements) {
|
public DeclarationStatement(List<Element> elements) {
|
||||||
myElements = elements;
|
myElements = elements;
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<String> toStringList(@NotNull List<Element> elements) {
|
|
||||||
List<String> result = new LinkedList<String>();
|
|
||||||
for (Element e : elements) {
|
|
||||||
if (e instanceof LocalVariable) {
|
|
||||||
LocalVariable v = (LocalVariable) e;
|
|
||||||
|
|
||||||
final String varKeyword = v.hasModifier(Modifier.FINAL) ? "val" : "var";
|
|
||||||
result.add(
|
|
||||||
varKeyword + SPACE + e.toKotlin()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
private static List<String> toStringList(@NotNull List<Element> elements) {
|
||||||
public String toKotlin() {
|
List<String> result = new LinkedList<String>();
|
||||||
return AstUtil.join(toStringList(myElements), N);
|
for (Element e : elements) {
|
||||||
}
|
if (e instanceof LocalVariable) {
|
||||||
|
LocalVariable v = (LocalVariable) e;
|
||||||
|
|
||||||
|
final String varKeyword = v.hasModifier(Modifier.FINAL) ? "val" : "var";
|
||||||
|
result.add(
|
||||||
|
varKeyword + SPACE + e.toKotlin()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return AstUtil.join(toStringList(myElements), N);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class DefaultSwitchLabelStatement extends Statement {
|
public class DefaultSwitchLabelStatement extends Statement {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "else";
|
return "else";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class DoWhileStatement extends WhileStatement {
|
public class DoWhileStatement extends WhileStatement {
|
||||||
public DoWhileStatement(Expression condition, Statement statement) {
|
public DoWhileStatement(Expression condition, Statement statement) {
|
||||||
super(condition, statement);
|
super(condition, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "do" + N +
|
return "do" + N +
|
||||||
myStatement.toKotlin() + N +
|
myStatement.toKotlin() + N +
|
||||||
"while" + SPACE + "(" + myCondition.toKotlin() + ")";
|
"while" + SPACE + "(" + myCondition.toKotlin() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,19 +6,19 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class DummyMethodCallExpression extends Expression {
|
public class DummyMethodCallExpression extends Expression {
|
||||||
private final Element myWho;
|
private final Element myWho;
|
||||||
private final String myMethodName;
|
private final String myMethodName;
|
||||||
private final Element myWhat;
|
private final Element myWhat;
|
||||||
|
|
||||||
public DummyMethodCallExpression(Element who, String methodName, Element what) {
|
public DummyMethodCallExpression(Element who, String methodName, Element what) {
|
||||||
myWho = who;
|
myWho = who;
|
||||||
myMethodName = methodName;
|
myMethodName = methodName;
|
||||||
myWhat = what;
|
myWhat = what;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myWho.toKotlin() + DOT + myMethodName + "(" + myWhat.toKotlin() + ")";
|
return myWho.toKotlin() + DOT + myMethodName + "(" + myWhat.toKotlin() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class DummyStringExpression extends Expression {
|
public class DummyStringExpression extends Expression {
|
||||||
private final String myString;
|
private final String myString;
|
||||||
|
|
||||||
public DummyStringExpression(String string) {
|
public DummyStringExpression(String string) {
|
||||||
myString = string;
|
myString = string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myString;
|
return myString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,26 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Element extends Node {
|
public abstract class Element extends Node {
|
||||||
@NotNull
|
|
||||||
public static final Element EMPTY_ELEMENT = new EmptyElement();
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ignatov
|
|
||||||
*/
|
|
||||||
private static class EmptyElement extends Element {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
public static final Element EMPTY_ELEMENT = new EmptyElement();
|
||||||
public String toKotlin() {
|
|
||||||
return EMPTY;
|
public boolean isEmpty() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean isEmpty() {
|
* @author ignatov
|
||||||
return true;
|
*/
|
||||||
|
private static class EmptyElement extends Element {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,30 +10,30 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Enum extends Class {
|
public class Enum extends Class {
|
||||||
public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
|
public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
|
||||||
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
|
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
|
||||||
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
|
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
|
||||||
}
|
}
|
||||||
|
|
||||||
String primaryConstructorSignatureToKotlin() {
|
String primaryConstructorSignatureToKotlin() {
|
||||||
String s = super.primaryConstructorSignatureToKotlin();
|
String s = super.primaryConstructorSignatureToKotlin();
|
||||||
return s.equals("()") ? EMPTY : s;
|
return s.equals("()") ? EMPTY : s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean needOpenModifier() {
|
boolean needOpenModifier() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return modifiersToKotlin() + "enum class" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() +
|
return modifiersToKotlin() + "enum class" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() +
|
||||||
typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N +
|
typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N +
|
||||||
AstUtil.joinNodes(membersExceptConstructors(), N) + N +
|
AstUtil.joinNodes(membersExceptConstructors(), N) + N +
|
||||||
primaryConstructorBodyToKotlin() + N +
|
primaryConstructorBodyToKotlin() + N +
|
||||||
"public fun name() : String { return \"\" }" + N + // TODO : remove hack
|
"public fun name() : String { return \"\" }" + N + // TODO : remove hack
|
||||||
"public fun order() : Int { return 0 }" + N +
|
"public fun order() : Int { return 0 }" + N +
|
||||||
"}";
|
"}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,15 +8,16 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class EnumConstant extends Field {
|
public class EnumConstant extends Field {
|
||||||
public EnumConstant(Identifier identifier, Set<String> modifiers, @NotNull Type type, Element params) {
|
public EnumConstant(Identifier identifier, Set<String> modifiers, @NotNull Type type, Element params) {
|
||||||
super(identifier, modifiers, type.convertedToNotNull(), params, 0);
|
super(identifier, modifiers, type.convertedToNotNull(), params, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myInitializer.toKotlin().isEmpty())
|
if (myInitializer.toKotlin().isEmpty()) {
|
||||||
return myIdentifier.toKotlin();
|
return myIdentifier.toKotlin();
|
||||||
return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + "(" + myInitializer.toKotlin() + ")";
|
}
|
||||||
}
|
return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + "(" + myInitializer.toKotlin() + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,26 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Expression extends Statement {
|
public abstract class Expression extends Statement {
|
||||||
@NotNull
|
|
||||||
public static final Expression EMPTY_EXPRESSION = new EmptyExpression();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ignatov
|
|
||||||
*/
|
|
||||||
private static class EmptyExpression extends Expression {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
public static final Expression EMPTY_EXPRESSION = new EmptyExpression();
|
||||||
public String toKotlin() {
|
|
||||||
return EMPTY;
|
/**
|
||||||
|
* @author ignatov
|
||||||
|
*/
|
||||||
|
private static class EmptyExpression extends Expression {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
boolean isNullable() {
|
||||||
public boolean isEmpty() {
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
boolean isNullable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ExpressionList extends Expression {
|
public class ExpressionList extends Expression {
|
||||||
private final List<Expression> myExpressions;
|
private final List<Expression> myExpressions;
|
||||||
|
|
||||||
public ExpressionList(List<Expression> expressions, List<Type> types) {
|
public ExpressionList(List<Expression> expressions, List<Type> types) {
|
||||||
myExpressions = expressions;
|
myExpressions = expressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExpressionList(List<Expression> expressions) {
|
public ExpressionList(List<Expression> expressions) {
|
||||||
myExpressions = expressions;
|
myExpressions = expressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return AstUtil.joinNodes(myExpressions, COMMA_WITH_SPACE);
|
return AstUtil.joinNodes(myExpressions, COMMA_WITH_SPACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ExpressionListStatement extends Expression {
|
public class ExpressionListStatement extends Expression {
|
||||||
private final List<Expression> myExpressions;
|
private final List<Expression> myExpressions;
|
||||||
|
|
||||||
public ExpressionListStatement(List<Expression> expressions) {
|
public ExpressionListStatement(List<Expression> expressions) {
|
||||||
myExpressions = expressions;
|
myExpressions = expressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return AstUtil.joinNodes(myExpressions, N);
|
return AstUtil.joinNodes(myExpressions, N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,65 +13,70 @@ import static org.jetbrains.jet.j2k.Converter.getDefaultInitializer;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Field extends Member {
|
public class Field extends Member {
|
||||||
final Identifier myIdentifier;
|
final Identifier myIdentifier;
|
||||||
private final int myWritingAccesses;
|
private final int myWritingAccesses;
|
||||||
final Type myType;
|
final Type myType;
|
||||||
final Element myInitializer;
|
final Element myInitializer;
|
||||||
|
|
||||||
public Field(Identifier identifier, Set<String> modifiers, Type type, Element initializer, int writingAccesses) {
|
public Field(Identifier identifier, Set<String> modifiers, Type type, Element initializer, int writingAccesses) {
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
myWritingAccesses = writingAccesses;
|
myWritingAccesses = writingAccesses;
|
||||||
myModifiers = modifiers;
|
myModifiers = modifiers;
|
||||||
myType = type;
|
myType = type;
|
||||||
myInitializer = initializer;
|
myInitializer = initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element getInitializer() {
|
public Element getInitializer() {
|
||||||
return myInitializer;
|
return myInitializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Identifier getIdentifier() {
|
public Identifier getIdentifier() {
|
||||||
return myIdentifier;
|
return myIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
return myType;
|
return myType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
String modifiersToKotlin() {
|
String modifiersToKotlin() {
|
||||||
List<String> modifierList = new LinkedList<String>();
|
List<String> modifierList = new LinkedList<String>();
|
||||||
|
|
||||||
if (isAbstract())
|
if (isAbstract()) {
|
||||||
modifierList.add(Modifier.ABSTRACT);
|
modifierList.add(Modifier.ABSTRACT);
|
||||||
|
}
|
||||||
|
|
||||||
modifierList.add(accessModifier());
|
modifierList.add(accessModifier());
|
||||||
|
|
||||||
modifierList.add(isVal() ? "val" : "var");
|
modifierList.add(isVal() ? "val" : "var");
|
||||||
|
|
||||||
if (modifierList.size() > 0)
|
if (modifierList.size() > 0) {
|
||||||
return AstUtil.join(modifierList, SPACE) + SPACE;
|
return AstUtil.join(modifierList, SPACE) + SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVal() {
|
public boolean isVal() {
|
||||||
return myModifiers.contains(Modifier.FINAL);
|
return myModifiers.contains(Modifier.FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return myModifiers.contains(Modifier.STATIC);
|
return myModifiers.contains(Modifier.STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
final String declaration = modifiersToKotlin() + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
|
final String declaration = modifiersToKotlin() + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
|
||||||
|
|
||||||
if (myInitializer.isEmpty())
|
if (myInitializer.isEmpty()) {
|
||||||
return declaration + (isVal() && !isStatic() && myWritingAccesses == 1 ? EMPTY : SPACE + EQUAL + SPACE + getDefaultInitializer(this));
|
return declaration + (isVal() && !isStatic() && myWritingAccesses == 1
|
||||||
|
? EMPTY
|
||||||
|
: SPACE + EQUAL + SPACE + getDefaultInitializer(this));
|
||||||
|
}
|
||||||
|
|
||||||
return declaration + SPACE + EQUAL + SPACE + myInitializer.toKotlin();
|
return declaration + SPACE + EQUAL + SPACE + myInitializer.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,25 +9,26 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class File extends Node {
|
public class File extends Node {
|
||||||
private final String myPackageName;
|
private final String myPackageName;
|
||||||
private final List<Import> myImports;
|
private final List<Import> myImports;
|
||||||
private final List<Class> myClasses;
|
private final List<Class> myClasses;
|
||||||
private final String myMainFunction;
|
private final String myMainFunction;
|
||||||
|
|
||||||
public File(String packageName, List<Import> imports, List<Class> classes, String mainFunction) {
|
public File(String packageName, List<Import> imports, List<Class> classes, String mainFunction) {
|
||||||
myPackageName = packageName;
|
myPackageName = packageName;
|
||||||
myImports = imports;
|
myImports = imports;
|
||||||
myClasses = classes;
|
myClasses = classes;
|
||||||
myMainFunction = mainFunction;
|
myMainFunction = mainFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N + myMainFunction;
|
final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N + myMainFunction;
|
||||||
if (myPackageName.isEmpty())
|
if (myPackageName.isEmpty()) {
|
||||||
return common;
|
return common;
|
||||||
return "package" + SPACE + myPackageName + N +
|
}
|
||||||
common;
|
return "package" + SPACE + myPackageName + N +
|
||||||
}
|
common;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,20 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ForeachStatement extends Statement {
|
public class ForeachStatement extends Statement {
|
||||||
private final Parameter myVariable;
|
private final Parameter myVariable;
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final Statement myStatement;
|
private final Statement myStatement;
|
||||||
|
|
||||||
public ForeachStatement(Parameter variable, Expression expression, Statement statement) {
|
public ForeachStatement(Parameter variable, Expression expression, Statement statement) {
|
||||||
myVariable = variable;
|
myVariable = variable;
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myStatement = statement;
|
myStatement = statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "for" + SPACE + "(" + myVariable.toKotlin() + SPACE + IN + SPACE + myExpression.toKotlin() + ")" + N +
|
return "for" + SPACE + "(" + myVariable.toKotlin() + SPACE + IN + SPACE + myExpression.toKotlin() + ")" + N +
|
||||||
myStatement.toKotlin();
|
myStatement.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,24 +6,24 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ForeachWithRangeStatement extends Statement {
|
public class ForeachWithRangeStatement extends Statement {
|
||||||
private final Expression myStart;
|
private final Expression myStart;
|
||||||
private final IdentifierImpl myIdentifier;
|
private final IdentifierImpl myIdentifier;
|
||||||
private final Expression myEnd;
|
private final Expression myEnd;
|
||||||
private final Statement myBody;
|
private final Statement myBody;
|
||||||
|
|
||||||
public ForeachWithRangeStatement(IdentifierImpl identifier, Expression start, Expression end, Statement body) {
|
public ForeachWithRangeStatement(IdentifierImpl identifier, Expression start, Expression end, Statement body) {
|
||||||
myStart = start;
|
myStart = start;
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
myEnd = end;
|
myEnd = end;
|
||||||
myBody = body;
|
myBody = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "for" + SPACE + "(" +
|
return "for" + SPACE + "(" +
|
||||||
myIdentifier.toKotlin() + SPACE + "in" + SPACE + myStart.toKotlin() + ".." + myEnd.toKotlin() +
|
myIdentifier.toKotlin() + SPACE + "in" + SPACE + myStart.toKotlin() + ".." + myEnd.toKotlin() +
|
||||||
")" + SPACE +
|
")" + SPACE +
|
||||||
myBody.toKotlin();
|
myBody.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,93 +11,101 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Function extends Member {
|
public class Function extends Member {
|
||||||
private final Identifier myName;
|
private final Identifier myName;
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
private final List<Element> myTypeParameters;
|
private final List<Element> myTypeParameters;
|
||||||
final Element myParams;
|
final Element myParams;
|
||||||
|
|
||||||
// TODO: maybe remove it?
|
// TODO: maybe remove it?
|
||||||
public void setBlock(Block block) {
|
public void setBlock(Block block) {
|
||||||
myBlock = block;
|
myBlock = block;
|
||||||
}
|
|
||||||
|
|
||||||
Block myBlock;
|
|
||||||
|
|
||||||
public Function(Identifier name, Set<String> modifiers, Type type, List<Element> typeParameters, Element params, Block block) {
|
|
||||||
myName = name;
|
|
||||||
myModifiers = modifiers;
|
|
||||||
myType = type;
|
|
||||||
myTypeParameters = typeParameters;
|
|
||||||
myParams = params;
|
|
||||||
myBlock = block;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Element> getTypeParameters() {
|
|
||||||
return myTypeParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element getParams() {
|
|
||||||
return myParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block getBlock() {
|
|
||||||
return myBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private String typeParametersToKotlin() {
|
|
||||||
return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasWhere() {
|
|
||||||
for (Element t : myTypeParameters)
|
|
||||||
if (t instanceof TypeParameter && ((TypeParameter) t).hasWhere())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String typeParameterWhereToKotlin() {
|
|
||||||
if (hasWhere()) {
|
|
||||||
List<String> wheres = new LinkedList<String>();
|
|
||||||
for (Element t : myTypeParameters)
|
|
||||||
if (t instanceof TypeParameter)
|
|
||||||
wheres.add(((TypeParameter) t).getWhereToKotlin());
|
|
||||||
return SPACE + "where" + SPACE + AstUtil.join(wheres, COMMA_WITH_SPACE) + SPACE;
|
|
||||||
}
|
}
|
||||||
return EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
String modifiersToKotlin() {
|
Block myBlock;
|
||||||
List<String> modifierList = new LinkedList<String>();
|
|
||||||
|
|
||||||
if (isAbstract())
|
public Function(Identifier name, Set<String> modifiers, Type type, List<Element> typeParameters, Element params, Block block) {
|
||||||
modifierList.add(Modifier.ABSTRACT);
|
myName = name;
|
||||||
|
myModifiers = modifiers;
|
||||||
|
myType = type;
|
||||||
|
myTypeParameters = typeParameters;
|
||||||
|
myParams = params;
|
||||||
|
myBlock = block;
|
||||||
|
}
|
||||||
|
|
||||||
if (myModifiers.contains(Modifier.OVERRIDE))
|
public List<Element> getTypeParameters() {
|
||||||
modifierList.add(Modifier.OVERRIDE);
|
return myTypeParameters;
|
||||||
|
}
|
||||||
|
|
||||||
if (!myModifiers.contains(Modifier.OVERRIDE) && !myModifiers.contains(Modifier.FINAL))
|
public Element getParams() {
|
||||||
modifierList.add(Modifier.OPEN);
|
return myParams;
|
||||||
|
}
|
||||||
|
|
||||||
if (myModifiers.contains(Modifier.NOT_OPEN))
|
public Block getBlock() {
|
||||||
modifierList.remove(Modifier.OPEN);
|
return myBlock;
|
||||||
|
}
|
||||||
|
|
||||||
String accessModifier = accessModifier();
|
@NotNull
|
||||||
if (!accessModifier.isEmpty())
|
private String typeParametersToKotlin() {
|
||||||
modifierList.add(accessModifier);
|
return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
if (modifierList.size() > 0)
|
private boolean hasWhere() {
|
||||||
return AstUtil.join(modifierList, SPACE) + SPACE;
|
for (Element t : myTypeParameters)
|
||||||
|
if (t instanceof TypeParameter && ((TypeParameter) t).hasWhere()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return EMPTY;
|
private String typeParameterWhereToKotlin() {
|
||||||
}
|
if (hasWhere()) {
|
||||||
|
List<String> wheres = new LinkedList<String>();
|
||||||
|
for (Element t : myTypeParameters)
|
||||||
|
if (t instanceof TypeParameter) {
|
||||||
|
wheres.add(((TypeParameter) t).getWhereToKotlin());
|
||||||
|
}
|
||||||
|
return SPACE + "where" + SPACE + AstUtil.join(wheres, COMMA_WITH_SPACE) + SPACE;
|
||||||
|
}
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
String modifiersToKotlin() {
|
||||||
@Override
|
List<String> modifierList = new LinkedList<String>();
|
||||||
public String toKotlin() {
|
|
||||||
return modifiersToKotlin() + "fun" + SPACE + myName.toKotlin() + typeParametersToKotlin() + "(" + myParams.toKotlin() + ")" + SPACE + COLON +
|
if (isAbstract()) {
|
||||||
SPACE + myType.toKotlin() + SPACE +
|
modifierList.add(Modifier.ABSTRACT);
|
||||||
typeParameterWhereToKotlin() +
|
}
|
||||||
myBlock.toKotlin();
|
|
||||||
}
|
if (myModifiers.contains(Modifier.OVERRIDE)) {
|
||||||
|
modifierList.add(Modifier.OVERRIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!myModifiers.contains(Modifier.OVERRIDE) && !myModifiers.contains(Modifier.FINAL)) {
|
||||||
|
modifierList.add(Modifier.OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myModifiers.contains(Modifier.NOT_OPEN)) {
|
||||||
|
modifierList.remove(Modifier.OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
String accessModifier = accessModifier();
|
||||||
|
if (!accessModifier.isEmpty()) {
|
||||||
|
modifierList.add(accessModifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modifierList.size() > 0) {
|
||||||
|
return AstUtil.join(modifierList, SPACE) + SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return modifiersToKotlin() + "fun" + SPACE + myName.toKotlin() + typeParametersToKotlin() + "(" + myParams.toKotlin() + ")" + SPACE + COLON +
|
||||||
|
SPACE + myType.toKotlin() + SPACE +
|
||||||
|
typeParameterWhereToKotlin() +
|
||||||
|
myBlock.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package org.jetbrains.jet.j2k.ast;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public interface IMember extends INode {
|
public interface IMember extends INode {
|
||||||
boolean isStatic();
|
boolean isStatic();
|
||||||
|
|
||||||
boolean isAbstract();
|
boolean isAbstract();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public interface INode {
|
public interface INode {
|
||||||
@NotNull
|
@NotNull
|
||||||
String toKotlin();
|
String toKotlin();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
Kind getKind();
|
Kind getKind();
|
||||||
|
|
||||||
enum Kind {
|
enum Kind {
|
||||||
UNDEFINED, TYPE, CONSTRUCTOR, BREAK, CONTINUE, VARARG, TRAIT, ASSIGNMENT_EXPRESSION, CALL_CHAIN, LITERAL, ARRAY_TYPE,
|
UNDEFINED, TYPE, CONSTRUCTOR, BREAK, CONTINUE, VARARG, TRAIT, ASSIGNMENT_EXPRESSION, CALL_CHAIN, LITERAL, ARRAY_TYPE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public interface Identifier extends INode {
|
public interface Identifier extends INode {
|
||||||
@NotNull
|
@NotNull
|
||||||
Identifier EMPTY_IDENTIFIER = new IdentifierImpl("");
|
Identifier EMPTY_IDENTIFIER = new IdentifierImpl("");
|
||||||
|
|
||||||
boolean isEmpty();
|
boolean isEmpty();
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,54 +6,55 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class IdentifierImpl extends Expression implements Identifier {
|
public class IdentifierImpl extends Expression implements Identifier {
|
||||||
private final String myName;
|
private final String myName;
|
||||||
private boolean myIsNullable = true;
|
private boolean myIsNullable = true;
|
||||||
private boolean myQuotingNeeded = true;
|
private boolean myQuotingNeeded = true;
|
||||||
|
|
||||||
public IdentifierImpl(String name) {
|
public IdentifierImpl(String name) {
|
||||||
myName = name;
|
myName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentifierImpl(String name, boolean isNullable) {
|
public IdentifierImpl(String name, boolean isNullable) {
|
||||||
myName = name;
|
myName = name;
|
||||||
myIsNullable = isNullable;
|
myIsNullable = isNullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentifierImpl(String name, boolean isNullable, boolean quotingNeeded) {
|
public IdentifierImpl(String name, boolean isNullable, boolean quotingNeeded) {
|
||||||
myName = name;
|
myName = name;
|
||||||
myIsNullable = isNullable;
|
myIsNullable = isNullable;
|
||||||
myQuotingNeeded = quotingNeeded;
|
myQuotingNeeded = quotingNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return myName.length() == 0;
|
return myName.length() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return myName;
|
return myName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String quote(String str) {
|
private static String quote(String str) {
|
||||||
return BACKTICK + str + BACKTICK;
|
return BACKTICK + str + BACKTICK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return myIsNullable;
|
return myIsNullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String ifNeedQuote() {
|
private String ifNeedQuote() {
|
||||||
if (myQuotingNeeded && (ONLY_KOTLIN_KEYWORDS.contains(myName) || myName.contains("$")))
|
if (myQuotingNeeded && (ONLY_KOTLIN_KEYWORDS.contains(myName) || myName.contains("$"))) {
|
||||||
return quote(myName);
|
return quote(myName);
|
||||||
return myName;
|
}
|
||||||
}
|
return myName;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return ifNeedQuote();
|
return ifNeedQuote();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,26 +6,27 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class IfStatement extends Expression {
|
public class IfStatement extends Expression {
|
||||||
private final Expression myCondition;
|
private final Expression myCondition;
|
||||||
private final Statement myThenStatement;
|
private final Statement myThenStatement;
|
||||||
private final Statement myElseStatement;
|
private final Statement myElseStatement;
|
||||||
|
|
||||||
public IfStatement(Expression condition, Statement thenStatement, Statement elseStatement) {
|
public IfStatement(Expression condition, Statement thenStatement, Statement elseStatement) {
|
||||||
myCondition = condition;
|
myCondition = condition;
|
||||||
myThenStatement = thenStatement;
|
myThenStatement = thenStatement;
|
||||||
myElseStatement = elseStatement;
|
myElseStatement = elseStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
String result = "if" + SPACE + "(" + myCondition.toKotlin() + ")" + N + myThenStatement.toKotlin() + N;
|
String result = "if" + SPACE + "(" + myCondition.toKotlin() + ")" + N + myThenStatement.toKotlin() + N;
|
||||||
|
|
||||||
if (myElseStatement != Statement.EMPTY_STATEMENT)
|
if (myElseStatement != Statement.EMPTY_STATEMENT) {
|
||||||
return result +
|
return result +
|
||||||
"else" + N +
|
"else" + N +
|
||||||
myElseStatement.toKotlin();
|
myElseStatement.toKotlin();
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,19 +6,19 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Import extends Node {
|
public class Import extends Node {
|
||||||
private final String myName;
|
private final String myName;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return myName;
|
return myName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Import(String name) {
|
public Import(String name) {
|
||||||
myName = name;
|
myName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "import" + SPACE + myName;
|
return "import" + SPACE + myName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class InProjectionType extends Type {
|
public class InProjectionType extends Type {
|
||||||
private final Type myBound;
|
private final Type myBound;
|
||||||
|
|
||||||
public InProjectionType(Type bound) {
|
public InProjectionType(Type bound) {
|
||||||
myBound = bound;
|
myBound = bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "in" + SPACE + myBound.toKotlin();
|
return "in" + SPACE + myBound.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Initializer extends Member {
|
public class Initializer extends Member {
|
||||||
private final Block myBlock;
|
private final Block myBlock;
|
||||||
|
|
||||||
public Initializer(Block block, Set<String> modifiers) {
|
public Initializer(Block block, Set<String> modifiers) {
|
||||||
myBlock = block;
|
myBlock = block;
|
||||||
myModifiers = modifiers;
|
myModifiers = modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myBlock.toKotlin();
|
return myBlock.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class IsOperator extends Expression {
|
public class IsOperator extends Expression {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final Element myTypeElement;
|
private final Element myTypeElement;
|
||||||
|
|
||||||
public IsOperator(Expression expression, Element typeElement) {
|
public IsOperator(Expression expression, Element typeElement) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myTypeElement = typeElement;
|
myTypeElement = typeElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "(" + myExpression.toKotlin() + SPACE + "is" + SPACE + myTypeElement.toKotlin() + ")";
|
return "(" + myExpression.toKotlin() + SPACE + "is" + SPACE + myTypeElement.toKotlin() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class LabelStatement extends Statement {
|
public class LabelStatement extends Statement {
|
||||||
private final Identifier myName;
|
private final Identifier myName;
|
||||||
private final Statement myStatement;
|
private final Statement myStatement;
|
||||||
|
|
||||||
public LabelStatement(Identifier name, Statement statement) {
|
public LabelStatement(Identifier name, Statement statement) {
|
||||||
myName = name;
|
myName = name;
|
||||||
myStatement = statement;
|
myStatement = statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return AT + myName.toKotlin() + SPACE + myStatement.toKotlin();
|
return AT + myName.toKotlin() + SPACE + myStatement.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class LiteralExpression extends Expression {
|
public class LiteralExpression extends Expression {
|
||||||
private final Identifier myIdentifier;
|
private final Identifier myIdentifier;
|
||||||
|
|
||||||
public LiteralExpression(Identifier identifier) {
|
public LiteralExpression(Identifier identifier) {
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.LITERAL;
|
return Kind.LITERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myIdentifier.toKotlin();
|
return myIdentifier.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,29 +8,30 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class LocalVariable extends Expression {
|
public class LocalVariable extends Expression {
|
||||||
private final Identifier myIdentifier;
|
private final Identifier myIdentifier;
|
||||||
private final Set<String> myModifiersSet;
|
private final Set<String> myModifiersSet;
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
private final Expression myInitializer;
|
private final Expression myInitializer;
|
||||||
|
|
||||||
public LocalVariable(Identifier identifier, Set<String> modifiersSet, Type type, Expression initializer) {
|
public LocalVariable(Identifier identifier, Set<String> modifiersSet, Type type, Expression initializer) {
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
myModifiersSet = modifiersSet;
|
myModifiersSet = modifiersSet;
|
||||||
myType = type;
|
myType = type;
|
||||||
myInitializer = initializer;
|
myInitializer = initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasModifier(String modifier) {
|
public boolean hasModifier(String modifier) {
|
||||||
return myModifiersSet.contains(modifier);
|
return myModifiersSet.contains(modifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myInitializer.isEmpty())
|
if (myInitializer.isEmpty()) {
|
||||||
return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
|
return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
|
||||||
|
}
|
||||||
|
|
||||||
return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + SPACE +
|
return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + SPACE +
|
||||||
EQUAL + SPACE + myInitializer.toKotlin();
|
EQUAL + SPACE + myInitializer.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,23 +8,24 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Member extends Node implements IMember {
|
public abstract class Member extends Node implements IMember {
|
||||||
Set<String> myModifiers;
|
Set<String> myModifiers;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
String accessModifier() {
|
String accessModifier() {
|
||||||
for (String m : myModifiers)
|
for (String m : myModifiers)
|
||||||
if (m.equals(Modifier.PUBLIC) || m.equals(Modifier.PROTECTED) || m.equals(Modifier.PRIVATE))
|
if (m.equals(Modifier.PUBLIC) || m.equals(Modifier.PROTECTED) || m.equals(Modifier.PRIVATE)) {
|
||||||
return m;
|
return m;
|
||||||
return EMPTY; // package local converted to internal, but we use internal by default
|
}
|
||||||
}
|
return EMPTY; // package local converted to internal, but we use internal by default
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAbstract() {
|
public boolean isAbstract() {
|
||||||
return myModifiers.contains(Modifier.ABSTRACT);
|
return myModifiers.contains(Modifier.ABSTRACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStatic() {
|
public boolean isStatic() {
|
||||||
return myModifiers.contains(Modifier.STATIC);
|
return myModifiers.contains(Modifier.STATIC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,34 +9,36 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class MethodCallExpression extends Expression {
|
public class MethodCallExpression extends Expression {
|
||||||
private final Expression myMethodCall;
|
private final Expression myMethodCall;
|
||||||
private final List<Expression> myArguments;
|
private final List<Expression> myArguments;
|
||||||
private final List<String> myConversions;
|
private final List<String> myConversions;
|
||||||
private final boolean myIsResultNullable;
|
private final boolean myIsResultNullable;
|
||||||
private final List<Type> myTypeParameters;
|
private final List<Type> myTypeParameters;
|
||||||
|
|
||||||
public MethodCallExpression(Expression methodCall, List<Expression> arguments, List<Type> typeParameters) {
|
public MethodCallExpression(Expression methodCall, List<Expression> arguments, List<Type> typeParameters) {
|
||||||
this(methodCall, arguments, AstUtil.createListWithEmptyString(arguments), false, typeParameters);
|
this(methodCall, arguments, AstUtil.createListWithEmptyString(arguments), false, typeParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodCallExpression(Expression methodCall, List<Expression> arguments, List<String> conversions, boolean nullable, List<Type> typeParameters) {
|
public MethodCallExpression(Expression methodCall, List<Expression> arguments, List<String> conversions, boolean nullable, List<Type> typeParameters) {
|
||||||
myMethodCall = methodCall;
|
myMethodCall = methodCall;
|
||||||
myArguments = arguments;
|
myArguments = arguments;
|
||||||
myConversions = conversions;
|
myConversions = conversions;
|
||||||
myIsResultNullable = nullable;
|
myIsResultNullable = nullable;
|
||||||
myTypeParameters = typeParameters;
|
myTypeParameters = typeParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return myIsResultNullable;
|
return myIsResultNullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
String typeParamsToKotlin = myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
|
String typeParamsToKotlin = myTypeParameters.size() > 0
|
||||||
List<String> applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
|
? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">"
|
||||||
return myMethodCall.toKotlin() + typeParamsToKotlin + "(" + AstUtil.join(applyConversions, COMMA_WITH_SPACE) + ")";
|
: EMPTY;
|
||||||
}
|
List<String> applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
|
||||||
|
return myMethodCall.toKotlin() + typeParamsToKotlin + "(" + AstUtil.join(applyConversions, COMMA_WITH_SPACE) + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,24 +6,24 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Modifier {
|
public abstract class Modifier {
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String PUBLIC = "public";
|
public static final String PUBLIC = "public";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String PROTECTED = "protected";
|
public static final String PROTECTED = "protected";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String PRIVATE = "private";
|
public static final String PRIVATE = "private";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String INTERNAL = "internal";
|
public static final String INTERNAL = "internal";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String STATIC = "static";
|
public static final String STATIC = "static";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String ABSTRACT = "abstract";
|
public static final String ABSTRACT = "abstract";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String FINAL = "final";
|
public static final String FINAL = "final";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String OPEN = "open";
|
public static final String OPEN = "open";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String NOT_OPEN = "not open";
|
public static final String NOT_OPEN = "not open";
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String OVERRIDE = "override";
|
public static final String OVERRIDE = "override";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,37 +10,38 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class NewClassExpression extends Expression {
|
public class NewClassExpression extends Expression {
|
||||||
private final Element myName;
|
private final Element myName;
|
||||||
private final List<Expression> myArguments;
|
private final List<Expression> myArguments;
|
||||||
private Expression myQualifier;
|
private Expression myQualifier;
|
||||||
private List<String> myConversions;
|
private List<String> myConversions;
|
||||||
@Nullable
|
@Nullable
|
||||||
private AnonymousClass myAnonymousClass = null;
|
private AnonymousClass myAnonymousClass = null;
|
||||||
|
|
||||||
private NewClassExpression(Element name, List<Expression> arguments) {
|
private NewClassExpression(Element name, List<Expression> arguments) {
|
||||||
myName = name;
|
myName = name;
|
||||||
myQualifier = EMPTY_EXPRESSION;
|
myQualifier = EMPTY_EXPRESSION;
|
||||||
myArguments = arguments;
|
myArguments = arguments;
|
||||||
myConversions = AstUtil.createListWithEmptyString(arguments);
|
myConversions = AstUtil.createListWithEmptyString(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NewClassExpression(@NotNull Expression qualifier, @NotNull Element name, @NotNull List<Expression> arguments,
|
public NewClassExpression(@NotNull Expression qualifier, @NotNull Element name, @NotNull List<Expression> arguments,
|
||||||
@NotNull List<String> conversions, @Nullable AnonymousClass anonymousClass) {
|
@NotNull List<String> conversions, @Nullable AnonymousClass anonymousClass) {
|
||||||
this(name, arguments);
|
this(name, arguments);
|
||||||
myQualifier = qualifier;
|
myQualifier = qualifier;
|
||||||
myConversions = conversions;
|
myConversions = conversions;
|
||||||
myAnonymousClass = anonymousClass;
|
myAnonymousClass = anonymousClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
|
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
|
||||||
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
|
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
|
||||||
List<String> applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
|
List<String> applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
|
||||||
String appliedArguments = AstUtil.join(applyConversions, COMMA_WITH_SPACE);
|
String appliedArguments = AstUtil.join(applyConversions, COMMA_WITH_SPACE);
|
||||||
return myAnonymousClass != null ?
|
return myAnonymousClass != null ?
|
||||||
"object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin() :
|
"object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin()
|
||||||
qualifier + myName.toKotlin() + "(" + appliedArguments + ")";
|
:
|
||||||
}
|
qualifier + myName.toKotlin() + "(" + appliedArguments + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,49 +10,49 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Node implements INode {
|
public abstract class Node implements INode {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.UNDEFINED;
|
return Kind.UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
final static Set<String> ONLY_KOTLIN_KEYWORDS = new HashSet<String>(Arrays.asList(
|
final static Set<String> ONLY_KOTLIN_KEYWORDS = new HashSet<String>(Arrays.asList(
|
||||||
"package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This"
|
"package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This"
|
||||||
));
|
));
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public final static Set<String> PRIMITIVE_TYPES = new HashSet<String>(Arrays.asList(
|
public final static Set<String> PRIMITIVE_TYPES = new HashSet<String>(Arrays.asList(
|
||||||
"double", "float", "long", "int", "short", "byte", "boolean", "char"
|
"double", "float", "long", "int", "short", "byte", "boolean", "char"
|
||||||
));
|
));
|
||||||
|
|
||||||
static final String N = "\n";
|
static final String N = "\n";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String N2 = N + N;
|
static final String N2 = N + N;
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String SPACE = " ";
|
static final String SPACE = " ";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String EQUAL = "=";
|
static final String EQUAL = "=";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String EMPTY = "";
|
static final String EMPTY = "";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String DOT = ".";
|
static final String DOT = ".";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String QUESTDOT = "?.";
|
static final String QUESTDOT = "?.";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String COLON = ":";
|
static final String COLON = ":";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String IN = "in";
|
static final String IN = "in";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String AT = "@";
|
static final String AT = "@";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String BACKTICK = "`";
|
static final String BACKTICK = "`";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String QUEST = "?";
|
static final String QUEST = "?";
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String COMMA_WITH_SPACE = "," + SPACE;
|
static final String COMMA_WITH_SPACE = "," + SPACE;
|
||||||
@NotNull
|
@NotNull
|
||||||
static final String STAR = "*";
|
static final String STAR = "*";
|
||||||
@NotNull
|
@NotNull
|
||||||
protected static final String ZERO = "0";
|
protected static final String ZERO = "0";
|
||||||
}
|
}
|
||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class OutProjectionType extends Type {
|
public class OutProjectionType extends Type {
|
||||||
private final Type myBound;
|
private final Type myBound;
|
||||||
|
|
||||||
public OutProjectionType(Type bound) {
|
public OutProjectionType(Type bound) {
|
||||||
myBound = bound;
|
myBound = bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "out" + SPACE + myBound.toKotlin();
|
return "out" + SPACE + myBound.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,26 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Parameter extends Expression {
|
public class Parameter extends Expression {
|
||||||
private final Identifier myIdentifier;
|
private final Identifier myIdentifier;
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
private boolean myReadOnly;
|
private boolean myReadOnly;
|
||||||
|
|
||||||
public Parameter(Identifier identifier, Type type) {
|
public Parameter(Identifier identifier, Type type) {
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
myType = type;
|
myType = type;
|
||||||
myReadOnly = true;
|
myReadOnly = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Parameter(IdentifierImpl identifier, Type type, boolean readOnly) {
|
public Parameter(IdentifierImpl identifier, Type type, boolean readOnly) {
|
||||||
this(identifier, type);
|
this(identifier, type);
|
||||||
myReadOnly = readOnly;
|
myReadOnly = readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
String vararg = myType.getKind() == Kind.VARARG ? "vararg" + SPACE : EMPTY;
|
String vararg = myType.getKind() == Kind.VARARG ? "vararg" + SPACE : EMPTY;
|
||||||
String var = myReadOnly ? EMPTY : "var" + SPACE;
|
String var = myReadOnly ? EMPTY : "var" + SPACE;
|
||||||
return vararg + var + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
|
return vararg + var + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ParameterList extends Expression {
|
public class ParameterList extends Expression {
|
||||||
private final List<Parameter> myParameters;
|
private final List<Parameter> myParameters;
|
||||||
|
|
||||||
public ParameterList(List<Parameter> parameters) {
|
public ParameterList(List<Parameter> parameters) {
|
||||||
myParameters = parameters;
|
myParameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return AstUtil.joinNodes(myParameters, COMMA_WITH_SPACE);
|
return AstUtil.joinNodes(myParameters, COMMA_WITH_SPACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ParenthesizedExpression extends Expression {
|
public class ParenthesizedExpression extends Expression {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
|
|
||||||
public ParenthesizedExpression(Expression expression) {
|
public ParenthesizedExpression(Expression expression) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "(" + myExpression.toKotlin() + ")";
|
return "(" + myExpression.toKotlin() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,21 +9,21 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class PolyadicExpression extends Expression {
|
public class PolyadicExpression extends Expression {
|
||||||
private final List<Expression> myExpressions;
|
private final List<Expression> myExpressions;
|
||||||
private final String myToken;
|
private final String myToken;
|
||||||
private final List<String> myConversions;
|
private final List<String> myConversions;
|
||||||
|
|
||||||
public PolyadicExpression(List<Expression> expressions, String token, List<String> conversions) {
|
public PolyadicExpression(List<Expression> expressions, String token, List<String> conversions) {
|
||||||
super();
|
super();
|
||||||
myExpressions = expressions;
|
myExpressions = expressions;
|
||||||
myToken = token;
|
myToken = token;
|
||||||
myConversions = conversions;
|
myConversions = conversions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
List<String> expressionsWithConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myExpressions), myConversions);
|
List<String> expressionsWithConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myExpressions), myConversions);
|
||||||
return AstUtil.join(expressionsWithConversions, SPACE + myToken + SPACE);
|
return AstUtil.join(expressionsWithConversions, SPACE + myToken + SPACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class PostfixOperator extends Expression {
|
public class PostfixOperator extends Expression {
|
||||||
private final String myOp;
|
private final String myOp;
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
|
|
||||||
public PostfixOperator(String op, Expression expression) {
|
public PostfixOperator(String op, Expression expression) {
|
||||||
myOp = op;
|
myOp = op;
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myExpression.toKotlin() + myOp;
|
return myExpression.toKotlin() + myOp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class PrefixOperator extends Expression {
|
public class PrefixOperator extends Expression {
|
||||||
private final String myOp;
|
private final String myOp;
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
|
|
||||||
public PrefixOperator(String op, Expression expression) {
|
public PrefixOperator(String op, Expression expression) {
|
||||||
myOp = op;
|
myOp = op;
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myOp + myExpression.toKotlin();
|
return myOp + myExpression.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,20 +6,20 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class PrimitiveType extends Type {
|
public class PrimitiveType extends Type {
|
||||||
private final Identifier myType;
|
private final Identifier myType;
|
||||||
|
|
||||||
public PrimitiveType(Identifier type) {
|
public PrimitiveType(Identifier type) {
|
||||||
myType = type;
|
myType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myType.toKotlin();
|
return myType.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,20 +9,20 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ReferenceElement extends Element {
|
public class ReferenceElement extends Element {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Identifier myReference;
|
private final Identifier myReference;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final List<Type> myTypes;
|
private final List<Type> myTypes;
|
||||||
|
|
||||||
public ReferenceElement(@NotNull Identifier reference, @NotNull List<Type> types) {
|
public ReferenceElement(@NotNull Identifier reference, @NotNull List<Type> types) {
|
||||||
myReference = reference;
|
myReference = reference;
|
||||||
myTypes = types;
|
myTypes = types;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
String typesIfNeeded = myTypes.size() > 0 ? "<" + AstUtil.joinNodes(myTypes, COMMA_WITH_SPACE) + ">" : EMPTY;
|
String typesIfNeeded = myTypes.size() > 0 ? "<" + AstUtil.joinNodes(myTypes, COMMA_WITH_SPACE) + ">" : EMPTY;
|
||||||
return myReference.toKotlin() + typesIfNeeded;
|
return myReference.toKotlin() + typesIfNeeded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ import org.jetbrains.jet.j2k.util.AstUtil;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ReturnStatement extends Statement {
|
public class ReturnStatement extends Statement {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private String myConversion = EMPTY;
|
private String myConversion = EMPTY;
|
||||||
|
|
||||||
public ReturnStatement(Expression expression) {
|
public ReturnStatement(Expression expression) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReturnStatement(final Expression expression, final String conversion) {
|
public ReturnStatement(final Expression expression, final String conversion) {
|
||||||
this(expression);
|
this(expression);
|
||||||
myConversion = conversion;
|
myConversion = conversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "return" + SPACE + AstUtil.applyConversionForOneItem(myExpression.toKotlin(), myConversion);
|
return "return" + SPACE + AstUtil.applyConversionForOneItem(myExpression.toKotlin(), myConversion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class StarProjectionType extends Type {
|
public class StarProjectionType extends Type {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
G g = new G("");
|
G g = new G("");
|
||||||
G<String> g2 = new G<String>("");
|
G<String> g2 = new G<String>("");
|
||||||
return STAR;
|
return STAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class G <T extends String> {
|
class G<T extends String> {
|
||||||
public <T> G(T t) {
|
public <T> G(T t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Statement extends Element {
|
public abstract class Statement extends Element {
|
||||||
@NotNull
|
|
||||||
public static final Statement EMPTY_STATEMENT = new EmptyStatement();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ignatov
|
|
||||||
*/
|
|
||||||
private static class EmptyStatement extends Statement {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
public static final Statement EMPTY_STATEMENT = new EmptyStatement();
|
||||||
public String toKotlin() {
|
|
||||||
return EMPTY;
|
/**
|
||||||
|
* @author ignatov
|
||||||
|
*/
|
||||||
|
private static class EmptyStatement extends Statement {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SuperExpression extends Expression {
|
public class SuperExpression extends Expression {
|
||||||
private final Identifier myIdentifier;
|
private final Identifier myIdentifier;
|
||||||
|
|
||||||
public SuperExpression(Identifier identifier) {
|
public SuperExpression(Identifier identifier) {
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myIdentifier.isEmpty())
|
if (myIdentifier.isEmpty()) {
|
||||||
return "super";
|
return "super";
|
||||||
return "super" + AT + myIdentifier.toKotlin();
|
}
|
||||||
}
|
return "super" + AT + myIdentifier.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SureCallChainExpression extends Expression {
|
public class SureCallChainExpression extends Expression {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final String myConversion;
|
private final String myConversion;
|
||||||
|
|
||||||
public SureCallChainExpression(Expression expression, String conversion) {
|
public SureCallChainExpression(Expression expression, String conversion) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myConversion = conversion;
|
myConversion = conversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return myExpression.isEmpty();
|
return myExpression.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myExpression.toKotlin() + myConversion;
|
return myExpression.toKotlin() + myConversion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SwitchContainer extends Statement {
|
public class SwitchContainer extends Statement {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final List<CaseContainer> myCaseContainers;
|
private final List<CaseContainer> myCaseContainers;
|
||||||
|
|
||||||
public SwitchContainer(final Expression expression, final List<CaseContainer> caseContainers) {
|
public SwitchContainer(final Expression expression, final List<CaseContainer> caseContainers) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myCaseContainers = caseContainers;
|
myCaseContainers = caseContainers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "when" + SPACE + "(" + myExpression.toKotlin() + ")" + SPACE + "{" + N +
|
return "when" + SPACE + "(" + myExpression.toKotlin() + ")" + SPACE + "{" + N +
|
||||||
AstUtil.joinNodes(myCaseContainers, N) + N +
|
AstUtil.joinNodes(myCaseContainers, N) + N +
|
||||||
"}";
|
"}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SwitchLabelStatement extends Statement {
|
public class SwitchLabelStatement extends Statement {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
|
|
||||||
public SwitchLabelStatement(final Expression expression) {
|
public SwitchLabelStatement(final Expression expression) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myExpression.toKotlin();
|
return myExpression.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SynchronizedStatement extends Statement {
|
public class SynchronizedStatement extends Statement {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
private final Block myBlock;
|
private final Block myBlock;
|
||||||
|
|
||||||
public SynchronizedStatement(Expression expression, Block block) {
|
public SynchronizedStatement(Expression expression, Block block) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
myBlock = block;
|
myBlock = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "synchronized" + SPACE + "(" + myExpression.toKotlin() + ")" + SPACE + myBlock.toKotlin();
|
return "synchronized" + SPACE + "(" + myExpression.toKotlin() + ")" + SPACE + myBlock.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ThisExpression extends Expression {
|
public class ThisExpression extends Expression {
|
||||||
private final Identifier myIdentifier;
|
private final Identifier myIdentifier;
|
||||||
|
|
||||||
public ThisExpression(Identifier identifier) {
|
public ThisExpression(Identifier identifier) {
|
||||||
myIdentifier = identifier;
|
myIdentifier = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myIdentifier.isEmpty())
|
if (myIdentifier.isEmpty()) {
|
||||||
return "this";
|
return "this";
|
||||||
return "this" + AT + myIdentifier.toKotlin();
|
}
|
||||||
}
|
return "this" + AT + myIdentifier.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ThrowStatement extends Expression {
|
public class ThrowStatement extends Expression {
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
|
|
||||||
public ThrowStatement(Expression expression) {
|
public ThrowStatement(Expression expression) {
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "throw" + SPACE + myExpression.toKotlin();
|
return "throw" + SPACE + myExpression.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Trait extends Class {
|
public class Trait extends Class {
|
||||||
public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
|
public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
|
||||||
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
|
List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
|
||||||
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
|
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members));
|
||||||
TYPE = "trait";
|
TYPE = "trait";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
String primaryConstructorSignatureToKotlin() {
|
String primaryConstructorSignatureToKotlin() {
|
||||||
return EMPTY;
|
return EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needOpenModifier() {
|
boolean needOpenModifier() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,22 +9,22 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class TryStatement extends Statement {
|
public class TryStatement extends Statement {
|
||||||
private final Block myBlock;
|
private final Block myBlock;
|
||||||
private final List<CatchStatement> myCatches;
|
private final List<CatchStatement> myCatches;
|
||||||
private final Block myFinallyBlock;
|
private final Block myFinallyBlock;
|
||||||
|
|
||||||
public TryStatement(Block block, List<CatchStatement> catches, Block finallyBlock) {
|
public TryStatement(Block block, List<CatchStatement> catches, Block finallyBlock) {
|
||||||
myBlock = block;
|
myBlock = block;
|
||||||
myCatches = catches;
|
myCatches = catches;
|
||||||
myFinallyBlock = finallyBlock;
|
myFinallyBlock = finallyBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "try" + N +
|
return "try" + N +
|
||||||
myBlock.toKotlin() + N +
|
myBlock.toKotlin() + N +
|
||||||
AstUtil.joinNodes(myCatches, N) + N +
|
AstUtil.joinNodes(myCatches, N) + N +
|
||||||
(myFinallyBlock.isEmpty() ? EMPTY : "finally" + N + myFinallyBlock.toKotlin());
|
(myFinallyBlock.isEmpty() ? EMPTY : "finally" + N + myFinallyBlock.toKotlin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,43 +6,43 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public abstract class Type extends Element {
|
public abstract class Type extends Element {
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final Type EMPTY_TYPE = new EmptyType();
|
public static final Type EMPTY_TYPE = new EmptyType();
|
||||||
boolean myNullable = true;
|
boolean myNullable = true;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Kind getKind() {
|
|
||||||
return Kind.TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Type convertedToNotNull() {
|
|
||||||
myNullable = false;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNullable() {
|
|
||||||
return myNullable;
|
|
||||||
}
|
|
||||||
|
|
||||||
String isNullableStr() {
|
|
||||||
return isNullable() ? QUEST : EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ignatov
|
|
||||||
*/
|
|
||||||
private static class EmptyType extends Type {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public Kind getKind() {
|
||||||
return "UNRESOLVED_TYPE";
|
return Kind.TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public boolean isNullable() {
|
public Type convertedToNotNull() {
|
||||||
return false;
|
myNullable = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNullable() {
|
||||||
|
return myNullable;
|
||||||
|
}
|
||||||
|
|
||||||
|
String isNullableStr() {
|
||||||
|
return isNullable() ? QUEST : EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ignatov
|
||||||
|
*/
|
||||||
|
private static class EmptyType extends Type {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String toKotlin() {
|
||||||
|
return "UNRESOLVED_TYPE";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNullable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class TypeCastExpression extends Expression {
|
public class TypeCastExpression extends Expression {
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
private final Expression myExpression;
|
private final Expression myExpression;
|
||||||
|
|
||||||
public TypeCastExpression(Type type, Expression expression) {
|
public TypeCastExpression(Type type, Expression expression) {
|
||||||
myType = type;
|
myType = type;
|
||||||
myExpression = expression;
|
myExpression = expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "(" + myExpression.toKotlin() + SPACE + "as" + SPACE + myType.toKotlin() + ")";
|
return "(" + myExpression.toKotlin() + SPACE + "as" + SPACE + myType.toKotlin() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class TypeElement extends Element {
|
public class TypeElement extends Element {
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
|
|
||||||
public TypeElement(Type type) {
|
public TypeElement(Type type) {
|
||||||
myType = type;
|
myType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myType.toKotlin();
|
return myType.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,30 +8,32 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class TypeParameter extends Element {
|
public class TypeParameter extends Element {
|
||||||
private final Identifier myName;
|
private final Identifier myName;
|
||||||
private final List<Type> myExtendsTypes;
|
private final List<Type> myExtendsTypes;
|
||||||
|
|
||||||
public TypeParameter(Identifier name, List<Type> extendsTypes) {
|
public TypeParameter(Identifier name, List<Type> extendsTypes) {
|
||||||
myName = name;
|
myName = name;
|
||||||
myExtendsTypes = extendsTypes;
|
myExtendsTypes = extendsTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasWhere() {
|
public boolean hasWhere() {
|
||||||
return myExtendsTypes.size() > 1;
|
return myExtendsTypes.size() > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String getWhereToKotlin() {
|
public String getWhereToKotlin() {
|
||||||
if (hasWhere())
|
if (hasWhere()) {
|
||||||
return myName.toKotlin() + SPACE + COLON + SPACE + myExtendsTypes.get(1).toKotlin();
|
return myName.toKotlin() + SPACE + COLON + SPACE + myExtendsTypes.get(1).toKotlin();
|
||||||
return EMPTY;
|
}
|
||||||
}
|
return EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
if (myExtendsTypes.size() > 0)
|
if (myExtendsTypes.size() > 0) {
|
||||||
return myName.toKotlin() + SPACE + COLON + SPACE + myExtendsTypes.get(0).toKotlin();
|
return myName.toKotlin() + SPACE + COLON + SPACE + myExtendsTypes.get(0).toKotlin();
|
||||||
return myName.toKotlin();
|
}
|
||||||
}
|
return myName.toKotlin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,21 +6,21 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class VarArg extends Type {
|
public class VarArg extends Type {
|
||||||
private final Type myType;
|
private final Type myType;
|
||||||
|
|
||||||
public VarArg(Type type) {
|
public VarArg(Type type) {
|
||||||
myType = type;
|
myType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Kind getKind() {
|
public Kind getKind() {
|
||||||
return Kind.VARARG;
|
return Kind.VARARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return myType.toKotlin();
|
return myType.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class WhileStatement extends Statement {
|
public class WhileStatement extends Statement {
|
||||||
final Expression myCondition;
|
final Expression myCondition;
|
||||||
final Statement myStatement;
|
final Statement myStatement;
|
||||||
|
|
||||||
public WhileStatement(Expression condition, Statement statement) {
|
public WhileStatement(Expression condition, Statement statement) {
|
||||||
myCondition = condition;
|
myCondition = condition;
|
||||||
myStatement = statement;
|
myStatement = statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
return "while" + SPACE + "(" + myCondition.toKotlin() + ")" + N +
|
return "while" + SPACE + "(" + myCondition.toKotlin() + ")" + N +
|
||||||
myStatement.toKotlin();
|
myStatement.toKotlin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,86 +12,91 @@ import java.util.Map;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class AstUtil {
|
public class AstUtil {
|
||||||
private AstUtil() {
|
private AstUtil() {
|
||||||
}
|
|
||||||
|
|
||||||
private static String join(@NotNull final String[] array, @Nullable final String delimiter) {
|
|
||||||
StringBuilder buffer = new StringBuilder();
|
|
||||||
boolean haveDelimiter = (delimiter != null);
|
|
||||||
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
buffer.append(array[i]);
|
|
||||||
|
|
||||||
if (haveDelimiter && (i + 1) < array.length)
|
|
||||||
buffer.append(delimiter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.toString();
|
private static String join(@NotNull final String[] array, @Nullable final String delimiter) {
|
||||||
}
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
boolean haveDelimiter = (delimiter != null);
|
||||||
|
|
||||||
public static String joinNodes(@NotNull final List<? extends INode> nodes, final String delimiter) {
|
for (int i = 0; i < array.length; i++) {
|
||||||
return join(nodesToKotlin(nodes), delimiter);
|
buffer.append(array[i]);
|
||||||
}
|
|
||||||
|
|
||||||
public static String join(@NotNull final List<String> array, final String delimiter) {
|
if (haveDelimiter && (i + 1) < array.length) {
|
||||||
return join(array.toArray(new String[array.size()]), delimiter);
|
buffer.append(delimiter);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
return buffer.toString();
|
||||||
public static List<String> nodesToKotlin(@NotNull List<? extends INode> nodes) {
|
|
||||||
List<String> result = new LinkedList<String>();
|
|
||||||
for (INode n : nodes)
|
|
||||||
result.add(n.toKotlin());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String upperFirstCharacter(@NotNull String string) {
|
|
||||||
return string.substring(0, 1).toUpperCase() + string.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String lowerFirstCharacter(@NotNull String string) {
|
|
||||||
return string.substring(0, 1).toLowerCase() + string.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static <T> List<String> createListWithEmptyString(@NotNull final List<T> arguments) {
|
|
||||||
final List<String> conversions = new LinkedList<String>();
|
|
||||||
//noinspection UnusedDeclaration
|
|
||||||
for (T argument : arguments) conversions.add("");
|
|
||||||
return conversions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static List<String> applyConversions(@NotNull List<String> first, @NotNull List<String> second) {
|
|
||||||
List<String> result = new LinkedList<String>();
|
|
||||||
assert first.size() == second.size() : "Lists must have the same size.";
|
|
||||||
for (int i = 0; i < first.size(); i++) {
|
|
||||||
result.add(applyConversionForOneItem(first.get(i), second.get(i)));
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
public static String joinNodes(@NotNull final List<? extends INode> nodes, final String delimiter) {
|
||||||
public static String applyConversionForOneItem(@NotNull String f, @NotNull String s) {
|
return join(nodesToKotlin(nodes), delimiter);
|
||||||
if (s.isEmpty())
|
}
|
||||||
return f;
|
|
||||||
else
|
|
||||||
return "(" + f + ")" + s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
public static String join(@NotNull final List<String> array, final String delimiter) {
|
||||||
public static <T> T getOrElse(@NotNull Map<T, T> map, @NotNull T e, @NotNull T orElse) {
|
return join(array.toArray(new String[array.size()]), delimiter);
|
||||||
if (map.containsKey(e))
|
}
|
||||||
return map.get(e);
|
|
||||||
return orElse;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String replaceLastQuest(@NotNull String str) {
|
public static List<String> nodesToKotlin(@NotNull List<? extends INode> nodes) {
|
||||||
if (str.endsWith("?"))
|
List<String> result = new LinkedList<String>();
|
||||||
return str.substring(0, str.length() - 1);
|
for (INode n : nodes)
|
||||||
return str;
|
result.add(n.toKotlin());
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String upperFirstCharacter(@NotNull String string) {
|
||||||
|
return string.substring(0, 1).toUpperCase() + string.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String lowerFirstCharacter(@NotNull String string) {
|
||||||
|
return string.substring(0, 1).toLowerCase() + string.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static <T> List<String> createListWithEmptyString(@NotNull final List<T> arguments) {
|
||||||
|
final List<String> conversions = new LinkedList<String>();
|
||||||
|
//noinspection UnusedDeclaration
|
||||||
|
for (T argument : arguments) conversions.add("");
|
||||||
|
return conversions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<String> applyConversions(@NotNull List<String> first, @NotNull List<String> second) {
|
||||||
|
List<String> result = new LinkedList<String>();
|
||||||
|
assert first.size() == second.size() : "Lists must have the same size.";
|
||||||
|
for (int i = 0; i < first.size(); i++) {
|
||||||
|
result.add(applyConversionForOneItem(first.get(i), second.get(i)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String applyConversionForOneItem(@NotNull String f, @NotNull String s) {
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "(" + f + ")" + s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static <T> T getOrElse(@NotNull Map<T, T> map, @NotNull T e, @NotNull T orElse) {
|
||||||
|
if (map.containsKey(e)) {
|
||||||
|
return map.get(e);
|
||||||
|
}
|
||||||
|
return orElse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static String replaceLastQuest(@NotNull String str) {
|
||||||
|
if (str.endsWith("?")) {
|
||||||
|
return str.substring(0, str.length() - 1);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,20 +11,20 @@ import java.util.Set;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ClassVisitor extends JavaRecursiveElementVisitor {
|
public class ClassVisitor extends JavaRecursiveElementVisitor {
|
||||||
private final Set<String> myClassIdentifiers;
|
private final Set<String> myClassIdentifiers;
|
||||||
|
|
||||||
public ClassVisitor() {
|
public ClassVisitor() {
|
||||||
myClassIdentifiers = new HashSet<String>();
|
myClassIdentifiers = new HashSet<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<String> getClassIdentifiers() {
|
public Set<String> getClassIdentifiers() {
|
||||||
return new HashSet<String>(myClassIdentifiers);
|
return new HashSet<String>(myClassIdentifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitClass(@NotNull PsiClass aClass) {
|
public void visitClass(@NotNull PsiClass aClass) {
|
||||||
myClassIdentifiers.add(aClass.getQualifiedName());
|
myClassIdentifiers.add(aClass.getQualifiedName());
|
||||||
super.visitClass(aClass);
|
super.visitClass(aClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ package org.jetbrains.jet.j2k.visitors;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class Dispatcher {
|
public class Dispatcher {
|
||||||
private ExpressionVisitor myExpressionVisitor;
|
private ExpressionVisitor myExpressionVisitor;
|
||||||
|
|
||||||
public void setExpressionVisitor(final ExpressionVisitor expressionVisitor) {
|
public void setExpressionVisitor(final ExpressionVisitor expressionVisitor) {
|
||||||
this.myExpressionVisitor = expressionVisitor;
|
this.myExpressionVisitor = expressionVisitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dispatcher() {
|
public Dispatcher() {
|
||||||
myExpressionVisitor = new ExpressionVisitor();
|
myExpressionVisitor = new ExpressionVisitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExpressionVisitor getExpressionVisitor() {
|
public ExpressionVisitor getExpressionVisitor() {
|
||||||
return myExpressionVisitor;
|
return myExpressionVisitor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,86 +7,87 @@ import org.jetbrains.jet.j2k.ast.*;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.jet.j2k.Converter.*;
|
import static org.jetbrains.jet.j2k.Converter.*;
|
||||||
import static org.jetbrains.jet.j2k.ConverterUtil.*;
|
import static org.jetbrains.jet.j2k.ConverterUtil.isAnnotatedAsNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ElementVisitor extends JavaElementVisitor {
|
public class ElementVisitor extends JavaElementVisitor {
|
||||||
@NotNull
|
@NotNull
|
||||||
private Element myResult = Element.EMPTY_ELEMENT;
|
private Element myResult = Element.EMPTY_ELEMENT;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Element getResult() {
|
public Element getResult() {
|
||||||
return myResult;
|
return myResult;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitLocalVariable(@NotNull PsiLocalVariable variable) {
|
|
||||||
super.visitLocalVariable(variable);
|
|
||||||
|
|
||||||
myResult = new LocalVariable(
|
|
||||||
new IdentifierImpl(variable.getName()), // TODO
|
|
||||||
modifiersListToModifiersSet(variable.getModifierList()),
|
|
||||||
typeToType(variable.getType(), isAnnotatedAsNotNull(variable.getModifierList())),
|
|
||||||
createSureCallOnlyForChain(variable.getInitializer(), variable.getType())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitExpressionList(@NotNull PsiExpressionList list) {
|
|
||||||
super.visitExpressionList(list);
|
|
||||||
myResult = new ExpressionList(
|
|
||||||
expressionsToExpressionList(list.getExpressions()),
|
|
||||||
typesToTypeList(list.getExpressionTypes())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) {
|
|
||||||
super.visitReferenceElement(reference);
|
|
||||||
|
|
||||||
final List<Type> types = typesToTypeList(reference.getTypeParameters());
|
|
||||||
if (!reference.isQualified()) {
|
|
||||||
myResult = new ReferenceElement(
|
|
||||||
new IdentifierImpl(reference.getReferenceName()),
|
|
||||||
types
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
String result = new IdentifierImpl(reference.getReferenceName()).toKotlin();
|
|
||||||
PsiElement qualifier = reference.getQualifier();
|
|
||||||
while (qualifier != null) {
|
|
||||||
final PsiJavaCodeReferenceElement p = (PsiJavaCodeReferenceElement) qualifier;
|
|
||||||
result = new IdentifierImpl(p.getReferenceName()).toKotlin() + "." + result; // TODO: maybe need to replace by safe call?
|
|
||||||
qualifier = p.getQualifier();
|
|
||||||
}
|
|
||||||
myResult = new ReferenceElement(
|
|
||||||
new IdentifierImpl(result),
|
|
||||||
types
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitTypeElement(@NotNull PsiTypeElement type) {
|
public void visitLocalVariable(@NotNull PsiLocalVariable variable) {
|
||||||
super.visitTypeElement(type);
|
super.visitLocalVariable(variable);
|
||||||
myResult = new TypeElement(typeToType(type.getType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
myResult = new LocalVariable(
|
||||||
public void visitTypeParameter(@NotNull PsiTypeParameter classParameter) {
|
new IdentifierImpl(variable.getName()), // TODO
|
||||||
super.visitTypeParameter(classParameter);
|
modifiersListToModifiersSet(variable.getModifierList()),
|
||||||
myResult = new TypeParameter(
|
typeToType(variable.getType(), isAnnotatedAsNotNull(variable.getModifierList())),
|
||||||
new IdentifierImpl(classParameter.getName()), // TODO
|
createSureCallOnlyForChain(variable.getInitializer(), variable.getType())
|
||||||
typesToTypeList(classParameter.getExtendsListTypes())
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitParameterList(@NotNull PsiParameterList list) {
|
public void visitExpressionList(@NotNull PsiExpressionList list) {
|
||||||
super.visitParameterList(list);
|
super.visitExpressionList(list);
|
||||||
myResult = new ParameterList(
|
myResult = new ExpressionList(
|
||||||
parametersToParameterList(list.getParameters())
|
expressionsToExpressionList(list.getExpressions()),
|
||||||
);
|
typesToTypeList(list.getExpressionTypes())
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) {
|
||||||
|
super.visitReferenceElement(reference);
|
||||||
|
|
||||||
|
final List<Type> types = typesToTypeList(reference.getTypeParameters());
|
||||||
|
if (!reference.isQualified()) {
|
||||||
|
myResult = new ReferenceElement(
|
||||||
|
new IdentifierImpl(reference.getReferenceName()),
|
||||||
|
types
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String result = new IdentifierImpl(reference.getReferenceName()).toKotlin();
|
||||||
|
PsiElement qualifier = reference.getQualifier();
|
||||||
|
while (qualifier != null) {
|
||||||
|
final PsiJavaCodeReferenceElement p = (PsiJavaCodeReferenceElement) qualifier;
|
||||||
|
result = new IdentifierImpl(p.getReferenceName()).toKotlin() + "." + result; // TODO: maybe need to replace by safe call?
|
||||||
|
qualifier = p.getQualifier();
|
||||||
|
}
|
||||||
|
myResult = new ReferenceElement(
|
||||||
|
new IdentifierImpl(result),
|
||||||
|
types
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypeElement(@NotNull PsiTypeElement type) {
|
||||||
|
super.visitTypeElement(type);
|
||||||
|
myResult = new TypeElement(typeToType(type.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypeParameter(@NotNull PsiTypeParameter classParameter) {
|
||||||
|
super.visitTypeParameter(classParameter);
|
||||||
|
myResult = new TypeParameter(
|
||||||
|
new IdentifierImpl(classParameter.getName()), // TODO
|
||||||
|
typesToTypeList(classParameter.getExtendsListTypes())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitParameterList(@NotNull PsiParameterList list) {
|
||||||
|
super.visitParameterList(list);
|
||||||
|
myResult = new ParameterList(
|
||||||
|
parametersToParameterList(list.getParameters())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,442 +16,469 @@ import static org.jetbrains.jet.j2k.visitors.TypeVisitor.*;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ExpressionVisitor extends StatementVisitor {
|
public class ExpressionVisitor extends StatementVisitor {
|
||||||
@NotNull
|
@NotNull
|
||||||
Expression myResult = Expression.EMPTY_EXPRESSION;
|
Expression myResult = Expression.EMPTY_EXPRESSION;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitExpression(final PsiExpression expression) {
|
public void visitExpression(final PsiExpression expression) {
|
||||||
myResult = Expression.EMPTY_EXPRESSION;
|
myResult = Expression.EMPTY_EXPRESSION;
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Expression getResult() {
|
|
||||||
return myResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitArrayAccessExpression(@NotNull PsiArrayAccessExpression expression) {
|
|
||||||
super.visitArrayAccessExpression(expression);
|
|
||||||
myResult = new ArrayAccessExpression(
|
|
||||||
expressionToExpression(expression.getArrayExpression()),
|
|
||||||
expressionToExpression(expression.getIndexExpression())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitArrayInitializerExpression(@NotNull PsiArrayInitializerExpression expression) {
|
|
||||||
super.visitArrayInitializerExpression(expression);
|
|
||||||
myResult = new ArrayInitializerExpression(
|
|
||||||
typeToType(expression.getType()),
|
|
||||||
expressionsToExpressionList(expression.getInitializers())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression) {
|
|
||||||
super.visitAssignmentExpression(expression);
|
|
||||||
|
|
||||||
// TODO: simplify
|
|
||||||
|
|
||||||
final IElementType tokenType = expression.getOperationSign().getTokenType();
|
|
||||||
|
|
||||||
String secondOp = "";
|
|
||||||
if (tokenType == JavaTokenType.GTGTEQ) secondOp = "shr";
|
|
||||||
if (tokenType == JavaTokenType.LTLTEQ) secondOp = "shl";
|
|
||||||
if (tokenType == JavaTokenType.XOREQ) secondOp = "xor";
|
|
||||||
if (tokenType == JavaTokenType.ANDEQ) secondOp = "and";
|
|
||||||
if (tokenType == JavaTokenType.OREQ) secondOp = "or";
|
|
||||||
if (tokenType == JavaTokenType.GTGTGTEQ) secondOp = "ushr";
|
|
||||||
|
|
||||||
if (!secondOp.isEmpty()) // if not Kotlin operators
|
|
||||||
myResult = new AssignmentExpression(
|
|
||||||
expressionToExpression(expression.getLExpression()),
|
|
||||||
new BinaryExpression(
|
|
||||||
expressionToExpression(expression.getLExpression()),
|
|
||||||
expressionToExpression(expression.getRExpression()),
|
|
||||||
secondOp
|
|
||||||
),
|
|
||||||
"="
|
|
||||||
);
|
|
||||||
else
|
|
||||||
myResult = new AssignmentExpression(
|
|
||||||
expressionToExpression(expression.getLExpression()),
|
|
||||||
expressionToExpression(expression.getRExpression()),
|
|
||||||
expression.getOperationSign().getText() // TODO
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String getOperatorString(@NotNull IElementType tokenType) {
|
|
||||||
if (tokenType == JavaTokenType.PLUS) return "+";
|
|
||||||
if (tokenType == JavaTokenType.MINUS) return "-";
|
|
||||||
if (tokenType == JavaTokenType.ASTERISK) return "*";
|
|
||||||
if (tokenType == JavaTokenType.DIV) return "/";
|
|
||||||
if (tokenType == JavaTokenType.PERC) return "%";
|
|
||||||
if (tokenType == JavaTokenType.GTGT) return "shr";
|
|
||||||
if (tokenType == JavaTokenType.LTLT) return "shl";
|
|
||||||
if (tokenType == JavaTokenType.XOR) return "xor";
|
|
||||||
if (tokenType == JavaTokenType.AND) return "and";
|
|
||||||
if (tokenType == JavaTokenType.OR) return "or";
|
|
||||||
if (tokenType == JavaTokenType.GTGTGT) return "ushr";
|
|
||||||
if (tokenType == JavaTokenType.GT) return ">";
|
|
||||||
if (tokenType == JavaTokenType.LT) return "<";
|
|
||||||
if (tokenType == JavaTokenType.GE) return ">=";
|
|
||||||
if (tokenType == JavaTokenType.LE) return "<=";
|
|
||||||
if (tokenType == JavaTokenType.EQEQ) return "==";
|
|
||||||
if (tokenType == JavaTokenType.NE) return "!=";
|
|
||||||
if (tokenType == JavaTokenType.ANDAND) return "&&";
|
|
||||||
if (tokenType == JavaTokenType.OROR) return "||";
|
|
||||||
if (tokenType == JavaTokenType.PLUSPLUS) return "++";
|
|
||||||
if (tokenType == JavaTokenType.MINUSMINUS) return "--";
|
|
||||||
if (tokenType == JavaTokenType.EXCL) return "!";
|
|
||||||
|
|
||||||
System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType.toString());
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitBinaryExpression(@NotNull PsiBinaryExpression expression) {
|
|
||||||
super.visitBinaryExpression(expression);
|
|
||||||
|
|
||||||
if (expression.getOperationSign().getTokenType() == JavaTokenType.GTGTGT)
|
|
||||||
myResult = new DummyMethodCallExpression(
|
|
||||||
expressionToExpression(expression.getLOperand()),
|
|
||||||
"ushr",
|
|
||||||
expressionToExpression(expression.getROperand()));
|
|
||||||
else
|
|
||||||
myResult =
|
|
||||||
new BinaryExpression(
|
|
||||||
expressionToExpression(expression.getLOperand()),
|
|
||||||
expressionToExpression(expression.getROperand()),
|
|
||||||
getOperatorString(expression.getOperationSign().getTokenType()),
|
|
||||||
createConversions(expression, PsiType.BOOLEAN)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitClassObjectAccessExpression(@NotNull PsiClassObjectAccessExpression expression) {
|
|
||||||
super.visitClassObjectAccessExpression(expression);
|
|
||||||
myResult = new ClassObjectAccessExpression(elementToElement(expression.getOperand()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitConditionalExpression(@NotNull PsiConditionalExpression expression) {
|
|
||||||
super.visitConditionalExpression(expression);
|
|
||||||
PsiExpression condition = expression.getCondition();
|
|
||||||
PsiType type = condition.getType();
|
|
||||||
Expression e = type != null ?
|
|
||||||
createSureCallOnlyForChain(condition, type) :
|
|
||||||
expressionToExpression(condition);
|
|
||||||
myResult = new ParenthesizedExpression(
|
|
||||||
new IfStatement(
|
|
||||||
e,
|
|
||||||
expressionToExpression(expression.getThenExpression()),
|
|
||||||
expressionToExpression(expression.getElseExpression())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitExpressionList(@NotNull PsiExpressionList list) {
|
|
||||||
super.visitExpressionList(list);
|
|
||||||
myResult = new ExpressionList(expressionsToExpressionList(list.getExpressions()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitInstanceOfExpression(@NotNull PsiInstanceOfExpression expression) {
|
|
||||||
super.visitInstanceOfExpression(expression);
|
|
||||||
myResult = new IsOperator(
|
|
||||||
expressionToExpression(expression.getOperand()),
|
|
||||||
elementToElement(expression.getCheckType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitLiteralExpression(@NotNull PsiLiteralExpression expression) {
|
|
||||||
super.visitLiteralExpression(expression);
|
|
||||||
|
|
||||||
final Object value = expression.getValue();
|
|
||||||
String text = expression.getText();
|
|
||||||
boolean isQuotingNeeded = true;
|
|
||||||
|
|
||||||
final PsiType type = expression.getType();
|
|
||||||
if (type != null) {
|
|
||||||
String canonicalTypeStr = type.getCanonicalText();
|
|
||||||
if (canonicalTypeStr.equals("double") || canonicalTypeStr.equals(JAVA_LANG_DOUBLE))
|
|
||||||
text = text.replace("D", "").replace("d", "");
|
|
||||||
if (canonicalTypeStr.equals("float") || canonicalTypeStr.equals(JAVA_LANG_FLOAT))
|
|
||||||
text = text.replace("F", "").replace("f", "") + "." + "flt";
|
|
||||||
if (canonicalTypeStr.equals("long") || canonicalTypeStr.equals(JAVA_LANG_LONG))
|
|
||||||
text = text.replace("L", "").replace("l", "");
|
|
||||||
if (canonicalTypeStr.equals("int") || canonicalTypeStr.equals(JAVA_LANG_INTEGER)) // need for hex support
|
|
||||||
text = value != null ? value.toString() : text;
|
|
||||||
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_STRING))
|
|
||||||
isQuotingNeeded = false;
|
|
||||||
if (canonicalTypeStr.equals("char") || canonicalTypeStr.equals(JAVA_LANG_CHARACTER))
|
|
||||||
isQuotingNeeded = false;
|
|
||||||
}
|
}
|
||||||
myResult = new LiteralExpression(new IdentifierImpl(text, false, isQuotingNeeded));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
@Override
|
||||||
super.visitMethodCallExpression(expression);
|
public Expression getResult() {
|
||||||
if (!SuperVisitor.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) {
|
return myResult;
|
||||||
myResult = // TODO: not resolved
|
}
|
||||||
new MethodCallExpression(
|
|
||||||
expressionToExpression(expression.getMethodExpression()),
|
@Override
|
||||||
expressionsToExpressionList(expression.getArgumentList().getExpressions()),
|
public void visitArrayAccessExpression(@NotNull PsiArrayAccessExpression expression) {
|
||||||
createConversions(expression),
|
super.visitArrayAccessExpression(expression);
|
||||||
typeToType(expression.getType()).isNullable(),
|
myResult = new ArrayAccessExpression(
|
||||||
typesToTypeList(expression.getTypeArguments())
|
expressionToExpression(expression.getArrayExpression()),
|
||||||
|
expressionToExpression(expression.getIndexExpression())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitCallExpression(PsiCallExpression callExpression) {
|
public void visitArrayInitializerExpression(@NotNull PsiArrayInitializerExpression expression) {
|
||||||
super.visitCallExpression(callExpression);
|
super.visitArrayInitializerExpression(expression);
|
||||||
}
|
myResult = new ArrayInitializerExpression(
|
||||||
|
typeToType(expression.getType()),
|
||||||
@Override
|
expressionsToExpressionList(expression.getInitializers())
|
||||||
public void visitNewExpression(@NotNull PsiNewExpression expression) {
|
);
|
||||||
super.visitNewExpression(expression);
|
|
||||||
if (expression.getArrayInitializer() != null) // new Foo[] {Foo(1), Foo(2)}
|
|
||||||
myResult = createNewEmptyArray(expression);
|
|
||||||
else if (expression.getArrayDimensions().length > 0) { // new Foo[5]
|
|
||||||
myResult = createNewEmptyArrayWithoutInitialization(expression);
|
|
||||||
} else { // new Class(): common case
|
|
||||||
myResult = createNewClassExpression(expression);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@Override
|
||||||
private static Expression createNewClassExpression(@NotNull PsiNewExpression expression) {
|
public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression) {
|
||||||
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
|
super.visitAssignmentExpression(expression);
|
||||||
final PsiMethod constructor = expression.resolveMethod();
|
|
||||||
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
|
||||||
final boolean isNotConvertedClass = classReference != null && !getClassIdentifiers().contains(classReference.getQualifiedName());
|
|
||||||
PsiExpressionList argumentList = expression.getArgumentList();
|
|
||||||
PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[]{};
|
|
||||||
if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) {
|
|
||||||
return new NewClassExpression(
|
|
||||||
expressionToExpression(expression.getQualifier()),
|
|
||||||
elementToElement(classReference),
|
|
||||||
expressionsToExpressionList(arguments),
|
|
||||||
createConversions(expression),
|
|
||||||
anonymousClass != null ? anonymousClassToAnonymousClass(anonymousClass) : null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// is constructor secondary
|
|
||||||
final PsiJavaCodeReferenceElement reference = expression.getClassReference();
|
|
||||||
final List<Type> typeParameters = reference != null ? typesToTypeList(reference.getTypeParameters()) : Collections.<Type>emptyList();
|
|
||||||
return new CallChainExpression(
|
|
||||||
new IdentifierImpl(constructor.getName(), false),
|
|
||||||
new MethodCallExpression(
|
|
||||||
new IdentifierImpl("init"),
|
|
||||||
expressionsToExpressionList(arguments),
|
|
||||||
typeParameters));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
// TODO: simplify
|
||||||
private static Expression createNewEmptyArrayWithoutInitialization(@NotNull PsiNewExpression expression) {
|
|
||||||
return new ArrayWithoutInitializationExpression(
|
|
||||||
typeToType(expression.getType(), true),
|
|
||||||
expressionsToExpressionList(expression.getArrayDimensions())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
final IElementType tokenType = expression.getOperationSign().getTokenType();
|
||||||
private static Expression createNewEmptyArray(@NotNull PsiNewExpression expression) {
|
|
||||||
return expressionToExpression(expression.getArrayInitializer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
String secondOp = "";
|
||||||
public void visitParenthesizedExpression(@NotNull PsiParenthesizedExpression expression) {
|
if (tokenType == JavaTokenType.GTGTEQ) secondOp = "shr";
|
||||||
super.visitParenthesizedExpression(expression);
|
if (tokenType == JavaTokenType.LTLTEQ) secondOp = "shl";
|
||||||
myResult = new ParenthesizedExpression(
|
if (tokenType == JavaTokenType.XOREQ) secondOp = "xor";
|
||||||
expressionToExpression(expression.getExpression())
|
if (tokenType == JavaTokenType.ANDEQ) secondOp = "and";
|
||||||
);
|
if (tokenType == JavaTokenType.OREQ) secondOp = "or";
|
||||||
}
|
if (tokenType == JavaTokenType.GTGTGTEQ) secondOp = "ushr";
|
||||||
|
|
||||||
@Override
|
if (!secondOp.isEmpty()) // if not Kotlin operators
|
||||||
public void visitPostfixExpression(@NotNull PsiPostfixExpression expression) {
|
{
|
||||||
super.visitPostfixExpression(expression);
|
myResult = new AssignmentExpression(
|
||||||
myResult = new PostfixOperator(
|
expressionToExpression(expression.getLExpression()),
|
||||||
getOperatorString(expression.getOperationSign().getTokenType()),
|
new BinaryExpression(
|
||||||
expressionToExpression(expression.getOperand())
|
expressionToExpression(expression.getLExpression()),
|
||||||
);
|
expressionToExpression(expression.getRExpression()),
|
||||||
}
|
secondOp
|
||||||
|
),
|
||||||
@Override
|
"="
|
||||||
public void visitPrefixExpression(@NotNull PsiPrefixExpression expression) {
|
);
|
||||||
super.visitPrefixExpression(expression);
|
|
||||||
if (expression.getOperationTokenType() == JavaTokenType.TILDE)
|
|
||||||
myResult = new DummyMethodCallExpression(
|
|
||||||
new ParenthesizedExpression(expressionToExpression(expression.getOperand())), "inv", Expression.EMPTY_EXPRESSION
|
|
||||||
);
|
|
||||||
else
|
|
||||||
myResult = new PrefixOperator(
|
|
||||||
getOperatorString(expression.getOperationSign().getTokenType()),
|
|
||||||
expressionToExpression(expression.getOperand())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
|
||||||
super.visitReferenceExpression(expression);
|
|
||||||
|
|
||||||
final boolean isFieldReference = isFieldReference(expression, getContainingClass(expression));
|
|
||||||
final boolean insideSecondaryConstructor = isInsideSecondaryConstructor(expression);
|
|
||||||
final boolean hasReceiver = isFieldReference && insideSecondaryConstructor;
|
|
||||||
final boolean isThis = isThisExpression(expression);
|
|
||||||
final boolean isNullable = typeToType(expression.getType()).isNullable();
|
|
||||||
final String className = getClassNameWithConstructor(expression);
|
|
||||||
|
|
||||||
Expression identifier = new IdentifierImpl(expression.getReferenceName(), isNullable);
|
|
||||||
|
|
||||||
final String __ = "__";
|
|
||||||
if (hasReceiver)
|
|
||||||
identifier = new CallChainExpression(new IdentifierImpl(__, false), new IdentifierImpl(expression.getReferenceName(), isNullable));
|
|
||||||
else if (insideSecondaryConstructor && isThis)
|
|
||||||
identifier = new IdentifierImpl("val __ = " + className); // TODO: hack
|
|
||||||
|
|
||||||
myResult = new CallChainExpression(
|
|
||||||
expressionToExpression(expression.getQualifierExpression()),
|
|
||||||
identifier // TODO: if type exists so identifier is nullable
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String getClassNameWithConstructor(@NotNull PsiReferenceExpression expression) {
|
|
||||||
PsiElement context = expression.getContext();
|
|
||||||
while (context != null) {
|
|
||||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
|
||||||
final PsiClass containingClass = ((PsiMethod) context).getContainingClass();
|
|
||||||
if (containingClass != null) {
|
|
||||||
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
|
||||||
if (identifier != null)
|
|
||||||
return identifier.getText();
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
context = context.getContext();
|
myResult = new AssignmentExpression(
|
||||||
}
|
expressionToExpression(expression.getLExpression()),
|
||||||
return "";
|
expressionToExpression(expression.getRExpression()),
|
||||||
}
|
expression.getOperationSign().getText() // TODO
|
||||||
|
);
|
||||||
@NotNull
|
|
||||||
static String getClassName(@NotNull PsiExpression expression) {
|
|
||||||
PsiElement context = expression.getContext();
|
|
||||||
while (context != null) {
|
|
||||||
if (context instanceof PsiClass) {
|
|
||||||
final PsiClass containingClass = (PsiClass) context;
|
|
||||||
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
|
||||||
if (identifier != null)
|
|
||||||
return identifier.getText();
|
|
||||||
}
|
|
||||||
context = context.getContext();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isFieldReference(@NotNull PsiReferenceExpression expression, PsiClass currentClass) {
|
|
||||||
final PsiReference reference = expression.getReference();
|
|
||||||
if (reference != null) {
|
|
||||||
final PsiElement resolvedReference = reference.resolve();
|
|
||||||
if (resolvedReference != null) {
|
|
||||||
if (resolvedReference instanceof PsiField) {
|
|
||||||
return ((PsiField) resolvedReference).getContainingClass() == currentClass;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isInsideSecondaryConstructor(@NotNull PsiReferenceExpression expression) {
|
@NotNull
|
||||||
PsiElement context = expression.getContext();
|
private static String getOperatorString(@NotNull IElementType tokenType) {
|
||||||
while (context != null) {
|
if (tokenType == JavaTokenType.PLUS) return "+";
|
||||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
|
if (tokenType == JavaTokenType.MINUS) return "-";
|
||||||
return !isConstructorPrimary((PsiMethod) context);
|
if (tokenType == JavaTokenType.ASTERISK) return "*";
|
||||||
context = context.getContext();
|
if (tokenType == JavaTokenType.DIV) return "/";
|
||||||
|
if (tokenType == JavaTokenType.PERC) return "%";
|
||||||
|
if (tokenType == JavaTokenType.GTGT) return "shr";
|
||||||
|
if (tokenType == JavaTokenType.LTLT) return "shl";
|
||||||
|
if (tokenType == JavaTokenType.XOR) return "xor";
|
||||||
|
if (tokenType == JavaTokenType.AND) return "and";
|
||||||
|
if (tokenType == JavaTokenType.OR) return "or";
|
||||||
|
if (tokenType == JavaTokenType.GTGTGT) return "ushr";
|
||||||
|
if (tokenType == JavaTokenType.GT) return ">";
|
||||||
|
if (tokenType == JavaTokenType.LT) return "<";
|
||||||
|
if (tokenType == JavaTokenType.GE) return ">=";
|
||||||
|
if (tokenType == JavaTokenType.LE) return "<=";
|
||||||
|
if (tokenType == JavaTokenType.EQEQ) return "==";
|
||||||
|
if (tokenType == JavaTokenType.NE) return "!=";
|
||||||
|
if (tokenType == JavaTokenType.ANDAND) return "&&";
|
||||||
|
if (tokenType == JavaTokenType.OROR) return "||";
|
||||||
|
if (tokenType == JavaTokenType.PLUSPLUS) return "++";
|
||||||
|
if (tokenType == JavaTokenType.MINUSMINUS) return "--";
|
||||||
|
if (tokenType == JavaTokenType.EXCL) return "!";
|
||||||
|
|
||||||
|
System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType.toString());
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isInsidePrimaryConstructor(@NotNull PsiExpression expression) {
|
@Override
|
||||||
PsiElement context = expression.getContext();
|
public void visitBinaryExpression(@NotNull PsiBinaryExpression expression) {
|
||||||
while (context != null) {
|
super.visitBinaryExpression(expression);
|
||||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
|
|
||||||
return isConstructorPrimary((PsiMethod) context);
|
if (expression.getOperationSign().getTokenType() == JavaTokenType.GTGTGT) {
|
||||||
context = context.getContext();
|
myResult = new DummyMethodCallExpression(
|
||||||
|
expressionToExpression(expression.getLOperand()),
|
||||||
|
"ushr",
|
||||||
|
expressionToExpression(expression.getROperand()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myResult =
|
||||||
|
new BinaryExpression(
|
||||||
|
expressionToExpression(expression.getLOperand()),
|
||||||
|
expressionToExpression(expression.getROperand()),
|
||||||
|
getOperatorString(expression.getOperationSign().getTokenType()),
|
||||||
|
createConversions(expression, PsiType.BOOLEAN)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Override
|
||||||
private static PsiClass getContainingClass(@NotNull PsiExpression expression) {
|
public void visitClassObjectAccessExpression(@NotNull PsiClassObjectAccessExpression expression) {
|
||||||
PsiElement context = expression.getContext();
|
super.visitClassObjectAccessExpression(expression);
|
||||||
while (context != null) {
|
myResult = new ClassObjectAccessExpression(elementToElement(expression.getOperand()));
|
||||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
|
|
||||||
return ((PsiMethod) context).getContainingClass();
|
|
||||||
context = context.getContext();
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isThisExpression(@NotNull PsiReferenceExpression expression) {
|
@Override
|
||||||
for (PsiReference r : expression.getReferences())
|
public void visitConditionalExpression(@NotNull PsiConditionalExpression expression) {
|
||||||
if (r.getCanonicalText().equals("this")) {
|
super.visitConditionalExpression(expression);
|
||||||
final PsiElement res = r.resolve();
|
PsiExpression condition = expression.getCondition();
|
||||||
if (res != null && res instanceof PsiMethod && ((PsiMethod) res).isConstructor())
|
PsiType type = condition.getType();
|
||||||
return true;
|
Expression e = type != null ?
|
||||||
}
|
createSureCallOnlyForChain(condition, type) :
|
||||||
return false;
|
expressionToExpression(condition);
|
||||||
}
|
myResult = new ParenthesizedExpression(
|
||||||
|
new IfStatement(
|
||||||
@Override
|
e,
|
||||||
public void visitSuperExpression(@NotNull PsiSuperExpression expression) {
|
expressionToExpression(expression.getThenExpression()),
|
||||||
super.visitSuperExpression(expression);
|
expressionToExpression(expression.getElseExpression())
|
||||||
final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
|
)
|
||||||
myResult = new SuperExpression(
|
);
|
||||||
qualifier != null ?
|
|
||||||
new IdentifierImpl(qualifier.getQualifiedName()) :
|
|
||||||
Identifier.EMPTY_IDENTIFIER
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitThisExpression(@NotNull PsiThisExpression expression) {
|
|
||||||
super.visitThisExpression(expression);
|
|
||||||
final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
|
|
||||||
myResult = new ThisExpression(
|
|
||||||
qualifier != null ?
|
|
||||||
new IdentifierImpl(qualifier.getQualifiedName()) :
|
|
||||||
Identifier.EMPTY_IDENTIFIER
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
|
|
||||||
super.visitTypeCastExpression(expression);
|
|
||||||
|
|
||||||
final PsiTypeElement castType = expression.getCastType();
|
|
||||||
if (castType != null) {
|
|
||||||
myResult = new TypeCastExpression(
|
|
||||||
typeToType(castType.getType()),
|
|
||||||
expressionToExpression(expression.getOperand())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitPolyadicExpression(@NotNull PsiPolyadicExpression expression) {
|
public void visitExpressionList(@NotNull PsiExpressionList list) {
|
||||||
super.visitPolyadicExpression(expression);
|
super.visitExpressionList(list);
|
||||||
myResult = new PolyadicExpression(
|
myResult = new ExpressionList(expressionsToExpressionList(list.getExpressions()));
|
||||||
expressionsToExpressionList(expression.getOperands()),
|
}
|
||||||
getOperatorString(expression.getOperationTokenType()),
|
|
||||||
createConversions(expression, PsiType.BOOLEAN)
|
@Override
|
||||||
);
|
public void visitInstanceOfExpression(@NotNull PsiInstanceOfExpression expression) {
|
||||||
}
|
super.visitInstanceOfExpression(expression);
|
||||||
|
myResult = new IsOperator(
|
||||||
|
expressionToExpression(expression.getOperand()),
|
||||||
|
elementToElement(expression.getCheckType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitLiteralExpression(@NotNull PsiLiteralExpression expression) {
|
||||||
|
super.visitLiteralExpression(expression);
|
||||||
|
|
||||||
|
final Object value = expression.getValue();
|
||||||
|
String text = expression.getText();
|
||||||
|
boolean isQuotingNeeded = true;
|
||||||
|
|
||||||
|
final PsiType type = expression.getType();
|
||||||
|
if (type != null) {
|
||||||
|
String canonicalTypeStr = type.getCanonicalText();
|
||||||
|
if (canonicalTypeStr.equals("double") || canonicalTypeStr.equals(JAVA_LANG_DOUBLE)) {
|
||||||
|
text = text.replace("D", "").replace("d", "");
|
||||||
|
}
|
||||||
|
if (canonicalTypeStr.equals("float") || canonicalTypeStr.equals(JAVA_LANG_FLOAT)) {
|
||||||
|
text = text.replace("F", "").replace("f", "") + "." + "flt";
|
||||||
|
}
|
||||||
|
if (canonicalTypeStr.equals("long") || canonicalTypeStr.equals(JAVA_LANG_LONG)) {
|
||||||
|
text = text.replace("L", "").replace("l", "");
|
||||||
|
}
|
||||||
|
if (canonicalTypeStr.equals("int") || canonicalTypeStr.equals(JAVA_LANG_INTEGER)) // need for hex support
|
||||||
|
{
|
||||||
|
text = value != null ? value.toString() : text;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_STRING)) {
|
||||||
|
isQuotingNeeded = false;
|
||||||
|
}
|
||||||
|
if (canonicalTypeStr.equals("char") || canonicalTypeStr.equals(JAVA_LANG_CHARACTER)) {
|
||||||
|
isQuotingNeeded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myResult = new LiteralExpression(new IdentifierImpl(text, false, isQuotingNeeded));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||||
|
super.visitMethodCallExpression(expression);
|
||||||
|
if (!SuperVisitor.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) {
|
||||||
|
myResult = // TODO: not resolved
|
||||||
|
new MethodCallExpression(
|
||||||
|
expressionToExpression(expression.getMethodExpression()),
|
||||||
|
expressionsToExpressionList(expression.getArgumentList().getExpressions()),
|
||||||
|
createConversions(expression),
|
||||||
|
typeToType(expression.getType()).isNullable(),
|
||||||
|
typesToTypeList(expression.getTypeArguments())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitCallExpression(PsiCallExpression callExpression) {
|
||||||
|
super.visitCallExpression(callExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNewExpression(@NotNull PsiNewExpression expression) {
|
||||||
|
super.visitNewExpression(expression);
|
||||||
|
if (expression.getArrayInitializer() != null) // new Foo[] {Foo(1), Foo(2)}
|
||||||
|
{
|
||||||
|
myResult = createNewEmptyArray(expression);
|
||||||
|
}
|
||||||
|
else if (expression.getArrayDimensions().length > 0) { // new Foo[5]
|
||||||
|
myResult = createNewEmptyArrayWithoutInitialization(expression);
|
||||||
|
}
|
||||||
|
else { // new Class(): common case
|
||||||
|
myResult = createNewClassExpression(expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static Expression createNewClassExpression(@NotNull PsiNewExpression expression) {
|
||||||
|
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
|
||||||
|
final PsiMethod constructor = expression.resolveMethod();
|
||||||
|
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||||
|
final boolean isNotConvertedClass = classReference != null && !getClassIdentifiers().contains(classReference.getQualifiedName());
|
||||||
|
PsiExpressionList argumentList = expression.getArgumentList();
|
||||||
|
PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[]{};
|
||||||
|
if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) {
|
||||||
|
return new NewClassExpression(
|
||||||
|
expressionToExpression(expression.getQualifier()),
|
||||||
|
elementToElement(classReference),
|
||||||
|
expressionsToExpressionList(arguments),
|
||||||
|
createConversions(expression),
|
||||||
|
anonymousClass != null ? anonymousClassToAnonymousClass(anonymousClass) : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// is constructor secondary
|
||||||
|
final PsiJavaCodeReferenceElement reference = expression.getClassReference();
|
||||||
|
final List<Type> typeParameters = reference != null
|
||||||
|
? typesToTypeList(reference.getTypeParameters())
|
||||||
|
: Collections.<Type>emptyList();
|
||||||
|
return new CallChainExpression(
|
||||||
|
new IdentifierImpl(constructor.getName(), false),
|
||||||
|
new MethodCallExpression(
|
||||||
|
new IdentifierImpl("init"),
|
||||||
|
expressionsToExpressionList(arguments),
|
||||||
|
typeParameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static Expression createNewEmptyArrayWithoutInitialization(@NotNull PsiNewExpression expression) {
|
||||||
|
return new ArrayWithoutInitializationExpression(
|
||||||
|
typeToType(expression.getType(), true),
|
||||||
|
expressionsToExpressionList(expression.getArrayDimensions())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static Expression createNewEmptyArray(@NotNull PsiNewExpression expression) {
|
||||||
|
return expressionToExpression(expression.getArrayInitializer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitParenthesizedExpression(@NotNull PsiParenthesizedExpression expression) {
|
||||||
|
super.visitParenthesizedExpression(expression);
|
||||||
|
myResult = new ParenthesizedExpression(
|
||||||
|
expressionToExpression(expression.getExpression())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPostfixExpression(@NotNull PsiPostfixExpression expression) {
|
||||||
|
super.visitPostfixExpression(expression);
|
||||||
|
myResult = new PostfixOperator(
|
||||||
|
getOperatorString(expression.getOperationSign().getTokenType()),
|
||||||
|
expressionToExpression(expression.getOperand())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPrefixExpression(@NotNull PsiPrefixExpression expression) {
|
||||||
|
super.visitPrefixExpression(expression);
|
||||||
|
if (expression.getOperationTokenType() == JavaTokenType.TILDE) {
|
||||||
|
myResult = new DummyMethodCallExpression(
|
||||||
|
new ParenthesizedExpression(expressionToExpression(expression.getOperand())), "inv", Expression.EMPTY_EXPRESSION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myResult = new PrefixOperator(
|
||||||
|
getOperatorString(expression.getOperationSign().getTokenType()),
|
||||||
|
expressionToExpression(expression.getOperand())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
||||||
|
super.visitReferenceExpression(expression);
|
||||||
|
|
||||||
|
final boolean isFieldReference = isFieldReference(expression, getContainingClass(expression));
|
||||||
|
final boolean insideSecondaryConstructor = isInsideSecondaryConstructor(expression);
|
||||||
|
final boolean hasReceiver = isFieldReference && insideSecondaryConstructor;
|
||||||
|
final boolean isThis = isThisExpression(expression);
|
||||||
|
final boolean isNullable = typeToType(expression.getType()).isNullable();
|
||||||
|
final String className = getClassNameWithConstructor(expression);
|
||||||
|
|
||||||
|
Expression identifier = new IdentifierImpl(expression.getReferenceName(), isNullable);
|
||||||
|
|
||||||
|
final String __ = "__";
|
||||||
|
if (hasReceiver) {
|
||||||
|
identifier = new CallChainExpression(new IdentifierImpl(__, false), new IdentifierImpl(expression.getReferenceName(), isNullable));
|
||||||
|
}
|
||||||
|
else if (insideSecondaryConstructor && isThis) {
|
||||||
|
identifier = new IdentifierImpl("val __ = " + className); // TODO: hack
|
||||||
|
}
|
||||||
|
|
||||||
|
myResult = new CallChainExpression(
|
||||||
|
expressionToExpression(expression.getQualifierExpression()),
|
||||||
|
identifier // TODO: if type exists so identifier is nullable
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getClassNameWithConstructor(@NotNull PsiReferenceExpression expression) {
|
||||||
|
PsiElement context = expression.getContext();
|
||||||
|
while (context != null) {
|
||||||
|
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||||
|
final PsiClass containingClass = ((PsiMethod) context).getContainingClass();
|
||||||
|
if (containingClass != null) {
|
||||||
|
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
||||||
|
if (identifier != null) {
|
||||||
|
return identifier.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context = context.getContext();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
static String getClassName(@NotNull PsiExpression expression) {
|
||||||
|
PsiElement context = expression.getContext();
|
||||||
|
while (context != null) {
|
||||||
|
if (context instanceof PsiClass) {
|
||||||
|
final PsiClass containingClass = (PsiClass) context;
|
||||||
|
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
||||||
|
if (identifier != null) {
|
||||||
|
return identifier.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context = context.getContext();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFieldReference(@NotNull PsiReferenceExpression expression, PsiClass currentClass) {
|
||||||
|
final PsiReference reference = expression.getReference();
|
||||||
|
if (reference != null) {
|
||||||
|
final PsiElement resolvedReference = reference.resolve();
|
||||||
|
if (resolvedReference != null) {
|
||||||
|
if (resolvedReference instanceof PsiField) {
|
||||||
|
return ((PsiField) resolvedReference).getContainingClass() == currentClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInsideSecondaryConstructor(@NotNull PsiReferenceExpression expression) {
|
||||||
|
PsiElement context = expression.getContext();
|
||||||
|
while (context != null) {
|
||||||
|
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||||
|
return !isConstructorPrimary((PsiMethod) context);
|
||||||
|
}
|
||||||
|
context = context.getContext();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInsidePrimaryConstructor(@NotNull PsiExpression expression) {
|
||||||
|
PsiElement context = expression.getContext();
|
||||||
|
while (context != null) {
|
||||||
|
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||||
|
return isConstructorPrimary((PsiMethod) context);
|
||||||
|
}
|
||||||
|
context = context.getContext();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static PsiClass getContainingClass(@NotNull PsiExpression expression) {
|
||||||
|
PsiElement context = expression.getContext();
|
||||||
|
while (context != null) {
|
||||||
|
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||||
|
return ((PsiMethod) context).getContainingClass();
|
||||||
|
}
|
||||||
|
context = context.getContext();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isThisExpression(@NotNull PsiReferenceExpression expression) {
|
||||||
|
for (PsiReference r : expression.getReferences())
|
||||||
|
if (r.getCanonicalText().equals("this")) {
|
||||||
|
final PsiElement res = r.resolve();
|
||||||
|
if (res != null && res instanceof PsiMethod && ((PsiMethod) res).isConstructor()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSuperExpression(@NotNull PsiSuperExpression expression) {
|
||||||
|
super.visitSuperExpression(expression);
|
||||||
|
final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
|
||||||
|
myResult = new SuperExpression(
|
||||||
|
qualifier != null ?
|
||||||
|
new IdentifierImpl(qualifier.getQualifiedName()) :
|
||||||
|
Identifier.EMPTY_IDENTIFIER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitThisExpression(@NotNull PsiThisExpression expression) {
|
||||||
|
super.visitThisExpression(expression);
|
||||||
|
final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
|
||||||
|
myResult = new ThisExpression(
|
||||||
|
qualifier != null ?
|
||||||
|
new IdentifierImpl(qualifier.getQualifiedName()) :
|
||||||
|
Identifier.EMPTY_IDENTIFIER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
|
||||||
|
super.visitTypeCastExpression(expression);
|
||||||
|
|
||||||
|
final PsiTypeElement castType = expression.getCastType();
|
||||||
|
if (castType != null) {
|
||||||
|
myResult = new TypeCastExpression(
|
||||||
|
typeToType(castType.getType()),
|
||||||
|
expressionToExpression(expression.getOperand())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPolyadicExpression(@NotNull PsiPolyadicExpression expression) {
|
||||||
|
super.visitPolyadicExpression(expression);
|
||||||
|
myResult = new PolyadicExpression(
|
||||||
|
expressionsToExpressionList(expression.getOperands()),
|
||||||
|
getOperatorString(expression.getOperationTokenType()),
|
||||||
|
createConversions(expression, PsiType.BOOLEAN)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+33
-28
@@ -13,33 +13,38 @@ import static org.jetbrains.jet.j2k.visitors.TypeVisitor.JAVA_LANG_OBJECT;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ExpressionVisitorForDirectObjectInheritors extends ExpressionVisitor {
|
public class ExpressionVisitorForDirectObjectInheritors extends ExpressionVisitor {
|
||||||
@Override
|
@Override
|
||||||
public void visitMethodCallExpression(@NotNull final PsiMethodCallExpression expression) {
|
public void visitMethodCallExpression(@NotNull final PsiMethodCallExpression expression) {
|
||||||
if (superMethodInvocation(expression.getMethodExpression(), "hashCode"))
|
if (superMethodInvocation(expression.getMethodExpression(), "hashCode")) {
|
||||||
myResult = new DummyMethodCallExpression(new IdentifierImpl("System"), "identityHashCode", new IdentifierImpl("this"));
|
myResult = new DummyMethodCallExpression(new IdentifierImpl("System"), "identityHashCode", new IdentifierImpl("this"));
|
||||||
else if (superMethodInvocation(expression.getMethodExpression(), "equals"))
|
}
|
||||||
myResult = new DummyMethodCallExpression(new IdentifierImpl("this"), "identityEquals", Converter.elementToElement(expression.getArgumentList()));
|
else if (superMethodInvocation(expression.getMethodExpression(), "equals")) {
|
||||||
else if (superMethodInvocation(expression.getMethodExpression(), "toString"))
|
myResult = new DummyMethodCallExpression(new IdentifierImpl("this"), "identityEquals", Converter.elementToElement(expression.getArgumentList()));
|
||||||
myResult = new DummyStringExpression(String.format("getJavaClass<%s>.getName() + '@' + Integer.toHexString(hashCode())", getClassName(expression.getMethodExpression())));
|
}
|
||||||
else
|
else if (superMethodInvocation(expression.getMethodExpression(), "toString")) {
|
||||||
super.visitMethodCallExpression(expression);
|
myResult = new DummyStringExpression(String.format("getJavaClass<%s>.getName() + '@' + Integer.toHexString(hashCode())", getClassName(expression.getMethodExpression())));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
@Override
|
super.visitMethodCallExpression(expression);
|
||||||
public void visitReferenceExpression(@NotNull final PsiReferenceExpression expression) {
|
}
|
||||||
super.visitReferenceExpression(expression);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
private static boolean superMethodInvocation(@NotNull final PsiReferenceExpression expression, final String methodName) {
|
public void visitReferenceExpression(@NotNull final PsiReferenceExpression expression) {
|
||||||
String referenceName = expression.getReferenceName();
|
super.visitReferenceExpression(expression);
|
||||||
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
}
|
||||||
if (referenceName != null && referenceName.equals(methodName)) {
|
|
||||||
if (qualifierExpression instanceof PsiSuperExpression) {
|
private static boolean superMethodInvocation(@NotNull final PsiReferenceExpression expression, final String methodName) {
|
||||||
PsiType type = qualifierExpression.getType();
|
String referenceName = expression.getReferenceName();
|
||||||
if (type != null && type.getCanonicalText().equals(JAVA_LANG_OBJECT))
|
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||||
return true;
|
if (referenceName != null && referenceName.equals(methodName)) {
|
||||||
}
|
if (qualifierExpression instanceof PsiSuperExpression) {
|
||||||
|
PsiType type = qualifierExpression.getType();
|
||||||
|
if (type != null && type.getCanonicalText().equals(JAVA_LANG_OBJECT)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,341 +19,358 @@ import static org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class StatementVisitor extends ElementVisitor {
|
public class StatementVisitor extends ElementVisitor {
|
||||||
private Statement myResult = Statement.EMPTY_STATEMENT;
|
private Statement myResult = Statement.EMPTY_STATEMENT;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Statement getResult() {
|
public Statement getResult() {
|
||||||
return myResult;
|
return myResult;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitAssertStatement(@NotNull PsiAssertStatement statement) {
|
|
||||||
super.visitAssertStatement(statement);
|
|
||||||
myResult = new AssertStatement(
|
|
||||||
expressionToExpression(statement.getAssertCondition()),
|
|
||||||
expressionToExpression(statement.getAssertDescription())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitBlockStatement(@NotNull PsiBlockStatement statement) {
|
|
||||||
super.visitBlockStatement(statement);
|
|
||||||
myResult = new Block(
|
|
||||||
statementsToStatementList(statement.getCodeBlock().getStatements()),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitBreakStatement(@NotNull PsiBreakStatement statement) {
|
|
||||||
super.visitBreakStatement(statement);
|
|
||||||
if (statement.getLabelIdentifier() == null)
|
|
||||||
myResult = new BreakStatement();
|
|
||||||
else
|
|
||||||
myResult = new BreakStatement(
|
|
||||||
identifierToIdentifier(statement.getLabelIdentifier())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitContinueStatement(@NotNull PsiContinueStatement statement) {
|
|
||||||
super.visitContinueStatement(statement);
|
|
||||||
if (statement.getLabelIdentifier() == null)
|
|
||||||
myResult = new ContinueStatement();
|
|
||||||
else
|
|
||||||
myResult = new ContinueStatement(
|
|
||||||
identifierToIdentifier(statement.getLabelIdentifier())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDeclarationStatement(@NotNull PsiDeclarationStatement statement) {
|
|
||||||
super.visitDeclarationStatement(statement);
|
|
||||||
myResult = new DeclarationStatement(
|
|
||||||
elementsToElementList(statement.getDeclaredElements())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDoWhileStatement(@NotNull PsiDoWhileStatement statement) {
|
|
||||||
super.visitDoWhileStatement(statement);
|
|
||||||
PsiExpression condition = statement.getCondition();
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
Expression expression = condition != null && condition.getType() != null ?
|
|
||||||
createSureCallOnlyForChain(condition, condition.getType()) :
|
|
||||||
expressionToExpression(condition);
|
|
||||||
myResult = new DoWhileStatement(
|
|
||||||
expression,
|
|
||||||
statementToStatement(statement.getBody())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitExpressionStatement(@NotNull PsiExpressionStatement statement) {
|
|
||||||
super.visitExpressionStatement(statement);
|
|
||||||
myResult = expressionToExpression(statement.getExpression());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitExpressionListStatement(@NotNull PsiExpressionListStatement statement) {
|
|
||||||
super.visitExpressionListStatement(statement);
|
|
||||||
myResult =
|
|
||||||
new ExpressionListStatement(expressionsToExpressionList(statement.getExpressionList().getExpressions()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitForStatement(@NotNull PsiForStatement statement) {
|
|
||||||
super.visitForStatement(statement);
|
|
||||||
|
|
||||||
final PsiStatement initialization = statement.getInitialization();
|
|
||||||
final PsiStatement update = statement.getUpdate();
|
|
||||||
final PsiExpression condition = statement.getCondition();
|
|
||||||
final PsiStatement body = statement.getBody();
|
|
||||||
|
|
||||||
final PsiLocalVariable firstChild = initialization != null && initialization.getFirstChild() instanceof PsiLocalVariable ?
|
|
||||||
(PsiLocalVariable) initialization.getFirstChild() : null;
|
|
||||||
|
|
||||||
int bodyWriteCount = countWritingAccesses(firstChild, body);
|
|
||||||
int conditionWriteCount = countWritingAccesses(firstChild, condition);
|
|
||||||
int updateWriteCount = countWritingAccesses(firstChild, update);
|
|
||||||
boolean onceWritableIterator = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0;
|
|
||||||
|
|
||||||
final IElementType operationTokenType = condition != null && condition instanceof PsiBinaryExpression ?
|
|
||||||
((PsiBinaryExpression) condition).getOperationTokenType() : null;
|
|
||||||
if (
|
|
||||||
initialization != null &&
|
|
||||||
initialization instanceof PsiDeclarationStatement
|
|
||||||
&& initialization.getFirstChild() == initialization.getLastChild()
|
|
||||||
&& condition != null
|
|
||||||
&& update != null
|
|
||||||
&& update.getChildren().length == 1
|
|
||||||
&& isPlusPlusExpression(update.getChildren()[0])
|
|
||||||
&& operationTokenType != null
|
|
||||||
&& (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
|
|
||||||
&& initialization.getFirstChild() != null
|
|
||||||
&& initialization.getFirstChild() instanceof PsiLocalVariable
|
|
||||||
&& firstChild != null
|
|
||||||
&& firstChild.getNameIdentifier() != null
|
|
||||||
&& onceWritableIterator
|
|
||||||
) {
|
|
||||||
final Expression end = expressionToExpression(((PsiBinaryExpression) condition).getROperand());
|
|
||||||
final Expression endExpression = operationTokenType == JavaTokenType.LT ?
|
|
||||||
new BinaryExpression(end, new IdentifierImpl("1"), "-") :
|
|
||||||
end;
|
|
||||||
myResult = new ForeachWithRangeStatement(
|
|
||||||
new IdentifierImpl(firstChild.getName()),
|
|
||||||
expressionToExpression(firstChild.getInitializer()),
|
|
||||||
endExpression,
|
|
||||||
statementToStatement(body)
|
|
||||||
);
|
|
||||||
} else { // common case: while loop instead of for loop
|
|
||||||
List<Statement> forStatements = new LinkedList<Statement>();
|
|
||||||
forStatements.add(statementToStatement(initialization));
|
|
||||||
forStatements.add(new WhileStatement(
|
|
||||||
expressionToExpression(condition),
|
|
||||||
new Block(
|
|
||||||
Arrays.asList(statementToStatement(body),
|
|
||||||
new Block(Arrays.asList(statementToStatement(update)))))));
|
|
||||||
myResult = new Block(forStatements);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isPlusPlusExpression(@NotNull PsiElement psiElement) {
|
@Override
|
||||||
return (psiElement instanceof PsiPostfixExpression && ((PsiPostfixExpression) psiElement).getOperationTokenType() == JavaTokenType.PLUSPLUS)
|
public void visitAssertStatement(@NotNull PsiAssertStatement statement) {
|
||||||
|| (psiElement instanceof PsiPrefixExpression && ((PsiPrefixExpression) psiElement).getOperationTokenType() == JavaTokenType.PLUSPLUS);
|
super.visitAssertStatement(statement);
|
||||||
}
|
myResult = new AssertStatement(
|
||||||
|
expressionToExpression(statement.getAssertCondition()),
|
||||||
|
expressionToExpression(statement.getAssertDescription())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitForeachStatement(@NotNull PsiForeachStatement statement) {
|
public void visitBlockStatement(@NotNull PsiBlockStatement statement) {
|
||||||
super.visitForeachStatement(statement);
|
super.visitBlockStatement(statement);
|
||||||
myResult = new ForeachStatement(
|
myResult = new Block(
|
||||||
parameterToParameter(statement.getIterationParameter()),
|
statementsToStatementList(statement.getCodeBlock().getStatements()),
|
||||||
expressionToExpression(statement.getIteratedValue()),
|
true
|
||||||
statementToStatement(statement.getBody())
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitIfStatement(@NotNull PsiIfStatement statement) {
|
public void visitBreakStatement(@NotNull PsiBreakStatement statement) {
|
||||||
super.visitIfStatement(statement);
|
super.visitBreakStatement(statement);
|
||||||
PsiExpression condition = statement.getCondition();
|
if (statement.getLabelIdentifier() == null) {
|
||||||
@SuppressWarnings("ConstantConditions")
|
myResult = new BreakStatement();
|
||||||
Expression expression = condition != null && condition.getType() != null ?
|
}
|
||||||
createSureCallOnlyForChain(condition, condition.getType()) :
|
else {
|
||||||
expressionToExpression(condition);
|
myResult = new BreakStatement(
|
||||||
myResult = new IfStatement(
|
identifierToIdentifier(statement.getLabelIdentifier())
|
||||||
expression,
|
);
|
||||||
statementToStatement(statement.getThenBranch()),
|
|
||||||
statementToStatement(statement.getElseBranch())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitLabeledStatement(@NotNull PsiLabeledStatement statement) {
|
|
||||||
super.visitLabeledStatement(statement);
|
|
||||||
myResult = new LabelStatement(
|
|
||||||
identifierToIdentifier(statement.getLabelIdentifier()),
|
|
||||||
statementToStatement(statement.getStatement())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSwitchLabelStatement(@NotNull PsiSwitchLabelStatement statement) {
|
|
||||||
super.visitSwitchLabelStatement(statement);
|
|
||||||
myResult = statement.isDefaultCase() ?
|
|
||||||
new DefaultSwitchLabelStatement() :
|
|
||||||
new SwitchLabelStatement(expressionToExpression(statement.getCaseValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) {
|
|
||||||
super.visitSwitchStatement(statement);
|
|
||||||
myResult = new SwitchContainer(
|
|
||||||
expressionToExpression(statement.getExpression()),
|
|
||||||
switchBodyToCases(statement.getBody())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static List<CaseContainer> switchBodyToCases(@Nullable final PsiCodeBlock body) {
|
|
||||||
final List<List<PsiStatement>> cases = splitToCases(body);
|
|
||||||
final List<PsiStatement> allSwitchStatements = body != null ? Arrays.asList(body.getStatements()) : Collections.<PsiStatement>emptyList();
|
|
||||||
|
|
||||||
List<CaseContainer> result = new LinkedList<CaseContainer>();
|
|
||||||
List<Statement> pendingLabels = new LinkedList<Statement>();
|
|
||||||
int i = 0;
|
|
||||||
for (List<PsiStatement> ls : cases) {
|
|
||||||
assert ls.size() > 0;
|
|
||||||
PsiStatement label = ls.get(0);
|
|
||||||
assert label instanceof PsiSwitchLabelStatement;
|
|
||||||
|
|
||||||
assert allSwitchStatements.get(i) == label : "not a right index";
|
|
||||||
|
|
||||||
if (ls.size() > 1) {
|
|
||||||
pendingLabels.add(statementToStatement(label));
|
|
||||||
List<PsiStatement> slice = ls.subList(1, ls.size());
|
|
||||||
|
|
||||||
if (!containsBreak(slice)) {
|
|
||||||
List<Statement> statements = statementsToStatementList(slice);
|
|
||||||
statements.addAll(
|
|
||||||
statementsToStatementList(getAllToNextBreak(allSwitchStatements, i + ls.size()))
|
|
||||||
);
|
|
||||||
result.add(new CaseContainer(pendingLabels, statements));
|
|
||||||
pendingLabels = new LinkedList<Statement>();
|
|
||||||
} else {
|
|
||||||
result.add(new CaseContainer(pendingLabels, statementsToStatementList(slice)));
|
|
||||||
pendingLabels = new LinkedList<Statement>();
|
|
||||||
}
|
}
|
||||||
} else // ls.size() == 1
|
|
||||||
pendingLabels.add(statementToStatement(label));
|
|
||||||
i += ls.size();
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean containsBreak(@NotNull final List<PsiStatement> slice) {
|
@Override
|
||||||
for (PsiStatement s : slice)
|
public void visitContinueStatement(@NotNull PsiContinueStatement statement) {
|
||||||
if (s instanceof PsiBreakStatement)
|
super.visitContinueStatement(statement);
|
||||||
return true;
|
if (statement.getLabelIdentifier() == null) {
|
||||||
return false;
|
myResult = new ContinueStatement();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
myResult = new ContinueStatement(
|
||||||
|
identifierToIdentifier(statement.getLabelIdentifier())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@Override
|
||||||
private static List<PsiStatement> getAllToNextBreak(@NotNull final List<PsiStatement> allStatements, final int start) {
|
public void visitDeclarationStatement(@NotNull PsiDeclarationStatement statement) {
|
||||||
List<PsiStatement> result = new LinkedList<PsiStatement>();
|
super.visitDeclarationStatement(statement);
|
||||||
for (int i = start; i < allStatements.size(); i++) {
|
myResult = new DeclarationStatement(
|
||||||
PsiStatement s = allStatements.get(i);
|
elementsToElementList(statement.getDeclaredElements())
|
||||||
if (s instanceof PsiBreakStatement || s instanceof PsiReturnStatement)
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDoWhileStatement(@NotNull PsiDoWhileStatement statement) {
|
||||||
|
super.visitDoWhileStatement(statement);
|
||||||
|
PsiExpression condition = statement.getCondition();
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
Expression expression = condition != null && condition.getType() != null ?
|
||||||
|
createSureCallOnlyForChain(condition, condition.getType()) :
|
||||||
|
expressionToExpression(condition);
|
||||||
|
myResult = new DoWhileStatement(
|
||||||
|
expression,
|
||||||
|
statementToStatement(statement.getBody())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExpressionStatement(@NotNull PsiExpressionStatement statement) {
|
||||||
|
super.visitExpressionStatement(statement);
|
||||||
|
myResult = expressionToExpression(statement.getExpression());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExpressionListStatement(@NotNull PsiExpressionListStatement statement) {
|
||||||
|
super.visitExpressionListStatement(statement);
|
||||||
|
myResult =
|
||||||
|
new ExpressionListStatement(expressionsToExpressionList(statement.getExpressionList().getExpressions()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitForStatement(@NotNull PsiForStatement statement) {
|
||||||
|
super.visitForStatement(statement);
|
||||||
|
|
||||||
|
final PsiStatement initialization = statement.getInitialization();
|
||||||
|
final PsiStatement update = statement.getUpdate();
|
||||||
|
final PsiExpression condition = statement.getCondition();
|
||||||
|
final PsiStatement body = statement.getBody();
|
||||||
|
|
||||||
|
final PsiLocalVariable firstChild = initialization != null && initialization.getFirstChild() instanceof PsiLocalVariable
|
||||||
|
?
|
||||||
|
(PsiLocalVariable) initialization.getFirstChild()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
int bodyWriteCount = countWritingAccesses(firstChild, body);
|
||||||
|
int conditionWriteCount = countWritingAccesses(firstChild, condition);
|
||||||
|
int updateWriteCount = countWritingAccesses(firstChild, update);
|
||||||
|
boolean onceWritableIterator = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0;
|
||||||
|
|
||||||
|
final IElementType operationTokenType = condition != null && condition instanceof PsiBinaryExpression ?
|
||||||
|
((PsiBinaryExpression) condition).getOperationTokenType() : null;
|
||||||
|
if (
|
||||||
|
initialization != null &&
|
||||||
|
initialization instanceof PsiDeclarationStatement
|
||||||
|
&& initialization.getFirstChild() == initialization.getLastChild()
|
||||||
|
&& condition != null
|
||||||
|
&& update != null
|
||||||
|
&& update.getChildren().length == 1
|
||||||
|
&& isPlusPlusExpression(update.getChildren()[0])
|
||||||
|
&& operationTokenType != null
|
||||||
|
&& (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
|
||||||
|
&& initialization.getFirstChild() != null
|
||||||
|
&& initialization.getFirstChild() instanceof PsiLocalVariable
|
||||||
|
&& firstChild != null
|
||||||
|
&& firstChild.getNameIdentifier() != null
|
||||||
|
&& onceWritableIterator
|
||||||
|
) {
|
||||||
|
final Expression end = expressionToExpression(((PsiBinaryExpression) condition).getROperand());
|
||||||
|
final Expression endExpression = operationTokenType == JavaTokenType.LT ?
|
||||||
|
new BinaryExpression(end, new IdentifierImpl("1"), "-") :
|
||||||
|
end;
|
||||||
|
myResult = new ForeachWithRangeStatement(
|
||||||
|
new IdentifierImpl(firstChild.getName()),
|
||||||
|
expressionToExpression(firstChild.getInitializer()),
|
||||||
|
endExpression,
|
||||||
|
statementToStatement(body)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else { // common case: while loop instead of for loop
|
||||||
|
List<Statement> forStatements = new LinkedList<Statement>();
|
||||||
|
forStatements.add(statementToStatement(initialization));
|
||||||
|
forStatements.add(new WhileStatement(
|
||||||
|
expressionToExpression(condition),
|
||||||
|
new Block(
|
||||||
|
Arrays.asList(statementToStatement(body),
|
||||||
|
new Block(Arrays.asList(statementToStatement(update)))))));
|
||||||
|
myResult = new Block(forStatements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isPlusPlusExpression(@NotNull PsiElement psiElement) {
|
||||||
|
return (psiElement instanceof PsiPostfixExpression && ((PsiPostfixExpression) psiElement).getOperationTokenType() == JavaTokenType.PLUSPLUS)
|
||||||
|
|| (psiElement instanceof PsiPrefixExpression && ((PsiPrefixExpression) psiElement).getOperationTokenType() == JavaTokenType.PLUSPLUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitForeachStatement(@NotNull PsiForeachStatement statement) {
|
||||||
|
super.visitForeachStatement(statement);
|
||||||
|
myResult = new ForeachStatement(
|
||||||
|
parameterToParameter(statement.getIterationParameter()),
|
||||||
|
expressionToExpression(statement.getIteratedValue()),
|
||||||
|
statementToStatement(statement.getBody())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitIfStatement(@NotNull PsiIfStatement statement) {
|
||||||
|
super.visitIfStatement(statement);
|
||||||
|
PsiExpression condition = statement.getCondition();
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
Expression expression = condition != null && condition.getType() != null ?
|
||||||
|
createSureCallOnlyForChain(condition, condition.getType()) :
|
||||||
|
expressionToExpression(condition);
|
||||||
|
myResult = new IfStatement(
|
||||||
|
expression,
|
||||||
|
statementToStatement(statement.getThenBranch()),
|
||||||
|
statementToStatement(statement.getElseBranch())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitLabeledStatement(@NotNull PsiLabeledStatement statement) {
|
||||||
|
super.visitLabeledStatement(statement);
|
||||||
|
myResult = new LabelStatement(
|
||||||
|
identifierToIdentifier(statement.getLabelIdentifier()),
|
||||||
|
statementToStatement(statement.getStatement())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSwitchLabelStatement(@NotNull PsiSwitchLabelStatement statement) {
|
||||||
|
super.visitSwitchLabelStatement(statement);
|
||||||
|
myResult = statement.isDefaultCase() ?
|
||||||
|
new DefaultSwitchLabelStatement() :
|
||||||
|
new SwitchLabelStatement(expressionToExpression(statement.getCaseValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) {
|
||||||
|
super.visitSwitchStatement(statement);
|
||||||
|
myResult = new SwitchContainer(
|
||||||
|
expressionToExpression(statement.getExpression()),
|
||||||
|
switchBodyToCases(statement.getBody())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<CaseContainer> switchBodyToCases(@Nullable final PsiCodeBlock body) {
|
||||||
|
final List<List<PsiStatement>> cases = splitToCases(body);
|
||||||
|
final List<PsiStatement> allSwitchStatements = body != null
|
||||||
|
? Arrays.asList(body.getStatements())
|
||||||
|
: Collections.<PsiStatement>emptyList();
|
||||||
|
|
||||||
|
List<CaseContainer> result = new LinkedList<CaseContainer>();
|
||||||
|
List<Statement> pendingLabels = new LinkedList<Statement>();
|
||||||
|
int i = 0;
|
||||||
|
for (List<PsiStatement> ls : cases) {
|
||||||
|
assert ls.size() > 0;
|
||||||
|
PsiStatement label = ls.get(0);
|
||||||
|
assert label instanceof PsiSwitchLabelStatement;
|
||||||
|
|
||||||
|
assert allSwitchStatements.get(i) == label : "not a right index";
|
||||||
|
|
||||||
|
if (ls.size() > 1) {
|
||||||
|
pendingLabels.add(statementToStatement(label));
|
||||||
|
List<PsiStatement> slice = ls.subList(1, ls.size());
|
||||||
|
|
||||||
|
if (!containsBreak(slice)) {
|
||||||
|
List<Statement> statements = statementsToStatementList(slice);
|
||||||
|
statements.addAll(
|
||||||
|
statementsToStatementList(getAllToNextBreak(allSwitchStatements, i + ls.size()))
|
||||||
|
);
|
||||||
|
result.add(new CaseContainer(pendingLabels, statements));
|
||||||
|
pendingLabels = new LinkedList<Statement>();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.add(new CaseContainer(pendingLabels, statementsToStatementList(slice)));
|
||||||
|
pendingLabels = new LinkedList<Statement>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // ls.size() == 1
|
||||||
|
{
|
||||||
|
pendingLabels.add(statementToStatement(label));
|
||||||
|
}
|
||||||
|
i += ls.size();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
if (!(s instanceof PsiSwitchLabelStatement))
|
|
||||||
result.add(s);
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
private static boolean containsBreak(@NotNull final List<PsiStatement> slice) {
|
||||||
private static List<List<PsiStatement>> splitToCases(@Nullable final PsiCodeBlock body) {
|
for (PsiStatement s : slice)
|
||||||
List<List<PsiStatement>> cases = new LinkedList<List<PsiStatement>>();
|
if (s instanceof PsiBreakStatement) {
|
||||||
List<PsiStatement> currentCaseStatements = new LinkedList<PsiStatement>();
|
return true;
|
||||||
boolean isFirst = true;
|
}
|
||||||
if (body != null) {
|
return false;
|
||||||
for (PsiStatement s : body.getStatements()) {
|
}
|
||||||
if (s instanceof PsiSwitchLabelStatement) {
|
|
||||||
if (isFirst)
|
@NotNull
|
||||||
isFirst = false;
|
private static List<PsiStatement> getAllToNextBreak(@NotNull final List<PsiStatement> allStatements, final int start) {
|
||||||
else {
|
List<PsiStatement> result = new LinkedList<PsiStatement>();
|
||||||
cases.add(currentCaseStatements);
|
for (int i = start; i < allStatements.size(); i++) {
|
||||||
currentCaseStatements = new LinkedList<PsiStatement>();
|
PsiStatement s = allStatements.get(i);
|
||||||
}
|
if (s instanceof PsiBreakStatement || s instanceof PsiReturnStatement) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!(s instanceof PsiSwitchLabelStatement)) {
|
||||||
|
result.add(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
currentCaseStatements.add(s);
|
return result;
|
||||||
}
|
|
||||||
cases.add(currentCaseStatements);
|
|
||||||
}
|
|
||||||
return cases;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) {
|
|
||||||
super.visitSynchronizedStatement(statement);
|
|
||||||
myResult = new SynchronizedStatement(
|
|
||||||
expressionToExpression(statement.getLockExpression()),
|
|
||||||
blockToBlock(statement.getBody())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitThrowStatement(@NotNull PsiThrowStatement statement) {
|
|
||||||
super.visitThrowStatement(statement);
|
|
||||||
myResult = new ThrowStatement(
|
|
||||||
expressionToExpression(statement.getException())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitTryStatement(@NotNull PsiTryStatement statement) {
|
|
||||||
super.visitTryStatement(statement);
|
|
||||||
|
|
||||||
List<CatchStatement> catches = new LinkedList<CatchStatement>();
|
|
||||||
for (int i = 0; i < statement.getCatchBlocks().length; i++) {
|
|
||||||
catches.add(new CatchStatement(
|
|
||||||
parameterToParameter(statement.getCatchBlockParameters()[i]),
|
|
||||||
blockToBlock(statement.getCatchBlocks()[i], true)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myResult = new TryStatement(
|
@NotNull
|
||||||
blockToBlock(statement.getTryBlock(), true),
|
private static List<List<PsiStatement>> splitToCases(@Nullable final PsiCodeBlock body) {
|
||||||
catches,
|
List<List<PsiStatement>> cases = new LinkedList<List<PsiStatement>>();
|
||||||
blockToBlock(statement.getFinallyBlock(), true)
|
List<PsiStatement> currentCaseStatements = new LinkedList<PsiStatement>();
|
||||||
);
|
boolean isFirst = true;
|
||||||
}
|
if (body != null) {
|
||||||
|
for (PsiStatement s : body.getStatements()) {
|
||||||
|
if (s instanceof PsiSwitchLabelStatement) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cases.add(currentCaseStatements);
|
||||||
|
currentCaseStatements = new LinkedList<PsiStatement>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentCaseStatements.add(s);
|
||||||
|
}
|
||||||
|
cases.add(currentCaseStatements);
|
||||||
|
}
|
||||||
|
return cases;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitWhileStatement(@NotNull PsiWhileStatement statement) {
|
public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) {
|
||||||
super.visitWhileStatement(statement);
|
super.visitSynchronizedStatement(statement);
|
||||||
PsiExpression condition = statement.getCondition();
|
myResult = new SynchronizedStatement(
|
||||||
@SuppressWarnings("ConstantConditions")
|
expressionToExpression(statement.getLockExpression()),
|
||||||
Expression expression = condition != null && condition.getType() != null ?
|
blockToBlock(statement.getBody())
|
||||||
createSureCallOnlyForChain(condition, condition.getType()) :
|
);
|
||||||
expressionToExpression(condition);
|
}
|
||||||
myResult = new WhileStatement(
|
|
||||||
expression,
|
|
||||||
statementToStatement(statement.getBody())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitReturnStatement(@NotNull PsiReturnStatement statement) {
|
public void visitThrowStatement(@NotNull PsiThrowStatement statement) {
|
||||||
super.visitReturnStatement(statement);
|
super.visitThrowStatement(statement);
|
||||||
PsiExpression returnValue = statement.getReturnValue();
|
myResult = new ThrowStatement(
|
||||||
PsiType methodReturnType = Converter.getMethodReturnType();
|
expressionToExpression(statement.getException())
|
||||||
Expression expression = returnValue != null && methodReturnType != null ?
|
);
|
||||||
createSureCallOnlyForChain(returnValue, methodReturnType) :
|
}
|
||||||
expressionToExpression(returnValue);
|
|
||||||
myResult = new ReturnStatement(
|
@Override
|
||||||
expression
|
public void visitTryStatement(@NotNull PsiTryStatement statement) {
|
||||||
);
|
super.visitTryStatement(statement);
|
||||||
}
|
|
||||||
|
List<CatchStatement> catches = new LinkedList<CatchStatement>();
|
||||||
|
for (int i = 0; i < statement.getCatchBlocks().length; i++) {
|
||||||
|
catches.add(new CatchStatement(
|
||||||
|
parameterToParameter(statement.getCatchBlockParameters()[i]),
|
||||||
|
blockToBlock(statement.getCatchBlocks()[i], true)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
myResult = new TryStatement(
|
||||||
|
blockToBlock(statement.getTryBlock(), true),
|
||||||
|
catches,
|
||||||
|
blockToBlock(statement.getFinallyBlock(), true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitWhileStatement(@NotNull PsiWhileStatement statement) {
|
||||||
|
super.visitWhileStatement(statement);
|
||||||
|
PsiExpression condition = statement.getCondition();
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
Expression expression = condition != null && condition.getType() != null ?
|
||||||
|
createSureCallOnlyForChain(condition, condition.getType()) :
|
||||||
|
expressionToExpression(condition);
|
||||||
|
myResult = new WhileStatement(
|
||||||
|
expression,
|
||||||
|
statementToStatement(statement.getBody())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReturnStatement(@NotNull PsiReturnStatement statement) {
|
||||||
|
super.visitReturnStatement(statement);
|
||||||
|
PsiExpression returnValue = statement.getReturnValue();
|
||||||
|
PsiType methodReturnType = Converter.getMethodReturnType();
|
||||||
|
Expression expression = returnValue != null && methodReturnType != null ?
|
||||||
|
createSureCallOnlyForChain(returnValue, methodReturnType) :
|
||||||
|
expressionToExpression(returnValue);
|
||||||
|
myResult = new ReturnStatement(
|
||||||
|
expression
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,32 +10,33 @@ import java.util.HashSet;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class SuperVisitor extends JavaRecursiveElementVisitor {
|
public class SuperVisitor extends JavaRecursiveElementVisitor {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final HashSet<PsiExpressionList> myResolvedSuperCallParameters;
|
private final HashSet<PsiExpressionList> myResolvedSuperCallParameters;
|
||||||
|
|
||||||
public SuperVisitor() {
|
public SuperVisitor() {
|
||||||
myResolvedSuperCallParameters = new HashSet<PsiExpressionList>();
|
myResolvedSuperCallParameters = new HashSet<PsiExpressionList>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public HashSet<PsiExpressionList> getResolvedSuperCallParameters() {
|
public HashSet<PsiExpressionList> getResolvedSuperCallParameters() {
|
||||||
return myResolvedSuperCallParameters;
|
return myResolvedSuperCallParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||||
super.visitMethodCallExpression(expression);
|
super.visitMethodCallExpression(expression);
|
||||||
if (isSuper(expression.getMethodExpression()))
|
if (isSuper(expression.getMethodExpression())) {
|
||||||
myResolvedSuperCallParameters.add(expression.getArgumentList());
|
myResolvedSuperCallParameters.add(expression.getArgumentList());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
static boolean isSuper(@NotNull PsiReference r) {
|
|
||||||
if (r.getCanonicalText().equals("super")) {
|
static boolean isSuper(@NotNull PsiReference r) {
|
||||||
final PsiElement baseConstructor = r.resolve();
|
if (r.getCanonicalText().equals("super")) {
|
||||||
if (baseConstructor != null && baseConstructor instanceof PsiMethod && ((PsiMethod) baseConstructor).isConstructor()) {
|
final PsiElement baseConstructor = r.resolve();
|
||||||
return true;
|
if (baseConstructor != null && baseConstructor instanceof PsiMethod && ((PsiMethod) baseConstructor).isConstructor()) {
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,28 +10,30 @@ import java.util.HashSet;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class ThisVisitor extends JavaRecursiveElementVisitor {
|
public class ThisVisitor extends JavaRecursiveElementVisitor {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final HashSet<PsiMethod> myResolvedConstructors = new HashSet<PsiMethod>();
|
private final HashSet<PsiMethod> myResolvedConstructors = new HashSet<PsiMethod>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
||||||
for (PsiReference r : expression.getReferences())
|
for (PsiReference r : expression.getReferences())
|
||||||
if (r.getCanonicalText().equals("this")) {
|
if (r.getCanonicalText().equals("this")) {
|
||||||
final PsiElement res = r.resolve();
|
final PsiElement res = r.resolve();
|
||||||
if (res != null && res instanceof PsiMethod && ((PsiMethod) res).isConstructor())
|
if (res != null && res instanceof PsiMethod && ((PsiMethod) res).isConstructor()) {
|
||||||
myResolvedConstructors.add((PsiMethod) res);
|
myResolvedConstructors.add((PsiMethod) res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Nullable
|
|
||||||
public PsiMethod getPrimaryConstructor() {
|
@Nullable
|
||||||
if (myResolvedConstructors.size() > 0) {
|
public PsiMethod getPrimaryConstructor() {
|
||||||
PsiMethod first = myResolvedConstructors.toArray(new PsiMethod[myResolvedConstructors.size()])[0];
|
if (myResolvedConstructors.size() > 0) {
|
||||||
for (PsiMethod m : myResolvedConstructors)
|
PsiMethod first = myResolvedConstructors.toArray(new PsiMethod[myResolvedConstructors.size()])[0];
|
||||||
if (m.hashCode() != first.hashCode())
|
for (PsiMethod m : myResolvedConstructors)
|
||||||
return null;
|
if (m.hashCode() != first.hashCode()) {
|
||||||
return first;
|
return null;
|
||||||
|
}
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,160 +17,176 @@ import static org.jetbrains.jet.j2k.Converter.typesToTypeList;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
public class TypeVisitor extends PsiTypeVisitor<Type> {
|
public class TypeVisitor extends PsiTypeVisitor<Type> {
|
||||||
public static final String JAVA_LANG_BYTE = "java.lang.Byte";
|
public static final String JAVA_LANG_BYTE = "java.lang.Byte";
|
||||||
public static final String JAVA_LANG_CHARACTER = "java.lang.Character";
|
public static final String JAVA_LANG_CHARACTER = "java.lang.Character";
|
||||||
public static final String JAVA_LANG_DOUBLE = "java.lang.Double";
|
public static final String JAVA_LANG_DOUBLE = "java.lang.Double";
|
||||||
public static final String JAVA_LANG_FLOAT = "java.lang.Float";
|
public static final String JAVA_LANG_FLOAT = "java.lang.Float";
|
||||||
public static final String JAVA_LANG_INTEGER = "java.lang.Integer";
|
public static final String JAVA_LANG_INTEGER = "java.lang.Integer";
|
||||||
public static final String JAVA_LANG_LONG = "java.lang.Long";
|
public static final String JAVA_LANG_LONG = "java.lang.Long";
|
||||||
public static final String JAVA_LANG_SHORT = "java.lang.Short";
|
public static final String JAVA_LANG_SHORT = "java.lang.Short";
|
||||||
private static final String JAVA_LANG_BOOLEAN = "java.lang.Boolean";
|
private static final String JAVA_LANG_BOOLEAN = "java.lang.Boolean";
|
||||||
public static final String JAVA_LANG_OBJECT = "java.lang.Object";
|
public static final String JAVA_LANG_OBJECT = "java.lang.Object";
|
||||||
public static final String JAVA_LANG_STRING = "java.lang.String";
|
public static final String JAVA_LANG_STRING = "java.lang.String";
|
||||||
private static final String JAVA_LANG_ITERABLE = "java.lang.Iterable";
|
private static final String JAVA_LANG_ITERABLE = "java.lang.Iterable";
|
||||||
private static final String JAVA_UTIL_ITERATOR = "java.util.Iterator";
|
private static final String JAVA_UTIL_ITERATOR = "java.util.Iterator";
|
||||||
private Type myResult = Type.EMPTY_TYPE;
|
private Type myResult = Type.EMPTY_TYPE;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Type getResult() {
|
public Type getResult() {
|
||||||
return myResult;
|
return myResult;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type visitPrimitiveType(@NotNull PsiPrimitiveType primitiveType) {
|
|
||||||
final String name = primitiveType.getCanonicalText();
|
|
||||||
final IdentifierImpl identifier = new IdentifierImpl(name);
|
|
||||||
|
|
||||||
if (name.equals("void"))
|
|
||||||
myResult = new PrimitiveType(new IdentifierImpl("Unit"));
|
|
||||||
else if (Node.PRIMITIVE_TYPES.contains(name))
|
|
||||||
myResult = new PrimitiveType(new IdentifierImpl(AstUtil.upperFirstCharacter(name)));
|
|
||||||
else
|
|
||||||
myResult = new PrimitiveType(identifier);
|
|
||||||
return super.visitPrimitiveType(primitiveType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type visitArrayType(@NotNull PsiArrayType arrayType) {
|
|
||||||
if (myResult == Type.EMPTY_TYPE)
|
|
||||||
myResult = new ArrayType(typeToType(arrayType.getComponentType()));
|
|
||||||
return super.visitArrayType(arrayType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type visitClassType(@NotNull PsiClassType classType) {
|
|
||||||
final IdentifierImpl identifier = constructClassTypeIdentifier(classType);
|
|
||||||
final List<Type> resolvedClassTypeParams = createRawTypesForResolvedReference(classType);
|
|
||||||
|
|
||||||
if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0)
|
|
||||||
myResult = new ClassType(identifier, resolvedClassTypeParams);
|
|
||||||
else
|
|
||||||
myResult = new ClassType(identifier, typesToTypeList(classType.getParameters()));
|
|
||||||
return super.visitClassType(classType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static IdentifierImpl constructClassTypeIdentifier(@NotNull PsiClassType classType) {
|
|
||||||
final PsiClass psiClass = classType.resolve();
|
|
||||||
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))
|
|
||||||
return new IdentifierImpl(JAVA_UTIL_ITERATOR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
final String classTypeName = createQualifiedName(classType);
|
|
||||||
|
|
||||||
if (classTypeName.isEmpty())
|
@Override
|
||||||
return new IdentifierImpl(getClassTypeName(classType));
|
public Type visitPrimitiveType(@NotNull PsiPrimitiveType primitiveType) {
|
||||||
|
final String name = primitiveType.getCanonicalText();
|
||||||
|
final IdentifierImpl identifier = new IdentifierImpl(name);
|
||||||
|
|
||||||
return new IdentifierImpl(classTypeName);
|
if (name.equals("void")) {
|
||||||
}
|
myResult = new PrimitiveType(new IdentifierImpl("Unit"));
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static String createQualifiedName(@NotNull PsiClassType classType) {
|
|
||||||
String classTypeName = "";
|
|
||||||
if (classType instanceof PsiClassReferenceType) {
|
|
||||||
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType) classType).getReference();
|
|
||||||
if (reference.isQualified()) {
|
|
||||||
String result = new IdentifierImpl(reference.getReferenceName()).toKotlin();
|
|
||||||
PsiElement qualifier = reference.getQualifier();
|
|
||||||
while (qualifier != null) {
|
|
||||||
final PsiJavaCodeReferenceElement p = (PsiJavaCodeReferenceElement) qualifier;
|
|
||||||
result = new IdentifierImpl(p.getReferenceName()).toKotlin() + "." + result; // TODO: maybe need to replace by safe call?
|
|
||||||
qualifier = p.getQualifier();
|
|
||||||
}
|
}
|
||||||
classTypeName = result;
|
else if (Node.PRIMITIVE_TYPES.contains(name)) {
|
||||||
}
|
myResult = new PrimitiveType(new IdentifierImpl(AstUtil.upperFirstCharacter(name)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myResult = new PrimitiveType(identifier);
|
||||||
|
}
|
||||||
|
return super.visitPrimitiveType(primitiveType);
|
||||||
}
|
}
|
||||||
return classTypeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@Override
|
||||||
private static List<Type> createRawTypesForResolvedReference(@NotNull PsiClassType classType) {
|
public Type visitArrayType(@NotNull PsiArrayType arrayType) {
|
||||||
final List<Type> typeParams = new LinkedList<Type>();
|
if (myResult == Type.EMPTY_TYPE) {
|
||||||
if (classType instanceof PsiClassReferenceType) {
|
myResult = new ArrayType(typeToType(arrayType.getComponentType()));
|
||||||
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType) classType).getReference();
|
}
|
||||||
final PsiElement resolve = reference.resolve();
|
return super.visitArrayType(arrayType);
|
||||||
if (resolve != null) {
|
|
||||||
if (resolve instanceof PsiClass)
|
|
||||||
//noinspection UnusedDeclaration
|
|
||||||
for (PsiTypeParameter p : ((PsiClass) resolve).getTypeParameters()) {
|
|
||||||
Type boundType = p.getSuperTypes().length > 0 ?
|
|
||||||
new ClassType(new IdentifierImpl(getClassTypeName(p.getSuperTypes()[0])), typesToTypeList(p.getSuperTypes()[0].getParameters()), true) :
|
|
||||||
new StarProjectionType();
|
|
||||||
|
|
||||||
typeParams.add(boundType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return typeParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@Override
|
||||||
private static String getClassTypeName(@NotNull PsiClassType classType) {
|
public Type visitClassType(@NotNull PsiClassType classType) {
|
||||||
String canonicalTypeStr = classType.getCanonicalText();
|
final IdentifierImpl identifier = constructClassTypeIdentifier(classType);
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_OBJECT)) return "Any";
|
final List<Type> resolvedClassTypeParams = createRawTypesForResolvedReference(classType);
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_BYTE)) return "Byte";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_CHARACTER)) return "Char";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_DOUBLE)) return "Double";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_FLOAT)) return "Float";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_INTEGER)) return "Int";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_LONG)) return "Long";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_SHORT)) return "Short";
|
|
||||||
if (canonicalTypeStr.equals(JAVA_LANG_BOOLEAN)) return "Boolean";
|
|
||||||
return classType.getClassName() != null ? classType.getClassName() : classType.getCanonicalText();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) {
|
||||||
public Type visitWildcardType(@NotNull PsiWildcardType wildcardType) {
|
myResult = new ClassType(identifier, resolvedClassTypeParams);
|
||||||
if (wildcardType.isExtends())
|
}
|
||||||
myResult = new OutProjectionType(typeToType(wildcardType.getExtendsBound()));
|
else {
|
||||||
else if (wildcardType.isSuper())
|
myResult = new ClassType(identifier, typesToTypeList(classType.getParameters()));
|
||||||
myResult = new InProjectionType(typeToType(wildcardType.getSuperBound()));
|
}
|
||||||
else
|
return super.visitClassType(classType);
|
||||||
myResult = new StarProjectionType();
|
}
|
||||||
return super.visitWildcardType(wildcardType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@NotNull
|
||||||
public Type visitEllipsisType(@NotNull PsiEllipsisType ellipsisType) {
|
private static IdentifierImpl constructClassTypeIdentifier(@NotNull PsiClassType classType) {
|
||||||
myResult = new VarArg(typeToType(ellipsisType.getComponentType()));
|
final PsiClass psiClass = classType.resolve();
|
||||||
return super.visitEllipsisType(ellipsisType);
|
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)) {
|
||||||
|
return new IdentifierImpl(JAVA_UTIL_ITERATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final String classTypeName = createQualifiedName(classType);
|
||||||
|
|
||||||
@Override
|
if (classTypeName.isEmpty()) {
|
||||||
public Type visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) {
|
return new IdentifierImpl(getClassTypeName(classType));
|
||||||
return super.visitCapturedWildcardType(capturedWildcardType);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
return new IdentifierImpl(classTypeName);
|
||||||
public Type visitDisjunctionType(PsiDisjunctionType disjunctionType) {
|
}
|
||||||
return super.visitDisjunctionType(disjunctionType);
|
|
||||||
}
|
@NotNull
|
||||||
|
private static String createQualifiedName(@NotNull PsiClassType classType) {
|
||||||
|
String classTypeName = "";
|
||||||
|
if (classType instanceof PsiClassReferenceType) {
|
||||||
|
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType) classType).getReference();
|
||||||
|
if (reference.isQualified()) {
|
||||||
|
String result = new IdentifierImpl(reference.getReferenceName()).toKotlin();
|
||||||
|
PsiElement qualifier = reference.getQualifier();
|
||||||
|
while (qualifier != null) {
|
||||||
|
final PsiJavaCodeReferenceElement p = (PsiJavaCodeReferenceElement) qualifier;
|
||||||
|
result = new IdentifierImpl(p.getReferenceName()).toKotlin() + "." + result; // TODO: maybe need to replace by safe call?
|
||||||
|
qualifier = p.getQualifier();
|
||||||
|
}
|
||||||
|
classTypeName = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return classTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<Type> createRawTypesForResolvedReference(@NotNull PsiClassType classType) {
|
||||||
|
final List<Type> typeParams = new LinkedList<Type>();
|
||||||
|
if (classType instanceof PsiClassReferenceType) {
|
||||||
|
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType) classType).getReference();
|
||||||
|
final PsiElement resolve = reference.resolve();
|
||||||
|
if (resolve != null) {
|
||||||
|
if (resolve instanceof PsiClass)
|
||||||
|
//noinspection UnusedDeclaration
|
||||||
|
{
|
||||||
|
for (PsiTypeParameter p : ((PsiClass) resolve).getTypeParameters()) {
|
||||||
|
Type boundType = p.getSuperTypes().length > 0 ?
|
||||||
|
new ClassType(new IdentifierImpl(getClassTypeName(p.getSuperTypes()[0])), typesToTypeList(p.getSuperTypes()[0].getParameters()), true)
|
||||||
|
:
|
||||||
|
new StarProjectionType();
|
||||||
|
|
||||||
|
typeParams.add(boundType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getClassTypeName(@NotNull PsiClassType classType) {
|
||||||
|
String canonicalTypeStr = classType.getCanonicalText();
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_OBJECT)) return "Any";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_BYTE)) return "Byte";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_CHARACTER)) return "Char";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_DOUBLE)) return "Double";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_FLOAT)) return "Float";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_INTEGER)) return "Int";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_LONG)) return "Long";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_SHORT)) return "Short";
|
||||||
|
if (canonicalTypeStr.equals(JAVA_LANG_BOOLEAN)) return "Boolean";
|
||||||
|
return classType.getClassName() != null ? classType.getClassName() : classType.getCanonicalText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitWildcardType(@NotNull PsiWildcardType wildcardType) {
|
||||||
|
if (wildcardType.isExtends()) {
|
||||||
|
myResult = new OutProjectionType(typeToType(wildcardType.getExtendsBound()));
|
||||||
|
}
|
||||||
|
else if (wildcardType.isSuper()) {
|
||||||
|
myResult = new InProjectionType(typeToType(wildcardType.getSuperBound()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myResult = new StarProjectionType();
|
||||||
|
}
|
||||||
|
return super.visitWildcardType(wildcardType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitEllipsisType(@NotNull PsiEllipsisType ellipsisType) {
|
||||||
|
myResult = new VarArg(typeToType(ellipsisType.getComponentType()));
|
||||||
|
return super.visitEllipsisType(ellipsisType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) {
|
||||||
|
return super.visitCapturedWildcardType(capturedWildcardType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitDisjunctionType(PsiDisjunctionType disjunctionType) {
|
||||||
|
return super.visitDisjunctionType(disjunctionType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,78 +16,79 @@ import java.util.List;
|
|||||||
* @author ignatov
|
* @author ignatov
|
||||||
*/
|
*/
|
||||||
abstract class TestCaseBuilder {
|
abstract class TestCaseBuilder {
|
||||||
@NotNull
|
|
||||||
private static final FilenameFilter emptyFilter = new FilenameFilter() {
|
|
||||||
@Override
|
|
||||||
public boolean accept(File file, String name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String getTestDataPathBase() {
|
|
||||||
return "testData";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getHomeDirectory() {
|
|
||||||
return new File(PathManager.getResourceRoot(TestCaseBuilder.class, "/org/jetbrains/jet/TestCaseBuilder.class")).getParentFile().getParentFile().getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface NamedTestFactory {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
Test createTest(@NotNull String dataPath, @NotNull String name);
|
private static final FilenameFilter emptyFilter = new FilenameFilter() {
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static TestSuite suiteForDirectory(String baseDataDir, @NotNull final String dataPath, @NotNull NamedTestFactory factory) {
|
|
||||||
return suiteForDirectory(baseDataDir, dataPath, true, emptyFilter, factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static TestSuite suiteForDirectory(String baseDataDir, @NotNull final String dataPath, boolean recursive, @NotNull final FilenameFilter filter, @NotNull NamedTestFactory factory) {
|
|
||||||
TestSuite suite = new TestSuite(dataPath);
|
|
||||||
final String extensionJava = ".jav";
|
|
||||||
|
|
||||||
final FilenameFilter extensionFilter = new FilenameFilter() {
|
|
||||||
@Override
|
|
||||||
public boolean accept(File dir, @NotNull String name) {
|
|
||||||
return name.endsWith(extensionJava);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
FilenameFilter resultFilter;
|
|
||||||
if (filter != emptyFilter) {
|
|
||||||
resultFilter = new FilenameFilter() {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File file, String s) {
|
public boolean accept(File file, String name) {
|
||||||
return extensionFilter.accept(file, s) && filter.accept(file, s);
|
return true;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
} else {
|
|
||||||
resultFilter = extensionFilter;
|
|
||||||
}
|
|
||||||
File dir = new File(baseDataDir + dataPath);
|
|
||||||
FileFilter dirFilter = new FileFilter() {
|
|
||||||
@Override
|
|
||||||
public boolean accept(@NotNull File pathname) {
|
|
||||||
return pathname.isDirectory();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if (recursive) {
|
|
||||||
File[] files = dir.listFiles(dirFilter);
|
@NotNull
|
||||||
assert files != null : dir;
|
public static String getTestDataPathBase() {
|
||||||
List<File> subdirs = Arrays.asList(files);
|
return "testData";
|
||||||
Collections.sort(subdirs);
|
|
||||||
for (File subdir : subdirs) {
|
|
||||||
suite.addTest(suiteForDirectory(baseDataDir, dataPath + "/" + subdir.getName(), recursive, filter, factory));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
List<File> files = Arrays.asList(dir.listFiles(resultFilter));
|
|
||||||
Collections.sort(files);
|
public static String getHomeDirectory() {
|
||||||
for (File file : files) {
|
return new File(PathManager.getResourceRoot(TestCaseBuilder.class, "/org/jetbrains/jet/TestCaseBuilder.class")).getParentFile().getParentFile().getParent();
|
||||||
String fileName = file.getName();
|
}
|
||||||
assert fileName != null;
|
|
||||||
suite.addTest(factory.createTest(dataPath, fileName.substring(0, fileName.length() - extensionJava.length())));
|
public interface NamedTestFactory {
|
||||||
|
@NotNull
|
||||||
|
Test createTest(@NotNull String dataPath, @NotNull String name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static TestSuite suiteForDirectory(String baseDataDir, @NotNull final String dataPath, @NotNull NamedTestFactory factory) {
|
||||||
|
return suiteForDirectory(baseDataDir, dataPath, true, emptyFilter, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static TestSuite suiteForDirectory(String baseDataDir, @NotNull final String dataPath, boolean recursive, @NotNull final FilenameFilter filter, @NotNull NamedTestFactory factory) {
|
||||||
|
TestSuite suite = new TestSuite(dataPath);
|
||||||
|
final String extensionJava = ".jav";
|
||||||
|
|
||||||
|
final FilenameFilter extensionFilter = new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File dir, @NotNull String name) {
|
||||||
|
return name.endsWith(extensionJava);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FilenameFilter resultFilter;
|
||||||
|
if (filter != emptyFilter) {
|
||||||
|
resultFilter = new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file, String s) {
|
||||||
|
return extensionFilter.accept(file, s) && filter.accept(file, s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resultFilter = extensionFilter;
|
||||||
|
}
|
||||||
|
File dir = new File(baseDataDir + dataPath);
|
||||||
|
FileFilter dirFilter = new FileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(@NotNull File pathname) {
|
||||||
|
return pathname.isDirectory();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (recursive) {
|
||||||
|
File[] files = dir.listFiles(dirFilter);
|
||||||
|
assert files != null : dir;
|
||||||
|
List<File> subdirs = Arrays.asList(files);
|
||||||
|
Collections.sort(subdirs);
|
||||||
|
for (File subdir : subdirs) {
|
||||||
|
suite.addTest(suiteForDirectory(baseDataDir, dataPath + "/" + subdir.getName(), recursive, filter, factory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<File> files = Arrays.asList(dir.listFiles(resultFilter));
|
||||||
|
Collections.sort(files);
|
||||||
|
for (File file : files) {
|
||||||
|
String fileName = file.getName();
|
||||||
|
assert fileName != null;
|
||||||
|
suite.addTest(factory.createTest(dataPath, fileName.substring(0, fileName.length() - extensionJava.length())));
|
||||||
|
}
|
||||||
|
return suite;
|
||||||
}
|
}
|
||||||
return suite;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user