converted to kotlin; doesn't compile yet because of errors in frontend
This commit is contained in:
committed by
Pavel V. Talanov
parent
c9499da055
commit
b17effd3a3
@@ -351,7 +351,7 @@ public open class Converter() {
|
||||
return typeVisitor.getResult()
|
||||
}
|
||||
|
||||
public open fun typesToTypeList(types: Array<PsiType?>): List<Type?> {
|
||||
public open fun typesToTypeList(types: Array<PsiType?>): List<Type> {
|
||||
return types.map { typeToType(it) }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,59 +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.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.j2k.util.AstUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class NewClassExpression extends Expression {
|
||||
private final Element myName;
|
||||
private final List<Expression> myArguments;
|
||||
private Expression myQualifier;
|
||||
@Nullable
|
||||
private AnonymousClass myAnonymousClass = null;
|
||||
|
||||
private NewClassExpression(Element name, List<Expression> arguments) {
|
||||
myName = name;
|
||||
myQualifier = EMPTY_EXPRESSION;
|
||||
myArguments = arguments;
|
||||
}
|
||||
|
||||
public NewClassExpression(@NotNull Element name, @NotNull List<Expression> arguments, @NotNull Expression qualifier,
|
||||
@Nullable AnonymousClass anonymousClass) {
|
||||
this(name, arguments);
|
||||
myQualifier = qualifier;
|
||||
myAnonymousClass = anonymousClass;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toKotlin() {
|
||||
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
|
||||
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
|
||||
String appliedArguments = AstUtil.joinNodes(myArguments, COMMA_WITH_SPACE);
|
||||
return myAnonymousClass != null ?
|
||||
"object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin()
|
||||
:
|
||||
qualifier + myName.toKotlin() + "(" + appliedArguments + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.jetbrains.jet.j2k.ast
|
||||
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.jetbrains.jet.j2k.util.AstUtil
|
||||
import java.util.List
|
||||
|
||||
public open class NewClassExpression(val name: Element,
|
||||
val arguments: List<Expression>,
|
||||
val qualifier: Expression = Expression.EMPTY_EXPRESSION,
|
||||
val anonymousClass: AnonymousClass? = null): Expression() {
|
||||
public override fun toKotlin(): String {
|
||||
val callOperator: String? = (if (qualifier.isNullable().sure())
|
||||
"?."
|
||||
else
|
||||
".")
|
||||
val qualifier: String? = (if (qualifier.isEmpty().sure())
|
||||
""
|
||||
else
|
||||
qualifier.toKotlin() + callOperator)
|
||||
val appliedArguments: String = arguments.toKotlin(", ")
|
||||
return (if (anonymousClass != null)
|
||||
"object : " + qualifier + name.toKotlin() + "(" + appliedArguments + ")" + anonymousClass.toKotlin()
|
||||
else
|
||||
qualifier + name.toKotlin() + "(" + appliedArguments + ")")
|
||||
}
|
||||
}
|
||||
@@ -115,3 +115,9 @@ public open class SwitchLabelStatement(val expression: Expression): Statement()
|
||||
public open class DefaultSwitchLabelStatement(): Statement() {
|
||||
public override fun toKotlin() = "else"
|
||||
}
|
||||
|
||||
// Other ------------------------------------------------------------------------------------------------------
|
||||
|
||||
public open class SynchronizedStatement(val expression: Expression, val block: Block): Statement() {
|
||||
public override fun toKotlin() = "synchronized (" + expression?.toKotlin() + ") "+ block.toKotlin()
|
||||
}
|
||||
|
||||
@@ -1,38 +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.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class SynchronizedStatement extends Statement {
|
||||
private final Expression myExpression;
|
||||
private final Block myBlock;
|
||||
|
||||
public SynchronizedStatement(Expression expression, Block block) {
|
||||
myExpression = expression;
|
||||
myBlock = block;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String toKotlin() {
|
||||
return "synchronized" + SPACE + "(" + myExpression.toKotlin() + ")" + SPACE + myBlock.toKotlin();
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public open class ElementVisitor(val myConverter : Converter) : JavaElementVisit
|
||||
|
||||
public override fun visitReferenceElement(reference : PsiJavaCodeReferenceElement?) : Unit {
|
||||
val theReference = reference!!
|
||||
val types : List<Type> = myConverter.typesToTypeList(theReference.getTypeParameters()).requireNoNulls()
|
||||
val types : List<Type> = myConverter.typesToTypeList(theReference.getTypeParameters())
|
||||
if (!theReference.isQualified()) {
|
||||
myResult = ReferenceElement(Identifier(theReference.getReferenceName()), types)
|
||||
}
|
||||
|
||||
@@ -1,508 +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.visitors;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.j2k.Converter;
|
||||
import org.jetbrains.jet.j2k.ast.*;
|
||||
import org.jetbrains.jet.j2k.ast.types.EmptyType;
|
||||
import org.jetbrains.jet.j2k.ast.types.Type;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.psi.CommonClassNames.*;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class ExpressionVisitor extends StatementVisitor {
|
||||
@NotNull
|
||||
Expression myResult = Expression.EMPTY_EXPRESSION;
|
||||
|
||||
public ExpressionVisitor(@NotNull Converter converter) {
|
||||
super(converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(final PsiExpression expression) {
|
||||
myResult = Expression.EMPTY_EXPRESSION;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Expression getResult() {
|
||||
return myResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArrayAccessExpression(@NotNull PsiArrayAccessExpression expression) {
|
||||
super.visitArrayAccessExpression(expression);
|
||||
myResult = new ArrayAccessExpression(
|
||||
getConverter().expressionToExpression(expression.getArrayExpression()),
|
||||
getConverter().expressionToExpression(expression.getIndexExpression())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(@NotNull PsiArrayInitializerExpression expression) {
|
||||
super.visitArrayInitializerExpression(expression);
|
||||
myResult = new ArrayInitializerExpression(
|
||||
getConverter().typeToType(expression.getType()),
|
||||
getConverter().expressionsToExpressionList(expression.getInitializers())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(@NotNull PsiAssignmentExpression expression) {
|
||||
super.visitAssignmentExpression(expression);
|
||||
|
||||
// TODO: simplify
|
||||
|
||||
final IElementType tokenType = expression.getOperationSign().getTokenType();
|
||||
|
||||
String secondOp = "";
|
||||
if (tokenType == JavaTokenType.GTGTEQ) secondOp = "shr";
|
||||
if (tokenType == JavaTokenType.LTLTEQ) secondOp = "shl";
|
||||
if (tokenType == JavaTokenType.XOREQ) secondOp = "xor";
|
||||
if (tokenType == JavaTokenType.ANDEQ) secondOp = "and";
|
||||
if (tokenType == JavaTokenType.OREQ) secondOp = "or";
|
||||
if (tokenType == JavaTokenType.GTGTGTEQ) secondOp = "ushr";
|
||||
|
||||
if (!secondOp.isEmpty()) // if not Kotlin operators
|
||||
{
|
||||
myResult = new AssignmentExpression(
|
||||
getConverter().expressionToExpression(expression.getLExpression()),
|
||||
new BinaryExpression(
|
||||
getConverter().expressionToExpression(expression.getLExpression()),
|
||||
getConverter().expressionToExpression(expression.getRExpression()),
|
||||
secondOp
|
||||
),
|
||||
"="
|
||||
);
|
||||
}
|
||||
else {
|
||||
myResult = new AssignmentExpression(
|
||||
getConverter().expressionToExpression(expression.getLExpression()),
|
||||
getConverter().expressionToExpression(expression.getRExpression()),
|
||||
expression.getOperationSign().getText() // TODO
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getOperatorString(@NotNull IElementType tokenType) {
|
||||
if (tokenType == JavaTokenType.PLUS) return "+";
|
||||
if (tokenType == JavaTokenType.MINUS) return "-";
|
||||
if (tokenType == JavaTokenType.ASTERISK) return "*";
|
||||
if (tokenType == JavaTokenType.DIV) return "/";
|
||||
if (tokenType == JavaTokenType.PERC) return "%";
|
||||
if (tokenType == JavaTokenType.GTGT) return "shr";
|
||||
if (tokenType == JavaTokenType.LTLT) return "shl";
|
||||
if (tokenType == JavaTokenType.XOR) return "xor";
|
||||
if (tokenType == JavaTokenType.AND) return "and";
|
||||
if (tokenType == JavaTokenType.OR) return "or";
|
||||
if (tokenType == JavaTokenType.GTGTGT) return "ushr";
|
||||
if (tokenType == JavaTokenType.GT) return ">";
|
||||
if (tokenType == JavaTokenType.LT) return "<";
|
||||
if (tokenType == JavaTokenType.GE) return ">=";
|
||||
if (tokenType == JavaTokenType.LE) return "<=";
|
||||
if (tokenType == JavaTokenType.EQEQ) return "==";
|
||||
if (tokenType == JavaTokenType.NE) return "!=";
|
||||
if (tokenType == JavaTokenType.ANDAND) return "&&";
|
||||
if (tokenType == JavaTokenType.OROR) return "||";
|
||||
if (tokenType == JavaTokenType.PLUSPLUS) return "++";
|
||||
if (tokenType == JavaTokenType.MINUSMINUS) return "--";
|
||||
if (tokenType == JavaTokenType.EXCL) return "!";
|
||||
|
||||
System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType.toString());
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBinaryExpression(@NotNull PsiBinaryExpression expression) {
|
||||
super.visitBinaryExpression(expression);
|
||||
|
||||
if (expression.getOperationSign().getTokenType() == JavaTokenType.GTGTGT) {
|
||||
myResult = new DummyMethodCallExpression(
|
||||
getConverter().expressionToExpression(expression.getLOperand()),
|
||||
"ushr",
|
||||
getConverter().expressionToExpression(expression.getROperand()));
|
||||
}
|
||||
else {
|
||||
myResult =
|
||||
new BinaryExpression(
|
||||
getConverter().expressionToExpression(expression.getLOperand(), expression.getType()),
|
||||
getConverter().expressionToExpression(expression.getROperand(), expression.getType()),
|
||||
getOperatorString(expression.getOperationSign().getTokenType())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassObjectAccessExpression(@NotNull PsiClassObjectAccessExpression expression) {
|
||||
super.visitClassObjectAccessExpression(expression);
|
||||
myResult = new ClassObjectAccessExpression(getConverter().elementToElement(expression.getOperand()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConditionalExpression(@NotNull PsiConditionalExpression expression) {
|
||||
super.visitConditionalExpression(expression);
|
||||
PsiExpression condition = expression.getCondition();
|
||||
PsiType type = condition.getType();
|
||||
Expression e = type != null ?
|
||||
this.getConverter().expressionToExpression(condition, type) :
|
||||
getConverter().expressionToExpression(condition);
|
||||
myResult = new ParenthesizedExpression(
|
||||
new IfStatement(
|
||||
e,
|
||||
getConverter().expressionToExpression(expression.getThenExpression()),
|
||||
getConverter().expressionToExpression(expression.getElseExpression())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpressionList(@NotNull PsiExpressionList list) {
|
||||
super.visitExpressionList(list);
|
||||
myResult = new ExpressionList(getConverter().expressionsToExpressionList(list.getExpressions()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInstanceOfExpression(@NotNull PsiInstanceOfExpression expression) {
|
||||
super.visitInstanceOfExpression(expression);
|
||||
PsiTypeElement checkType = expression.getCheckType();
|
||||
myResult = new IsOperator(
|
||||
getConverter().expressionToExpression(expression.getOperand()),
|
||||
new TypeElement(checkType == null ? new EmptyType() : myConverter.typeToType(checkType.getType())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLiteralExpression(@NotNull PsiLiteralExpression expression) {
|
||||
super.visitLiteralExpression(expression);
|
||||
|
||||
final Object value = expression.getValue();
|
||||
String text = expression.getText();
|
||||
boolean isQuotingNeeded = true;
|
||||
|
||||
final PsiType type = expression.getType();
|
||||
if (type != null) {
|
||||
String canonicalTypeStr = type.getCanonicalText();
|
||||
if (canonicalTypeStr.equals("double") || canonicalTypeStr.equals(JAVA_LANG_DOUBLE)) {
|
||||
text = text.replace("D", "").replace("d", "");
|
||||
if (!text.contains(".")) {
|
||||
text += ".0";
|
||||
}
|
||||
}
|
||||
if (canonicalTypeStr.equals("float") || canonicalTypeStr.equals(JAVA_LANG_FLOAT)) {
|
||||
text = text.replace("F", "").replace("f", "") + "." + OperatorConventions.FLOAT + "()";
|
||||
}
|
||||
if (canonicalTypeStr.equals("long") || canonicalTypeStr.equals(JAVA_LANG_LONG)) {
|
||||
text = text.replace("L", "").replace("l", "");
|
||||
}
|
||||
if (canonicalTypeStr.equals("int") || canonicalTypeStr.equals(JAVA_LANG_INTEGER)) // need for hex support
|
||||
{
|
||||
text = value != null ? value.toString() : text;
|
||||
}
|
||||
|
||||
if (canonicalTypeStr.equals(JAVA_LANG_STRING)) {
|
||||
isQuotingNeeded = false;
|
||||
}
|
||||
if (canonicalTypeStr.equals("char") || canonicalTypeStr.equals(JAVA_LANG_CHARACTER)) {
|
||||
isQuotingNeeded = false;
|
||||
}
|
||||
}
|
||||
myResult = new LiteralExpression(new Identifier(text, false, isQuotingNeeded));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
|
||||
super.visitMethodCallExpression(expression);
|
||||
if (!SuperVisitor.$classobj.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) {
|
||||
myResult = // TODO: not resolved
|
||||
new MethodCallExpression(
|
||||
getConverter().expressionToExpression(expression.getMethodExpression()),
|
||||
getConverter().argumentsToExpressionList(expression),
|
||||
getConverter().typesToTypeList(expression.getTypeArguments()), getConverter().typeToType(expression.getType()).getNullable()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCallExpression(PsiCallExpression callExpression) {
|
||||
super.visitCallExpression(callExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(@NotNull PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if (expression.getArrayInitializer() != null) // new Foo[] {Foo(1), Foo(2)}
|
||||
{
|
||||
myResult = createNewEmptyArray(expression);
|
||||
}
|
||||
else if (expression.getArrayDimensions().length > 0) { // new Foo[5]
|
||||
myResult = createNewEmptyArrayWithoutInitialization(expression);
|
||||
}
|
||||
else { // new Class(): common case
|
||||
myResult = createNewClassExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Expression createNewClassExpression(@NotNull PsiNewExpression expression) {
|
||||
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
|
||||
final PsiMethod constructor = expression.resolveMethod();
|
||||
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
final boolean isNotConvertedClass = classReference != null && !getConverter().getClassIdentifiers().contains(classReference.getQualifiedName());
|
||||
PsiExpressionList argumentList = expression.getArgumentList();
|
||||
PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[]{};
|
||||
if (constructor == null || Converter.$classobj.isConstructorPrimary(constructor) || isNotConvertedClass) {
|
||||
return new NewClassExpression(
|
||||
getConverter().elementToElement(classReference), getConverter().argumentsToExpressionList(expression), getConverter().expressionToExpression(expression.getQualifier()),
|
||||
anonymousClass != null ? getConverter().anonymousClassToAnonymousClass(anonymousClass) : null
|
||||
);
|
||||
}
|
||||
// is constructor secondary
|
||||
final PsiJavaCodeReferenceElement reference = expression.getClassReference();
|
||||
final List<Type> typeParameters = reference != null
|
||||
? getConverter().typesToTypeList(reference.getTypeParameters())
|
||||
: Collections.<Type>emptyList();
|
||||
return new CallChainExpression(
|
||||
new Identifier(constructor.getName(), false),
|
||||
new MethodCallExpression(
|
||||
new Identifier("init"),
|
||||
getConverter().expressionsToExpressionList(arguments),
|
||||
typeParameters, false));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Expression createNewEmptyArrayWithoutInitialization(@NotNull PsiNewExpression expression) {
|
||||
return new ArrayWithoutInitializationExpression(
|
||||
getConverter().typeToType(expression.getType(), true),
|
||||
getConverter().expressionsToExpressionList(expression.getArrayDimensions())
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Expression createNewEmptyArray(@NotNull PsiNewExpression expression) {
|
||||
return getConverter().expressionToExpression(expression.getArrayInitializer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParenthesizedExpression(@NotNull PsiParenthesizedExpression expression) {
|
||||
super.visitParenthesizedExpression(expression);
|
||||
myResult = new ParenthesizedExpression(
|
||||
getConverter().expressionToExpression(expression.getExpression())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPostfixExpression(@NotNull PsiPostfixExpression expression) {
|
||||
super.visitPostfixExpression(expression);
|
||||
myResult = new PostfixOperator(
|
||||
getOperatorString(expression.getOperationSign().getTokenType()),
|
||||
getConverter().expressionToExpression(expression.getOperand())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrefixExpression(@NotNull PsiPrefixExpression expression) {
|
||||
super.visitPrefixExpression(expression);
|
||||
if (expression.getOperationTokenType() == JavaTokenType.TILDE) {
|
||||
myResult = new DummyMethodCallExpression(
|
||||
new ParenthesizedExpression(getConverter().expressionToExpression(expression.getOperand())), "inv", Expression.EMPTY_EXPRESSION
|
||||
);
|
||||
}
|
||||
else {
|
||||
myResult = new PrefixOperator(
|
||||
getOperatorString(expression.getOperationSign().getTokenType()),
|
||||
getConverter().expressionToExpression(expression.getOperand())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
|
||||
final boolean isFieldReference = isFieldReference(expression, getContainingClass(expression));
|
||||
final boolean insideSecondaryConstructor = isInsideSecondaryConstructor(expression);
|
||||
final boolean hasReceiver = isFieldReference && insideSecondaryConstructor;
|
||||
final boolean isThis = isThisExpression(expression);
|
||||
final boolean isNullable = getConverter().typeToType(expression.getType()).getNullable();
|
||||
final String className = getClassNameWithConstructor(expression);
|
||||
|
||||
Expression identifier = new Identifier(expression.getReferenceName(), isNullable);
|
||||
|
||||
final String __ = "__";
|
||||
if (hasReceiver) {
|
||||
identifier = new CallChainExpression(new Identifier(__, false), new Identifier(expression.getReferenceName(), isNullable));
|
||||
}
|
||||
else if (insideSecondaryConstructor && isThis) {
|
||||
identifier = new Identifier("val __ = " + className); // TODO: hack
|
||||
}
|
||||
|
||||
myResult = new CallChainExpression(
|
||||
getConverter().expressionToExpression(expression.getQualifierExpression()),
|
||||
identifier // TODO: if type exists so identifier is nullable
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getClassNameWithConstructor(@NotNull PsiReferenceExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||
final PsiClass containingClass = ((PsiMethod) context).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
return identifier.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
context = context.getContext();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static String getClassName(@NotNull PsiExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiClass) {
|
||||
final PsiClass containingClass = (PsiClass) context;
|
||||
final PsiIdentifier identifier = containingClass.getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
return identifier.getText();
|
||||
}
|
||||
}
|
||||
context = context.getContext();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static boolean isFieldReference(@NotNull PsiReferenceExpression expression, PsiClass currentClass) {
|
||||
final PsiReference reference = expression.getReference();
|
||||
if (reference != null) {
|
||||
final PsiElement resolvedReference = reference.resolve();
|
||||
if (resolvedReference != null) {
|
||||
if (resolvedReference instanceof PsiField) {
|
||||
return ((PsiField) resolvedReference).getContainingClass() == currentClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isInsideSecondaryConstructor(@NotNull PsiReferenceExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||
return !Converter.$classobj.isConstructorPrimary((PsiMethod) context);
|
||||
}
|
||||
context = context.getContext();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isInsidePrimaryConstructor(@NotNull PsiExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||
return Converter.$classobj.isConstructorPrimary((PsiMethod) context);
|
||||
}
|
||||
context = context.getContext();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getContainingClass(@NotNull PsiExpression expression) {
|
||||
PsiElement context = expression.getContext();
|
||||
while (context != null) {
|
||||
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
|
||||
return ((PsiMethod) context).getContainingClass();
|
||||
}
|
||||
context = context.getContext();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isThisExpression(@NotNull PsiReferenceExpression expression) {
|
||||
for (PsiReference r : expression.getReferences())
|
||||
if (r.getCanonicalText().equals("this")) {
|
||||
final PsiElement res = r.resolve();
|
||||
if (res != null && res instanceof PsiMethod && ((PsiMethod) res).isConstructor()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSuperExpression(@NotNull PsiSuperExpression expression) {
|
||||
super.visitSuperExpression(expression);
|
||||
final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
|
||||
myResult = new SuperExpression(
|
||||
qualifier != null ?
|
||||
new Identifier(qualifier.getQualifiedName()) :
|
||||
Identifier.EMPTY_IDENTIFIER
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitThisExpression(@NotNull PsiThisExpression expression) {
|
||||
super.visitThisExpression(expression);
|
||||
final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
|
||||
myResult = new ThisExpression(
|
||||
qualifier != null ?
|
||||
new Identifier(qualifier.getQualifiedName()) :
|
||||
Identifier.EMPTY_IDENTIFIER
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeCastExpression(@NotNull PsiTypeCastExpression expression) {
|
||||
super.visitTypeCastExpression(expression);
|
||||
|
||||
final PsiTypeElement castType = expression.getCastType();
|
||||
if (castType != null) {
|
||||
myResult = new TypeCastExpression(
|
||||
getConverter().typeToType(castType.getType()),
|
||||
getConverter().expressionToExpression(expression.getOperand())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPolyadicExpression(@NotNull PsiPolyadicExpression expression) {
|
||||
List<Expression> parameters = new ArrayList<Expression>();
|
||||
for (PsiExpression operand : expression.getOperands()) {
|
||||
parameters.add(getConverter().expressionToExpression(operand, expression.getType()));
|
||||
}
|
||||
myResult = new PolyadicExpression(
|
||||
parameters,
|
||||
getOperatorString(expression.getOperationTokenType())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
package org.jetbrains.jet.j2k.visitors
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.jetbrains.jet.j2k.Converter
|
||||
import org.jetbrains.jet.j2k.ast.*
|
||||
import org.jetbrains.jet.j2k.ast.types.EmptyType
|
||||
import org.jetbrains.jet.j2k.ast.types.Type
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
import java.util.List
|
||||
import com.intellij.psi.CommonClassNames.*
|
||||
|
||||
public open class ExpressionVisitor(converter: Converter): StatementVisitor(converter) {
|
||||
var myResult: Expression = Expression.EMPTY_EXPRESSION
|
||||
|
||||
public override fun visitExpression(expression: PsiExpression?): Unit {
|
||||
myResult = Expression.EMPTY_EXPRESSION
|
||||
}
|
||||
|
||||
public override fun getResult(): Expression {
|
||||
return myResult
|
||||
}
|
||||
|
||||
public override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression?): Unit {
|
||||
myResult = ArrayAccessExpression(getConverter().expressionToExpression(expression?.getArrayExpression()),
|
||||
getConverter().expressionToExpression(expression?.getIndexExpression()))
|
||||
}
|
||||
|
||||
public override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression?): Unit {
|
||||
myResult = ArrayInitializerExpression(getConverter().typeToType(expression?.getType()),
|
||||
getConverter().expressionsToExpressionList(expression?.getInitializers()!!))
|
||||
}
|
||||
|
||||
public override fun visitAssignmentExpression(expression: PsiAssignmentExpression?): Unit {
|
||||
val tokenType: IElementType = expression?.getOperationSign()?.getTokenType()!!
|
||||
val secondOp: String = when(tokenType) {
|
||||
JavaTokenType.GTGTEQ -> "shr"
|
||||
JavaTokenType.LTLTEQ -> "shl"
|
||||
JavaTokenType.XOREQ -> "xor"
|
||||
JavaTokenType.ANDEQ -> "and"
|
||||
JavaTokenType.OREQ -> "or"
|
||||
JavaTokenType.GTGTGTEQ -> "ushr"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
val lhs = getConverter().expressionToExpression(expression?.getLExpression()!!)
|
||||
val rhs = getConverter().expressionToExpression(expression?.getRExpression()!!)
|
||||
if (!secondOp.isEmpty()) {
|
||||
myResult = AssignmentExpression(lhs, BinaryExpression(lhs, rhs, secondOp), "=")
|
||||
}
|
||||
else {
|
||||
myResult = AssignmentExpression(lhs, rhs, expression?.getOperationSign()?.getText()!!)
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitBinaryExpression(expression: PsiBinaryExpression?): Unit {
|
||||
val lhs = getConverter().expressionToExpression(expression?.getLOperand()!!, expression?.getType())
|
||||
val rhs = getConverter().expressionToExpression(expression?.getROperand(), expression?.getType())
|
||||
if (expression?.getOperationSign()?.getTokenType() == JavaTokenType.GTGTGT) {
|
||||
myResult = DummyMethodCallExpression(lhs, "ushr", rhs)
|
||||
}
|
||||
else {
|
||||
myResult = BinaryExpression(lhs, rhs,
|
||||
getOperatorString(expression?.getOperationSign()?.getTokenType()!!))
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitClassObjectAccessExpression(expression: PsiClassObjectAccessExpression?): Unit {
|
||||
myResult = ClassObjectAccessExpression(getConverter().elementToElement(expression?.getOperand()))
|
||||
}
|
||||
|
||||
public override fun visitConditionalExpression(expression: PsiConditionalExpression?): Unit {
|
||||
val condition: PsiExpression? = expression?.getCondition()
|
||||
val `type`: PsiType? = condition?.getType()
|
||||
val e: Expression = (if (`type` != null)
|
||||
getConverter().expressionToExpression(condition, `type`)
|
||||
else
|
||||
getConverter().expressionToExpression(condition))
|
||||
myResult = ParenthesizedExpression(IfStatement(e,
|
||||
getConverter().expressionToExpression(expression?.getThenExpression()),
|
||||
getConverter().expressionToExpression(expression?.getElseExpression())))
|
||||
}
|
||||
|
||||
public override fun visitExpressionList(list: PsiExpressionList?): Unit {
|
||||
myResult = ExpressionList(getConverter().expressionsToExpressionList(list!!.getExpressions()))
|
||||
}
|
||||
|
||||
public override fun visitInstanceOfExpression(expression: PsiInstanceOfExpression?): Unit {
|
||||
val checkType: PsiTypeElement? = expression?.getCheckType()
|
||||
myResult = IsOperator(getConverter().expressionToExpression(expression?.getOperand()), TypeElement(if (checkType == null)
|
||||
EmptyType()
|
||||
else
|
||||
myConverter.typeToType(checkType.getType())))
|
||||
}
|
||||
|
||||
public override fun visitLiteralExpression(expression: PsiLiteralExpression?): Unit {
|
||||
val value: Any? = expression?.getValue()
|
||||
var text: String = expression?.getText()!!
|
||||
var isQuotingNeeded: Boolean = true
|
||||
val `type`: PsiType? = expression?.getType()
|
||||
if (`type` != null)
|
||||
{
|
||||
var canonicalTypeStr: String? = `type`.getCanonicalText()
|
||||
if (canonicalTypeStr?.equals("double")!! || canonicalTypeStr?.equals(JAVA_LANG_DOUBLE)!!) {
|
||||
text = text.replace("D", "").replace("d", "")
|
||||
if (!text.contains(".")) {
|
||||
text += ".0"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (canonicalTypeStr?.equals("float")!! || canonicalTypeStr?.equals(JAVA_LANG_FLOAT)!!) {
|
||||
text = text.replace("F", "").replace("f", "") + "." + OperatorConventions.FLOAT + "()"
|
||||
}
|
||||
|
||||
if (canonicalTypeStr?.equals("long")!! || canonicalTypeStr?.equals(JAVA_LANG_LONG)!!) {
|
||||
text = text.replace("L", "").replace("l", "")
|
||||
}
|
||||
|
||||
if (canonicalTypeStr?.equals("int")!! || canonicalTypeStr?.equals(JAVA_LANG_INTEGER)!!) {
|
||||
text = (if (value != null) value.toString() else text)
|
||||
}
|
||||
|
||||
if (canonicalTypeStr?.equals(JAVA_LANG_STRING)!!) {
|
||||
isQuotingNeeded = false
|
||||
}
|
||||
|
||||
if (canonicalTypeStr?.equals("char")!! || canonicalTypeStr?.equals(JAVA_LANG_CHARACTER)!!) {
|
||||
isQuotingNeeded = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
myResult = LiteralExpression(Identifier(text, false, isQuotingNeeded))
|
||||
}
|
||||
|
||||
public override fun visitMethodCallExpression(expression: PsiMethodCallExpression?): Unit {
|
||||
if (!SuperVisitor.isSuper(expression!!.getMethodExpression()) || !isInsidePrimaryConstructor(expression!!))
|
||||
{
|
||||
myResult = MethodCallExpression(getConverter().expressionToExpression(expression?.getMethodExpression()),
|
||||
getConverter().argumentsToExpressionList(expression!!),
|
||||
getConverter().typesToTypeList(expression?.getTypeArguments()!!),
|
||||
getConverter().typeToType(expression?.getType()).nullable)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override fun visitNewExpression(expression: PsiNewExpression?): Unit {
|
||||
if (expression?.getArrayInitializer() != null)
|
||||
{
|
||||
myResult = createNewEmptyArray(expression)
|
||||
}
|
||||
else
|
||||
if (expression?.getArrayDimensions()?.size!! > 0) {
|
||||
myResult = createNewEmptyArrayWithoutInitialization(expression!!)
|
||||
}
|
||||
else
|
||||
{
|
||||
myResult = createNewClassExpression(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNewClassExpression(expression: PsiNewExpression?): Expression {
|
||||
val anonymousClass: PsiAnonymousClass? = expression?.getAnonymousClass()
|
||||
val constructor: PsiMethod? = expression?.resolveMethod()
|
||||
var classReference: PsiJavaCodeReferenceElement? = expression?.getClassOrAnonymousClassReference()
|
||||
val isNotConvertedClass: Boolean = classReference != null && !getConverter().getClassIdentifiers().contains(classReference?.getQualifiedName())
|
||||
var argumentList: PsiExpressionList? = expression?.getArgumentList()
|
||||
var arguments: Array<PsiExpression?> = (if (argumentList != null)
|
||||
argumentList?.getExpressions()!!
|
||||
else
|
||||
array<PsiExpression?>())
|
||||
if (constructor == null || Converter.isConstructorPrimary(constructor) || isNotConvertedClass)
|
||||
{
|
||||
return NewClassExpression(getConverter().elementToElement(classReference),
|
||||
getConverter().argumentsToExpressionList(expression!!),
|
||||
getConverter().expressionToExpression(expression?.getQualifier()),
|
||||
(if (anonymousClass != null)
|
||||
getConverter().anonymousClassToAnonymousClass(anonymousClass)
|
||||
else
|
||||
null))
|
||||
}
|
||||
|
||||
val reference: PsiJavaCodeReferenceElement? = expression?.getClassReference()
|
||||
val typeParameters: List<Type> = (if (reference != null)
|
||||
getConverter().typesToTypeList(reference.getTypeParameters())
|
||||
else
|
||||
Collections.emptyList<Type>()!!)
|
||||
return CallChainExpression(Identifier(constructor.getName(), false),
|
||||
MethodCallExpression(Identifier("init"), getConverter().expressionsToExpressionList(arguments), typeParameters, false))
|
||||
}
|
||||
|
||||
private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression {
|
||||
return ArrayWithoutInitializationExpression(
|
||||
getConverter().typeToType(expression?.getType(), true),
|
||||
getConverter().expressionsToExpressionList(expression?.getArrayDimensions()))
|
||||
}
|
||||
|
||||
private fun createNewEmptyArray(expression: PsiNewExpression?): Expression {
|
||||
return getConverter().expressionToExpression(expression?.getArrayInitializer())
|
||||
}
|
||||
|
||||
public override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression?): Unit {
|
||||
myResult = ParenthesizedExpression(getConverter().expressionToExpression(expression?.getExpression()))
|
||||
}
|
||||
|
||||
public override fun visitPostfixExpression(expression: PsiPostfixExpression?): Unit {
|
||||
myResult = PostfixOperator(getOperatorString(expression!!.getOperationSign().getTokenType()!!),
|
||||
getConverter().expressionToExpression(expression?.getOperand()))
|
||||
}
|
||||
|
||||
public override fun visitPrefixExpression(expression: PsiPrefixExpression?): Unit {
|
||||
val operand = getConverter().expressionToExpression(expression?.getOperand(), expression?.getOperand()!!.getType())
|
||||
val token = expression?.getOperationTokenType()!!
|
||||
if (token == JavaTokenType.TILDE) {
|
||||
myResult = DummyMethodCallExpression(ParenthesizedExpression(operand), "inv", Expression.EMPTY_EXPRESSION)
|
||||
}
|
||||
else {
|
||||
myResult = PrefixOperator(getOperatorString(token), operand)
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitReferenceExpression(expression: PsiReferenceExpression?): Unit {
|
||||
val isFieldReference: Boolean = isFieldReference(expression!!, getContainingClass(expression!!))
|
||||
val insideSecondaryConstructor: Boolean = isInsideSecondaryConstructor(expression!!)
|
||||
val hasReceiver: Boolean = isFieldReference && insideSecondaryConstructor
|
||||
val isThis: Boolean = isThisExpression(expression!!)
|
||||
val isNullable: Boolean = getConverter().typeToType(expression?.getType()).nullable
|
||||
val className: String = getClassNameWithConstructor(expression!!)
|
||||
var identifier: Expression = Identifier(expression?.getReferenceName(), isNullable)
|
||||
val __: String? = "__"
|
||||
if (hasReceiver){
|
||||
identifier = CallChainExpression(Identifier(__, false), Identifier(expression?.getReferenceName(), isNullable))
|
||||
}
|
||||
else
|
||||
if (insideSecondaryConstructor && isThis) {
|
||||
identifier = Identifier("val __ = " + className)
|
||||
}
|
||||
|
||||
myResult = CallChainExpression(getConverter().expressionToExpression(expression?.getQualifierExpression()), identifier)
|
||||
}
|
||||
|
||||
public override fun visitSuperExpression(expression: PsiSuperExpression?): Unit {
|
||||
val qualifier: PsiJavaCodeReferenceElement? = expression?.getQualifier()
|
||||
myResult = SuperExpression((if (qualifier != null)
|
||||
Identifier(qualifier.getQualifiedName())
|
||||
else
|
||||
Identifier.EMPTY_IDENTIFIER))
|
||||
}
|
||||
|
||||
public override fun visitThisExpression(expression: PsiThisExpression?): Unit {
|
||||
val qualifier: PsiJavaCodeReferenceElement? = expression?.getQualifier()
|
||||
myResult = ThisExpression((if (qualifier != null)
|
||||
Identifier(qualifier.getQualifiedName())
|
||||
else
|
||||
Identifier.EMPTY_IDENTIFIER))
|
||||
}
|
||||
|
||||
public override fun visitTypeCastExpression(expression: PsiTypeCastExpression?): Unit {
|
||||
val castType: PsiTypeElement? = expression?.getCastType()
|
||||
if (castType != null) {
|
||||
myResult = TypeCastExpression(getConverter()?.typeToType(castType.getType()),
|
||||
getConverter().expressionToExpression(expression?.getOperand()))
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitPolyadicExpression(expression: PsiPolyadicExpression?): Unit {
|
||||
var parameters: List<Expression> = ArrayList<Expression>()
|
||||
for (operand : PsiExpression? in expression?.getOperands()) {
|
||||
parameters?.add(getConverter().expressionToExpression(operand, expression?.getType()))
|
||||
}
|
||||
myResult = PolyadicExpression(parameters, getOperatorString(expression?.getOperationTokenType()!!))
|
||||
}
|
||||
|
||||
class object {
|
||||
private fun getOperatorString(tokenType: IElementType): String {
|
||||
if (tokenType == JavaTokenType.PLUS)
|
||||
return "+"
|
||||
|
||||
if (tokenType == JavaTokenType.MINUS)
|
||||
return "-"
|
||||
|
||||
if (tokenType == JavaTokenType.ASTERISK)
|
||||
return "*"
|
||||
|
||||
if (tokenType == JavaTokenType.DIV)
|
||||
return "/"
|
||||
|
||||
if (tokenType == JavaTokenType.PERC)
|
||||
return "%"
|
||||
|
||||
if (tokenType == JavaTokenType.GTGT)
|
||||
return "shr"
|
||||
|
||||
if (tokenType == JavaTokenType.LTLT)
|
||||
return "shl"
|
||||
|
||||
if (tokenType == JavaTokenType.XOR)
|
||||
return "xor"
|
||||
|
||||
if (tokenType == JavaTokenType.AND)
|
||||
return "and"
|
||||
|
||||
if (tokenType == JavaTokenType.OR)
|
||||
return "or"
|
||||
|
||||
if (tokenType == JavaTokenType.GTGTGT)
|
||||
return "ushr"
|
||||
|
||||
if (tokenType == JavaTokenType.GT)
|
||||
return ">"
|
||||
|
||||
if (tokenType == JavaTokenType.LT)
|
||||
return "<"
|
||||
|
||||
if (tokenType == JavaTokenType.GE)
|
||||
return ">="
|
||||
|
||||
if (tokenType == JavaTokenType.LE)
|
||||
return "<="
|
||||
|
||||
if (tokenType == JavaTokenType.EQEQ)
|
||||
return "=="
|
||||
|
||||
if (tokenType == JavaTokenType.NE)
|
||||
return "!="
|
||||
|
||||
if (tokenType == JavaTokenType.ANDAND)
|
||||
return "&&"
|
||||
|
||||
if (tokenType == JavaTokenType.OROR)
|
||||
return "||"
|
||||
|
||||
if (tokenType == JavaTokenType.PLUSPLUS)
|
||||
return "++"
|
||||
|
||||
if (tokenType == JavaTokenType.MINUSMINUS)
|
||||
return "--"
|
||||
|
||||
if (tokenType == JavaTokenType.EXCL)
|
||||
return "!"
|
||||
|
||||
System.out?.println("UNSUPPORTED TOKEN TYPE: " + tokenType?.toString())
|
||||
return ""
|
||||
}
|
||||
|
||||
private fun getClassNameWithConstructor(expression: PsiReferenceExpression): String {
|
||||
var context: PsiElement? = expression?.getContext()
|
||||
while (context != null) {
|
||||
if (context is PsiMethod && ((context as PsiMethod)).isConstructor()) {
|
||||
val containingClass: PsiClass? = ((context as PsiMethod)).getContainingClass()
|
||||
if (containingClass != null) {
|
||||
val identifier: PsiIdentifier? = containingClass?.getNameIdentifier()
|
||||
if (identifier != null) {
|
||||
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) {
|
||||
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
|
||||
}
|
||||
|
||||
private fun isInsideSecondaryConstructor(expression: PsiReferenceExpression): Boolean {
|
||||
var context: PsiElement? = expression.getContext()
|
||||
while (context != null) {
|
||||
if (context is PsiMethod && (context as PsiMethod).isConstructor()) {
|
||||
return !Converter.isConstructorPrimary((context as PsiMethod))
|
||||
}
|
||||
|
||||
context = context?.getContext()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isInsidePrimaryConstructor(expression: PsiExpression): Boolean {
|
||||
var context: PsiElement? = expression.getContext()
|
||||
while (context != null) {
|
||||
if (context is PsiMethod && (context as PsiMethod).isConstructor()) {
|
||||
return Converter.isConstructorPrimary(context as PsiMethod)
|
||||
}
|
||||
|
||||
context = context?.getContext()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getContainingClass(expression: PsiExpression): PsiClass? {
|
||||
var context: PsiElement? = expression.getContext()
|
||||
while (context != null)
|
||||
{
|
||||
if (context is PsiMethod && (context as PsiMethod).isConstructor())
|
||||
{
|
||||
return (context as PsiMethod).getContainingClass()
|
||||
}
|
||||
|
||||
context = context?.getContext()
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,393 +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.visitors;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.j2k.Converter;
|
||||
import org.jetbrains.jet.j2k.ast.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses;
|
||||
|
||||
/**
|
||||
* @author ignatov
|
||||
*/
|
||||
public class StatementVisitor extends ElementVisitor {
|
||||
private Statement myResult = Statement.EMPTY_STATEMENT;
|
||||
|
||||
public StatementVisitor(@NotNull Converter converter) {
|
||||
super(converter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Statement getResult() {
|
||||
return myResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssertStatement(@NotNull PsiAssertStatement statement) {
|
||||
super.visitAssertStatement(statement);
|
||||
myResult = new AssertStatement(
|
||||
getConverter().expressionToExpression(statement.getAssertCondition()),
|
||||
getConverter().expressionToExpression(statement.getAssertDescription())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBlockStatement(@NotNull PsiBlockStatement statement) {
|
||||
super.visitBlockStatement(statement);
|
||||
myResult = new Block(
|
||||
getConverter().statementsToStatementList(statement.getCodeBlock().getStatements()),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBreakStatement(@NotNull PsiBreakStatement statement) {
|
||||
super.visitBreakStatement(statement);
|
||||
if (statement.getLabelIdentifier() == null) {
|
||||
myResult = new BreakStatement(Identifier.EMPTY_IDENTIFIER);
|
||||
}
|
||||
else {
|
||||
myResult = new BreakStatement(
|
||||
Converter.$classobj.identifierToIdentifier(statement.getLabelIdentifier())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitContinueStatement(@NotNull PsiContinueStatement statement) {
|
||||
super.visitContinueStatement(statement);
|
||||
if (statement.getLabelIdentifier() == null) {
|
||||
myResult = new ContinueStatement(Identifier.EMPTY_IDENTIFIER);
|
||||
}
|
||||
else {
|
||||
myResult = new ContinueStatement(
|
||||
Converter.$classobj.identifierToIdentifier(statement.getLabelIdentifier())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDeclarationStatement(@NotNull PsiDeclarationStatement statement) {
|
||||
super.visitDeclarationStatement(statement);
|
||||
myResult = new DeclarationStatement(
|
||||
getConverter().elementsToElementList(statement.getDeclaredElements())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDoWhileStatement(@NotNull PsiDoWhileStatement statement) {
|
||||
super.visitDoWhileStatement(statement);
|
||||
PsiExpression condition = statement.getCondition();
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Expression expression = condition != null && condition.getType() != null ?
|
||||
this.getConverter().expressionToExpression(condition, condition.getType()) :
|
||||
getConverter().expressionToExpression(condition);
|
||||
myResult = new DoWhileStatement(
|
||||
expression,
|
||||
getConverter().statementToStatement(statement.getBody())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpressionStatement(@NotNull PsiExpressionStatement statement) {
|
||||
super.visitExpressionStatement(statement);
|
||||
myResult = getConverter().expressionToExpression(statement.getExpression());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpressionListStatement(@NotNull PsiExpressionListStatement statement) {
|
||||
super.visitExpressionListStatement(statement);
|
||||
myResult =
|
||||
new ExpressionListStatement(getConverter().expressionsToExpressionList(statement.getExpressionList().getExpressions()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitForStatement(@NotNull PsiForStatement statement) {
|
||||
super.visitForStatement(statement);
|
||||
|
||||
final PsiStatement initialization = statement.getInitialization();
|
||||
final PsiStatement update = statement.getUpdate();
|
||||
final PsiExpression condition = statement.getCondition();
|
||||
final PsiStatement body = statement.getBody();
|
||||
|
||||
final PsiLocalVariable firstChild = initialization != null && initialization.getFirstChild() instanceof PsiLocalVariable
|
||||
?
|
||||
(PsiLocalVariable) initialization.getFirstChild()
|
||||
: null;
|
||||
|
||||
int bodyWriteCount = countWritingAccesses(firstChild, body);
|
||||
int conditionWriteCount = countWritingAccesses(firstChild, condition);
|
||||
int updateWriteCount = countWritingAccesses(firstChild, update);
|
||||
boolean onceWritableIterator = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0;
|
||||
|
||||
final IElementType operationTokenType = condition != null && condition instanceof PsiBinaryExpression ?
|
||||
((PsiBinaryExpression) condition).getOperationTokenType() : null;
|
||||
if (
|
||||
initialization != null &&
|
||||
initialization instanceof PsiDeclarationStatement
|
||||
&& initialization.getFirstChild() == initialization.getLastChild()
|
||||
&& condition != null
|
||||
&& update != null
|
||||
&& update.getChildren().length == 1
|
||||
&& isPlusPlusExpression(update.getChildren()[0])
|
||||
&& operationTokenType != null
|
||||
&& (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
|
||||
&& initialization.getFirstChild() != null
|
||||
&& initialization.getFirstChild() instanceof PsiLocalVariable
|
||||
&& firstChild != null
|
||||
&& firstChild.getNameIdentifier() != null
|
||||
&& onceWritableIterator
|
||||
) {
|
||||
final Expression end = getConverter().expressionToExpression(((PsiBinaryExpression) condition).getROperand());
|
||||
final Expression endExpression = operationTokenType == JavaTokenType.LT ?
|
||||
new BinaryExpression(end, new Identifier("1"), "-") :
|
||||
end;
|
||||
myResult = new ForeachWithRangeStatement(
|
||||
new org.jetbrains.jet.j2k.ast.Identifier(firstChild.getName()),
|
||||
getConverter().expressionToExpression(firstChild.getInitializer()),
|
||||
endExpression,
|
||||
getConverter().statementToStatement(body)
|
||||
);
|
||||
}
|
||||
else { // common case: while loop instead of for loop
|
||||
List<Statement> forStatements = new LinkedList<Statement>();
|
||||
forStatements.add(getConverter().statementToStatement(initialization));
|
||||
forStatements.add(new WhileStatement(
|
||||
getConverter().expressionToExpression(condition),
|
||||
new Block(
|
||||
Arrays.asList(getConverter().statementToStatement(body),
|
||||
new Block(Arrays.asList(getConverter().statementToStatement(update)), false)), false)));
|
||||
myResult = new Block(forStatements, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPlusPlusExpression(@NotNull PsiElement psiElement) {
|
||||
return (psiElement instanceof PsiPostfixExpression && ((PsiPostfixExpression) psiElement).getOperationTokenType() == JavaTokenType.PLUSPLUS)
|
||||
|| (psiElement instanceof PsiPrefixExpression && ((PsiPrefixExpression) psiElement).getOperationTokenType() == JavaTokenType.PLUSPLUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitForeachStatement(@NotNull PsiForeachStatement statement) {
|
||||
super.visitForeachStatement(statement);
|
||||
myResult = new ForeachStatement(
|
||||
getConverter().parameterToParameter(statement.getIterationParameter()),
|
||||
getConverter().expressionToExpression(statement.getIteratedValue()),
|
||||
getConverter().statementToStatement(statement.getBody())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitIfStatement(@NotNull PsiIfStatement statement) {
|
||||
super.visitIfStatement(statement);
|
||||
PsiExpression condition = statement.getCondition();
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Expression expression = getConverter().expressionToExpression(condition, PsiType.BOOLEAN);
|
||||
myResult = new IfStatement(
|
||||
expression,
|
||||
getConverter().statementToStatement(statement.getThenBranch()),
|
||||
getConverter().statementToStatement(statement.getElseBranch())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLabeledStatement(@NotNull PsiLabeledStatement statement) {
|
||||
super.visitLabeledStatement(statement);
|
||||
myResult = new LabelStatement(
|
||||
Converter.$classobj.identifierToIdentifier(statement.getLabelIdentifier()),
|
||||
getConverter().statementToStatement(statement.getStatement())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchLabelStatement(@NotNull PsiSwitchLabelStatement statement) {
|
||||
super.visitSwitchLabelStatement(statement);
|
||||
myResult = statement.isDefaultCase() ?
|
||||
new DefaultSwitchLabelStatement() :
|
||||
new SwitchLabelStatement(getConverter().expressionToExpression(statement.getCaseValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSwitchStatement(@NotNull PsiSwitchStatement statement) {
|
||||
super.visitSwitchStatement(statement);
|
||||
myResult = new SwitchContainer(
|
||||
getConverter().expressionToExpression(statement.getExpression()),
|
||||
switchBodyToCases(statement.getBody())
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<CaseContainer> switchBodyToCases(@Nullable final PsiCodeBlock body) {
|
||||
final List<List<PsiStatement>> cases = splitToCases(body);
|
||||
final List<PsiStatement> allSwitchStatements = body != null
|
||||
? Arrays.asList(body.getStatements())
|
||||
: Collections.<PsiStatement>emptyList();
|
||||
|
||||
List<CaseContainer> result = new LinkedList<CaseContainer>();
|
||||
List<Statement> pendingLabels = new LinkedList<Statement>();
|
||||
int i = 0;
|
||||
for (List<PsiStatement> ls : cases) {
|
||||
assert ls.size() > 0;
|
||||
PsiStatement label = ls.get(0);
|
||||
assert label instanceof PsiSwitchLabelStatement;
|
||||
|
||||
assert allSwitchStatements.get(i) == label : "not a right index";
|
||||
|
||||
if (ls.size() > 1) {
|
||||
pendingLabels.add(getConverter().statementToStatement(label));
|
||||
List<PsiStatement> slice = ls.subList(1, ls.size());
|
||||
|
||||
if (!containsBreak(slice)) {
|
||||
List<Statement> statements = getConverter().statementsToStatementList(slice);
|
||||
statements.addAll(
|
||||
getConverter().statementsToStatementList(getAllToNextBreak(allSwitchStatements, i + ls.size()))
|
||||
);
|
||||
result.add(new CaseContainer(pendingLabels, statements));
|
||||
pendingLabels = new LinkedList<Statement>();
|
||||
}
|
||||
else {
|
||||
result.add(new CaseContainer(pendingLabels, getConverter().statementsToStatementList(slice)));
|
||||
pendingLabels = new LinkedList<Statement>();
|
||||
}
|
||||
}
|
||||
else // ls.size() == 1
|
||||
{
|
||||
pendingLabels.add(getConverter().statementToStatement(label));
|
||||
}
|
||||
i += ls.size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean containsBreak(@NotNull final List<PsiStatement> slice) {
|
||||
for (PsiStatement s : slice)
|
||||
if (s instanceof PsiBreakStatement) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiStatement> getAllToNextBreak(@NotNull final List<PsiStatement> allStatements, final int start) {
|
||||
List<PsiStatement> result = new LinkedList<PsiStatement>();
|
||||
for (int i = start; i < allStatements.size(); i++) {
|
||||
PsiStatement s = allStatements.get(i);
|
||||
if (s instanceof PsiBreakStatement || s instanceof PsiReturnStatement) {
|
||||
return result;
|
||||
}
|
||||
if (!(s instanceof PsiSwitchLabelStatement)) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<List<PsiStatement>> splitToCases(@Nullable final PsiCodeBlock body) {
|
||||
List<List<PsiStatement>> cases = new LinkedList<List<PsiStatement>>();
|
||||
List<PsiStatement> currentCaseStatements = new LinkedList<PsiStatement>();
|
||||
boolean isFirst = true;
|
||||
if (body != null) {
|
||||
for (PsiStatement s : body.getStatements()) {
|
||||
if (s instanceof PsiSwitchLabelStatement) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
}
|
||||
else {
|
||||
cases.add(currentCaseStatements);
|
||||
currentCaseStatements = new LinkedList<PsiStatement>();
|
||||
}
|
||||
}
|
||||
currentCaseStatements.add(s);
|
||||
}
|
||||
cases.add(currentCaseStatements);
|
||||
}
|
||||
return cases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSynchronizedStatement(@NotNull PsiSynchronizedStatement statement) {
|
||||
super.visitSynchronizedStatement(statement);
|
||||
myResult = new SynchronizedStatement(
|
||||
getConverter().expressionToExpression(statement.getLockExpression()),
|
||||
getConverter().blockToBlock(statement.getBody())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitThrowStatement(@NotNull PsiThrowStatement statement) {
|
||||
super.visitThrowStatement(statement);
|
||||
myResult = new ThrowStatement(
|
||||
getConverter().expressionToExpression(statement.getException())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTryStatement(@NotNull PsiTryStatement statement) {
|
||||
super.visitTryStatement(statement);
|
||||
|
||||
List<CatchStatement> catches = new LinkedList<CatchStatement>();
|
||||
for (int i = 0; i < statement.getCatchBlocks().length; i++) {
|
||||
catches.add(new CatchStatement(
|
||||
getConverter().parameterToParameter(statement.getCatchBlockParameters()[i]),
|
||||
getConverter().blockToBlock(statement.getCatchBlocks()[i], true)
|
||||
));
|
||||
}
|
||||
|
||||
myResult = new TryStatement(
|
||||
getConverter().blockToBlock(statement.getTryBlock(), true),
|
||||
catches,
|
||||
getConverter().blockToBlock(statement.getFinallyBlock(), true)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhileStatement(@NotNull PsiWhileStatement statement) {
|
||||
super.visitWhileStatement(statement);
|
||||
PsiExpression condition = statement.getCondition();
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Expression expression = condition != null && condition.getType() != null ?
|
||||
this.getConverter().expressionToExpression(condition, condition.getType()) :
|
||||
getConverter().expressionToExpression(condition);
|
||||
myResult = new WhileStatement(
|
||||
expression,
|
||||
getConverter().statementToStatement(statement.getBody())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReturnStatement(@NotNull PsiReturnStatement statement) {
|
||||
super.visitReturnStatement(statement);
|
||||
PsiExpression returnValue = statement.getReturnValue();
|
||||
PsiType methodReturnType = getConverter().getMethodReturnType();
|
||||
Expression expression = returnValue != null && methodReturnType != null ?
|
||||
this.getConverter().expressionToExpression(returnValue, methodReturnType) :
|
||||
getConverter().expressionToExpression(returnValue);
|
||||
myResult = new ReturnStatement(
|
||||
expression
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package org.jetbrains.jet.j2k.visitors
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.jetbrains.jet.j2k.Converter
|
||||
import org.jetbrains.jet.j2k.ast.*
|
||||
import java.util.Arrays
|
||||
import java.util.Collections
|
||||
import java.util.LinkedList
|
||||
import java.util.List
|
||||
import org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses
|
||||
|
||||
public open class StatementVisitor(converter: Converter): ElementVisitor(converter) {
|
||||
private var myResult: Statement = Statement.EMPTY_STATEMENT
|
||||
public override fun getResult(): Statement {
|
||||
return myResult
|
||||
}
|
||||
|
||||
public override fun visitAssertStatement(statement: PsiAssertStatement?): Unit {
|
||||
myResult = AssertStatement(getConverter().expressionToExpression(statement?.getAssertCondition()),
|
||||
getConverter().expressionToExpression(statement?.getAssertDescription()))
|
||||
}
|
||||
|
||||
public override fun visitBlockStatement(statement: PsiBlockStatement?): Unit {
|
||||
myResult = Block(getConverter().statementsToStatementList(statement?.getCodeBlock()?.getStatements().requireNoNulls()), true)
|
||||
}
|
||||
|
||||
public override fun visitBreakStatement(statement: PsiBreakStatement?): Unit {
|
||||
if (statement?.getLabelIdentifier() == null) {
|
||||
myResult = BreakStatement(Identifier.EMPTY_IDENTIFIER)
|
||||
}
|
||||
else
|
||||
{
|
||||
myResult = BreakStatement(Converter.identifierToIdentifier(statement?.getLabelIdentifier()))
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitContinueStatement(statement: PsiContinueStatement?): Unit {
|
||||
if (statement?.getLabelIdentifier() == null)
|
||||
{
|
||||
myResult = ContinueStatement(Identifier.EMPTY_IDENTIFIER)
|
||||
}
|
||||
else
|
||||
{
|
||||
myResult = ContinueStatement(Converter.identifierToIdentifier(statement?.getLabelIdentifier()))
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitDeclarationStatement(statement: PsiDeclarationStatement?): Unit {
|
||||
myResult = DeclarationStatement(getConverter().elementsToElementList(statement?.getDeclaredElements()!!))
|
||||
}
|
||||
|
||||
public override fun visitDoWhileStatement(statement: PsiDoWhileStatement?): Unit {
|
||||
val condition: PsiExpression? = statement?.getCondition()
|
||||
val expression: Expression = (if (condition != null && condition.getType() != null)
|
||||
getConverter().expressionToExpression(condition, condition.getType())
|
||||
else
|
||||
getConverter().expressionToExpression(condition))
|
||||
myResult = DoWhileStatement(expression, getConverter().statementToStatement(statement?.getBody()))
|
||||
}
|
||||
|
||||
public override fun visitExpressionStatement(statement: PsiExpressionStatement?): Unit {
|
||||
myResult = getConverter().expressionToExpression(statement?.getExpression())
|
||||
}
|
||||
|
||||
public override fun visitExpressionListStatement(statement: PsiExpressionListStatement?): Unit {
|
||||
myResult = ExpressionListStatement(getConverter().expressionsToExpressionList(
|
||||
statement?.getExpressionList()?.getExpressions()!!))
|
||||
}
|
||||
|
||||
public override fun visitForStatement(statement: PsiForStatement?): Unit {
|
||||
val initialization: PsiStatement? = statement?.getInitialization()
|
||||
val update: PsiStatement? = statement?.getUpdate()
|
||||
val condition: PsiExpression? = statement?.getCondition()
|
||||
val body: PsiStatement? = statement?.getBody()
|
||||
val firstChild: PsiLocalVariable? = (if (initialization != null && (initialization.getFirstChild() is PsiLocalVariable))
|
||||
(initialization.getFirstChild() as PsiLocalVariable)
|
||||
else
|
||||
null)
|
||||
var bodyWriteCount: Int = countWritingAccesses(firstChild, body)
|
||||
var conditionWriteCount: Int = countWritingAccesses(firstChild, condition)
|
||||
var updateWriteCount: Int = countWritingAccesses(firstChild, update)
|
||||
val onceWritableIterator: Boolean = updateWriteCount == 1 && bodyWriteCount + conditionWriteCount == 0
|
||||
val operationTokenType: IElementType? = (if (condition is PsiBinaryExpression)
|
||||
condition.getOperationTokenType()
|
||||
else
|
||||
null)
|
||||
if (initialization is PsiDeclarationStatement && initialization.getFirstChild() == initialization.getLastChild() &&
|
||||
condition != null && update != null && update.getChildren().size == 1 &&
|
||||
(isPlusPlusExpression(update.getChildren()[0]!!)) && (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE) &&
|
||||
initialization.getFirstChild() != null && (initialization.getFirstChild() is PsiLocalVariable) &&
|
||||
firstChild != null && firstChild.getNameIdentifier() != null && onceWritableIterator) {
|
||||
val end: Expression = getConverter().expressionToExpression((condition as PsiBinaryExpression).getROperand())
|
||||
val endExpression: Expression = (if (operationTokenType == JavaTokenType.LT)
|
||||
BinaryExpression(end, Identifier("1"), "-")
|
||||
else
|
||||
end)
|
||||
myResult = ForeachWithRangeStatement(Identifier(firstChild.getName()),
|
||||
getConverter().expressionToExpression(firstChild.getInitializer()),
|
||||
endExpression,
|
||||
getConverter().statementToStatement(body))
|
||||
}
|
||||
else {
|
||||
var forStatements: List<Statement> = arrayList()
|
||||
forStatements.add(getConverter().statementToStatement(initialization))
|
||||
forStatements.add(WhileStatement(getConverter().expressionToExpression(condition),
|
||||
Block(arrayList(getConverter().statementToStatement(body),
|
||||
Block(arrayList(getConverter().statementToStatement(update)), false)), false)))
|
||||
myResult = Block(forStatements, false)
|
||||
}
|
||||
}
|
||||
|
||||
public override fun visitForeachStatement(statement: PsiForeachStatement?): Unit {
|
||||
myResult = ForeachStatement(getConverter().parameterToParameter(statement?.getIterationParameter()!!),
|
||||
getConverter().expressionToExpression(statement?.getIteratedValue()),
|
||||
getConverter().statementToStatement(statement?.getBody()))
|
||||
}
|
||||
|
||||
public override fun visitIfStatement(statement: PsiIfStatement?): Unit {
|
||||
val condition: PsiExpression? = statement?.getCondition()
|
||||
val expression: Expression = getConverter().expressionToExpression(condition, PsiType.BOOLEAN)
|
||||
myResult = IfStatement(expression,
|
||||
getConverter().statementToStatement(statement?.getThenBranch()),
|
||||
getConverter().statementToStatement(statement?.getElseBranch()))
|
||||
}
|
||||
|
||||
public override fun visitLabeledStatement(statement: PsiLabeledStatement?): Unit {
|
||||
myResult = LabelStatement(Converter.identifierToIdentifier(statement?.getLabelIdentifier()),
|
||||
getConverter().statementToStatement(statement?.getStatement()))
|
||||
}
|
||||
|
||||
public override fun visitSwitchLabelStatement(statement: PsiSwitchLabelStatement?): Unit {
|
||||
myResult = (if (statement?.isDefaultCase().sure())
|
||||
DefaultSwitchLabelStatement()
|
||||
else
|
||||
SwitchLabelStatement(getConverter().expressionToExpression(statement?.getCaseValue())))
|
||||
}
|
||||
|
||||
public override fun visitSwitchStatement(statement: PsiSwitchStatement?): Unit {
|
||||
myResult = SwitchContainer(getConverter().expressionToExpression(statement?.getExpression()),
|
||||
switchBodyToCases(statement?.getBody()))
|
||||
}
|
||||
|
||||
private open fun switchBodyToCases(body: PsiCodeBlock?): List<CaseContainer> {
|
||||
val cases: List<List<PsiStatement?>> = splitToCases(body)
|
||||
val allSwitchStatements: List<PsiStatement?> = arrayList()
|
||||
if (body != null) {
|
||||
// TODO Arrays.asList()
|
||||
for(s in body.getStatements()) allSwitchStatements.add(s)
|
||||
}
|
||||
val result: List<CaseContainer> = arrayList()
|
||||
var pendingLabels: List<Statement> = arrayList()
|
||||
var i: Int = 0
|
||||
for (ls : List<PsiStatement?> in cases) {
|
||||
// TODO assert {(ls?.size()).sure() > 0}
|
||||
var label: PsiStatement? = ls[0]
|
||||
// TODO assert {(label is PsiSwitchLabelStatement?)}
|
||||
// TODO assert("not a right index") {allSwitchStatements?.get(i) == label}
|
||||
if (ls.size() > 1) {
|
||||
pendingLabels.add(getConverter().statementToStatement(label))
|
||||
val slice: List<PsiStatement?> = ls.subList(1, (ls.size()))
|
||||
if (!containsBreak(slice)) {
|
||||
val statements = getConverter().statementsToStatementList(slice)
|
||||
statements.addAll(getConverter().statementsToStatementList(getAllToNextBreak(allSwitchStatements, i + ls.size())))
|
||||
result.add(CaseContainer(pendingLabels, statements))
|
||||
pendingLabels = arrayList()
|
||||
}
|
||||
else {
|
||||
result.add(CaseContainer(pendingLabels, getConverter().statementsToStatementList(slice)))
|
||||
pendingLabels = arrayList()
|
||||
}
|
||||
}
|
||||
else {
|
||||
pendingLabels.add(getConverter().statementToStatement(label))
|
||||
}
|
||||
i += ls.size()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public override fun visitSynchronizedStatement(statement: PsiSynchronizedStatement?): Unit {
|
||||
myResult = SynchronizedStatement(getConverter().expressionToExpression(statement?.getLockExpression()),
|
||||
getConverter().blockToBlock(statement?.getBody()))
|
||||
}
|
||||
|
||||
public override fun visitThrowStatement(statement: PsiThrowStatement?): Unit {
|
||||
myResult = ThrowStatement(getConverter().expressionToExpression(statement?.getException()))
|
||||
}
|
||||
|
||||
public override fun visitTryStatement(statement: PsiTryStatement?): Unit {
|
||||
val catches: List<CatchStatement> = arrayList()
|
||||
val catchBlocks = statement?.getCatchBlocks()!!
|
||||
val catchBlockParameters = statement?.getCatchBlockParameters()!!
|
||||
for (i in 0..catchBlocks.size - 1) {
|
||||
catches.add(CatchStatement(getConverter().parameterToParameter(catchBlockParameters[i]!!),
|
||||
getConverter().blockToBlock(catchBlocks[i], true)))
|
||||
}
|
||||
myResult = TryStatement(getConverter().blockToBlock(statement?.getTryBlock(), true),
|
||||
catches, getConverter().blockToBlock(statement?.getFinallyBlock(), true))
|
||||
}
|
||||
|
||||
public override fun visitWhileStatement(statement: PsiWhileStatement?): Unit {
|
||||
var condition: PsiExpression? = statement?.getCondition()
|
||||
val expression: Expression = (if (condition != null && condition?.getType() != null)
|
||||
this.getConverter().expressionToExpression(condition, condition?.getType())
|
||||
else
|
||||
getConverter().expressionToExpression(condition))
|
||||
myResult = WhileStatement(expression, getConverter().statementToStatement(statement?.getBody()))
|
||||
}
|
||||
|
||||
public override fun visitReturnStatement(statement: PsiReturnStatement?): Unit {
|
||||
val returnValue: PsiExpression? = statement?.getReturnValue()
|
||||
val methodReturnType: PsiType? = getConverter().getMethodReturnType()
|
||||
val expression: Expression = (if (returnValue != null && methodReturnType != null)
|
||||
this.getConverter().expressionToExpression(returnValue, methodReturnType)
|
||||
else
|
||||
getConverter().expressionToExpression(returnValue))
|
||||
myResult = ReturnStatement(expression)
|
||||
}
|
||||
|
||||
class object {
|
||||
private open fun isPlusPlusExpression(psiElement: PsiElement): Boolean {
|
||||
return (psiElement is PsiPostfixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS) ||
|
||||
(psiElement is PsiPrefixExpression && psiElement.getOperationTokenType() == JavaTokenType.PLUSPLUS)
|
||||
}
|
||||
|
||||
private open fun containsBreak(slice: List<PsiStatement?>): Boolean {
|
||||
for (s : PsiStatement? in slice)
|
||||
if ((s is PsiBreakStatement?))
|
||||
{
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private open fun getAllToNextBreak(allStatements: List<PsiStatement?>, start: Int): List<PsiStatement?> {
|
||||
var result: List<PsiStatement?> = LinkedList<PsiStatement?>()
|
||||
for (i in start..allStatements.size() - 1) {
|
||||
var s: PsiStatement? = allStatements.get(i)
|
||||
if (s is PsiBreakStatement || s is PsiReturnStatement) {
|
||||
return result
|
||||
}
|
||||
|
||||
if (!(s is PsiSwitchLabelStatement)) {
|
||||
result.add(s)
|
||||
}
|
||||
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private open fun splitToCases(body: PsiCodeBlock?): List<List<PsiStatement?>> {
|
||||
val cases: List<List<PsiStatement?>> = arrayList()
|
||||
var currentCaseStatements: List<PsiStatement?> = arrayList()
|
||||
var isFirst: Boolean = true
|
||||
if (body != null) {
|
||||
for (s : PsiStatement? in body.getStatements()) {
|
||||
if ((s is PsiSwitchLabelStatement?)) {
|
||||
if (isFirst) {
|
||||
isFirst = false
|
||||
}
|
||||
else {
|
||||
cases.add(currentCaseStatements)
|
||||
currentCaseStatements = LinkedList<PsiStatement?>()
|
||||
}
|
||||
}
|
||||
|
||||
currentCaseStatements.add(s)
|
||||
}
|
||||
cases.add(currentCaseStatements)
|
||||
}
|
||||
|
||||
return cases
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisi
|
||||
myResult = ClassType(identifier, resolvedClassTypeParams, true)
|
||||
}
|
||||
else {
|
||||
myResult = ClassType(identifier, myConverter.typesToTypeList(classType.getParameters()).requireNoNulls(), true)
|
||||
myResult = ClassType(identifier, myConverter.typesToTypeList(classType.getParameters()), true)
|
||||
}
|
||||
return myResult
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisi
|
||||
val superTypes = p!!.getSuperTypes()
|
||||
val boundType : Type = (if (superTypes.size > 0)
|
||||
ClassType(Identifier(getClassTypeName(superTypes[0]!!)),
|
||||
myConverter.typesToTypeList(superTypes[0]!!.getParameters()).requireNoNulls(),
|
||||
myConverter.typesToTypeList(superTypes[0]!!.getParameters()),
|
||||
true)
|
||||
else
|
||||
StarProjectionType())
|
||||
|
||||
Reference in New Issue
Block a user