Java to Kotlin convertor: making code more "Kolin-like" + numerous micro refactorings

This commit is contained in:
Valentin Kipyatkov
2014-05-29 23:28:09 +04:00
parent 37532e8d02
commit 1e39021bd3
36 changed files with 1378 additions and 1141 deletions
+1
View File
@@ -1,6 +1,7 @@
<component name="ProjectDictionaryState"> <component name="ProjectDictionaryState">
<dictionary name="valentin"> <dictionary name="valentin">
<words> <words>
<w>initializers</w>
<w>pparent</w> <w>pparent</w>
<w>rparenth</w> <w>rparenth</w>
</words> </words>
@@ -1,10 +1,245 @@
<root> <root>
<item name='com.intellij.psi.ImplicitVariable'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaCodeFragment'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaCodeFragment java.lang.String importsToString()'> <item name='com.intellij.psi.JavaCodeFragment java.lang.String importsToString()'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='com.intellij.psi.JavaElementVisitor void visitAnnotation(com.intellij.psi.PsiAnnotation) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitAnonymousClass(com.intellij.psi.PsiAnonymousClass) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitArrayAccessExpression(com.intellij.psi.PsiArrayAccessExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitArrayInitializerExpression(com.intellij.psi.PsiArrayInitializerExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitAssertStatement(com.intellij.psi.PsiAssertStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitAssignmentExpression(com.intellij.psi.PsiAssignmentExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitBinaryExpression(com.intellij.psi.PsiBinaryExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitBlockStatement(com.intellij.psi.PsiBlockStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitBreakStatement(com.intellij.psi.PsiBreakStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitCatchSection(com.intellij.psi.PsiCatchSection) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitClass(com.intellij.psi.PsiClass) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitClassInitializer(com.intellij.psi.PsiClassInitializer) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitClassObjectAccessExpression(com.intellij.psi.PsiClassObjectAccessExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitCodeBlock(com.intellij.psi.PsiCodeBlock) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitConditionalExpression(com.intellij.psi.PsiConditionalExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitContinueStatement(com.intellij.psi.PsiContinueStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitDeclarationStatement(com.intellij.psi.PsiDeclarationStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitDoWhileStatement(com.intellij.psi.PsiDoWhileStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitDocComment(com.intellij.psi.javadoc.PsiDocComment) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitDocTag(com.intellij.psi.javadoc.PsiDocTag) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitDocToken(com.intellij.psi.javadoc.PsiDocToken) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitEmptyStatement(com.intellij.psi.PsiEmptyStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitEnumConstant(com.intellij.psi.PsiEnumConstant) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitExpressionList(com.intellij.psi.PsiExpressionList) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitExpressionListStatement(com.intellij.psi.PsiExpressionListStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitExpressionStatement(com.intellij.psi.PsiExpressionStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitField(com.intellij.psi.PsiField) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitForStatement(com.intellij.psi.PsiForStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitForeachStatement(com.intellij.psi.PsiForeachStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitIfStatement(com.intellij.psi.PsiIfStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitImplicitVariable(com.intellij.psi.ImplicitVariable) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item
name='com.intellij.psi.JavaElementVisitor void visitImportStaticReferenceElement(com.intellij.psi.PsiImportStaticReferenceElement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitInstanceOfExpression(com.intellij.psi.PsiInstanceOfExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitJavaFile(com.intellij.psi.PsiJavaFile) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitJavaToken(com.intellij.psi.PsiJavaToken) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitKeyword(com.intellij.psi.PsiKeyword) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitLabeledStatement(com.intellij.psi.PsiLabeledStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitLiteralExpression(com.intellij.psi.PsiLiteralExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitLocalVariable(com.intellij.psi.PsiLocalVariable) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitMethod(com.intellij.psi.PsiMethod) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitMethodCallExpression(com.intellij.psi.PsiMethodCallExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitMethodReferenceExpression(com.intellij.psi.PsiMethodReferenceExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitNewExpression(com.intellij.psi.PsiNewExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitPackage(com.intellij.psi.PsiPackage) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitParameter(com.intellij.psi.PsiParameter) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitParameterList(com.intellij.psi.PsiParameterList) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitParenthesizedExpression(com.intellij.psi.PsiParenthesizedExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitPolyadicExpression(com.intellij.psi.PsiPolyadicExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitPostfixExpression(com.intellij.psi.PsiPostfixExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitPrefixExpression(com.intellij.psi.PsiPrefixExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitReferenceElement(com.intellij.psi.PsiJavaCodeReferenceElement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitReferenceExpression(com.intellij.psi.PsiReferenceExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitReferenceList(com.intellij.psi.PsiReferenceList) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitReferenceParameterList(com.intellij.psi.PsiReferenceParameterList) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitResourceList(com.intellij.psi.PsiResourceList) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitResourceVariable(com.intellij.psi.PsiResourceVariable) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitReturnStatement(com.intellij.psi.PsiReturnStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitStatement(com.intellij.psi.PsiStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitSuperExpression(com.intellij.psi.PsiSuperExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitSwitchLabelStatement(com.intellij.psi.PsiSwitchLabelStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitSwitchStatement(com.intellij.psi.PsiSwitchStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitSynchronizedStatement(com.intellij.psi.PsiSynchronizedStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitThisExpression(com.intellij.psi.PsiThisExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitThrowStatement(com.intellij.psi.PsiThrowStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitTryStatement(com.intellij.psi.PsiTryStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitTypeCastExpression(com.intellij.psi.PsiTypeCastExpression) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitTypeElement(com.intellij.psi.PsiTypeElement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitTypeParameter(com.intellij.psi.PsiTypeParameter) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitTypeParameterList(com.intellij.psi.PsiTypeParameterList) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitVariable(com.intellij.psi.PsiVariable) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaElementVisitor void visitWhileStatement(com.intellij.psi.PsiWhileStatement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.JavaPsiFacade com.intellij.psi.JavaPsiFacade getInstance(com.intellij.openapi.project.Project)'> <item name='com.intellij.psi.JavaPsiFacade com.intellij.psi.JavaPsiFacade getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='com.intellij.psi.PsiAnnotationMethod'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiAnnotationParameterList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiArrayInitializerMemberValue'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiCallExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiDoWhileStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiDocumentManager com.intellij.psi.PsiDocumentManager getInstance(com.intellij.openapi.project.Project)'> <item name='com.intellij.psi.PsiDocumentManager com.intellij.psi.PsiDocumentManager getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
@@ -14,16 +249,217 @@
<item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement replace(com.intellij.psi.PsiElement)'> <item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement replace(com.intellij.psi.PsiElement)'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='com.intellij.psi.PsiElementVisitor void visitBinaryFile(com.intellij.psi.PsiBinaryFile) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitComment(com.intellij.psi.PsiComment) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitDirectory(com.intellij.psi.PsiDirectory) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitElement(com.intellij.psi.PsiElement) 0'> <item name='com.intellij.psi.PsiElementVisitor void visitElement(com.intellij.psi.PsiElement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='com.intellij.psi.PsiElementVisitor void visitErrorElement(com.intellij.psi.PsiErrorElement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitFile(com.intellij.psi.PsiFile) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitOuterLanguageElement(com.intellij.psi.templateLanguages.OuterLanguageElement) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitPlainText(com.intellij.psi.PsiPlainText) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitPlainTextFile(com.intellij.psi.PsiPlainTextFile) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiElementVisitor void visitWhiteSpace(com.intellij.psi.PsiWhiteSpace) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiEmptyStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiEnumConstantInitializer'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiExpressionList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiExpressionListStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiExpressionListStatement com.intellij.psi.PsiExpressionList getExpressionList()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiExpressionStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiForStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiForeachStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiIdentifier'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiIfStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiImportList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiImportStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiImportStaticReferenceElement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiImportStaticStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiInstanceOfExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiJavaCodeReferenceElement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiJavaToken com.intellij.psi.tree.IElementType getTokenType()'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiLabeledStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiLambdaExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiLiteralExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiLocalVariable'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiMethodCallExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiMethodReferenceExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiModifierList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiNameValuePair'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiNewExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiPackageStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiParameterList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiParenthesizedExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiPolyadicExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiPostfixExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiPrefixExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiReference com.intellij.psi.PsiElement getElement()'> <item name='com.intellij.psi.PsiReference com.intellij.psi.PsiElement getElement()'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='com.intellij.psi.PsiReferenceExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiReferenceParameterList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item <item
name='com.intellij.psi.PsiReferenceService java.util.List&lt;com.intellij.psi.PsiReference&gt; getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'> name='com.intellij.psi.PsiReferenceService java.util.List&lt;com.intellij.psi.PsiReference&gt; getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
<item name='com.intellij.psi.PsiResourceVariable'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiSuperExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiSwitchLabelStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiSwitchStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiSynchronizedStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiThisExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiThrowStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeCastExpression'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeParameter'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeParameterList'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitArrayType(com.intellij.psi.PsiArrayType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitCapturedWildcardType(com.intellij.psi.PsiCapturedWildcardType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitClassType(com.intellij.psi.PsiClassType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitDiamondType(com.intellij.psi.PsiDiamondType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitDisjunctionType(com.intellij.psi.PsiDisjunctionType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitEllipsisType(com.intellij.psi.PsiEllipsisType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitIntersectionType(com.intellij.psi.PsiIntersectionType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitLambdaExpressionType(com.intellij.psi.PsiLambdaExpressionType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitMethodReferenceType(com.intellij.psi.PsiMethodReferenceType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitPrimitiveType(com.intellij.psi.PsiPrimitiveType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitType(com.intellij.psi.PsiType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiTypeVisitor A visitWildcardType(com.intellij.psi.PsiWildcardType) 0'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.PsiWhileStatement'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
<item name='com.intellij.psi.SmartPointerManager com.intellij.psi.SmartPointerManager getInstance(com.intellij.openapi.project.Project)'> <item name='com.intellij.psi.SmartPointerManager com.intellij.psi.SmartPointerManager getInstance(com.intellij.openapi.project.Project)'>
<annotation name='org.jetbrains.annotations.NotNull'/> <annotation name='org.jetbrains.annotations.NotNull'/>
</item> </item>
@@ -56,7 +56,7 @@ public fun JetDeclaration.toLightElements(): List<PsiNamedElement> =
elements elements
} }
is JetTypeParameter -> toPsiTypeParameters() is JetTypeParameter -> toPsiTypeParameters()
else -> Collections.emptyList() else -> listOf()
} }
public fun PsiElement.toLightMethods(): List<PsiMethod> = public fun PsiElement.toLightMethods(): List<PsiMethod> =
@@ -66,7 +66,7 @@ public fun PsiElement.toLightMethods(): List<PsiMethod> =
is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).toList() is JetParameter -> LightClassUtil.getLightClassPropertyMethods(this).toList()
is JetPropertyAccessor -> Collections.singletonList(LightClassUtil.getLightClassAccessorMethod(this)) is JetPropertyAccessor -> Collections.singletonList(LightClassUtil.getLightClassAccessorMethod(this))
is PsiMethod -> Collections.singletonList(this) is PsiMethod -> Collections.singletonList(this)
else -> Collections.emptyList() else -> listOf()
} }
public fun PsiElement.getRepresentativeLightMethod(): PsiMethod? = public fun PsiElement.getRepresentativeLightMethod(): PsiMethod? =
@@ -102,13 +102,13 @@ public fun JetParameter.toPsiParameter(): PsiParameter? {
public fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> { public fun JetTypeParameter.toPsiTypeParameters(): List<PsiTypeParameter> {
val paramList = getParentByType(javaClass<JetTypeParameterList>()) val paramList = getParentByType(javaClass<JetTypeParameterList>())
if (paramList == null) return Collections.emptyList() if (paramList == null) return listOf()
val paramIndex = paramList.getParameters().indexOf(this) val paramIndex = paramList.getParameters().indexOf(this)
val lightOwners = paramList.getParentByType(javaClass<JetDeclaration>())?.toLightElements() val jetDeclaration = paramList.getParentByType(javaClass<JetDeclaration>()) ?: return listOf()
val lightOwners = jetDeclaration.toLightElements()
return lightOwners?.map { lightOwner -> (lightOwner as PsiTypeParameterListOwner).getTypeParameters()[paramIndex] } return lightOwners.map { lightOwner -> (lightOwner as PsiTypeParameterListOwner).getTypeParameters()[paramIndex] }
?: Collections.emptyList()
} }
// Returns original declaration if given PsiElement is a Kotlin light element, and element itself otherwise // Returns original declaration if given PsiElement is a Kotlin light element, and element itself otherwise
@@ -39,7 +39,7 @@ public class JavaToKotlinActionUtil {
static void setClassIdentifiers(@NotNull Converter converter, @NotNull PsiFile psiFile) { static void setClassIdentifiers(@NotNull Converter converter, @NotNull PsiFile psiFile) {
ClassVisitor c = new ClassVisitor(); ClassVisitor c = new ClassVisitor();
psiFile.accept(c); psiFile.accept(c);
converter.setClassIdentifiers(c.getClassIdentifiers()); converter.setClassIdentifiers(new HashSet<String>(c.getClassIdentifiers()));
} }
@NotNull @NotNull
@@ -52,8 +52,8 @@ public abstract class AbstractJetExtractionTest() : LightCodeInsightFixtureTestC
var explicitPreviousSibling: PsiElement? = null var explicitPreviousSibling: PsiElement? = null
file.accept( file.accept(
object: JetTreeVisitorVoid() { object: JetTreeVisitorVoid() {
override fun visitComment(comment: PsiComment?) { override fun visitComment(comment: PsiComment) {
if (comment?.getText() == "// SIBLING:") { if (comment.getText() == "// SIBLING:") {
explicitPreviousSibling = PsiTreeUtil.skipSiblingsForward( explicitPreviousSibling = PsiTreeUtil.skipSiblingsForward(
comment, comment,
javaClass<PsiWhiteSpace>(), javaClass<PsiWhiteSpace>(),
@@ -19,9 +19,9 @@ package org.jetbrains.jet.j2k
import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiClass import com.intellij.psi.PsiClass
import com.intellij.psi.PsiReferenceExpression import com.intellij.psi.PsiReferenceExpression
import com.intellij.psi.PsiElement
import com.intellij.psi.JavaRecursiveElementVisitor import com.intellij.psi.JavaRecursiveElementVisitor
import java.util.LinkedHashSet import java.util.LinkedHashSet
import com.intellij.psi.PsiReference
fun isConstructorPrimary(constructor: PsiMethod): Boolean { fun isConstructorPrimary(constructor: PsiMethod): Boolean {
val parent = constructor.getParent() val parent = constructor.getParent()
@@ -30,8 +30,9 @@ fun isConstructorPrimary(constructor: PsiMethod): Boolean {
return true return true
} }
else { else {
val c = getPrimaryConstructorForThisCase(parent) val primary = getPrimaryConstructorForThisCase(parent)
if (c != null && c.hashCode() == constructor.hashCode()) { //TODO: I do not understand code below
if (primary != null && primary.hashCode() == constructor.hashCode()) {
return true return true
} }
} }
@@ -39,37 +40,39 @@ fun isConstructorPrimary(constructor: PsiMethod): Boolean {
return false return false
} }
private fun getPrimaryConstructorForThisCase(psiClass: PsiClass): PsiMethod? { fun getPrimaryConstructorForThisCase(psiClass: PsiClass): PsiMethod? {
val tv = FindPrimaryConstructorVisitor() class FindPrimaryConstructorVisitor() : JavaRecursiveElementVisitor() {
psiClass.accept(tv) private val resolvedConstructors = LinkedHashSet<PsiMethod>()
return tv.getPrimaryConstructor()
}
private class FindPrimaryConstructorVisitor() : JavaRecursiveElementVisitor() { override fun visitReferenceExpression(expression: PsiReferenceExpression) {
private val myResolvedConstructors = LinkedHashSet<PsiMethod>() expression.getReferences()
.filter { it.getCanonicalText() == "this" }
.map { it.resolve() }
.filterIsInstance(javaClass<PsiMethod>())
.filterTo(resolvedConstructors) { it.isConstructor() }
}
override fun visitReferenceExpression(expression: PsiReferenceExpression?) { val result: PsiMethod?
for (r in expression?.getReferences()!!) { get() {
if (r.getCanonicalText() == "this") { if (resolvedConstructors.isEmpty()) return null
val res: PsiElement? = r.resolve() //TODO: I do not understand code below
if (res is PsiMethod && res.isConstructor()) { val first = resolvedConstructors.first()
myResolvedConstructors.add(res) return if (resolvedConstructors.all { it.hashCode() == first.hashCode() }) first else null
}
} }
}
} }
fun getPrimaryConstructor(): PsiMethod? { val visitor = FindPrimaryConstructorVisitor()
if (myResolvedConstructors.size() > 0) { psiClass.accept(visitor)
val first: PsiMethod = myResolvedConstructors.iterator().next() return visitor.result
for (m in myResolvedConstructors)
if (m.hashCode() != first.hashCode()) {
return null
}
return first
}
return null
}
} }
fun isSuperConstructorRef(ref: PsiReference): Boolean {
if (ref.getCanonicalText().equals("super")) {
val baseConstructor = ref.resolve()
if (baseConstructor is PsiMethod && baseConstructor.isConstructor()) {
return true
}
}
return false
}
+176 -308
View File
@@ -16,36 +16,31 @@
package org.jetbrains.jet.j2k package org.jetbrains.jet.j2k
import com.google.common.collect.ImmutableMap
import com.google.common.collect.ImmutableSet
import com.google.common.collect.Sets
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.ast.types.ClassType import org.jetbrains.jet.j2k.ast.types.ClassType
import org.jetbrains.jet.j2k.ast.types.EmptyType import org.jetbrains.jet.j2k.ast.types.EmptyType
import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.j2k.visitors.* import org.jetbrains.jet.j2k.visitors.*
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
import java.util.* import java.util.*
import com.intellij.psi.CommonClassNames.* import com.intellij.psi.CommonClassNames.*
import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* import org.jetbrains.jet.lang.types.expressions.OperatorConventions.*
import com.intellij.psi.util.PsiUtil
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
public class Converter(val project: Project, val settings: ConverterSettings) { public class Converter(val project: Project, val settings: ConverterSettings) {
private var classIdentifiersSet: MutableSet<String> = Sets.newHashSet()!! private var classIdentifiersSet: MutableSet<String> = HashSet()
private val dispatcher: Dispatcher = Dispatcher(this) private val dispatcher: Dispatcher = Dispatcher(this)
var methodReturnType: PsiType? = null public var methodReturnType: PsiType? = null
private set private set
public fun setClassIdentifiers(identifiers: MutableSet<String>) { public fun setClassIdentifiers(identifiers: MutableSet<String>) {
classIdentifiersSet = identifiers classIdentifiersSet = identifiers
} }
fun getClassIdentifiers(): Set<String> { public fun getClassIdentifiers(): Set<String> {
return Collections.unmodifiableSet(classIdentifiersSet) return Collections.unmodifiableSet(classIdentifiersSet)
} }
@@ -53,12 +48,10 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
classIdentifiersSet.clear() classIdentifiersSet.clear()
} }
public fun elementToKotlin(element: PsiElement): String { public fun elementToKotlin(element: PsiElement): String
val kElement = convertTopElement(element) = convertTopElement(element)?.toKotlin() ?: ""
return kElement?.toKotlin() ?: ""
}
fun convertTopElement(element: PsiElement?): Element? = when(element) { private fun convertTopElement(element: PsiElement?): Element? = when(element) {
is PsiJavaFile -> convertFile(element) is PsiJavaFile -> convertFile(element)
is PsiClass -> convertClass(element) is PsiClass -> convertClass(element)
is PsiMethod -> convertMethod(element) is PsiMethod -> convertMethod(element)
@@ -74,22 +67,18 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
public fun convertFile(javaFile: PsiJavaFile): File { public fun convertFile(javaFile: PsiJavaFile): File {
val fileMembers = FileMemberList(javaFile.getChildren() .map { convertTopElement(it) } .filterNotNull()) val fileMembers = FileMemberList(javaFile.getChildren().map { convertTopElement(it) }.filterNotNull())
return File(fileMembers, createMainFunction(javaFile)) return File(fileMembers, createMainFunction(javaFile))
} }
fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { public fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass {
return AnonymousClass(this, convertMembers(anonymousClass)) return AnonymousClass(this, convertMembers(anonymousClass))
} }
private fun convertMembers(psiClass: PsiClass): List<Element> { private fun convertMembers(psiClass: PsiClass): List<Element> {
val members = ArrayList<Element>()
val allChildren = psiClass.getChildren().toList() val allChildren = psiClass.getChildren().toList()
for (e in allChildren.subList(allChildren.indexOf(psiClass.getLBrace()), allChildren.size)) { val lBraceIndex = allChildren.indexOf(psiClass.getLBrace())
val converted = convertMember(e, psiClass) return allChildren.subList(lBraceIndex, allChildren.size).map { convertMember(it, psiClass) }.filterNotNull()
if (converted != null) members.add(converted)
}
return members
} }
private fun getComments(member: PsiMember): MemberComments { private fun getComments(member: PsiMember): MemberComments {
@@ -118,59 +107,60 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList()) val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList())
val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes()) val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes())
val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes()) val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes())
val name: Identifier = Identifier(psiClass.getName()!!) val name = Identifier(psiClass.getName()!!)
val baseClassParams = ArrayList<Expression>()
val members = ArrayList(convertMembers(psiClass)) val members = ArrayList(convertMembers(psiClass))
val visitor = SuperVisitor()
psiClass.accept(visitor) val baseClassParams: List<Expression> = run {
val resolvedSuperCallParameters = visitor.resolvedSuperCallParameters val superVisitor = SuperVisitor()
if (resolvedSuperCallParameters.size() == 1) { psiClass.accept(superVisitor)
val psiExpressionList = resolvedSuperCallParameters.iterator().next() val resolvedSuperCallParameters = superVisitor.resolvedSuperCallParameters
baseClassParams.addAll(convertExpressions(psiExpressionList.getExpressions())) if (resolvedSuperCallParameters.size() == 1) {
convertExpressions(resolvedSuperCallParameters.single().getExpressions())
}
else {
listOf()
}
} }
if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().size > 1 && if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().size > 1 && getPrimaryConstructorForThisCase(psiClass) == null) {
getPrimaryConstructorForThisCase(psiClass) == null) { val finalOrWithEmptyInitializer = fields.filter { it.isVal() || it.initializer.toKotlin().isEmpty() }
val finalOrWithEmptyInitializer: List<Field> = getFinalOrWithEmptyInitializer(fields)
val initializers = HashMap<String, String>() val initializers = HashMap<String, String>()
for (m in members) { for (member in members) {
if (m is Constructor) { if (member is Constructor && !member.isPrimary) {
if (!m.isPrimary) { for (field in finalOrWithEmptyInitializer) {
for (fo in finalOrWithEmptyInitializer) { initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field))
val init = getDefaultInitializer(fo)
initializers.put(fo.identifier.toKotlin(), init)
}
val newStatements = ArrayList<Statement>()
for (s in m.block!!.statements) {
var isRemoved: Boolean = false
if (s is AssignmentExpression) {
val assignee = s.left
if (assignee is CallChainExpression) {
for (fo : Field in finalOrWithEmptyInitializer) {
val id: String = fo.identifier.toKotlin()
if (assignee.identifier.toKotlin().endsWith("." + id)) {
initializers.put(id, s.right.toKotlin())
isRemoved = true
}
}
}
}
if (!isRemoved) {
newStatements.add(s)
}
}
newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializer, initializers)))
m.block = Block(newStatements)
} }
val newStatements = ArrayList<Statement>()
for (statement in member.block!!.statements) {
var isRemoved = false
if (statement is AssignmentExpression) {
val assignee = statement.left
if (assignee is CallChainExpression) {
for (field in finalOrWithEmptyInitializer) {
val id = field.identifier.toKotlin()
if (assignee.identifier.toKotlin().endsWith("." + id)) {
initializers.put(id, statement.right.toKotlin())
isRemoved = true
}
}
}
}
if (!isRemoved) {
newStatements.add(statement)
}
}
newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializer, initializers)))
member.block = Block(newStatements)
} }
} }
//TODO: comments? //TODO: comments?
members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet<Modifier>(), members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet<Modifier>(),
ClassType(name, Collections.emptyList<Element>(), false, this), ClassType(name, listOf(), false, this),
TypeParameterList.Empty, TypeParameterList.Empty,
ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)), Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)),
@@ -178,18 +168,18 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
if (psiClass.isInterface()) { if (psiClass.isInterface()) {
return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, Collections.emptyList<Expression>(), implementsTypes, members) return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, members)
} }
if (psiClass.isEnum()) { if (psiClass.isEnum()) {
return Enum(this, name, getComments(psiClass), modifiers, typeParameters, Collections.emptyList<Type>(), Collections.emptyList<Expression>(), implementsTypes, members) return Enum(this, name, getComments(psiClass), modifiers, typeParameters, listOf(), listOf(), implementsTypes, members)
} }
return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members)
} }
private fun convertInitializer(i: PsiClassInitializer): Initializer { private fun convertInitializer(initializer: PsiClassInitializer): Initializer {
return Initializer(convertBlock(i.getBody(), true), convertModifierList(i.getModifierList())) return Initializer(convertBlock(initializer.getBody(), true), convertModifierList(initializer.getModifierList()))
} }
private fun convertFields(fields: Array<PsiField>, psiClass: PsiClass): List<Field> { private fun convertFields(fields: Array<PsiField>, psiClass: PsiClass): List<Field> {
@@ -216,7 +206,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
modifiers, modifiers,
kType, kType,
convertExpression(field.getInitializer(), field.getType()), convertExpression(field.getInitializer(), field.getType()),
countWritingAccesses(field, psiClass)) countWriteAccesses(field, psiClass))
} }
private fun convertMethod(method: PsiMethod): Function { private fun convertMethod(method: PsiMethod): Function {
@@ -231,13 +221,13 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
dispatcher.expressionVisitor = ExpressionVisitor(this) dispatcher.expressionVisitor = ExpressionVisitor(this)
} }
methodReturnType = method.getReturnType() methodReturnType = method.getReturnType()
val identifier: Identifier = Identifier(method.getName()) val identifier = Identifier(method.getName())
val returnType: Type = convertType(method.getReturnType(), isAnnotatedAsNotNull(method.getModifierList())) val returnType = convertType(method.getReturnType(), isAnnotatedAsNotNull(method.getModifierList()))
val body = convertBlock(method.getBody(), notEmpty) val body = convertBlock(method.getBody(), notEmpty)
val params: Element = createFunctionParameters(method) val params = createFunctionParameters(method)
val typeParameterList = convertTypeParameterList(method.getTypeParameterList()) val typeParameterList = convertTypeParameterList(method.getTypeParameterList())
val modifiers = convertModifierList(method.getModifierList()) val modifiers = HashSet(convertModifierList(method.getModifierList()))
if (isOverride(method)) { if (isOverride(method)) {
modifiers.add(Modifier.OVERRIDE) modifiers.add(Modifier.OVERRIDE)
} }
@@ -261,62 +251,49 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
private fun createFunctionParameters(method: PsiMethod): ParameterList { private fun createFunctionParameters(method: PsiMethod): ParameterList {
val result = ArrayList<Parameter>() val result = ArrayList<Parameter>()
for (parameter : PsiParameter? in method.getParameterList().getParameters()) { for (parameter in method.getParameterList().getParameters()) {
result.add(Parameter(Identifier(parameter?.getName()!!), result.add(Parameter(Identifier(parameter.getName()!!),
convertType(parameter?.getType(), convertType(parameter.getType(), isAnnotatedAsNotNull(parameter.getModifierList())),
isAnnotatedAsNotNull(parameter?.getModifierList())),
isReadOnly(parameter, method.getBody()))) isReadOnly(parameter, method.getBody())))
} }
return ParameterList(result) return ParameterList(result)
} }
fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean): Block { public fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean = true): Block {
if (block == null) if (block == null) return Block.Empty
return Block.Empty
return Block(convertStatements(block.getChildren().toList()), notEmpty) return Block(convertStatements(block.getChildren().toList()), notEmpty)
} }
fun convertBlock(block: PsiCodeBlock?): Block { public fun convertStatements(statements: List<PsiElement>): StatementList {
return convertBlock(block, true)
}
fun convertStatements(statements: List<PsiElement>): StatementList {
return StatementList(statements.map { if (it is PsiStatement) convertStatement(it) else convertElement(it) }) return StatementList(statements.map { if (it is PsiStatement) convertStatement(it) else convertElement(it) })
} }
fun convertStatement(s: PsiStatement?): Statement { public fun convertStatement(statement: PsiStatement?): Statement {
if (s == null) if (statement == null) return Statement.Empty
return Statement.Empty
val statementVisitor: StatementVisitor = StatementVisitor(this) val statementVisitor: StatementVisitor = StatementVisitor(this)
s.accept(statementVisitor) statement.accept(statementVisitor)
return statementVisitor.getResult() as Statement return statementVisitor.result
} }
fun convertExpressions(expressions: Array<PsiExpression>): List<Expression> { public fun convertExpressions(expressions: Array<PsiExpression>): List<Expression>
val result = ArrayList<Expression>() = expressions.map { convertExpression(it) }
for (e : PsiExpression? in expressions)
result.add(convertExpression(e)) public fun convertExpression(expression: PsiExpression?): Expression {
return result if (expression == null) return Expression.Empty
val expressionVisitor = dispatcher.expressionVisitor
expression.accept(expressionVisitor)
return expressionVisitor.result
} }
fun convertExpression(e: PsiExpression?): Expression { public fun convertElement(element: PsiElement?): Element {
if (e == null) if (element == null) return Element.Empty
return Expression.Empty
val expressionVisitor: ExpressionVisitor = dispatcher.expressionVisitor val elementVisitor = ElementVisitor(this)
e.accept(expressionVisitor) element.accept(elementVisitor)
return expressionVisitor.getResult() return elementVisitor.result
}
fun convertElement(e: PsiElement?): Element {
if (e == null)
return Element.Empty
val elementVisitor: ElementVisitor = ElementVisitor(this)
e.accept(elementVisitor)
return elementVisitor.getResult()
} }
fun convertElements(elements: Array<out PsiElement?>): List<Element> { fun convertElements(elements: Array<out PsiElement?>): List<Element> {
@@ -327,28 +304,25 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return result return result
} }
fun convertTypeElement(element: PsiTypeElement?): TypeElement { public fun convertTypeElement(element: PsiTypeElement?): TypeElement {
return TypeElement(if (element == null) return TypeElement(if (element == null)
EmptyType() EmptyType()
else else
convertType(element.getType())) convertType(element.getType()))
} }
fun convertType(`type`: PsiType?): Type { public fun convertType(`type`: PsiType?): Type {
if (`type` == null) if (`type` == null) return EmptyType()
return EmptyType()
val typeVisitor: TypeVisitor = TypeVisitor(this) return `type`.accept<Type>(TypeVisitor(this))!!
`type`.accept<Type>(typeVisitor)
return typeVisitor.getResult()
} }
fun convertTypes(types: Array<PsiType>): List<Type> { public fun convertTypes(types: Array<PsiType>): List<Type> {
return types.map { convertType(it) } return types.map { convertType(it) }
} }
fun convertType(`type`: PsiType?, notNull: Boolean): Type { public fun convertType(`type`: PsiType?, notNull: Boolean): Type {
val result: Type = convertType(`type`) val result = convertType(`type`)
if (notNull) { if (notNull) {
return result.convertedToNotNull() return result.convertedToNotNull()
} }
@@ -356,57 +330,39 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return result return result
} }
private fun convertToNotNullableTypes(types: Array<out PsiType?>): List<Type> { private fun convertToNotNullableTypes(types: Array<out PsiType?>): List<Type>
val result = ArrayList<Type>() = types.map { convertType(it).convertedToNotNull() }
for (aType in types) {
result.add(convertType(aType).convertedToNotNull())
}
return result
}
fun convertParameterList(parameters: Array<PsiParameter>): List<Parameter?> { public fun convertParameterList(parameters: Array<PsiParameter>): List<Parameter>
return parameters.map { convertParameter(it) } = parameters.map { convertParameter(it) }
}
fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter { public fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter {
return Parameter(Identifier(parameter.getName()!!), return Parameter(Identifier(parameter.getName()!!),
convertType(parameter.getType(), convertType(parameter.getType(),
forceNotNull || isAnnotatedAsNotNull(parameter.getModifierList())), true) forceNotNull || isAnnotatedAsNotNull(parameter.getModifierList())), true)
} }
fun convertArguments(expression: PsiCallExpression): List<Expression> { public fun convertArguments(expression: PsiCallExpression): List<Expression> {
val argumentList: PsiExpressionList? = expression.getArgumentList() val arguments = expression.getArgumentList()?.getExpressions() ?: array()
val arguments: Array<PsiExpression> = (if (argumentList != null) val resolved = expression.resolveMethod()
argumentList.getExpressions() val expectedTypes = if (resolved != null)
resolved.getParameterList().getParameters().map { it.getType() }
else else
PsiExpression.EMPTY_ARRAY) listOf()
val result = ArrayList<Expression>()
val resolved: PsiMethod? = expression.resolveMethod()
val expectedTypes = ArrayList<PsiType?>()
if (resolved != null) {
for (p : PsiParameter? in resolved.getParameterList().getParameters())
expectedTypes.add(p?.getType())
}
if (arguments.size == expectedTypes.size()) { return if (arguments.size == expectedTypes.size())
for (i in 0..expectedTypes.size() - 1) result.add(convertExpression(arguments[i], expectedTypes.get(i))) (0..expectedTypes.lastIndex).map { i -> convertExpression(arguments[i], expectedTypes[i]) }
} else
else { arguments.map { convertExpression(it) }
for (argument : PsiExpression? in arguments) {
result.add(convertExpression(argument))
}
}
return result
} }
fun convertExpression(argument: PsiExpression?, expectedType: PsiType?): Expression { public fun convertExpression(argument: PsiExpression?, expectedType: PsiType?): Expression {
if (argument == null) if (argument == null) return Identifier.Empty
return Identifier.Empty
var expression: Expression = convertExpression(argument) var expression = convertExpression(argument)
val actualType: PsiType? = argument.getType() val actualType = argument.getType()
val isPrimitiveTypeOrNull: Boolean = actualType == null || actualType is PsiPrimitiveType val isPrimitiveTypeOrNull = actualType == null || actualType is PsiPrimitiveType
if (isPrimitiveTypeOrNull && expression.isNullable()) { if (isPrimitiveTypeOrNull && expression.isNullable) {
expression = BangBangExpression(expression) expression = BangBangExpression(expression)
} }
else if (expectedType is PsiPrimitiveType && actualType is PsiClassType) { else if (expectedType is PsiPrimitiveType && actualType is PsiClassType) {
@@ -416,9 +372,8 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
if (actualType != null) { if (actualType != null) {
if (isConversionNeeded(actualType, expectedType) && !(expression is LiteralExpression)) if (isConversionNeeded(actualType, expectedType) && expression !is LiteralExpression) {
{ val conversion = PRIMITIVE_TYPE_CONVERSIONS[expectedType?.getCanonicalText()]
val conversion: String? = PRIMITIVE_TYPE_CONVERSIONS.get(expectedType?.getCanonicalText())
if (conversion != null) { if (conversion != null) {
expression = MethodCallExpression.build(expression, conversion) expression = MethodCallExpression.build(expression, conversion)
} }
@@ -429,29 +384,15 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return expression return expression
} }
fun quoteKeywords(packageName: String): String {
return packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".")
}
private fun getFinalOrWithEmptyInitializer(fields: List<Field>): List<Field> {
val result = ArrayList<Field>()
for (f : Field in fields)
if (f.isVal() || f.initializer.toKotlin().isEmpty()) {
result.add(f)
}
return result
}
private fun createParametersFromFields(fields: List<Field>): List<Parameter> { private fun createParametersFromFields(fields: List<Field>): List<Parameter> {
return fields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, true) } return fields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, true) }
} }
private fun createInitStatementsFromFields(fields: List<Field>): List<Statement> { private fun createInitStatementsFromFields(fields: List<Field>): List<Statement> {
val result = ArrayList<Statement>() val result = ArrayList<Statement>()
for (f : Field in fields) { for (field in fields) {
val identifierToKotlin: String? = f.identifier.toKotlin() val kotlinIdentifier = field.identifier.toKotlin()
result.add(DummyStringExpression(identifierToKotlin + " = " + "_" + identifierToKotlin)) result.add(DummyStringExpression(kotlinIdentifier + " = " + "_" + kotlinIdentifier))
} }
return result return result
} }
@@ -460,151 +401,78 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return s + "(" + fields.map { initializers[it.identifier.toKotlin()] }.makeString(", ") + ")" return s + "(" + fields.map { initializers[it.identifier.toKotlin()] }.makeString(", ") + ")"
} }
fun convertIdentifier(identifier: PsiIdentifier?): Identifier { public fun convertIdentifier(identifier: PsiIdentifier?): Identifier {
if (identifier == null) if (identifier == null) return Identifier.Empty
return Identifier.Empty
return Identifier(identifier.getText()!!) return Identifier(identifier.getText()!!)
} }
fun convertModifierList(modifierList: PsiModifierList?): MutableSet<Modifier> { public fun convertModifierList(modifierList: PsiModifierList?): Set<Modifier> {
val modifiersSet: HashSet<Modifier> = hashSetOf() if (modifierList == null) return setOf()
if (modifierList != null) {
if (modifierList.hasExplicitModifier(PsiModifier.ABSTRACT))
modifiersSet.add(Modifier.ABSTRACT)
if (modifierList.hasModifierProperty(PsiModifier.FINAL)) val modifiersSet = HashSet<Modifier>()
modifiersSet.add(Modifier.FINAL)
if (modifierList.hasModifierProperty(PsiModifier.STATIC)) if (modifierList.hasExplicitModifier(PsiModifier.ABSTRACT))
modifiersSet.add(Modifier.STATIC) modifiersSet.add(Modifier.ABSTRACT)
if (modifierList.hasExplicitModifier(PsiModifier.PUBLIC)) if (modifierList.hasModifierProperty(PsiModifier.FINAL))
modifiersSet.add(Modifier.PUBLIC) modifiersSet.add(Modifier.FINAL)
if (modifierList.hasExplicitModifier(PsiModifier.PROTECTED)) if (modifierList.hasModifierProperty(PsiModifier.STATIC))
modifiersSet.add(Modifier.PROTECTED) modifiersSet.add(Modifier.STATIC)
if (modifierList.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)) if (modifierList.hasExplicitModifier(PsiModifier.PUBLIC))
modifiersSet.add(Modifier.INTERNAL) modifiersSet.add(Modifier.PUBLIC)
if (modifierList.hasExplicitModifier(PsiModifier.PRIVATE)) if (modifierList.hasExplicitModifier(PsiModifier.PROTECTED))
modifiersSet.add(Modifier.PRIVATE) modifiersSet.add(Modifier.PROTECTED)
}
if (modifierList.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL))
modifiersSet.add(Modifier.INTERNAL)
if (modifierList.hasExplicitModifier(PsiModifier.PRIVATE))
modifiersSet.add(Modifier.PRIVATE)
return modifiersSet return modifiersSet
} }
private val TYPE_MAP: Map<String, String> = mapOf(
JAVA_LANG_BYTE to "byte",
JAVA_LANG_SHORT to "short",
JAVA_LANG_INTEGER to "int",
JAVA_LANG_LONG to "long",
JAVA_LANG_FLOAT to "float",
JAVA_LANG_DOUBLE to "double",
JAVA_LANG_CHARACTER to "char"
)
private fun isConversionNeeded(actual: PsiType?, expected: PsiType?): Boolean { private fun isConversionNeeded(actual: PsiType?, expected: PsiType?): Boolean {
if (actual == null || expected == null) { if (actual == null || expected == null) return false
return false
}
val typeMap = HashMap<String, String>() val expectedStr = expected.getCanonicalText()
typeMap.put(JAVA_LANG_BYTE, "byte") val actualStr = actual.getCanonicalText()
typeMap.put(JAVA_LANG_SHORT, "short") if (expectedStr == actualStr) return false
typeMap.put(JAVA_LANG_INTEGER, "int") val o1 = expectedStr == TYPE_MAP[actualStr]
typeMap.put(JAVA_LANG_LONG, "long") val o2 = actualStr == TYPE_MAP[expectedStr]
typeMap.put(JAVA_LANG_FLOAT, "float") return o1 == o2
typeMap.put(JAVA_LANG_DOUBLE, "double")
typeMap.put(JAVA_LANG_CHARACTER, "char")
val expectedStr: String? = expected.getCanonicalText()
val actualStr: String? = actual.getCanonicalText()
val o1: Boolean = expectedStr == typeMap[actualStr]
val o2: Boolean = actualStr == typeMap[expectedStr]
return actualStr != expectedStr && (!(o1 xor o2))
} }
} }
val NOT_NULL_ANNOTATIONS: Set<String> = ImmutableSet.of<String>("org.jetbrains.annotations.NotNull", "com.sun.istack.internal.NotNull", "javax.annotation.Nonnull")!! val NOT_NULL_ANNOTATIONS: Set<String> = setOf("org.jetbrains.annotations.NotNull", "com.sun.istack.internal.NotNull", "javax.annotation.Nonnull")
val PRIMITIVE_TYPE_CONVERSIONS: Map<String, String> = ImmutableMap.builder<String, String>()
?.put("byte", BYTE.asString())
?.put("short", SHORT.asString())
?.put("int", INT.asString())
?.put("long", LONG.asString())
?.put("float", FLOAT.asString())
?.put("double", DOUBLE.asString())
?.put("char", CHAR.asString())
?.put(JAVA_LANG_BYTE, BYTE.asString())
?.put(JAVA_LANG_SHORT, SHORT.asString())
?.put(JAVA_LANG_INTEGER, INT.asString())
?.put(JAVA_LANG_LONG, LONG.asString())
?.put(JAVA_LANG_FLOAT, FLOAT.asString())
?.put(JAVA_LANG_DOUBLE, DOUBLE.asString())
?.put(JAVA_LANG_CHARACTER, CHAR.asString())
?.build()!!
val PRIMITIVE_TYPE_CONVERSIONS: Map<String, String> = mapOf(
fun countWritingAccesses(element: PsiElement?, container: PsiElement?): Int { "byte" to BYTE.asString(),
var counter: Int = 0 "short" to SHORT.asString(),
if (container != null) { "int" to INT.asString(),
val visitor: ReferenceCollector = ReferenceCollector() "long" to LONG.asString(),
container.accept(visitor) "float" to FLOAT.asString(),
for (e : PsiReferenceExpression in visitor.getCollectedReferences()) "double" to DOUBLE.asString(),
if (e.isReferenceTo(element) && PsiUtil.isAccessedForWriting(e)) { "char" to CHAR.asString(),
counter++ JAVA_LANG_BYTE to BYTE.asString(),
} JAVA_LANG_SHORT to SHORT.asString(),
} JAVA_LANG_INTEGER to INT.asString(),
JAVA_LANG_LONG to LONG.asString(),
return counter JAVA_LANG_FLOAT to FLOAT.asString(),
} JAVA_LANG_DOUBLE to DOUBLE.asString(),
JAVA_LANG_CHARACTER to CHAR.asString()
open class ReferenceCollector() : JavaRecursiveElementVisitor() { )
private val myCollectedReferences = ArrayList<PsiReferenceExpression>()
open fun getCollectedReferences(): List<PsiReferenceExpression> {
return myCollectedReferences
}
override fun visitReferenceExpression(expression: PsiReferenceExpression?) {
super.visitReferenceExpression(expression)
if (expression != null) {
myCollectedReferences.add(expression)
}
}
}
fun isReadOnly(element: PsiElement?, container: PsiElement?): Boolean {
return countWritingAccesses(element, container) == 0
}
fun isAnnotatedAsNotNull(modifierList: PsiModifierList?): Boolean {
if (modifierList != null) {
val annotations: Array<PsiAnnotation> = modifierList.getAnnotations()
for (a : PsiAnnotation in annotations) {
val qualifiedName: String? = a.getQualifiedName()
if (qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)) {
return true
}
}
}
return false
}
fun isDefinitelyNotNull(element: PsiElement?): Boolean = when(element) {
is PsiLiteralExpression -> element.getValue() != null
is PsiNewExpression -> true
else -> false
}
fun getDefaultInitializer(f: Field): String {
if (f.`type`.nullable) {
return "null"
}
else {
val typeToKotlin = f.`type`.toKotlin()
if (typeToKotlin.equals("Boolean"))
return "false"
if (typeToKotlin.equals("Char"))
return "' '"
if (typeToKotlin.equals("Double"))
return "0." + OperatorConventions.DOUBLE + "()"
if (typeToKotlin.equals("Float"))
return "0." + OperatorConventions.FLOAT + "()"
return "0"
}
}
@@ -92,7 +92,7 @@ public object JavaToKotlinTranslator {
val c = ClassVisitor() val c = ClassVisitor()
psiFile.accept(c) psiFile.accept(c)
converter.clearClassIdentifiers() converter.clearClassIdentifiers()
converter.setClassIdentifiers(HashSet(c.getClassIdentifiers())) converter.setClassIdentifiers(HashSet(c.classIdentifiers))
} }
fun generateKotlinCode(javaCode: String): String { fun generateKotlinCode(javaCode: String): String {
+2 -4
View File
@@ -69,10 +69,8 @@ fun isNotOpenMethod(method: PsiMethod): Boolean {
fun directlyOverridesMethodFromObject(method: PsiMethod): Boolean { fun directlyOverridesMethodFromObject(method: PsiMethod): Boolean {
var superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures() var superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures()
if (superSignatures.size() == 1) { if (superSignatures.size() == 1) {
val qualifiedName = superSignatures.first!!.getMethod().getContainingClass()?.getQualifiedName() val qualifiedName = superSignatures.single().getMethod().getContainingClass()?.getQualifiedName()
if (qualifiedName == JAVA_LANG_OBJECT) { return qualifiedName == JAVA_LANG_OBJECT
return true
}
} }
return false return false
} }
+86
View File
@@ -0,0 +1,86 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.j2k
import org.jetbrains.jet.j2k.ast.Identifier
import com.intellij.psi.PsiElement
import com.intellij.psi.JavaRecursiveElementVisitor
import java.util.ArrayList
import com.intellij.psi.PsiReferenceExpression
import com.intellij.psi.util.PsiUtil
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiNewExpression
import org.jetbrains.jet.j2k.ast.Field
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".")
fun countWriteAccesses(element: PsiElement?, container: PsiElement?): Int {
if (container == null) return 0
class ReferenceCollector() : JavaRecursiveElementVisitor() {
private val _collectedReferences = ArrayList<PsiReferenceExpression>()
public val collectedReferences: List<PsiReferenceExpression>
get() = _collectedReferences
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
super.visitReferenceExpression(expression)
_collectedReferences.add(expression)
}
}
val collector = ReferenceCollector()
container.accept(collector)
return collector.collectedReferences.count { it.isReferenceTo(element) && PsiUtil.isAccessedForWriting(it) }
}
fun isReadOnly(element: PsiElement?, container: PsiElement?): Boolean
= countWriteAccesses(element, container) == 0
fun isAnnotatedAsNotNull(modifierList: PsiModifierList?): Boolean {
if (modifierList != null) {
for (annotation in modifierList.getAnnotations()) {
val qualifiedName = annotation.getQualifiedName()
return qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)
}
}
return false
}
fun isDefinitelyNotNull(element: PsiElement?): Boolean = when(element) {
is PsiLiteralExpression -> element.getValue() != null
is PsiNewExpression -> true
else -> false
}
fun getDefaultInitializer(field: Field): String {
if (field.`type`.isNullable) {
return "null"
}
else {
return when(field.`type`.toKotlin()) {
"Boolean" -> "false"
"Char" -> "' '"
"Double" -> "0." + OperatorConventions.DOUBLE + "()"
"Float" -> "0." + OperatorConventions.FLOAT + "()"
else -> "0"
}
}
}
@@ -26,8 +26,9 @@ class AnonymousClass(converter: Converter, members: List<Element>)
MemberComments.Empty, MemberComments.Empty,
Collections.emptySet<Modifier>(), Collections.emptySet<Modifier>(),
TypeParameterList.Empty, TypeParameterList.Empty,
Collections.emptyList<Type>(), listOf(),
Collections.emptyList<Expression>(), listOf(),
Collections.emptyList<Type>(), members) { listOf(),
members) {
override fun toKotlin() = bodyToKotlin() override fun toKotlin() = bodyToKotlin()
} }
+4 -4
View File
@@ -30,12 +30,12 @@ class Block(val statementList: StatementList, val notEmpty: Boolean = false) : S
val statements: List<Statement> = statementList.statements val statements: List<Statement> = statementList.statements
override fun isEmpty(): Boolean {
return !notEmpty && statements.all { it.isEmpty() } override val isEmpty: Boolean
} get() = !notEmpty && statements.all { it.isEmpty }
override fun toKotlin(): String { override fun toKotlin(): String {
if (!isEmpty()) { if (!isEmpty) {
return "{${statementList.toKotlin()}}" return "{${statementList.toKotlin()}}"
} }
@@ -17,14 +17,15 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
class CallChainExpression(val expression: Expression, val identifier: Expression) : Expression() { class CallChainExpression(val expression: Expression, val identifier: Expression) : Expression() {
override fun isNullable(): Boolean { override val isNullable: Boolean
if (!expression.isEmpty() && expression.isNullable()) return true get() {
return identifier.isNullable() if (!expression.isEmpty && expression.isNullable) return true
} return identifier.isNullable
}
override fun toKotlin(): String { override fun toKotlin(): String {
if (!expression.isEmpty()) { if (!expression.isEmpty) {
return expression.toKotlin() + (if (expression.isNullable()) "?." else ".") + identifier.toKotlin() return expression.toKotlin() + (if (expression.isNullable) "?." else ".") + identifier.toKotlin()
} }
return identifier.toKotlin() return identifier.toKotlin()
+1 -1
View File
@@ -45,7 +45,7 @@ open class Class(
fun primaryConstructorBodyToKotlin(): String? { fun primaryConstructorBodyToKotlin(): String? {
val maybeConstructor = classMembers.primaryConstructor val maybeConstructor = classMembers.primaryConstructor
if (maybeConstructor != null && !(maybeConstructor.block?.isEmpty() ?: true)) { if (maybeConstructor != null && !(maybeConstructor.block?.isEmpty ?: true)) {
return "\n" + maybeConstructor.primaryBodyToKotlin() + "\n" return "\n" + maybeConstructor.primaryBodyToKotlin() + "\n"
} }
return "" return ""
+2 -2
View File
@@ -18,11 +18,11 @@ package org.jetbrains.jet.j2k.ast
trait Element : Node { trait Element : Node {
fun isEmpty(): Boolean = false val isEmpty: Boolean get() = false
object Empty : Element { object Empty : Element {
override fun toKotlin() = "" override fun toKotlin() = ""
override fun isEmpty() = true override val isEmpty: Boolean get() = true
} }
} }
@@ -18,12 +18,11 @@ package org.jetbrains.jet.j2k.ast
abstract class Expression() : Statement() { abstract class Expression() : Statement() {
open fun isNullable(): Boolean { open val isNullable: Boolean get() = false
return false
}
object Empty : Expression() { object Empty : Expression() {
override fun toKotlin() = "" override fun toKotlin() = ""
override fun isEmpty() = true
override val isEmpty: Boolean get() = true
} }
} }
@@ -18,5 +18,7 @@ package org.jetbrains.jet.j2k.ast
open class ExpressionList(val expressions: List<Expression>) : Expression() { open class ExpressionList(val expressions: List<Expression>) : Expression() {
override fun toKotlin(): String = expressions.map { it.toKotlin() }.makeString(", ") override fun toKotlin(): String = expressions.map { it.toKotlin() }.makeString(", ")
override fun isEmpty(): Boolean = expressions.isEmpty()
override val isEmpty: Boolean
get() = expressions.isEmpty()
} }
@@ -20,7 +20,7 @@ import org.jetbrains.jet.j2k.ast.types.Type
open class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() { open class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() {
override fun toKotlin() = expression.toKotlin() + override fun toKotlin() = expression.toKotlin() +
(if (!lvalue && expression.isNullable()) "!!" else "") + (if (!lvalue && expression.isNullable) "!!" else "") +
"[" + index.toKotlin() + "]" "[" + index.toKotlin() + "]"
} }
@@ -58,7 +58,9 @@ open class ParenthesizedExpression(val expression: Expression) : Expression() {
open class PrefixOperator(val op: String, val expression: Expression) : Expression() { open class PrefixOperator(val op: String, val expression: Expression) : Expression() {
override fun toKotlin() = op + expression.toKotlin() override fun toKotlin() = op + expression.toKotlin()
override fun isNullable() = expression.isNullable()
override val isNullable: Boolean
get() = expression.isNullable
} }
open class PostfixOperator(val op: String, val expression: Expression) : Expression() { open class PostfixOperator(val op: String, val expression: Expression) : Expression() {
+1 -1
View File
@@ -48,7 +48,7 @@ open class Field(
override fun toKotlin(): String { override fun toKotlin(): String {
val declaration: String = commentsToKotlin() + val declaration: String = commentsToKotlin() +
modifiersToKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin() modifiersToKotlin() + identifier.toKotlin() + " : " + `type`.toKotlin()
if (initializer.isEmpty()) { if (initializer.isEmpty) {
return declaration + ((if (isVal() && !isStatic() && writingAccesses != 0) return declaration + ((if (isVal() && !isStatic() && writingAccesses != 0)
"" ""
else else
@@ -17,31 +17,28 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
open class Identifier( class Identifier(
val name: String, val name: String,
val myNullable: Boolean = true, public override val isNullable: Boolean = true,
val quotingNeeded: Boolean = true private val quotingNeeded: Boolean = true
) : Expression() { ) : Expression() {
override fun isEmpty() = name.length() == 0
private open fun ifNeedQuote(): String { override val isEmpty: Boolean
if (quotingNeeded && (ONLY_KOTLIN_KEYWORDS.contains(name)) || name.contains("$")) { get() = name.isEmpty()
override fun toKotlin(): String {
if (quotingNeeded && ONLY_KOTLIN_KEYWORDS.contains(name) || name.contains("$")) {
return quote(name) return quote(name)
} }
return name return name
} }
override fun toKotlin(): String = ifNeedQuote() private fun quote(str: String): String = "`" + str + "`"
override fun isNullable(): Boolean = myNullable
class object { class object {
val Empty = Identifier("") val Empty = Identifier("")
private open fun quote(str: String): String {
return "`" + str + "`"
}
val ONLY_KOTLIN_KEYWORDS: Set<String> = setOf( val ONLY_KOTLIN_KEYWORDS: Set<String> = setOf(
"package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This" "package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This"
); );
+3 -3
View File
@@ -42,9 +42,9 @@ class ImportList(val imports: List<Import>) : Element {
} }
} }
override fun isEmpty(): Boolean {
return filteredImports.isEmpty() override val isEmpty: Boolean
} get() = filteredImports.isEmpty()
override fun toKotlin() = filteredImports.toKotlin("\n") override fun toKotlin() = filteredImports.toKotlin("\n")
} }
@@ -27,11 +27,11 @@ class LocalVariable(
val converter: Converter val converter: Converter
) : Expression() { ) : Expression() {
fun isImmutable(): Boolean = val isImmutable: Boolean
converter.settings.forceLocalVariableImmutability || modifiersSet.contains(Modifier.FINAL) get() = converter.settings.forceLocalVariableImmutability || modifiersSet.contains(Modifier.FINAL)
override fun toKotlin(): String { override fun toKotlin(): String {
if (initializer.isEmpty()) { if (initializer.isEmpty) {
return "${identifier.toKotlin()} : ${javaType.toKotlin()}" return "${identifier.toKotlin()} : ${javaType.toKotlin()}"
} }
@@ -25,7 +25,9 @@ open class MethodCallExpression(
val typeParameters: List<Type>, val typeParameters: List<Type>,
val resultIsNullable: Boolean = false val resultIsNullable: Boolean = false
) : Expression() { ) : Expression() {
override fun isNullable(): Boolean = methodCall.isNullable() || resultIsNullable
override val isNullable: Boolean
get() = methodCall.isNullable || resultIsNullable
override fun toKotlin(): String { override fun toKotlin(): String {
val typeParamsToKotlin: String = typeParameters.toKotlin(", ", "<", ">") val typeParamsToKotlin: String = typeParameters.toKotlin(", ", "<", ">")
@@ -23,11 +23,11 @@ open class NewClassExpression(
val anonymousClass: AnonymousClass? = null val anonymousClass: AnonymousClass? = null
) : Expression() { ) : Expression() {
override fun toKotlin(): String { override fun toKotlin(): String {
val callOperator: String? = (if (qualifier.isNullable()) val callOperator: String? = (if (qualifier.isNullable)
"?." "?."
else else
".") ".")
val qualifier: String? = (if (qualifier.isEmpty()) val qualifier: String? = (if (qualifier.isEmpty)
"" ""
else else
qualifier.toKotlin() + callOperator) qualifier.toKotlin() + callOperator)
+21 -24
View File
@@ -20,22 +20,18 @@ package org.jetbrains.jet.j2k.ast
abstract class Statement() : Element { abstract class Statement() : Element {
object Empty : Statement() { object Empty : Statement() {
override fun toKotlin() = "" override fun toKotlin() = ""
override fun isEmpty() = true
override val isEmpty: Boolean
get() = true
} }
} }
open class DeclarationStatement(val elements: List<Element>) : Statement() { open class DeclarationStatement(val elements: List<Element>) : Statement() {
override fun toKotlin(): String { override fun toKotlin(): String
return elements.filter { it is LocalVariable }.map { convertDeclaration(it as LocalVariable) }.makeString("\n") = elements.filterIsInstance(javaClass<LocalVariable>()).map { convertDeclaration(it) }.makeString("\n")
}
private fun convertDeclaration(v: LocalVariable): String { private fun convertDeclaration(v: LocalVariable): String
val varKeyword: String? = (if (v.isImmutable()) = (if (v.isImmutable) "val" else "var") + " " + v.toKotlin()
"val"
else
"var")
return varKeyword + " " + v.toKotlin()
}
} }
open class ExpressionListStatement(val expressions: List<Expression>) : Expression() { open class ExpressionListStatement(val expressions: List<Expression>) : Expression() {
@@ -80,7 +76,7 @@ open class ForeachStatement(
val expression: Expression, val expression: Expression,
val body: Element val body: Element
) : Statement() { ) : Statement() {
override fun toKotlin() = "for (" + variable.identifier.name + " in " + override fun toKotlin() = "for (" + variable.identifier.toKotlin() + " in " +
expression.toKotlin() + ")\n" + body.toKotlin() expression.toKotlin() + ")\n" + body.toKotlin()
} }
@@ -104,10 +100,16 @@ open class ContinueStatement(val label: Identifier = Identifier.Empty) : Stateme
open class TryStatement(val block: Block, val catches: List<CatchStatement>, val finallyBlock: Block) : Statement() { open class TryStatement(val block: Block, val catches: List<CatchStatement>, val finallyBlock: Block) : Statement() {
override fun toKotlin(): String { override fun toKotlin(): String {
return "try\n" + block.toKotlin() + "\n" + catches.toKotlin("\n") + "\n" + (if (finallyBlock.isEmpty()) val builder = StringBuilder()
"" .append("try\n")
else .append(block.toKotlin())
"finally\n" + finallyBlock.toKotlin()) .append("\n")
.append(catches.toKotlin("\n"))
.append("\n")
if (!finallyBlock.isEmpty) {
builder.append("finally\n").append(finallyBlock.toKotlin())
}
return builder.toString()
} }
} }
@@ -126,14 +128,9 @@ open class SwitchContainer(val expression: Expression, val caseContainers: List<
} }
open class CaseContainer(val caseStatement: List<Element>, statements: List<Statement>) : Statement() { open class CaseContainer(val caseStatement: List<Element>, statements: List<Statement>) : Statement() {
private val myBlock: Block private val block = Block(statements.filterNot { it is BreakStatement || it is ContinueStatement }, true)
{ override fun toKotlin() = caseStatement.toKotlin(", ") + " -> " + block.toKotlin()
val newStatements = statements.filterNot { it is BreakStatement || it is ContinueStatement }
myBlock = Block(newStatements, true)
}
override fun toKotlin() = caseStatement.toKotlin(", ") + " -> " + myBlock.toKotlin()
} }
open class SwitchLabelStatement(val expression: Expression) : Statement() { open class SwitchLabelStatement(val expression: Expression) : Statement() {
@@ -152,5 +149,5 @@ open class SynchronizedStatement(val expression: Expression, val block: Block) :
class StatementList(elements: List<Element>) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NewLine) { class StatementList(elements: List<Element>) : WhiteSpaceSeparatedElementList(elements, WhiteSpace.NewLine) {
val statements: List<Statement> val statements: List<Statement>
get() = elements.filter { it is Statement }.map { it as Statement } get() = elements.filterIsInstance(javaClass<Statement>())
} }
@@ -56,7 +56,9 @@ class TypeParameterList(val parameters: List<TypeParameter>) : Element {
return "" return ""
} }
override fun isEmpty(): Boolean = parameters.isEmpty()
override val isEmpty: Boolean
get() = parameters.isEmpty()
private fun hasWhere(): Boolean = parameters.any { it.hasWhere() } private fun hasWhere(): Boolean = parameters.any { it.hasWhere() }
+12 -42
View File
@@ -18,60 +18,32 @@ package org.jetbrains.jet.j2k.ast
import java.util.ArrayList import java.util.ArrayList
fun List<Node>.toKotlin(separator: String, prefix: String = "", suffix: String = ""): String { fun List<Node>.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String
val result = StringBuilder() = if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else ""
if (size() > 0) {
result.append(prefix)
var first = true
for (x in this) {
if (!first) result.append(separator)
first = false
result.append(x.toKotlin())
}
result.append(suffix)
}
return result.toString()
}
fun Collection<Modifier>.toKotlin(separator: String = " "): String { fun Collection<Modifier>.toKotlin(separator: String = " "): String
val result = StringBuilder() = if (isNotEmpty()) map { it.name }.makeString(separator) + separator else ""
for (x in this) {
result.append(x.name)
result.append(separator)
}
return result.toString()
}
fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix
fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this
fun Expression.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + toKotlin() fun Expression.withPrefix(prefix: String): String = if (isEmpty) "" else prefix + toKotlin()
open class WhiteSpaceSeparatedElementList( open class WhiteSpaceSeparatedElementList(
val elements: List<Element>, val elements: List<Element>,
val minimalWhiteSpace: WhiteSpace, val minimalWhiteSpace: WhiteSpace,
val ensureSurroundedByWhiteSpace: Boolean = true val ensureSurroundedByWhiteSpace: Boolean = true
) { ) {
val nonEmptyElements = elements.filterNot { it.isEmpty() } val nonEmptyElements = elements.filter { !it.isEmpty }
fun isEmpty() = nonEmptyElements.all { it is WhiteSpace } fun isEmpty() = nonEmptyElements.all { it is WhiteSpace }
fun toKotlin(): String { fun toKotlin(): String {
if (isEmpty()) { if (isEmpty()) return ""
return ""
}
return nonEmptyElements.surroundWithWhiteSpaces().insertAndMergeWhiteSpaces().map { it.toKotlin() }.makeString("") return nonEmptyElements.surroundWithWhiteSpaces().insertAndMergeWhiteSpaces().map { it.toKotlin() }.makeString("")
} }
private fun List<Element>.surroundWithWhiteSpaces(): List<Element> { private fun List<Element>.surroundWithWhiteSpaces(): List<Element>
if (!ensureSurroundedByWhiteSpace) { = if (ensureSurroundedByWhiteSpace) listOf(minimalWhiteSpace) + this + listOf(minimalWhiteSpace) else this
return this
}
val result = ArrayList<Element>()
result.add(minimalWhiteSpace)
result.addAll(this)
result.add(minimalWhiteSpace)
return result
}
// ensure that there is whitespace between non-whitespace elements // ensure that there is whitespace between non-whitespace elements
@@ -80,22 +52,20 @@ open class WhiteSpaceSeparatedElementList(
private fun List<Element>.insertAndMergeWhiteSpaces(): List<Element> { private fun List<Element>.insertAndMergeWhiteSpaces(): List<Element> {
var currentWhiteSpace: WhiteSpace? = null var currentWhiteSpace: WhiteSpace? = null
val result = ArrayList<Element>() val result = ArrayList<Element>()
var isFirst = true for (i in 0..lastIndex) {
for (element in this) { val element = get(i)
if (element is WhiteSpace) { if (element is WhiteSpace) {
if (currentWhiteSpace == null || element > currentWhiteSpace!!) { if (currentWhiteSpace == null || element > currentWhiteSpace!!) {
currentWhiteSpace = if (element > minimalWhiteSpace) element else minimalWhiteSpace currentWhiteSpace = if (element > minimalWhiteSpace) element else minimalWhiteSpace
} }
} }
else { else {
if (!isFirst) { if (i != 0) { //do not insert whitespace before first element
//do not insert whitespace before first element
result.add(currentWhiteSpace ?: minimalWhiteSpace) result.add(currentWhiteSpace ?: minimalWhiteSpace)
} }
result.add(element) result.add(element)
currentWhiteSpace = null currentWhiteSpace = null
} }
isFirst = false
} }
if (currentWhiteSpace != null) { if (currentWhiteSpace != null) {
result.add(currentWhiteSpace!!) result.add(currentWhiteSpace!!)
@@ -19,16 +19,16 @@ package org.jetbrains.jet.j2k.ast
class WhiteSpace(val text: String) : Element { class WhiteSpace(val text: String) : Element {
override fun toKotlin() = text override fun toKotlin() = text
override fun isEmpty() = text.isEmpty()
override val isEmpty: Boolean
get() = text.isEmpty()
fun compareTo(other: WhiteSpace): Int { fun compareTo(other: WhiteSpace): Int {
fun newLinesCount(w: WhiteSpace) = w.text.count { it == '\n' } fun newLinesCount(w: WhiteSpace) = w.text.count { it == '\n' }
val lineCountDiff = newLinesCount(this) - newLinesCount(other) val lineCountDiff = newLinesCount(this) - newLinesCount(other)
if (lineCountDiff != 0) { if (lineCountDiff != 0) return lineCountDiff
return lineCountDiff
}
fun spacesCount(w: WhiteSpace) = w.text.count { it == ' ' } fun spacesCount(w: WhiteSpace) = w.text.count { it == ' ' }
@@ -23,11 +23,11 @@ fun Type.isPrimitive(): Boolean = this is PrimitiveType
fun Type.isUnit(): Boolean = this == UnitType fun Type.isUnit(): Boolean = this == UnitType
abstract class MayBeNullableType(nullable: Boolean, val converter: Converter) : Type { abstract class MayBeNullableType(nullable: Boolean, val converter: Converter) : Type {
override val nullable: Boolean = !converter.settings.forceNotNullTypes && nullable override val isNullable: Boolean = !converter.settings.forceNotNullTypes && nullable
} }
trait NotNullType : Type { trait NotNullType : Type {
override val nullable: Boolean override val isNullable: Boolean
get() = false get() = false
} }
@@ -36,15 +36,14 @@ object UnitType: NotNullType {
} }
trait Type : Element { trait Type : Element {
val isNullable: Boolean
val nullable: Boolean
open fun convertedToNotNull(): Type { open fun convertedToNotNull(): Type {
if (nullable) throw UnsupportedOperationException("convertedToNotNull must be defined") if (isNullable) throw UnsupportedOperationException("convertedToNotNull must be defined")
return this return this
} }
protected fun isNullableStr(): String? { protected fun isNullableStr(): String? {
return if (nullable) "?" else "" return if (isNullable) "?" else ""
} }
} }
@@ -21,16 +21,15 @@ import com.intellij.psi.PsiClass
import java.util.HashSet import java.util.HashSet
public open class ClassVisitor() : JavaRecursiveElementVisitor() { public open class ClassVisitor() : JavaRecursiveElementVisitor() {
private val myClassIdentifiers = HashSet<String>() private val _classIdentifiers = HashSet<String>()
public fun getClassIdentifiers(): Set<String> { public val classIdentifiers: Set<String>
return HashSet<String>(myClassIdentifiers) get() = _classIdentifiers
}
override fun visitClass(aClass: PsiClass?) { override fun visitClass(aClass: PsiClass) {
val qName = aClass?.getQualifiedName() val qName = aClass.getQualifiedName()
if (qName != null) { if (qName != null) {
myClassIdentifiers.add(qName) _classIdentifiers.add(qName)
} }
super.visitClass(aClass) super.visitClass(aClass)
} }
@@ -21,71 +21,61 @@ import org.jetbrains.jet.j2k.*
import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.ast.types.Type
open class ElementVisitor(val myConverter: Converter) : JavaElementVisitor() { class ElementVisitor(public val converter: Converter) : JavaElementVisitor() {
protected var myResult: Element = Element.Empty public var result: Element = Element.Empty
protected set
fun getConverter(): Converter { override fun visitLocalVariable(variable: PsiLocalVariable) {
return myConverter var kType = converter.convertType(variable.getType(), isAnnotatedAsNotNull(variable.getModifierList()))
} if (variable.hasModifierProperty(PsiModifier.FINAL) && isDefinitelyNotNull(variable.getInitializer())) {
open fun getResult(): Element {
return myResult
}
override fun visitLocalVariable(variable: PsiLocalVariable?) {
val theVariable = variable!!
var kType = myConverter.convertType(theVariable.getType(), isAnnotatedAsNotNull(theVariable.getModifierList()))
if (theVariable.hasModifierProperty(PsiModifier.FINAL) && isDefinitelyNotNull(theVariable.getInitializer())) {
kType = kType.convertedToNotNull(); kType = kType.convertedToNotNull();
} }
myResult = LocalVariable(Identifier(theVariable.getName()!!), result = LocalVariable(Identifier(variable.getName()!!),
myConverter.convertModifierList(theVariable.getModifierList()), converter.convertModifierList(variable.getModifierList()),
kType, kType,
myConverter.convertExpression(theVariable.getInitializer(), theVariable.getType()), converter.convertExpression(variable.getInitializer(), variable.getType()),
myConverter) converter)
} }
override fun visitExpressionList(list: PsiExpressionList?) { override fun visitExpressionList(list: PsiExpressionList) {
myResult = ExpressionList(myConverter.convertExpressions(list!!.getExpressions())) result = ExpressionList(converter.convertExpressions(list.getExpressions()))
} }
override fun visitReferenceElement(reference: PsiJavaCodeReferenceElement?) { override fun visitReferenceElement(reference: PsiJavaCodeReferenceElement) {
val theReference = reference!! val types = converter.convertTypes(reference.getTypeParameters())
val types: List<Type> = myConverter.convertTypes(theReference.getTypeParameters()) if (!reference.isQualified()) {
if (!theReference.isQualified()) { result = ReferenceElement(Identifier(reference.getReferenceName()!!), types)
myResult = ReferenceElement(Identifier(theReference.getReferenceName()!!), types)
} }
else { else {
var result: String = Identifier(reference.getReferenceName()!!).toKotlin() var code = Identifier(reference.getReferenceName()!!).toKotlin()
var qualifier: PsiElement? = theReference.getQualifier() var qualifier = reference.getQualifier()
while (qualifier != null) while (qualifier != null) {
{ val p = qualifier as PsiJavaCodeReferenceElement
val p: PsiJavaCodeReferenceElement = (qualifier as PsiJavaCodeReferenceElement) code = Identifier(p.getReferenceName()!!).toKotlin() + "." + code
result = Identifier(p.getReferenceName()!!).toKotlin() + "." + result
qualifier = p.getQualifier() qualifier = p.getQualifier()
} }
myResult = ReferenceElement(Identifier(result), types) result = ReferenceElement(Identifier(code), types)
} }
} }
override fun visitTypeElement(`type`: PsiTypeElement?) { override fun visitTypeElement(`type`: PsiTypeElement) {
myResult = TypeElement(myConverter.convertType(`type`!!.getType())) result = TypeElement(converter.convertType(`type`.getType()))
} }
override fun visitTypeParameter(classParameter: PsiTypeParameter?) { override fun visitTypeParameter(classParameter: PsiTypeParameter) {
myResult = TypeParameter(Identifier(classParameter!!.getName()!!), result = TypeParameter(Identifier(classParameter.getName()!!),
classParameter.getExtendsListTypes().map { myConverter.convertType(it) }) classParameter.getExtendsListTypes().map { converter.convertType(it) })
} }
override fun visitParameterList(list: PsiParameterList?) { override fun visitParameterList(list: PsiParameterList) {
myResult = ParameterList(myConverter.convertParameterList(list!!.getParameters()).requireNoNulls()) result = ParameterList(converter.convertParameterList(list.getParameters()))
} }
override fun visitComment(comment: PsiComment?) { override fun visitComment(comment: PsiComment) {
myResult = Comment(comment!!.getText()!!) result = Comment(comment.getText()!!)
} }
override fun visitWhiteSpace(space: PsiWhiteSpace?) { override fun visitWhiteSpace(space: PsiWhiteSpace) {
myResult = WhiteSpace(space!!.getText()!!) result = WhiteSpace(space.getText()!!)
} }
} }
@@ -19,43 +19,36 @@ package org.jetbrains.jet.j2k.visitors
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.lang.types.expressions.OperatorConventions import org.jetbrains.jet.lang.types.expressions.OperatorConventions
import java.util.ArrayList import java.util.ArrayList
import java.util.Collections
import com.intellij.psi.CommonClassNames.* import com.intellij.psi.CommonClassNames.*
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.types.lang.PrimitiveType import org.jetbrains.jet.lang.types.lang.PrimitiveType
import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.*
import org.jetbrains.jet.j2k.ast.types.ArrayType import org.jetbrains.jet.j2k.ast.types.ArrayType
open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter) { open class ExpressionVisitor(public val converter: Converter) : JavaElementVisitor() {
{ public var result: Expression = Expression.Empty
myResult = Expression.Empty protected set
}
override fun getResult(): Expression { override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression) {
return myResult as Expression
}
override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression?) {
val assignment = PsiTreeUtil.getParentOfType(expression, javaClass<PsiAssignmentExpression>()) val assignment = PsiTreeUtil.getParentOfType(expression, javaClass<PsiAssignmentExpression>())
val lvalue = assignment != null && expression == assignment.getLExpression(); val lvalue = assignment != null && expression == assignment.getLExpression();
myResult = ArrayAccessExpression(getConverter().convertExpression(expression?.getArrayExpression()), result = ArrayAccessExpression(converter.convertExpression(expression.getArrayExpression()),
getConverter().convertExpression(expression?.getIndexExpression()), converter.convertExpression(expression.getIndexExpression()),
lvalue) lvalue)
} }
override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression?) { override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression) {
val expressionType = getConverter().convertType(expression?.getType()) val expressionType = converter.convertType(expression.getType())
assert(expressionType is ArrayType) { "Array initializer must have array type" } assert(expressionType is ArrayType) { "Array initializer must have array type" }
myResult = ArrayInitializerExpression(expressionType as ArrayType, result = ArrayInitializerExpression(expressionType as ArrayType,
getConverter().convertExpressions(expression?.getInitializers()!!)) converter.convertExpressions(expression.getInitializers()))
} }
override fun visitAssignmentExpression(expression: PsiAssignmentExpression?) { override fun visitAssignmentExpression(expression: PsiAssignmentExpression) {
val tokenType: IElementType = expression?.getOperationSign()?.getTokenType()!! val tokenType = expression.getOperationSign().getTokenType()
val secondOp: String = when(tokenType) { val secondOp = when(tokenType) {
JavaTokenType.GTGTEQ -> "shr" JavaTokenType.GTGTEQ -> "shr"
JavaTokenType.LTLTEQ -> "shl" JavaTokenType.LTLTEQ -> "shl"
JavaTokenType.XOREQ -> "xor" JavaTokenType.XOREQ -> "xor"
@@ -65,61 +58,61 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter)
else -> "" else -> ""
} }
val lhs = getConverter().convertExpression(expression?.getLExpression()!!) val lhs = converter.convertExpression(expression.getLExpression())
val rhs = getConverter().convertExpression(expression?.getRExpression()!!, expression?.getLExpression()?.getType()) val rhs = converter.convertExpression(expression.getRExpression()!!, expression.getLExpression().getType())
if (!secondOp.isEmpty()) { if (!secondOp.isEmpty()) {
myResult = AssignmentExpression(lhs, BinaryExpression(lhs, rhs, secondOp), "=") result = AssignmentExpression(lhs, BinaryExpression(lhs, rhs, secondOp), "=")
} }
else { else {
myResult = AssignmentExpression(lhs, rhs, expression?.getOperationSign()?.getText()!!) result = AssignmentExpression(lhs, rhs, expression.getOperationSign().getText()!!)
} }
} }
override fun visitBinaryExpression(expression: PsiBinaryExpression?) { override fun visitBinaryExpression(expression: PsiBinaryExpression) {
val lhs = getConverter().convertExpression(expression?.getLOperand()!!, expression?.getType()) val lhs = converter.convertExpression(expression.getLOperand(), expression.getType())
val rhs = getConverter().convertExpression(expression?.getROperand(), expression?.getType()) val rhs = converter.convertExpression(expression.getROperand(), expression.getType())
if (expression?.getOperationSign()?.getTokenType() == JavaTokenType.GTGTGT) { if (expression.getOperationSign().getTokenType() == JavaTokenType.GTGTGT) {
myResult = MethodCallExpression.build(lhs, "ushr", listOf(rhs)) result = MethodCallExpression.build(lhs, "ushr", listOf(rhs))
} }
else { else {
myResult = BinaryExpression(lhs, rhs, result = BinaryExpression(lhs, rhs,
getOperatorString(expression?.getOperationSign()?.getTokenType()!!)) getOperatorString(expression.getOperationSign().getTokenType()))
} }
} }
override fun visitClassObjectAccessExpression(expression: PsiClassObjectAccessExpression?) { override fun visitClassObjectAccessExpression(expression: PsiClassObjectAccessExpression) {
myResult = ClassObjectAccessExpression(getConverter().convertTypeElement(expression?.getOperand())) result = ClassObjectAccessExpression(converter.convertTypeElement(expression.getOperand()))
} }
override fun visitConditionalExpression(expression: PsiConditionalExpression?) { override fun visitConditionalExpression(expression: PsiConditionalExpression) {
val condition: PsiExpression? = expression?.getCondition() val condition = expression.getCondition()
val `type`: PsiType? = condition?.getType() val `type` = condition.getType()
val e: Expression = (if (`type` != null) val e = if (`type` != null)
getConverter().convertExpression(condition, `type`) converter.convertExpression(condition, `type`)
else else
getConverter().convertExpression(condition)) converter.convertExpression(condition)
myResult = ParenthesizedExpression(IfStatement(e, result = ParenthesizedExpression(IfStatement(e,
getConverter().convertExpression(expression?.getThenExpression()), converter.convertExpression(expression.getThenExpression()),
getConverter().convertExpression(expression?.getElseExpression()))) converter.convertExpression(expression.getElseExpression())))
} }
override fun visitExpressionList(list: PsiExpressionList?) { override fun visitExpressionList(list: PsiExpressionList) {
myResult = ExpressionList(getConverter().convertExpressions(list!!.getExpressions())) result = ExpressionList(converter.convertExpressions(list.getExpressions()))
} }
override fun visitInstanceOfExpression(expression: PsiInstanceOfExpression?) { override fun visitInstanceOfExpression(expression: PsiInstanceOfExpression) {
val checkType: PsiTypeElement? = expression?.getCheckType() val checkType = expression.getCheckType()
myResult = IsOperator(getConverter().convertExpression(expression?.getOperand()), result = IsOperator(converter.convertExpression(expression.getOperand()),
myConverter.convertTypeElement(checkType)) converter.convertTypeElement(checkType))
} }
override fun visitLiteralExpression(expression: PsiLiteralExpression?) { override fun visitLiteralExpression(expression: PsiLiteralExpression) {
val value: Any? = expression?.getValue() val value = expression.getValue()
var text: String = expression?.getText()!! var text = expression.getText()!!
val `type`: PsiType? = expression?.getType() val `type` = expression.getType()
if (`type` != null) { if (`type` != null) {
val canonicalTypeStr: String? = `type`.getCanonicalText() val canonicalTypeStr = `type`.getCanonicalText()
if (canonicalTypeStr?.equals("double")!! || canonicalTypeStr?.equals(JAVA_LANG_DOUBLE)!!) { if (canonicalTypeStr == "double" || canonicalTypeStr == JAVA_LANG_DOUBLE) {
text = text.replace("D", "").replace("d", "") text = text.replace("D", "").replace("d", "")
if (!text.contains(".")) { if (!text.contains(".")) {
text += ".0" text += ".0"
@@ -127,124 +120,110 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter)
} }
if (canonicalTypeStr?.equals("float")!! || canonicalTypeStr?.equals(JAVA_LANG_FLOAT)!!) { if (canonicalTypeStr == "float" || canonicalTypeStr == JAVA_LANG_FLOAT) {
text = text.replace("F", "").replace("f", "") + "." + OperatorConventions.FLOAT + "()" text = text.replace("F", "").replace("f", "") + "." + OperatorConventions.FLOAT + "()"
} }
if (canonicalTypeStr?.equals("long")!! || canonicalTypeStr?.equals(JAVA_LANG_LONG)!!) { if (canonicalTypeStr == "long" || canonicalTypeStr == JAVA_LANG_LONG) {
text = text.replace("L", "").replace("l", "") text = text.replace("L", "").replace("l", "")
} }
if (canonicalTypeStr?.equals("int")!! || canonicalTypeStr?.equals(JAVA_LANG_INTEGER)!!) { if (canonicalTypeStr == "int" || canonicalTypeStr == JAVA_LANG_INTEGER) {
text = (if (value != null) value.toString() else text) text = if (value != null) value.toString() else text
} }
} }
myResult = LiteralExpression(text) result = LiteralExpression(text)
} }
override fun visitMethodCallExpression(expression: PsiMethodCallExpression?) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
convertMethodCallExpression(expression!!) convertMethodCallExpression(expression)
} }
protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) { protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) {
if (!SuperVisitor.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) { if (!isSuperConstructorRef(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) {
myResult = MethodCallExpression(getConverter().convertExpression(expression.getMethodExpression()), result = MethodCallExpression(converter.convertExpression(expression.getMethodExpression()),
getConverter().convertArguments(expression), converter.convertArguments(expression),
getConverter().convertTypes(expression.getTypeArguments()), converter.convertTypes(expression.getTypeArguments()),
getConverter().convertType(expression.getType()).nullable) converter.convertType(expression.getType()).isNullable)
} }
} }
override fun visitNewExpression(expression: PsiNewExpression?) { override fun visitNewExpression(expression: PsiNewExpression) {
if (expression?.getArrayInitializer() != null) if (expression.getArrayInitializer() != null) {
{ result = createNewEmptyArray(expression)
myResult = createNewEmptyArray(expression) }
else if (expression.getArrayDimensions().size > 0) {
result = createNewEmptyArrayWithoutInitialization(expression)
}
else {
result = createNewClassExpression(expression)
} }
else
if (expression?.getArrayDimensions()?.size!! > 0) {
myResult = createNewEmptyArrayWithoutInitialization(expression!!)
}
else
{
myResult = createNewClassExpression(expression)
}
} }
private fun createNewClassExpression(expression: PsiNewExpression?): Expression { private fun createNewClassExpression(expression: PsiNewExpression): Expression {
val anonymousClass: PsiAnonymousClass? = expression?.getAnonymousClass() val anonymousClass = expression.getAnonymousClass()
val constructor: PsiMethod? = expression?.resolveMethod() val constructor = expression.resolveMethod()
var classReference: PsiJavaCodeReferenceElement? = expression?.getClassOrAnonymousClassReference() val classReference = expression.getClassOrAnonymousClassReference()
val isNotConvertedClass: Boolean = classReference != null && !getConverter().getClassIdentifiers().contains(classReference?.getQualifiedName()) val isNotConvertedClass = classReference != null && !converter.getClassIdentifiers().contains(classReference.getQualifiedName())
var argumentList: PsiExpressionList? = expression?.getArgumentList() val argumentList = expression.getArgumentList()
var arguments: Array<PsiExpression> = (if (argumentList != null) var arguments = argumentList?.getExpressions() ?: array()
argumentList?.getExpressions()!! if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) {
else return NewClassExpression(converter.convertElement(classReference),
array<PsiExpression>()) converter.convertArguments(expression),
if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) converter.convertExpression(expression.getQualifier()),
{ if (anonymousClass != null) converter.convertAnonymousClass(anonymousClass) else null)
return NewClassExpression(getConverter().convertElement(classReference),
getConverter().convertArguments(expression!!),
getConverter().convertExpression(expression.getQualifier()),
(if (anonymousClass != null)
getConverter().convertAnonymousClass(anonymousClass)
else
null))
} }
val reference: PsiJavaCodeReferenceElement? = expression?.getClassReference() val reference = expression.getClassReference()
val typeParameters: List<Type> = (if (reference != null) val typeParameters = if (reference != null) converter.convertTypes(reference.getTypeParameters()) else listOf()
getConverter().convertTypes(reference.getTypeParameters())
else
Collections.emptyList<Type>())
return CallChainExpression(Identifier(constructor.getName(), false), return CallChainExpression(Identifier(constructor.getName(), false),
MethodCallExpression(Identifier("init"), getConverter().convertExpressions(arguments), typeParameters, false)) MethodCallExpression(Identifier("init"), converter.convertExpressions(arguments), typeParameters, false))
} }
private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression { private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression {
return ArrayWithoutInitializationExpression( return ArrayWithoutInitializationExpression(
getConverter().convertType(expression.getType(), true), converter.convertType(expression.getType(), true),
getConverter().convertExpressions(expression.getArrayDimensions())) converter.convertExpressions(expression.getArrayDimensions()))
} }
private fun createNewEmptyArray(expression: PsiNewExpression?): Expression { private fun createNewEmptyArray(expression: PsiNewExpression): Expression {
return getConverter().convertExpression(expression?.getArrayInitializer()) return converter.convertExpression(expression.getArrayInitializer())
} }
override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression?) { override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression) {
myResult = ParenthesizedExpression(getConverter().convertExpression(expression?.getExpression())) result = ParenthesizedExpression(converter.convertExpression(expression.getExpression()))
} }
override fun visitPostfixExpression(expression: PsiPostfixExpression?) { override fun visitPostfixExpression(expression: PsiPostfixExpression) {
myResult = PostfixOperator(getOperatorString(expression!!.getOperationSign().getTokenType()!!), result = PostfixOperator(getOperatorString(expression.getOperationSign().getTokenType()),
getConverter().convertExpression(expression.getOperand())) converter.convertExpression(expression.getOperand()))
} }
override fun visitPrefixExpression(expression: PsiPrefixExpression?) { override fun visitPrefixExpression(expression: PsiPrefixExpression) {
val operand = getConverter().convertExpression(expression?.getOperand(), expression?.getOperand()!!.getType()) val operand = converter.convertExpression(expression.getOperand(), expression.getOperand()!!.getType())
val token = expression?.getOperationTokenType()!! val token = expression.getOperationTokenType()
if (token == JavaTokenType.TILDE) { if (token == JavaTokenType.TILDE) {
myResult = MethodCallExpression.build(ParenthesizedExpression(operand), "inv", ArrayList()) result = MethodCallExpression.build(ParenthesizedExpression(operand), "inv", ArrayList())
} }
else { else {
myResult = PrefixOperator(getOperatorString(token), operand) result = PrefixOperator(getOperatorString(token), operand)
} }
} }
override fun visitReferenceExpression(expression: PsiReferenceExpression?) { override fun visitReferenceExpression(expression: PsiReferenceExpression) {
val isFieldReference: Boolean = isFieldReference(expression!!, getContainingClass(expression)) val isFieldReference = isFieldReference(expression, getContainingClass(expression))
val insideSecondaryConstructor: Boolean = isInsideSecondaryConstructor(expression) val insideSecondaryConstructor = isInsideSecondaryConstructor(expression)
val hasReceiver: Boolean = isFieldReference && insideSecondaryConstructor val hasReceiver = isFieldReference && insideSecondaryConstructor
val isThis: Boolean = isThisExpression(expression) val isThis = isThisExpression(expression)
val notNull = isResolvedToNotNull(expression) val notNull = isResolvedToNotNull(expression)
val isNullable: Boolean = getConverter().convertType(expression.getType(), notNull).nullable val isNullable = converter.convertType(expression.getType(), notNull).isNullable
val className: String = getClassNameWithConstructor(expression) val className = getClassNameWithConstructor(expression)
val referencedName = expression.getReferenceName()!! val referencedName = expression.getReferenceName()!!
var identifier: Expression = Identifier(referencedName, isNullable) var identifier: Expression = Identifier(referencedName, isNullable)
val __: String = "__"
val qualifier = expression.getQualifierExpression() val qualifier = expression.getQualifierExpression()
if (hasReceiver) { if (hasReceiver) {
identifier = CallChainExpression(Identifier(__, false), Identifier(referencedName, isNullable)) identifier = CallChainExpression(Identifier("__", false), Identifier(referencedName, isNullable))
} }
else if (insideSecondaryConstructor && isThis) { else if (insideSecondaryConstructor && isThis) {
identifier = Identifier("val __ = " + className) identifier = Identifier("val __ = " + className)
@@ -255,29 +234,29 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter)
else if (qualifier == null) { else if (qualifier == null) {
val resolved = expression.getReference()?.resolve() val resolved = expression.getReference()?.resolve()
if (resolved is PsiClass) { if (resolved is PsiClass) {
val clazz = resolved as PsiClass if (PrimitiveType.values() any { it.getTypeName().asString() == resolved.getName() }) {
result = Identifier(resolved.getQualifiedName()!!, false)
if (PrimitiveType.values() any { it.getTypeName().asString() == clazz.getName() }) {
myResult = Identifier(clazz.getQualifiedName()!!, false)
return return
} }
} }
if (resolved is PsiMember && resolved.hasModifierProperty(PsiModifier.STATIC) &&
resolved.getContainingClass() != null && if (resolved is PsiMember
PsiTreeUtil.getParentOfType(expression, javaClass<PsiClass>()) != resolved.getContainingClass() && && resolved.hasModifierProperty(PsiModifier.STATIC)
!isStaticallyImported(resolved, expression)) { && resolved.getContainingClass() != null
&& PsiTreeUtil.getParentOfType(expression, javaClass<PsiClass>()) != resolved.getContainingClass()
&& !isStaticallyImported(resolved, expression)) {
var member = resolved as PsiMember var member = resolved as PsiMember
var result = Identifier(referencedName).toKotlin() var code = Identifier(referencedName).toKotlin()
while (member.getContainingClass() != null) { while (member.getContainingClass() != null) {
result = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + result code = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + code
member = member.getContainingClass()!! member = member.getContainingClass()!!
} }
myResult = Identifier(result, false, false) result = Identifier(code, false, false)
return return
} }
} }
myResult = CallChainExpression(getConverter().convertExpression(qualifier), identifier) result = CallChainExpression(converter.convertExpression(qualifier), identifier)
} }
private fun isResolvedToNotNull(expression: PsiReference): Boolean { private fun isResolvedToNotNull(expression: PsiReference): Boolean {
@@ -291,238 +270,193 @@ open class ExpressionVisitor(converter: Converter) : StatementVisitor(converter)
return false; return false;
} }
override fun visitSuperExpression(expression: PsiSuperExpression?) { override fun visitSuperExpression(expression: PsiSuperExpression) {
val qualifier: PsiJavaCodeReferenceElement? = expression?.getQualifier() val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier()
myResult = SuperExpression((if (qualifier != null) result = SuperExpression((if (qualifier != null)
Identifier(qualifier.getQualifiedName()!!) Identifier(qualifier.getQualifiedName()!!)
else else
Identifier.Empty)) Identifier.Empty))
} }
override fun visitThisExpression(expression: PsiThisExpression?) { override fun visitThisExpression(expression: PsiThisExpression) {
val qualifier: PsiJavaCodeReferenceElement? = expression?.getQualifier() val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier()
myResult = ThisExpression((if (qualifier != null) result = ThisExpression((if (qualifier != null)
Identifier(qualifier.getQualifiedName()!!) Identifier(qualifier.getQualifiedName()!!)
else else
Identifier.Empty)) Identifier.Empty))
} }
override fun visitTypeCastExpression(expression: PsiTypeCastExpression?) { override fun visitTypeCastExpression(expression: PsiTypeCastExpression) {
val castType: PsiTypeElement? = expression?.getCastType() val castType: PsiTypeElement? = expression.getCastType()
if (castType != null) { if (castType != null) {
val operand = expression?.getOperand() val operand = expression.getOperand()
val operandType = operand?.getType() val operandType = operand?.getType()
val typeText = castType.getType().getCanonicalText() val typeText = castType.getType().getCanonicalText()
val typeConversion = PRIMITIVE_TYPE_CONVERSIONS[typeText] val typeConversion = PRIMITIVE_TYPE_CONVERSIONS[typeText]
if (operandType is PsiPrimitiveType && typeConversion != null) { if (operandType is PsiPrimitiveType && typeConversion != null) {
myResult = MethodCallExpression.build(getConverter().convertExpression(operand), typeConversion) result = MethodCallExpression.build(converter.convertExpression(operand), typeConversion)
} }
else { else {
myResult = TypeCastExpression(getConverter().convertType(castType.getType()), result = TypeCastExpression(converter.convertType(castType.getType()),
getConverter().convertExpression(operand)) converter.convertExpression(operand))
} }
} }
} }
override fun visitPolyadicExpression(expression: PsiPolyadicExpression?) { override fun visitPolyadicExpression(expression: PsiPolyadicExpression) {
var parameters = ArrayList<Expression>() var parameters = ArrayList<Expression>()
for (operand : PsiExpression in expression?.getOperands()!!) { for (operand : PsiExpression in expression.getOperands()) {
parameters.add(getConverter().convertExpression(operand, expression?.getType())) parameters.add(converter.convertExpression(operand, expression.getType()))
} }
myResult = PolyadicExpression(parameters, getOperatorString(expression?.getOperationTokenType()!!)) result = PolyadicExpression(parameters, getOperatorString(expression.getOperationTokenType()))
} }
class object { private fun getOperatorString(tokenType: IElementType): String {
private fun getOperatorString(tokenType: IElementType): String { return when(tokenType) {
if (tokenType == JavaTokenType.PLUS) JavaTokenType.EQEQ -> "=="
return "+" JavaTokenType.NE -> "!="
JavaTokenType.ANDAND -> "&&"
if (tokenType == JavaTokenType.MINUS) JavaTokenType.OROR -> "||"
return "-" JavaTokenType.GT -> ">"
JavaTokenType.LT -> "<"
if (tokenType == JavaTokenType.ASTERISK) JavaTokenType.GE -> ">="
return "*" JavaTokenType.LE -> "<="
JavaTokenType.EXCL -> "!"
if (tokenType == JavaTokenType.DIV) JavaTokenType.PLUS -> "+"
return "/" JavaTokenType.MINUS -> "-"
JavaTokenType.ASTERISK -> "*"
if (tokenType == JavaTokenType.PERC) JavaTokenType.DIV -> "/"
return "%" JavaTokenType.PERC -> "%"
JavaTokenType.GTGT -> "shr"
if (tokenType == JavaTokenType.GTGT) JavaTokenType.LTLT -> "shl"
return "shr" JavaTokenType.XOR -> "xor"
JavaTokenType.AND -> "and"
if (tokenType == JavaTokenType.LTLT) JavaTokenType.OR -> "or"
return "shl" JavaTokenType.GTGTGT -> "ushr"
JavaTokenType.PLUSPLUS -> "++"
if (tokenType == JavaTokenType.XOR) JavaTokenType.MINUSMINUS -> "--"
return "xor" else -> "" //System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType?.toString())
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 ""
} }
}
private fun getClassNameWithConstructor(expression: PsiReferenceExpression): String { private fun getClassNameWithConstructor(expression: PsiReferenceExpression): String {
var context: PsiElement? = expression.getContext() var context = expression.getContext()
while (context != null) { while (context != null) {
if (context is PsiMethod && ((context as PsiMethod)).isConstructor()) { val _context = context!!
val containingClass: PsiClass? = ((context as PsiMethod)).getContainingClass() if (_context is PsiMethod && _context.isConstructor()) {
if (containingClass != null) { val containingClass = _context.getContainingClass()
val identifier: PsiIdentifier? = containingClass.getNameIdentifier() if (containingClass != null) {
if (identifier != null) { val identifier = containingClass.getNameIdentifier()
return identifier.getText()!!
}
}
}
context = context?.getContext()
}
return ""
}
open fun getClassName(expression: PsiExpression): String {
var context: PsiElement? = expression.getContext()
while (context != null)
{
if ((context is PsiClass?)) {
val containingClass: PsiClass? = (context as PsiClass?)
val identifier: PsiIdentifier? = containingClass?.getNameIdentifier()
if (identifier != null) { if (identifier != null) {
return identifier.getText()!! return identifier.getText()!!
} }
} }
context = context?.getContext()
}
return ""
}
private fun isFieldReference(expression: PsiReferenceExpression, currentClass: PsiClass?): Boolean {
val reference: PsiReference? = expression.getReference()
if (reference != null) {
val resolvedReference: PsiElement? = reference.resolve()
if (resolvedReference is PsiField) {
return (resolvedReference as PsiField).getContainingClass() == currentClass
}
} }
return false context = _context.getContext()
} }
return ""
}
private fun isInsideSecondaryConstructor(expression: PsiReferenceExpression): Boolean { protected fun getClassName(expression: PsiExpression): String {
var context: PsiElement? = expression.getContext() var context = expression.getContext()
while (context != null) { while (context != null) {
if (context is PsiMethod && (context as PsiMethod).isConstructor()) { val _context = context!!
return !isConstructorPrimary((context as PsiMethod)) if (_context is PsiClass) {
val identifier = _context.getNameIdentifier()
if (identifier != null) {
return identifier.getText()!!
} }
context = context?.getContext()
} }
return false
context = _context.getContext()
} }
return ""
}
private fun isInsidePrimaryConstructor(expression: PsiExpression): Boolean { private fun isFieldReference(expression: PsiReferenceExpression, currentClass: PsiClass?): Boolean {
var context: PsiElement? = expression.getContext() val reference = expression.getReference()
while (context != null) { if (reference != null) {
if (context is PsiMethod && (context as PsiMethod).isConstructor()) { val target = reference.resolve()
return isConstructorPrimary(context as PsiMethod) if (target is PsiField) {
} return target.getContainingClass() == currentClass
context = context?.getContext()
} }
return false
} }
private fun getContainingClass(expression: PsiExpression): PsiClass? { return false
var context: PsiElement? = expression.getContext() }
while (context != null)
{
if (context is PsiMethod && (context as PsiMethod).isConstructor())
{
return (context as PsiMethod).getContainingClass()
}
context = context?.getContext() private fun isInsideSecondaryConstructor(expression: PsiReferenceExpression): Boolean {
var context = expression.getContext()
while (context != null) {
val _context = context!!
if (_context is PsiMethod && _context.isConstructor()) {
return !isConstructorPrimary(_context)
} }
return null
}
private fun isThisExpression(expression: PsiReferenceExpression): Boolean {
for (r : PsiReference? in expression.getReferences())
if (r?.getCanonicalText()?.equals("this")!!)
{
val res: PsiElement? = r?.resolve()
if (res is PsiMethod && res.isConstructor()) {
return true
}
context = _context.getContext()
}
return false
}
private fun isInsidePrimaryConstructor(expression: PsiExpression): Boolean {
var context = expression.getContext()
while (context != null) {
val _context = context!!
if (_context is PsiMethod && _context.isConstructor()) {
return isConstructorPrimary(_context)
}
context = _context.getContext()
}
return false
}
private fun getContainingClass(expression: PsiExpression): PsiClass? {
var context = expression.getContext()
while (context != null) {
val _context = context!!
if (_context is PsiMethod && _context.isConstructor()) {
return _context.getContainingClass()
}
context = _context.getContext()
}
return null
}
private fun isThisExpression(expression: PsiReferenceExpression): Boolean {
for (ref in expression.getReferences()) {
if (ref.getCanonicalText() == "this") {
val target = ref.resolve()
if (target is PsiMethod && target.isConstructor()) {
return true
} }
return false }
} }
return false
}
private fun isStaticallyImported(member: PsiMember, context: PsiElement): Boolean {
val containingFile = context.getContainingFile()
val targetContainingClass = member.getContainingClass()
if (containingFile is PsiJavaFile && targetContainingClass != null) {
val importList = containingFile.getImportList();
if (importList != null) {
return importList.getImportStaticStatements().any { importResolvesTo(it, member) }
}
}
return false
}
private fun importResolvesTo(importStatement: PsiImportStaticStatement, member: PsiMember): Boolean {
val targetContainingClass = member.getContainingClass()
val importedClass = importStatement.resolveTargetClass()
return importedClass == targetContainingClass
&& (importStatement.isOnDemand() || importStatement.getReferenceName() == member.getName())
} }
} }
private fun isStaticallyImported(member: PsiMember, context: PsiElement): Boolean {
val containingFile = context.getContainingFile()
val targetContainingClass = member.getContainingClass()
if (containingFile is PsiJavaFile && targetContainingClass != null) {
val importList = containingFile.getImportList();
if (importList != null) {
val importStatics = importList.getImportStaticStatements();
return importStatics.any { importResolvesTo(it, member) }
}
}
return false
}
private fun importResolvesTo(stmt: PsiImportStaticStatement?, member: PsiMember): Boolean {
val targetContainingClass = member.getContainingClass()
var importedClass = stmt?.resolveTargetClass()
return importedClass == targetContainingClass && (stmt?.isOnDemand() ?: false ||
stmt?.getReferenceName() == member.getName())
}
@@ -24,34 +24,30 @@ import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
import org.jetbrains.jet.j2k.ast.MethodCallExpression import org.jetbrains.jet.j2k.ast.MethodCallExpression
open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : ExpressionVisitor(converter) { open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : ExpressionVisitor(converter) {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression?) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
val methodExpression = expression?.getMethodExpression()!! val methodExpression = expression.getMethodExpression()
if (superMethodInvocation(methodExpression, "hashCode")) { if (superMethodInvocation(methodExpression, "hashCode")) {
myResult = MethodCallExpression.build(Identifier("System", false), "identityHashCode", listOf(Identifier("this"))) result = MethodCallExpression.build(Identifier("System", false), "identityHashCode", listOf(Identifier("this")))
} }
else if (superMethodInvocation(methodExpression, "equals")) { else if (superMethodInvocation(methodExpression, "equals")) {
myResult = MethodCallExpression.build(Identifier("this", false), "identityEquals", getConverter().convertArguments(expression!!)) result = MethodCallExpression.build(Identifier("this", false), "identityEquals", converter.convertArguments(expression))
} }
else if (superMethodInvocation(methodExpression, "toString")) { else if (superMethodInvocation(methodExpression, "toString")) {
myResult = DummyStringExpression(java.lang.String.format("getJavaClass<%s>.getName() + '@' + Integer.toHexString(hashCode())", result = DummyStringExpression("getJavaClass<${getClassName(methodExpression)}>.getName() + '@' + Integer.toHexString(hashCode())")
ExpressionVisitor.getClassName(methodExpression)))
} }
else { else {
convertMethodCallExpression(expression!!) convertMethodCallExpression(expression)
} }
} }
class object { private fun superMethodInvocation(expression: PsiReferenceExpression, methodName: String?): Boolean {
private fun superMethodInvocation(expression: PsiReferenceExpression, methodName: String?): Boolean { val referenceName: String? = expression.getReferenceName()
val referenceName: String? = expression.getReferenceName() val qualifierExpression: PsiExpression? = expression.getQualifierExpression()
val qualifierExpression: PsiExpression? = expression.getQualifierExpression() if (referenceName == methodName && qualifierExpression is PsiSuperExpression) {
if (referenceName == methodName && qualifierExpression is PsiSuperExpression) { if (qualifierExpression.getType()?.getCanonicalText() == JAVA_LANG_OBJECT) {
val `type`: PsiType? = qualifierExpression.getType() return true
if (`type` != null && `type`.getCanonicalText() == JAVA_LANG_OBJECT) {
return true
}
} }
return false
} }
return false
} }
} }
@@ -19,157 +19,154 @@ package org.jetbrains.jet.j2k.visitors
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.countWritingAccesses import org.jetbrains.jet.j2k.countWriteAccesses
import java.util.ArrayList import java.util.ArrayList
open class StatementVisitor(converter: Converter) : ElementVisitor(converter) { class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
override fun visitAssertStatement(statement: PsiAssertStatement?) { public var result: Statement = Statement.Empty
myResult = AssertStatement(getConverter().convertExpression(statement?.getAssertCondition()), private set
getConverter().convertExpression(statement?.getAssertDescription()))
override fun visitAssertStatement(statement: PsiAssertStatement) {
result = AssertStatement(converter.convertExpression(statement.getAssertCondition()),
converter.convertExpression(statement.getAssertDescription()))
} }
override fun visitBlockStatement(statement: PsiBlockStatement?) { override fun visitBlockStatement(statement: PsiBlockStatement) {
myResult = getConverter().convertBlock(statement?.getCodeBlock(), true) result = converter.convertBlock(statement.getCodeBlock(), true)
} }
override fun visitBreakStatement(statement: PsiBreakStatement?) { override fun visitBreakStatement(statement: PsiBreakStatement) {
if (statement?.getLabelIdentifier() == null) { if (statement.getLabelIdentifier() == null) {
myResult = BreakStatement(Identifier.Empty) result = BreakStatement(Identifier.Empty)
} }
else else {
{ result = BreakStatement(converter.convertIdentifier(statement.getLabelIdentifier()))
myResult = BreakStatement(getConverter().convertIdentifier(statement?.getLabelIdentifier()))
} }
} }
override fun visitContinueStatement(statement: PsiContinueStatement?) { override fun visitContinueStatement(statement: PsiContinueStatement) {
if (statement?.getLabelIdentifier() == null) if (statement.getLabelIdentifier() == null) {
{ result = ContinueStatement(Identifier.Empty)
myResult = ContinueStatement(Identifier.Empty)
} }
else else {
{ result = ContinueStatement(converter.convertIdentifier(statement.getLabelIdentifier()))
myResult = ContinueStatement(getConverter().convertIdentifier(statement?.getLabelIdentifier()))
} }
} }
override fun visitDeclarationStatement(statement: PsiDeclarationStatement?) { override fun visitDeclarationStatement(statement: PsiDeclarationStatement) {
myResult = DeclarationStatement(getConverter().convertElements(statement?.getDeclaredElements()!!)) result = DeclarationStatement(converter.convertElements(statement.getDeclaredElements()))
} }
override fun visitDoWhileStatement(statement: PsiDoWhileStatement?) { override fun visitDoWhileStatement(statement: PsiDoWhileStatement) {
val condition: PsiExpression? = statement?.getCondition() val condition = statement.getCondition()
val expression: Expression = (if (condition != null && condition.getType() != null) val expression = if (condition != null && condition.getType() != null)
getConverter().convertExpression(condition, condition.getType()) converter.convertExpression(condition, condition.getType())
else else
getConverter().convertExpression(condition)) converter.convertExpression(condition)
myResult = DoWhileStatement(expression, getConverter().convertStatement(statement?.getBody())) result = DoWhileStatement(expression, converter.convertStatement(statement.getBody()))
} }
override fun visitExpressionStatement(statement: PsiExpressionStatement?) { override fun visitExpressionStatement(statement: PsiExpressionStatement) {
myResult = getConverter().convertExpression(statement?.getExpression()) result = converter.convertExpression(statement.getExpression())
} }
override fun visitExpressionListStatement(statement: PsiExpressionListStatement?) { override fun visitExpressionListStatement(statement: PsiExpressionListStatement) {
myResult = ExpressionListStatement(getConverter().convertExpressions( result = ExpressionListStatement(converter.convertExpressions(statement.getExpressionList().getExpressions()))
statement?.getExpressionList()?.getExpressions()!!))
} }
override fun visitForStatement(statement: PsiForStatement?) { override fun visitForStatement(statement: PsiForStatement) {
val initialization = statement?.getInitialization() val initialization = statement.getInitialization()
val update = statement?.getUpdate() val update = statement.getUpdate()
val condition = statement?.getCondition() val condition = statement.getCondition()
val body = statement?.getBody() val body = statement.getBody()
val firstChild = (if (initialization != null && (initialization.getFirstChild() is PsiLocalVariable)) val firstChildLocalVar = initialization?.getFirstChild() as? PsiLocalVariable
(initialization.getFirstChild() as PsiLocalVariable) var bodyWriteCount = countWriteAccesses(firstChildLocalVar, body)
else var conditionWriteCount = countWriteAccesses(firstChildLocalVar, condition)
null) var updateWriteCount = countWriteAccesses(firstChildLocalVar, update)
var bodyWriteCount = countWritingAccesses(firstChild, body)
var conditionWriteCount = countWritingAccesses(firstChild, condition)
var updateWriteCount = countWritingAccesses(firstChild, update)
val onceWritableIterator = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0 val onceWritableIterator = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0
val operationTokenType = (if (condition is PsiBinaryExpression) val operationTokenType = (condition as? PsiBinaryExpression)?.getOperationTokenType()
condition.getOperationTokenType() if (initialization is PsiDeclarationStatement
else && initialization.getFirstChild() == initialization.getLastChild()
null) && condition != null
if (initialization is PsiDeclarationStatement && initialization.getFirstChild() == initialization.getLastChild() && && update != null
condition != null && update != null && update.getChildren().size == 1 && && update.getChildren().size == 1
(isPlusPlusExpression(update.getChildren()[0])) && (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE) && && isPlusPlusExpression(update.getChildren().single())
initialization.getFirstChild() != null && (initialization.getFirstChild() is PsiLocalVariable) && && (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
firstChild != null && firstChild.getNameIdentifier() != null && onceWritableIterator) { && firstChildLocalVar != null
val end = getConverter().convertExpression((condition as PsiBinaryExpression).getROperand()) && firstChildLocalVar.getNameIdentifier() != null
val endExpression = (if (operationTokenType == JavaTokenType.LT) && onceWritableIterator) {
val end = converter.convertExpression((condition as PsiBinaryExpression).getROperand())
val endExpression = if (operationTokenType == JavaTokenType.LT)
BinaryExpression(end, Identifier("1"), "-") BinaryExpression(end, Identifier("1"), "-")
else else
end) end
myResult = ForeachWithRangeStatement(Identifier(firstChild.getName()!!), result = ForeachWithRangeStatement(Identifier(firstChildLocalVar.getName()!!),
getConverter().convertExpression(firstChild.getInitializer()), converter.convertExpression(firstChildLocalVar.getInitializer()),
endExpression, endExpression,
getConverter().convertStatement(body)) converter.convertStatement(body))
} }
else { else {
var forStatements = ArrayList<Statement>() var forStatements = ArrayList<Statement>()
forStatements.add(getConverter().convertStatement(initialization)) forStatements.add(converter.convertStatement(initialization))
val bodyAndUpdate = listOf(getConverter().convertStatement(body), val bodyAndUpdate = listOf(converter.convertStatement(body),
Block(listOf(getConverter().convertStatement(update)))) Block(listOf(converter.convertStatement(update))))
forStatements.add(WhileStatement( forStatements.add(WhileStatement(
if (condition == null) if (condition == null)
LiteralExpression("true") LiteralExpression("true")
else else
getConverter().convertExpression(condition), converter.convertExpression(condition),
Block(bodyAndUpdate))) Block(bodyAndUpdate)))
myResult = Block(forStatements) result = Block(forStatements)
} }
} }
override fun visitForeachStatement(statement: PsiForeachStatement?) { override fun visitForeachStatement(statement: PsiForeachStatement) {
val iterator = { val iterator = run {
val iteratorExpr = getConverter().convertExpression(statement?.getIteratedValue()) val iteratorExpr = converter.convertExpression(statement.getIteratedValue())
if (iteratorExpr.isNullable()) if (iteratorExpr.isNullable)
BangBangExpression(iteratorExpr) BangBangExpression(iteratorExpr)
else else
iteratorExpr iteratorExpr
}() }
myResult = ForeachStatement(getConverter().convertParameter(statement?.getIterationParameter()!!), result = ForeachStatement(converter.convertParameter(statement.getIterationParameter()),
iterator, iterator,
getConverter().convertStatement(statement?.getBody())) converter.convertStatement(statement.getBody()))
} }
override fun visitIfStatement(statement: PsiIfStatement?) { override fun visitIfStatement(statement: PsiIfStatement) {
val condition: PsiExpression? = statement?.getCondition() val condition = statement.getCondition()
val expression: Expression = getConverter().convertExpression(condition, PsiType.BOOLEAN) val expression = converter.convertExpression(condition, PsiType.BOOLEAN)
myResult = IfStatement(expression, result = IfStatement(expression,
getConverter().convertStatement(statement?.getThenBranch()), converter.convertStatement(statement.getThenBranch()),
getConverter().convertStatement(statement?.getElseBranch())) converter.convertStatement(statement.getElseBranch()))
} }
override fun visitLabeledStatement(statement: PsiLabeledStatement?) { override fun visitLabeledStatement(statement: PsiLabeledStatement) {
myResult = LabelStatement(getConverter().convertIdentifier(statement?.getLabelIdentifier()), result = LabelStatement(converter.convertIdentifier(statement.getLabelIdentifier()),
getConverter().convertStatement(statement?.getStatement())) converter.convertStatement(statement.getStatement()))
} }
override fun visitSwitchLabelStatement(statement: PsiSwitchLabelStatement?) { override fun visitSwitchLabelStatement(statement: PsiSwitchLabelStatement) {
myResult = (if (statement?.isDefaultCase()!!) result = if (statement.isDefaultCase())
DefaultSwitchLabelStatement() DefaultSwitchLabelStatement()
else else
SwitchLabelStatement(getConverter().convertExpression(statement?.getCaseValue()))) SwitchLabelStatement(converter.convertExpression(statement.getCaseValue()))
} }
override fun visitSwitchStatement(statement: PsiSwitchStatement?) { override fun visitSwitchStatement(statement: PsiSwitchStatement) {
myResult = SwitchContainer(getConverter().convertExpression(statement?.getExpression()), result = SwitchContainer(converter.convertExpression(statement.getExpression()),
switchBodyToCases(statement?.getBody())) switchBodyToCases(statement.getBody()))
} }
private open fun switchBodyToCases(body: PsiCodeBlock?): List<CaseContainer> { private fun switchBodyToCases(body: PsiCodeBlock?): List<CaseContainer> {
val cases: List<List<PsiElement>> = splitToCases(body) val cases: List<List<PsiElement>> = splitToCases(body)
val allSwitchStatements = ArrayList<PsiElement>() val allSwitchStatements = ArrayList<PsiElement>()
if (body != null) { if (body != null) {
// TODO Arrays.asList() allSwitchStatements.addAll(body.getStatements())
for (s in body.getStatements()) allSwitchStatements.add(s)
} }
val result = ArrayList<CaseContainer>() val result = ArrayList<CaseContainer>()
var pendingLabels = ArrayList<Element>() var pendingLabels = ArrayList<Element>()
var i: Int = 0 var i = 0
var hasDefaultCase: Boolean = false var hasDefaultCase: Boolean = false
for (ls in cases) { for (ls in cases) {
// TODO assert {(ls?.size()).sure() > 0} // TODO assert {(ls?.size()).sure() > 0}
@@ -179,21 +176,21 @@ open class StatementVisitor(converter: Converter) : ElementVisitor(converter) {
// TODO assert {(label is PsiSwitchLabelStatement?)} // TODO assert {(label is PsiSwitchLabelStatement?)}
// TODO assert("not a right index") {allSwitchStatements?.get(i) == label} // TODO assert("not a right index") {allSwitchStatements?.get(i) == label}
if (ls.size() > 1) { if (ls.size() > 1) {
pendingLabels.add(getConverter().convertStatement(label)) pendingLabels.add(converter.convertStatement(label))
val slice: List<PsiElement> = ls.subList(1, (ls.size())) val slice: List<PsiElement> = ls.subList(1, (ls.size()))
if (!containsBreak(slice)) { if (!containsBreak(slice)) {
val statements = ArrayList(getConverter().convertStatements(slice).statements) val statements = ArrayList(converter.convertStatements(slice).statements)
statements.addAll(getConverter().convertStatements(getAllToNextBreak(allSwitchStatements, i + ls.size())).statements) statements.addAll(converter.convertStatements(getAllToNextBreak(allSwitchStatements, i + ls.size())).statements)
result.add(CaseContainer(pendingLabels, statements)) result.add(CaseContainer(pendingLabels, statements))
pendingLabels = ArrayList() pendingLabels = ArrayList()
} }
else { else {
result.add(CaseContainer(pendingLabels, getConverter().convertStatements(slice).statements)) result.add(CaseContainer(pendingLabels, converter.convertStatements(slice).statements))
pendingLabels = ArrayList() pendingLabels = ArrayList()
} }
} }
else { else {
pendingLabels.add(getConverter().convertStatement(label)) pendingLabels.add(converter.convertStatement(label))
} }
i += ls.size() i += ls.size()
} }
@@ -203,97 +200,95 @@ open class StatementVisitor(converter: Converter) : ElementVisitor(converter) {
return result return result
} }
override fun visitSynchronizedStatement(statement: PsiSynchronizedStatement?) { override fun visitSynchronizedStatement(statement: PsiSynchronizedStatement) {
myResult = SynchronizedStatement(getConverter().convertExpression(statement?.getLockExpression()), result = SynchronizedStatement(converter.convertExpression(statement.getLockExpression()),
getConverter().convertBlock(statement?.getBody())) converter.convertBlock(statement.getBody()))
} }
override fun visitThrowStatement(statement: PsiThrowStatement?) { override fun visitThrowStatement(statement: PsiThrowStatement) {
myResult = ThrowStatement(getConverter().convertExpression(statement?.getException())) result = ThrowStatement(converter.convertExpression(statement.getException()))
} }
override fun visitTryStatement(statement: PsiTryStatement?) { override fun visitTryStatement(statement: PsiTryStatement) {
val catches = ArrayList<CatchStatement>() val catches = ArrayList<CatchStatement>()
val catchBlocks = statement?.getCatchBlocks()!! val catchBlocks = statement.getCatchBlocks()
val catchBlockParameters = statement?.getCatchBlockParameters()!! val catchBlockParameters = statement.getCatchBlockParameters()
for (i in 0..catchBlocks.size - 1) { for (i in 0..catchBlocks.size - 1) {
catches.add(CatchStatement(getConverter().convertParameter(catchBlockParameters[i], true), catches.add(CatchStatement(converter.convertParameter(catchBlockParameters[i], true),
getConverter().convertBlock(catchBlocks[i], true))) converter.convertBlock(catchBlocks[i], true)))
} }
myResult = TryStatement(getConverter().convertBlock(statement?.getTryBlock(), true), result = TryStatement(converter.convertBlock(statement.getTryBlock(), true),
catches, getConverter().convertBlock(statement?.getFinallyBlock(), true)) catches, converter.convertBlock(statement.getFinallyBlock(), true))
} }
override fun visitWhileStatement(statement: PsiWhileStatement?) { override fun visitWhileStatement(statement: PsiWhileStatement) {
var condition: PsiExpression? = statement?.getCondition() var condition: PsiExpression? = statement.getCondition()
val expression: Expression = (if (condition != null && condition?.getType() != null) val expression: Expression = (if (condition != null && condition?.getType() != null)
this.getConverter().convertExpression(condition, condition?.getType()) this.converter.convertExpression(condition, condition?.getType())
else else
getConverter().convertExpression(condition)) converter.convertExpression(condition))
myResult = WhileStatement(expression, getConverter().convertStatement(statement?.getBody())) result = WhileStatement(expression, converter.convertStatement(statement.getBody()))
} }
override fun visitReturnStatement(statement: PsiReturnStatement?) { override fun visitReturnStatement(statement: PsiReturnStatement) {
val returnValue: PsiExpression? = statement?.getReturnValue() val returnValue = statement.getReturnValue()
val methodReturnType: PsiType? = getConverter().methodReturnType val methodReturnType = converter.methodReturnType
val expression: Expression = (if (returnValue != null && methodReturnType != null) val expression = (if (returnValue != null && methodReturnType != null)
this.getConverter().convertExpression(returnValue, methodReturnType) this.converter.convertExpression(returnValue, methodReturnType)
else else
getConverter().convertExpression(returnValue)) converter.convertExpression(returnValue))
myResult = ReturnStatement(expression) result = ReturnStatement(expression)
} }
class object { override fun visitEmptyStatement(statement: PsiEmptyStatement) {
private open fun isPlusPlusExpression(psiElement: PsiElement): Boolean { result = Statement.Empty
return (psiElement is PsiPostfixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) || }
(psiElement is PsiPrefixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS)
}
private fun containsBreak(slice: List<PsiElement?>) = slice.any { it is PsiBreakStatement } private fun isPlusPlusExpression(psiElement: PsiElement): Boolean {
return (psiElement is PsiPostfixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) ||
(psiElement is PsiPrefixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS)
}
private open fun getAllToNextBreak(allStatements: List<PsiElement>, start: Int): List<PsiElement> { private fun containsBreak(slice: List<PsiElement?>) = slice.any { it is PsiBreakStatement }
val result = ArrayList<PsiElement>()
for (i in start..allStatements.size() - 1) {
val s = allStatements.get(i)
if (s is PsiBreakStatement || s is PsiReturnStatement) {
return result
}
if (!(s is PsiSwitchLabelStatement)) {
result.add(s)
}
private fun getAllToNextBreak(allStatements: List<PsiElement>, start: Int): List<PsiElement> {
val result = ArrayList<PsiElement>()
for (i in start..allStatements.size() - 1) {
val s = allStatements[i]
if (s is PsiBreakStatement || s is PsiReturnStatement) {
return result
} }
return result
}
private open fun splitToCases(body: PsiCodeBlock?): List<List<PsiElement>> { if (s !is PsiSwitchLabelStatement) {
val cases = ArrayList<List<PsiElement>>() result.add(s)
var currentCaseStatements = ArrayList<PsiElement>() }
var isFirst: Boolean = true
if (body != null) { }
for (s in body.getChildren()) { return result
if (s !is PsiStatement && s !is PsiComment) continue }
if (s is PsiSwitchLabelStatement) {
if (isFirst) { private fun splitToCases(body: PsiCodeBlock?): List<List<PsiElement>> {
isFirst = false val cases = ArrayList<List<PsiElement>>()
} var currentCaseStatements = ArrayList<PsiElement>()
else { if (body != null) {
cases.add(currentCaseStatements) var isFirst = true
currentCaseStatements = ArrayList() for (s in body.getChildren()) {
} if (s !is PsiStatement && s !is PsiComment) continue
if (s is PsiSwitchLabelStatement) {
if (isFirst) {
isFirst = false
}
else {
cases.add(currentCaseStatements)
currentCaseStatements = ArrayList()
} }
currentCaseStatements.add(s)
} }
cases.add(currentCaseStatements)
currentCaseStatements.add(s)
} }
cases.add(currentCaseStatements)
return cases
} }
}
override fun visitEmptyStatement(statement: PsiEmptyStatement?) { return cases
myResult = Statement.Empty
} }
} }
@@ -18,25 +18,17 @@ package org.jetbrains.jet.j2k.visitors
import com.intellij.psi.* import com.intellij.psi.*
import java.util.HashSet import java.util.HashSet
import org.jetbrains.jet.j2k.isSuperConstructorRef
open class SuperVisitor() : JavaRecursiveElementVisitor() { class SuperVisitor() : JavaRecursiveElementVisitor() {
val resolvedSuperCallParameters: HashSet<PsiExpressionList> = HashSet() private val _resolvedSuperCallParameters = HashSet<PsiExpressionList>()
override fun visitMethodCallExpression(expression: PsiMethodCallExpression?) { public val resolvedSuperCallParameters: Set<PsiExpressionList>
if (expression != null && isSuper(expression.getMethodExpression())) { get() = _resolvedSuperCallParameters
resolvedSuperCallParameters.add(expression.getArgumentList())
}
}
class object {
open fun isSuper(r: PsiReference): Boolean {
if (r.getCanonicalText().equals("super")) {
val baseConstructor: PsiElement? = r.resolve()
if (baseConstructor != null && baseConstructor is PsiMethod && baseConstructor.isConstructor()) {
return true
}
}
return false override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
if (isSuperConstructorRef(expression.getMethodExpression())) {
_resolvedSuperCallParameters.add(expression.getArgumentList())
} }
} }
} }
@@ -28,75 +28,55 @@ import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType
private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getName() } private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getName() }
open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor<Type>() { open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor<Type>() {
private var myResult: Type = EmptyType() override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type {
open fun getResult(): Type { val name = primitiveType.getCanonicalText()
return myResult return if (name == "void") {
} UnitType
override fun visitPrimitiveType(primitiveType: PsiPrimitiveType?): Type {
val name: String = primitiveType?.getCanonicalText()!!
if (name == "void") {
myResult = UnitType
} }
else if (PRIMITIVE_TYPES_NAMES.contains(name)) { else if (PRIMITIVE_TYPES_NAMES.contains(name)) {
myResult = PrimitiveType(Identifier(StringUtil.capitalize(name))) PrimitiveType(Identifier(StringUtil.capitalize(name)))
} }
else { else {
myResult = PrimitiveType(Identifier(name)) PrimitiveType(Identifier(name))
} }
return myResult
} }
override fun visitArrayType(arrayType: PsiArrayType?): Type { override fun visitArrayType(arrayType: PsiArrayType): Type {
if (myResult is EmptyType) { return ArrayType(converter.convertType(arrayType.getComponentType()), true, converter)
myResult = ArrayType(myConverter.convertType(arrayType?.getComponentType()), true, myConverter)
}
return myResult
} }
override fun visitClassType(classType: PsiClassType?): Type { override fun visitClassType(classType: PsiClassType): Type {
if (classType == null) return myResult val identifier = constructClassTypeIdentifier(classType)
val identifier: Identifier = constructClassTypeIdentifier(classType) val resolvedClassTypeParams = createRawTypesForResolvedReference(classType)
val resolvedClassTypeParams: List<Type> = createRawTypesForResolvedReference(classType)
if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) { if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) {
val starParamList: ArrayList<Type> = ArrayList<Type>() val starParamList = ArrayList<Type>()
if (resolvedClassTypeParams.size() == 1) { if (resolvedClassTypeParams.size() == 1) {
if ((resolvedClassTypeParams.get(0) as ClassType).`type`.name == "Any") { if ((resolvedClassTypeParams.single() as ClassType).`type`.name == "Any") {
starParamList.add(StarProjectionType()) starParamList.add(StarProjectionType())
myResult = ClassType(identifier, starParamList, true, myConverter) return ClassType(identifier, starParamList, true, converter)
} }
else { else {
myResult = ClassType(identifier, resolvedClassTypeParams, true, myConverter) return ClassType(identifier, resolvedClassTypeParams, true, converter)
} }
} }
else { else {
myResult = ClassType(identifier, resolvedClassTypeParams, true, myConverter) return ClassType(identifier, resolvedClassTypeParams, true, converter)
} }
} }
else { else {
myResult = ClassType(identifier, myConverter.convertTypes(classType.getParameters()), true, myConverter) return ClassType(identifier, converter.convertTypes(classType.getParameters()), true, converter)
} }
return myResult
} }
private fun constructClassTypeIdentifier(classType: PsiClassType): Identifier { private fun constructClassTypeIdentifier(classType: PsiClassType): Identifier {
val psiClass: PsiClass? = classType.resolve() val psiClass = classType.resolve()
if (psiClass != null) { if (psiClass != null) {
val qualifiedName: String? = psiClass.getQualifiedName() val qualifiedName = psiClass.getQualifiedName()
if (qualifiedName != null) { when(qualifiedName) {
if (qualifiedName.equals(CommonClassNames.JAVA_LANG_ITERABLE)) { CommonClassNames.JAVA_LANG_ITERABLE -> return Identifier(CommonClassNames.JAVA_LANG_ITERABLE)
return Identifier(CommonClassNames.JAVA_LANG_ITERABLE) CommonClassNames.JAVA_UTIL_ITERATOR -> return Identifier(CommonClassNames.JAVA_UTIL_ITERATOR)
} CommonClassNames.JAVA_UTIL_LIST -> return Identifier("MutableList")
if (qualifiedName.equals(CommonClassNames.JAVA_UTIL_ITERATOR)) {
return Identifier(CommonClassNames.JAVA_UTIL_ITERATOR)
}
if (qualifiedName.equals(CommonClassNames.JAVA_UTIL_LIST)) {
return Identifier("MutableList")
}
} }
} }
@@ -111,17 +91,18 @@ open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor<Type
private fun createRawTypesForResolvedReference(classType: PsiClassType): List<Type> { private fun createRawTypesForResolvedReference(classType: PsiClassType): List<Type> {
val typeParams = LinkedList<Type>() val typeParams = LinkedList<Type>()
if (classType is PsiClassReferenceType) { if (classType is PsiClassReferenceType) {
val reference: PsiJavaCodeReferenceElement? = (classType as PsiClassReferenceType).getReference() val reference = classType.getReference()
val resolve: PsiElement? = reference?.resolve() val resolve = reference.resolve()
if (resolve is PsiClass) { if (resolve is PsiClass) {
for (p : PsiTypeParameter? in (resolve as PsiClass).getTypeParameters()) { for (typeParam in resolve.getTypeParameters()) {
val superTypes = p!!.getSuperTypes() val superTypes = typeParam.getSuperTypes()
val boundType: Type = (if (superTypes.size > 0) val boundType = if (superTypes.size > 0)
ClassType(Identifier(getClassTypeName(superTypes[0])), ClassType(Identifier(getClassTypeName(superTypes[0])),
myConverter.convertTypes(superTypes[0].getParameters()), converter.convertTypes(superTypes[0].getParameters()),
true, myConverter) true,
converter)
else else
StarProjectionType()) StarProjectionType()
typeParams.add(boundType) typeParams.add(boundType)
} }
} }
@@ -130,64 +111,50 @@ open class TypeVisitor(private val myConverter: Converter) : PsiTypeVisitor<Type
return typeParams return typeParams
} }
override fun visitWildcardType(wildcardType: PsiWildcardType?): Type { override fun visitWildcardType(wildcardType: PsiWildcardType): Type {
if (wildcardType!!.isExtends()) { return when {
myResult = OutProjectionType(myConverter.convertType(wildcardType.getExtendsBound())) wildcardType.isExtends() -> OutProjectionType(converter.convertType(wildcardType.getExtendsBound()))
wildcardType.isSuper() -> InProjectionType(converter.convertType(wildcardType.getSuperBound()))
else -> StarProjectionType()
} }
else
if (wildcardType.isSuper()) {
myResult = InProjectionType(myConverter.convertType(wildcardType.getSuperBound()))
}
else {
myResult = StarProjectionType()
}
return myResult
} }
override fun visitEllipsisType(ellipsisType: PsiEllipsisType?): Type { override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type {
myResult = VarArg(myConverter.convertType(ellipsisType?.getComponentType())) return VarArg(converter.convertType(ellipsisType.getComponentType()))
return myResult
} }
class object { private fun createQualifiedName(classType: PsiClassType): String {
private fun createQualifiedName(classType: PsiClassType): String { if (classType is PsiClassReferenceType) {
if (classType is PsiClassReferenceType) val reference = classType.getReference()
{ if (reference.isQualified()) {
val reference: PsiJavaCodeReferenceElement? = (classType as PsiClassReferenceType).getReference() var result = Identifier(reference.getReferenceName()!!).toKotlin()
if (reference != null && reference.isQualified()) { var qualifier = reference.getQualifier()
var result: String = Identifier(reference.getReferenceName()!!).toKotlin() while (qualifier != null) {
var qualifier: PsiElement? = reference.getQualifier() val codeRefElement = qualifier as PsiJavaCodeReferenceElement
while (qualifier != null) result = Identifier(codeRefElement.getReferenceName()!!).toKotlin() + "." + result
{ qualifier = codeRefElement.getQualifier()
val p: PsiJavaCodeReferenceElement = (qualifier as PsiJavaCodeReferenceElement)
result = Identifier(p.getReferenceName()!!).toKotlin() + "." + result
qualifier = p.getQualifier()
}
return result
} }
return result
} }
return ""
} }
private fun getClassTypeName(classType: PsiClassType): String { return ""
var canonicalTypeStr: String? = classType.getCanonicalText() }
return when(canonicalTypeStr) {
CommonClassNames.JAVA_LANG_OBJECT -> "Any"
CommonClassNames.JAVA_LANG_BYTE -> "Byte"
CommonClassNames.JAVA_LANG_CHARACTER -> "Char"
CommonClassNames.JAVA_LANG_DOUBLE -> "Double"
CommonClassNames.JAVA_LANG_FLOAT -> "Float"
CommonClassNames.JAVA_LANG_INTEGER -> "Int"
CommonClassNames.JAVA_LANG_LONG -> "Long"
CommonClassNames.JAVA_LANG_SHORT -> "Short"
CommonClassNames.JAVA_LANG_BOOLEAN -> "Boolean"
else -> (if (classType.getClassName() != null) private fun getClassTypeName(classType: PsiClassType): String {
classType.getClassName()!! var canonicalTypeStr: String? = classType.getCanonicalText()
else return when(canonicalTypeStr) {
classType.getCanonicalText())!! CommonClassNames.JAVA_LANG_OBJECT -> "Any"
} CommonClassNames.JAVA_LANG_BYTE -> "Byte"
CommonClassNames.JAVA_LANG_CHARACTER -> "Char"
CommonClassNames.JAVA_LANG_DOUBLE -> "Double"
CommonClassNames.JAVA_LANG_FLOAT -> "Float"
CommonClassNames.JAVA_LANG_INTEGER -> "Int"
CommonClassNames.JAVA_LANG_LONG -> "Long"
CommonClassNames.JAVA_LANG_SHORT -> "Short"
CommonClassNames.JAVA_LANG_BOOLEAN -> "Boolean"
else -> classType.getClassName() ?: classType.getCanonicalText()
} }
} }
} }