JetBlockExpression.getStatements() returns List<JetExpression> instead of List<JetElement>

This commit is contained in:
Valentin Kipyatkov
2015-05-23 12:42:11 +03:00
parent 4927a58101
commit eef0e8e447
25 changed files with 52 additions and 58 deletions
@@ -403,7 +403,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
if (expr instanceof JetBlockExpression) {
JetBlockExpression blockExpression = (JetBlockExpression) expr;
List<JetElement> statements = blockExpression.getStatements();
List<JetExpression> statements = blockExpression.getStatements();
if (statements.size() == 0 || statements.size() == 1 && isEmptyExpression(statements.get(0))) {
return true;
}
@@ -497,9 +497,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (body instanceof JetBlockExpression) {
// If body's a block, it can contain variable declarations which may be used in the condition of a do-while loop.
// We handle this case separately because otherwise such variable will be out of the frame map after the block ends
List<JetElement> doWhileStatements = ((JetBlockExpression) body).getStatements();
List<JetExpression> doWhileStatements = ((JetBlockExpression) body).getStatements();
List<JetElement> statements = new ArrayList<JetElement>(doWhileStatements.size() + 1);
List<JetExpression> statements = new ArrayList<JetExpression>(doWhileStatements.size() + 1);
statements.addAll(doWhileStatements);
statements.add(condition);
@@ -1539,7 +1539,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private StackValue generateBlock(
List<JetElement> statements,
List<JetExpression> statements,
boolean isStatement,
Label labelBeforeLastExpression,
@Nullable final Label labelBlockEnd
@@ -1550,13 +1550,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
StackValue answer = StackValue.none();
for (Iterator<JetElement> iterator = statements.iterator(); iterator.hasNext(); ) {
JetElement possiblyLabeledStatement = iterator.next();
JetElement statement = possiblyLabeledStatement instanceof JetExpression
? JetPsiUtil.safeDeparenthesize((JetExpression) possiblyLabeledStatement, true)
: possiblyLabeledStatement;
for (Iterator<JetExpression> iterator = statements.iterator(); iterator.hasNext(); ) {
JetExpression possiblyLabeledStatement = iterator.next();
JetElement statement = JetPsiUtil.safeDeparenthesize(possiblyLabeledStatement, true);
if (statement instanceof JetNamedDeclaration) {
JetNamedDeclaration declaration = (JetNamedDeclaration) statement;
@@ -1915,7 +1912,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private static boolean endsWithReturn(JetElement bodyExpression) {
if (bodyExpression instanceof JetBlockExpression) {
List<JetElement> statements = ((JetBlockExpression) bodyExpression).getStatements();
List<JetExpression> statements = ((JetBlockExpression) bodyExpression).getStatements();
return statements.size() > 0 && statements.get(statements.size() - 1) instanceof JetReturnExpression;
}
@@ -1186,8 +1186,8 @@ public class JetControlFlowProcessor {
builder.enterLexicalScope(expression);
}
mark(expression);
List<JetElement> statements = expression.getStatements();
for (JetElement statement : statements) {
List<JetExpression> statements = expression.getStatements();
for (JetExpression statement : statements) {
generateInstructions(statement);
}
if (statements.isEmpty()) {
@@ -46,8 +46,8 @@ public class JetBlockExpression extends JetExpressionImpl implements JetStatemen
@ReadOnly
@NotNull
public List<JetElement> getStatements() {
return Arrays.asList(findChildrenByClass(JetElement.class));
public List<JetExpression> getStatements() {
return Arrays.asList(findChildrenByClass(JetExpression.class));
}
@Nullable
@@ -599,7 +599,7 @@ public class JetPsiFactory(private val project: Project) {
}
private class BlockWrapper(fakeBlockExpression: JetBlockExpression, private val expression: JetExpression) : JetBlockExpression(fakeBlockExpression.getNode()), JetPsiUtil.JetExpressionWrapper {
override fun getStatements(): List<JetElement> {
override fun getStatements(): List<JetExpression> {
return listOf(expression)
}
@@ -409,7 +409,7 @@ public class JetPsiUtil {
}
@Nullable
public static JetElement getExpressionOrLastStatementInBlock(@Nullable JetExpression expression) {
public static JetExpression getExpressionOrLastStatementInBlock(@Nullable JetExpression expression) {
if (expression instanceof JetBlockExpression) {
return getLastStatementInABlock((JetBlockExpression) expression);
}
@@ -417,9 +417,9 @@ public class JetPsiUtil {
}
@Nullable
public static JetElement getLastStatementInABlock(@Nullable JetBlockExpression blockExpression) {
public static JetExpression getLastStatementInABlock(@Nullable JetBlockExpression blockExpression) {
if (blockExpression == null) return null;
List<JetElement> statements = blockExpression.getStatements();
List<JetExpression> statements = blockExpression.getStatements();
return statements.isEmpty() ? null : statements.get(statements.size() - 1);
}
@@ -587,7 +587,7 @@ public class JetPsiUtil {
}
public static boolean checkVariableDeclarationInBlock(@NotNull JetBlockExpression block, @NotNull String varName) {
for (JetElement element : block.getStatements()) {
for (JetExpression element : block.getStatements()) {
if (element instanceof JetVariableDeclaration) {
if (((JetVariableDeclaration) element).getNameAsSafeName().asString().equals(varName)) {
return true;
@@ -152,7 +152,7 @@ public fun JetElement.blockExpressionsOrSingle(): Sequence<JetElement> =
if (this is JetBlockExpression) getStatements().asSequence() else sequenceOf(this)
public fun JetExpression.lastBlockStatementOrThis(): JetExpression
= (this as? JetBlockExpression)?.getStatements()?.lastIsInstanceOrNull<JetExpression>() ?: this
= (this as? JetBlockExpression)?.getStatements()?.lastOrNull() ?: this
public fun JetBlockExpression.contentRange(): PsiChildRange {
val first = (getLBrace()?.getNextSibling() ?: getFirstChild())
@@ -16,13 +16,14 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetBlockExpression
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetPsiUtil
public open class StatementFilter {
public open val filter: ((JetElement) -> Boolean)?
public open val filter: ((JetExpression) -> Boolean)?
get() = null
companion object {
@@ -30,7 +31,7 @@ public open class StatementFilter {
}
}
fun StatementFilter.filterStatements(block: JetBlockExpression): List<JetElement> {
fun StatementFilter.filterStatements(block: JetBlockExpression): List<JetExpression> {
if (filter == null || block is JetPsiUtil.JetExpressionWrapper) return block.getStatements()
return block.getStatements().filter { filter!!(it) }
}
@@ -180,9 +180,9 @@ public class ArgumentTypeResolver {
// This case is a temporary hack for 'if' branches.
// The right way to implement this logic is to interpret 'if' branches as function literals with explicitly-typed signatures
// (no arguments and no receiver) and therefore analyze them straight away (not in the 'complete' phase).
JetElement lastStatementInABlock = ResolvePackage.getLastStatementInABlock(context.statementFilter, blockExpression);
if (lastStatementInABlock instanceof JetExpression) {
return getLastElementDeparenthesized((JetExpression) lastStatementInABlock, context);
JetExpression lastStatementInABlock = ResolvePackage.getLastStatementInABlock(context.statementFilter, blockExpression);
if (lastStatementInABlock != null) {
return getLastElementDeparenthesized(lastStatementInABlock, context);
}
}
return deparenthesizedExpression;
@@ -321,7 +321,7 @@ public class CandidateResolver {
TemporaryTraceAndCache temporaryToResolveFunctionLiteral = TemporaryTraceAndCache.create(
context, "trace to resolve function literal with expected return type", argumentExpression);
JetElement statementExpression = JetPsiUtil.getExpressionOrLastStatementInBlock(functionLiteral.getBodyExpression());
JetExpression statementExpression = JetPsiUtil.getExpressionOrLastStatementInBlock(functionLiteral.getBodyExpression());
if (statementExpression == null) return;
boolean[] mismatch = new boolean[1];
ObservableBindingTrace errorInterceptingTrace = ExpressionTypingUtils.makeTraceInterceptingTypeMismatch(
@@ -313,9 +313,9 @@ public class ControlStructureTypingUtils {
if (expression.getStatements().isEmpty()) {
return checkExpressionType(expression, c);
}
JetElement lastStatement = JetPsiUtil.getLastStatementInABlock(expression);
if (lastStatement instanceof JetExpression) {
return checkExpressionTypeRecursively((JetExpression) lastStatement, c);
JetExpression lastStatement = JetPsiUtil.getLastStatementInABlock(expression);
if (lastStatement != null) {
return checkExpressionTypeRecursively(lastStatement, c);
}
return false;
}
@@ -320,12 +320,12 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
else if (body != null) {
WritableScope writableScope = newWritableScopeImpl(context, "do..while body scope");
conditionScope = writableScope;
List<JetElement> block;
List<JetExpression> block;
if (body instanceof JetBlockExpression) {
block = ((JetBlockExpression)body).getStatements();
}
else {
block = Collections.<JetElement>singletonList(body);
block = Collections.singletonList(body);
}
bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(
writableScope, block, CoercionStrategy.NO_COERCION, context);
@@ -150,7 +150,7 @@ public class ExpressionTypingServices {
@NotNull CoercionStrategy coercionStrategyForLastExpression,
@NotNull ExpressionTypingContext context
) {
List<JetElement> block = ResolvePackage.filterStatements(statementFilter, expression);
List<JetExpression> block = ResolvePackage.filterStatements(statementFilter, expression);
// SCRIPT: get code descriptor for script declaration
DeclarationDescriptor containingDescriptor = context.scope.getContainingDeclaration();
@@ -240,7 +240,7 @@ public abstract class ElementResolver protected(
get() {
val context = getContext()
if (context is JetBlockExpression) {
return context.getStatements().filterIsInstance<JetExpression>().lastOrNull() ?: context
return context.getStatements().lastOrNull() ?: context
}
return context
}
@@ -45,7 +45,7 @@ class PartialBodyResolveFilter(
private val nothingFunctionNames = HashSet(probablyNothingCallableNames.functionNames())
private val nothingVariableNames = HashSet(probablyNothingCallableNames.propertyNames())
override val filter: ((JetElement) -> Boolean)? = { it is JetExpression && statementMarks.statementMark(it) != MarkLevel.SKIP }
override val filter: ((JetExpression) -> Boolean)? = { statementMarks.statementMark(it) != MarkLevel.SKIP }
init {
assert(declaration.isAncestor(elementToResolve))
@@ -55,11 +55,11 @@ public class CodeInsightUtils {
}
if (element instanceof JetBlockExpression) {
List<JetElement> statements = ((JetBlockExpression) element).getStatements();
List<JetExpression> statements = ((JetBlockExpression) element).getStatements();
if (statements.size() == 1) {
JetElement elem = statements.get(0);
if (elem.getText().equals(element.getText()) && elem instanceof JetExpression) {
return (JetExpression) elem;
JetExpression statement = statements.get(0);
if (statement.getText().equals(element.getText())) {
return statement;
}
}
}
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.psi.JetElement;
import org.jetbrains.kotlin.psi.JetExpression;
import org.jetbrains.kotlin.psi.JetFinallySection;
import org.jetbrains.kotlin.psi.JetTryExpression;
@@ -51,7 +51,7 @@ public class KotlinTryFinallySurrounder extends KotlinTrySurrounderBase {
protected TextRange getTextRangeForCaret(@NotNull JetTryExpression expression) {
JetFinallySection block = expression.getFinallyBlock();
assert block != null : "Finally block should exists for " + expression.getText();
JetElement blockExpression = block.getFinalExpression().getStatements().get(0);
JetExpression blockExpression = block.getFinalExpression().getStatements().get(0);
return blockExpression.getTextRange();
}
@@ -63,7 +63,7 @@ public abstract class KotlinUnwrapRemoveBase extends AbstractUnwrapper<KotlinUnw
}
public void extractFromBlock(@NotNull JetBlockExpression block, @NotNull JetElement from) throws IncorrectOperationException {
List<JetElement> expressions = block.getStatements();
List<JetExpression> expressions = block.getStatements();
if (!expressions.isEmpty()) {
extract(expressions.get(0), expressions.get(expressions.size() - 1), from);
}
@@ -90,7 +90,7 @@ public class ConvertToExpressionBodyIntention : JetSelfTargetingOffsetIndependen
// Workaround for anonymous objects and similar expressions without resolution scope
// TODO: This should probably be fixed in front-end so that resolution scope is recorded for anonymous objects as well
val scopeExpression = ((declaration as? JetDeclarationWithBody)?.getBodyExpression() as? JetBlockExpression)
?.getStatements()?.singleOrNull() as? JetExpression
?.getStatements()?.singleOrNull()
?: return false
val declaredType = (declaration.resolveToDescriptor() as? CallableDescriptor)?.getReturnType() ?: return false
@@ -113,14 +113,12 @@ public class ConvertToExpressionBodyIntention : JetSelfTargetingOffsetIndependen
//TODO: IMO this is not good code, there should be a way to detect that JetExpression does not have value
is JetDeclaration, is JetLoopExpression -> return null // is JetExpression but does not have value
is JetExpression -> {
else -> {
if (statement is JetBinaryExpression && statement.getOperationToken() == JetTokens.EQ) return null // assignment does not have value
val expressionType = statement.analyze().getType(statement) ?: return null
if (!KotlinBuiltIns.isUnit(expressionType) && !KotlinBuiltIns.isNothing(expressionType)) return null
return statement
}
else -> return null
}
}
@@ -102,7 +102,7 @@ public class IfNullToElvisIntention : JetSelfTargetingRangeIntention<JetIfExpres
val then = ifExpression.getThen() ?: return null
if (then is JetBlockExpression) {
val statement = then.getStatements().singleOrNull() as? JetExpression ?: return null
val statement = then.getStatements().singleOrNull() ?: return null
return Data(initializer, prevStatement, statement)
}
else {
@@ -159,7 +159,7 @@ public class InvertIfConditionIntention : JetSelfTargetingIntention<JetIfExpress
private fun exitStatementExecutedAfter(expression: JetExpression): JetExpression? {
val parent = expression.getParent()
if (parent is JetBlockExpression) {
val lastStatement = parent.getStatements().lastIsInstanceOrNull<JetExpression>()!!
val lastStatement = parent.getStatements().last()
if (expression == lastStatement) {
return exitStatementExecutedAfter(parent)
}
@@ -53,7 +53,7 @@ fun JetBinaryExpression.expressionComparedToNull(): JetExpression? {
fun JetExpression.unwrapBlockOrParenthesis(): JetExpression {
val innerExpression = JetPsiUtil.safeDeparenthesize(this)
if (innerExpression is JetBlockExpression) {
val statement = innerExpression.getStatements().singleOrNull() as? JetExpression ?: return this
val statement = innerExpression.getStatements().singleOrNull() ?: return this
return JetPsiUtil.safeDeparenthesize(statement)
}
return innerExpression
@@ -80,7 +80,7 @@ public class ConvertMemberToExtensionIntention : JetSelfTargetingRangeIntention<
fun selectBody(declaration: JetDeclarationWithBody) {
if (bodyToSelect == null) {
val body = declaration.getBodyExpression()
bodyToSelect = if (body is JetBlockExpression) body.getStatements().single() as JetExpression else body
bodyToSelect = if (body is JetBlockExpression) body.getStatements().single() else body
}
}
@@ -61,7 +61,7 @@ object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() {
} as JetBlockExpression
if (actualContainer != container) {
val bodyExpression = actualContainer.getStatements().first() as JetExpression
val bodyExpression = actualContainer.getStatements().first()
originalElement = (bodyExpression as? JetReturnExpression)?.getReturnedExpression() ?: bodyExpression
}
@@ -504,7 +504,7 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
val defaultValue = descriptor.controlFlow.defaultOutputValue
val lastExpression = body.getStatements().lastOrNull() as? JetExpression
val lastExpression = body.getStatements().lastOrNull()
if (lastExpression is JetReturnExpression) return
val (defaultExpression, expressionToUnifyWith) =
@@ -110,12 +110,10 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override
@NotNull
public JsNode visitBlockExpression(@NotNull JetBlockExpression jetBlock, @NotNull TranslationContext context) {
List<JetElement> statements = jetBlock.getStatements();
List<JetExpression> statements = jetBlock.getStatements();
JsBlock jsBlock = new JsBlock();
for (JetElement statement : statements) {
assert statement instanceof JetExpression : "Elements in JetBlockExpression " +
"should be of type JetExpression";
JsNode jsNode = Translation.translateExpression((JetExpression)statement, context, jsBlock);
for (JetExpression statement : statements) {
JsNode jsNode = Translation.translateExpression(statement, context, jsBlock);
JsStatement jsStatement = convertToStatement(jsNode);
if (!JsAstUtils.isEmptyStatement(jsStatement)) {
jsBlock.getStatements().add(jsStatement);