From 9093d4c373b3727aa908712ec39e9316051910ef Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 16 Aug 2013 19:22:57 +0400 Subject: [PATCH] wrap if branches in blocks --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 17 +++++++++++++++++ .../lang/resolve/calls/CandidateResolver.java | 11 ++++++++++- .../calls/autocasts/DataFlowValueFactory.java | 11 +++++++++++ .../ControlStructureTypingUtils.java | 18 ++++++++++-------- .../ControlStructureTypingVisitor.java | 4 +++- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 34de2425d94..f4bf83011f0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -31,6 +31,7 @@ import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.JetFileType; +import java.util.Collections; import java.util.List; public class JetPsiFactory { @@ -484,4 +485,20 @@ public class JetPsiFactory { JetClass klass = createClass(project, "class foo { class object { } }"); return klass.getClassObject(); } + + public static JetBlockExpression wrapInABlock(@NotNull final JetExpression expression) { + if (expression instanceof JetBlockExpression) { + return (JetBlockExpression) expression; + } + JetNamedFunction function = createFunction(expression.getProject(), "fun f() { " + expression.getText() + "}"); + JetBlockExpression block = (JetBlockExpression) function.getBodyExpression(); + assert block != null; + return new JetBlockExpression(block.getNode()) { + @NotNull + @Override + public List getStatements() { + return Collections.singletonList(expression); + } + }; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index 40870e98777..6696a5758d6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -478,7 +478,16 @@ public class CandidateResolver { BindingContextUtils.updateRecordedType(numberType, expression, context.trace, false); if (!(expression instanceof JetConstantExpression)) { - updateNumberType(numberType, JetPsiUtil.deparenthesizeWithNoTypeResolution(expression, false), context); + JetExpression deparenthesized = JetPsiUtil.deparenthesizeWithNoTypeResolution(expression, false); + if (deparenthesized != expression) { + updateNumberType(numberType, deparenthesized, context); + } + if (deparenthesized instanceof JetBlockExpression) { + JetElement lastStatement = JetPsiUtil.getLastStatementInABlock((JetBlockExpression) deparenthesized); + if (lastStatement instanceof JetExpression) { + updateNumberType(numberType, (JetExpression) lastStatement, context); + } + } return; } CompileTimeConstant constant = diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java index 780169f9878..87e53cfa9e5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java @@ -30,6 +30,8 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import java.util.List; + import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL; @@ -158,6 +160,15 @@ public class DataFlowValueFactory { return getIdForStableIdentifier(innerExpression, bindingContext); } + else if (expression instanceof JetBlockExpression) { + List statements = ((JetBlockExpression) expression).getStatements(); + if (statements.size() == 1) { + JetElement lastStatement = JetPsiUtil.getLastStatementInABlock((JetBlockExpression) expression); + if (lastStatement instanceof JetExpression) { + return getIdForStableIdentifier((JetExpression) lastStatement, bindingContext); + } + } + } else if (expression instanceof JetQualifiedExpression) { JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) expression; JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java index b86ed94ec5a..c3d974c61e5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java @@ -95,7 +95,8 @@ public class ControlStructureTypingUtils { noAnnotations, specialFunctionName, CallableMemberDescriptor.Kind.DECLARATION); TypeParameterDescriptor typeParameter = TypeParameterDescriptorImpl.createWithDefaultBound( - function, noAnnotations, false, Variance.INVARIANT, Name.identifierNoValidate(""), 0); + function, noAnnotations, false, Variance.INVARIANT, + Name.identifierNoValidate(""), 0); JetType type = new JetTypeImpl(typeParameter.getTypeConstructor(), JetScope.EMPTY); JetType nullableType = new JetTypeImpl( @@ -163,7 +164,7 @@ public class ControlStructureTypingUtils { /*package*/ static Call createCallForSpecialConstruction( @NotNull final JetExpression expression, - @NotNull List arguments + @NotNull List arguments ) { final List valueArguments = Lists.newArrayList(); for (JetExpression argument : arguments) { @@ -272,12 +273,13 @@ public class ControlStructureTypingUtils { @Override public Void visitBlockExpression(JetBlockExpression expression, CheckTypeContext c) { - List statements = expression.getStatements(); - if (!statements.isEmpty()) { - JetElement lastElement = statements.get(statements.size() - 1); - if (lastElement instanceof JetExpression) { - checkExpressionType((JetExpression) lastElement, c); - } + if (expression.getStatements().isEmpty()) { + visitExpression(expression, c); + return null; + } + JetElement lastStatement = JetPsiUtil.getLastStatementInABlock(expression); + if (lastStatement instanceof JetExpression) { + checkExpressionType((JetExpression) lastStatement, c); } return null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index c2b9bfb7b0f..3a789cfb40e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -114,7 +114,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { return getTypeInfoWhenOnlyOneBranchIsPresent( elseBranch, elseScope, elseInfo, thenInfo, contextWithExpectedType, ifExpression, isStatement); } - Call callForIf = createCallForSpecialConstruction(ifExpression, Lists.newArrayList(thenBranch, elseBranch)); + JetBlockExpression thenBlock = JetPsiFactory.wrapInABlock(thenBranch); + JetBlockExpression elseBlock = JetPsiFactory.wrapInABlock(elseBranch); + Call callForIf = createCallForSpecialConstruction(ifExpression, Lists.newArrayList(thenBlock, elseBlock)); MutableDataFlowInfoForArguments dataFlowInfoForArguments = createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo); ResolvedCall resolvedCall = resolveSpecialConstructionAsCall(