ConverterUtil to namespace-level functions in Converter.kt

This commit is contained in:
Dmitry Jemerov
2012-06-01 17:03:06 +02:00
committed by Pavel V. Talanov
parent a59d15c090
commit 055cad793c
4 changed files with 123 additions and 140 deletions
+121 -6
View File
@@ -14,10 +14,11 @@ import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.j2k.visitors.*
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
import java.util.*
import org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses
import org.jetbrains.jet.j2k.ConverterUtil.createMainFunction
import com.intellij.psi.CommonClassNames.*
import org.jetbrains.jet.lang.types.expressions.OperatorConventions.*
import com.intellij.openapi.util.Pair
import java.text.MessageFormat
import com.intellij.psi.util.PsiUtil
public open class Converter() {
private var classIdentifiers: Set<String> = hashSet()
@@ -244,7 +245,7 @@ public open class Converter() {
}
methodReturnType = method.getReturnType()
val identifier: Identifier = Identifier(method.getName())
val returnType: Type = typeToType(method.getReturnType(), ConverterUtil.isAnnotatedAsNotNull(method.getModifierList()))
val returnType: Type = typeToType(method.getReturnType(), isAnnotatedAsNotNull(method.getModifierList()))
val body: Block = (if (hasFlag(J2KConverterFlags.SKIP_BODIES))
Block.EMPTY_BLOCK
else
@@ -281,8 +282,8 @@ public open class Converter() {
for (parameter : PsiParameter? in method.getParameterList().getParameters()) {
result.add(Parameter(Identifier(parameter?.getName()!!),
typeToType(parameter?.getType(),
ConverterUtil.isAnnotatedAsNotNull(parameter?.getModifierList())),
ConverterUtil.isReadOnly(parameter, method.getBody())))
isAnnotatedAsNotNull(parameter?.getModifierList())),
isReadOnly(parameter, method.getBody())))
}
return ParameterList(result)
}
@@ -413,7 +414,7 @@ public open class Converter() {
public open fun parameterToParameter(parameter: PsiParameter): Parameter {
return Parameter(Identifier(parameter.getName()!!),
typeToType(parameter.getType(),
ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList())), true)
isAnnotatedAsNotNull(parameter.getModifierList())), true)
}
public open fun argumentsToExpressionList(expression: PsiCallExpression): List<Expression> {
@@ -712,3 +713,117 @@ public open class Converter() {
}
}
}
public open fun createMainFunction(file: PsiFile): String {
val classNamesWithMains: List<Pair<String?, PsiMethod?>?> = arrayList()
for (c : PsiClass? in (file as PsiJavaFile).getClasses()) {
var main: PsiMethod? = findMainMethod(c)
if (main != null) {
classNamesWithMains.add(Pair<String?, PsiMethod?>(c?.getName(), main))
}
}
if (classNamesWithMains.size() > 0) {
var className: String? = classNamesWithMains.get(0)?.getFirst()
return MessageFormat.format("fun main(args : Array<String?>?) = {0}.main(args)", className)!!
}
return ""
}
private fun findMainMethod(aClass: PsiClass?): PsiMethod? {
if (isMainClass(aClass)) {
val mainMethods: Array<PsiMethod?>? = aClass?.findMethodsByName("main", false)
if (mainMethods != null) {
return findMainMethod(mainMethods)
}
}
return null
}
private fun isMainClass(psiClass: PsiClass?): Boolean {
if (psiClass == null || psiClass is PsiAnonymousClass)
return false
if (psiClass.isInterface())
return false
return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC)
}
private fun findMainMethod(mainMethods: Array<PsiMethod?>): PsiMethod? {
return mainMethods.find { isMainMethod(it) }
}
public open fun isMainMethod(method: PsiMethod?): Boolean {
if (method == null || method.getContainingClass() == null)
return false
if (PsiType.VOID != method.getReturnType())
return false
if (!method.hasModifierProperty(PsiModifier.STATIC))
return false
if (!method.hasModifierProperty(PsiModifier.PUBLIC))
return false
val parameters: Array<PsiParameter?>? = method.getParameterList().getParameters()
if (parameters?.size!! != 1)
return false
val `type`: PsiType? = parameters!![0]?.getType()
if (`type` !is PsiArrayType)
return false
val componentType: PsiType? = `type`.getComponentType()
return componentType?.equalsToText("java.lang.String")!!
}
public open fun countWritingAccesses(element: PsiElement?, container: PsiElement?): Int {
var counter: Int = 0
if (container != null) {
val visitor: ReferenceCollector = ReferenceCollector()
container.accept(visitor)
for (e : PsiReferenceExpression? in visitor.getCollectedReferences())
if (e?.isReferenceTo(element)!! && PsiUtil.isAccessedForWriting(e)) {
counter++
}
}
return counter
}
open class ReferenceCollector(): JavaRecursiveElementVisitor() {
private val myCollectedReferences: List<PsiReferenceExpression> = arrayList()
public open fun getCollectedReferences(): List<PsiReferenceExpression> {
return myCollectedReferences
}
public override fun visitReferenceExpression(expression: PsiReferenceExpression?): Unit {
super.visitReferenceExpression(expression)
if (expression != null) {
myCollectedReferences.add(expression)
}
}
}
public open fun isReadOnly(element: PsiElement?, container: PsiElement?): Boolean {
return countWritingAccesses(element, container) == 0
}
public open 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 && Converter.NOT_NULL_ANNOTATIONS.contains(qualifiedName)) {
return true
}
}
}
return false
}
@@ -1,132 +0,0 @@
/*
* Copyright 2010-2012 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 com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.MessageFormat;
import java.util.LinkedList;
import java.util.List;
/**
* @author ignatov
*/
public class ConverterUtil {
private ConverterUtil() {
}
@NotNull
public static String createMainFunction(@NotNull PsiFile file) {
List<Pair<String, PsiMethod>> classNamesWithMains = new LinkedList<Pair<String, PsiMethod>>();
for (PsiClass c : ((PsiJavaFile) file).getClasses()) {
PsiMethod main = findMainMethod(c);
if (main != null) {
classNamesWithMains.add(new Pair<String, PsiMethod>(c.getName(), main));
}
}
if (classNamesWithMains.size() > 0) {
String className = classNamesWithMains.get(0).getFirst();
return MessageFormat.format("fun main(args : Array<String?>?) = {0}.main(args)", className);
}
return "";
}
@Nullable
private static PsiMethod findMainMethod(@NotNull PsiClass aClass) {
if (isMainClass(aClass)) {
final PsiMethod[] mainMethods = aClass.findMethodsByName("main", false);
return findMainMethod(mainMethods);
}
return null;
}
@Nullable
private static PsiMethod findMainMethod(@NotNull PsiMethod[] mainMethods) {
for (PsiMethod mainMethod : mainMethods) {
if (isMainMethod(mainMethod)) return mainMethod;
}
return null;
}
private static boolean isMainClass(@NotNull PsiClass psiClass) {
if (psiClass instanceof PsiAnonymousClass) return false;
if (psiClass.isInterface()) return false;
return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC);
}
public static boolean isMainMethod(@Nullable PsiMethod method) {
if (method == null || method.getContainingClass() == null) return false;
if (PsiType.VOID != method.getReturnType()) return false;
if (!method.hasModifierProperty(PsiModifier.STATIC)) return false;
if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return false;
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) return false;
final PsiType type = parameters[0].getType();
if (!(type instanceof PsiArrayType)) return false;
final PsiType componentType = ((PsiArrayType) type).getComponentType();
return componentType.equalsToText("java.lang.String");
}
public static int countWritingAccesses(@Nullable PsiElement element, @Nullable PsiElement container) {
int counter = 0;
if (container != null) {
ReferenceCollector visitor = new ReferenceCollector();
container.accept(visitor);
for (PsiReferenceExpression e : visitor.getCollectedReferences())
if (e.isReferenceTo(element) && PsiUtil.isAccessedForWriting(e)) {
counter++;
}
}
return counter;
}
public static boolean isReadOnly(PsiElement element, PsiElement container) {
return countWritingAccesses(element, container) == 0;
}
public static boolean isAnnotatedAsNotNull(@Nullable PsiModifierList modifierList) {
if (modifierList != null) {
PsiAnnotation[] annotations = modifierList.getAnnotations();
for (PsiAnnotation a : annotations) {
String qualifiedName = a.getQualifiedName();
if (qualifiedName != null && Converter.$classobj.NOT_NULL_ANNOTATIONS.contains(qualifiedName)) {
return true;
}
}
}
return false;
}
static class ReferenceCollector extends JavaRecursiveElementVisitor {
public List<PsiReferenceExpression> getCollectedReferences() {
return myCollectedReferences;
}
private List<PsiReferenceExpression> myCollectedReferences = new LinkedList<PsiReferenceExpression>();
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression);
myCollectedReferences.add(expression);
}
}
}
@@ -5,7 +5,7 @@ import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.ast.types.Type
import java.util.List
import org.jetbrains.jet.j2k.ConverterUtil.isAnnotatedAsNotNull
import org.jetbrains.jet.j2k.isAnnotatedAsNotNull
public open class ElementVisitor(val myConverter : Converter) : JavaElementVisitor() {
protected var myResult : Element = Element.EMPTY_ELEMENT
@@ -9,7 +9,7 @@ import java.util.Arrays
import java.util.Collections
import java.util.LinkedList
import java.util.List
import org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses
import org.jetbrains.jet.j2k.countWritingAccesses
public open class StatementVisitor(converter: Converter): ElementVisitor(converter) {
public override fun visitAssertStatement(statement: PsiAssertStatement?): Unit {