From 73c5cb07d8d527424402a26c1b0f75daacd7bac6 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 17 Sep 2013 18:56:54 +0400 Subject: [PATCH] get rid of 'unwrapFromBlock' do the logic in 'deparenthesize' method --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 40 ++++++++++++++----- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 32 +++++++-------- .../resolve/calls/ArgumentTypeResolver.java | 2 +- .../lang/resolve/calls/CandidateResolver.java | 7 ++-- .../calls/autocasts/DataFlowValueFactory.java | 12 +++--- .../BasicExpressionTypingVisitor.java | 5 +-- .../lang/types/expressions/DataFlowUtils.java | 5 +-- .../checkDeparenthesizedType.kt | 27 +++++++++++++ .../TypeMismatchOnUnaryOperations.kt | 6 +-- .../checkers/JetDiagnosticsTestGenerated.java | 5 +++ 10 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/deparenthesize/checkDeparenthesizedType.kt 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 096fbcc3a38..3d0a793aa65 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -535,19 +535,37 @@ public class JetPsiFactory { } @NotNull - public static JetBlockExpression wrapInABlock(@NotNull final JetExpression expression) { + public static JetBlockExpression wrapInABlock(@NotNull 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); - } - }; + return BlockWrapper.create(expression); + } + + private static class BlockWrapper extends JetBlockExpression implements JetPsiUtil.JetExpressionWrapper { + private final JetExpression expression; + + public static BlockWrapper create(@NotNull JetExpression expressionToWrap) { + JetNamedFunction function = createFunction(expressionToWrap.getProject(), "fun f() { " + expressionToWrap.getText() + "}"); + JetBlockExpression block = (JetBlockExpression) function.getBodyExpression(); + assert block != null; + return new BlockWrapper(block, expressionToWrap); + } + + private BlockWrapper(@NotNull JetBlockExpression fakeBlockExpression, @NotNull JetExpression expressionToWrap) { + super(fakeBlockExpression.getNode()); + this.expression = expressionToWrap; + } + + @NotNull + @Override + public List getStatements() { + return Collections.singletonList(expression); + } + + @Override + public JetExpression getBaseExpression() { + return expression; + } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 114ee6ea72a..610a3f47fb2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -53,6 +53,10 @@ public class JetPsiUtil { private JetPsiUtil() { } + public interface JetExpressionWrapper { + JetExpression getBaseExpression(); + } + public static void visitChildren(@NotNull JetElement element, @NotNull JetTreeVisitor visitor, D data) { PsiElement child = element.getFirstChild(); while (child != null) { @@ -63,14 +67,20 @@ public class JetPsiUtil { } } + @NotNull + public static JetExpression safeDeparenthesize(@NotNull JetExpression expression, boolean deparenthesizeBinaryExpressionWithTypeRHS) { + JetExpression deparenthesized = deparenthesize(expression, deparenthesizeBinaryExpressionWithTypeRHS); + return deparenthesized != null ? deparenthesized : expression; + } + @Nullable - public static JetExpression deparenthesize(@NotNull JetExpression expression) { + public static JetExpression deparenthesize(@Nullable JetExpression expression) { return deparenthesize(expression, true); } @Nullable public static JetExpression deparenthesize( - @NotNull JetExpression expression, + @Nullable JetExpression expression, boolean deparenthesizeBinaryExpressionWithTypeRHS ) { return deparenthesizeWithResolutionStrategy(expression, deparenthesizeBinaryExpressionWithTypeRHS, null); @@ -100,6 +110,9 @@ public class JetPsiUtil { expression = baseExpression; } } + else if (expression instanceof JetExpressionWrapper) { + expression = ((JetExpressionWrapper) expression).getBaseExpression(); + } if (expression instanceof JetParenthesizedExpression) { JetExpression innerExpression = ((JetParenthesizedExpression) expression).getExpression(); return innerExpression != null ? deparenthesizeWithResolutionStrategy( @@ -564,21 +577,6 @@ public class JetPsiUtil { return statements.isEmpty() ? null : statements.get(statements.size() - 1); } - @NotNull - public static JetExpression unwrapFromBlock(@NotNull JetExpression expression) { - //used for 'if' branches that are wrapped in a block - if (expression instanceof JetBlockExpression) { - List statements = ((JetBlockExpression) expression).getStatements(); - if (statements.size() == 1) { - JetElement lastStatement = getLastStatementInABlock((JetBlockExpression) expression); - if (lastStatement instanceof JetExpression) { - return (JetExpression) lastStatement; - } - } - } - return expression; - } - public static boolean isLocalClass(@NotNull JetClassOrObject classOrObject) { return getOutermostClassOrObject(classOrObject) == null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java index a863f092128..6f13e67e66a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java @@ -174,7 +174,7 @@ public class ArgumentTypeResolver { if (expression == null) { return JetTypeInfo.create(null, context.dataFlowInfo); } - JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(JetPsiUtil.unwrapFromBlock(expression), false); + JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(expression, false); if (deparenthesizedExpression instanceof JetFunctionLiteralExpression) { return getFunctionLiteralTypeInfo(expression, (JetFunctionLiteralExpression) deparenthesizedExpression, context, resolveArgumentsMode); } 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 e9e470c84ae..941952349e8 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 @@ -470,8 +470,7 @@ public class CandidateResolver { ) { JetExpression argumentExpression = valueArgument.getArgumentExpression(); if (argumentExpression == null) return; - JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize( - JetPsiUtil.unwrapFromBlock(argumentExpression), false); + JetExpression deparenthesizedExpression = JetPsiUtil.deparenthesize(argumentExpression, false); if (!(deparenthesizedExpression instanceof JetFunctionLiteralExpression)) return; JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) deparenthesizedExpression; @@ -640,7 +639,7 @@ public class CandidateResolver { if (argumentExpression == null || type == null) return type; DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue( - JetPsiUtil.unwrapFromBlock(argumentExpression), type, trace.getBindingContext()); + argumentExpression, type, trace.getBindingContext()); if (!dataFlowValue.isStableIdentifier()) return type; Set possibleTypes = dataFlowInfoForArgument.getPossibleTypes(dataFlowValue); @@ -763,7 +762,7 @@ public class CandidateResolver { @NotNull JetType actualType, @NotNull ResolutionContext context ) { - ExpressionReceiver receiverToCast = new ExpressionReceiver(JetPsiUtil.unwrapFromBlock(expression), actualType); + ExpressionReceiver receiverToCast = new ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType); List variants = AutoCastUtils.getAutoCastVariants(context.trace.getBindingContext(), context.dataFlowInfo, receiverToCast); for (ReceiverValue receiverValue : variants) { 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 af4862cb167..45be05bd896 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 @@ -131,13 +131,13 @@ public class DataFlowValueFactory { @Nullable JetExpression expression, @NotNull BindingContext bindingContext ) { - if (expression instanceof JetParenthesizedExpression) { - JetParenthesizedExpression parenthesizedExpression = (JetParenthesizedExpression) expression; - JetExpression innerExpression = parenthesizedExpression.getExpression(); - - return getIdForStableIdentifier(innerExpression, bindingContext); + if (expression != null) { + JetExpression deparenthesized = JetPsiUtil.deparenthesize(expression); + if (expression != deparenthesized) { + return getIdForStableIdentifier(deparenthesized, bindingContext); + } } - else if (expression instanceof JetQualifiedExpression) { + if (expression instanceof JetQualifiedExpression) { JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) expression; JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); JetExpression selectorExpression = qualifiedExpression.getSelectorExpression(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 282f338f6fc..8deece0c42b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -114,8 +114,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (innerExpression == null) { return JetTypeInfo.create(null, context.dataFlowInfo); } - JetTypeInfo typeInfo = facade.getTypeInfo(innerExpression, context.replaceScope(context.scope), isStatement); - return DataFlowUtils.checkType(typeInfo, expression, context); + return facade.getTypeInfo(innerExpression, context.replaceScope(context.scope), isStatement); } private static JetTypeInfo createNumberValueTypeInfo( @@ -727,7 +726,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { // TODO : Some processing for the label? JetTypeInfo typeInfo = facade.getTypeInfo(baseExpression, context, isStatement); context.labelResolver.exitLabeledElement(baseExpression); - return DataFlowUtils.checkType(typeInfo, expression, context); + return typeInfo; } private static boolean isKnownToBeNotNull(JetExpression expression, ExpressionTypingContext context) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java index 24c02e87996..ae4b1fd54a3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java @@ -154,11 +154,10 @@ public class DataFlowUtils { } @Nullable - public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression possiblyWrappedInBlockExpression, + public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expressionToCheck, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace ) { - // non-block 'if' branches are wrapped in a block, but here genuine expressions (not wrappers) should be checked - JetExpression expression = JetPsiUtil.unwrapFromBlock(possiblyWrappedInBlockExpression); + JetExpression expression = JetPsiUtil.safeDeparenthesize(expressionToCheck, false); recordExpectedType(trace, expression, expectedType); if (expressionType == null || noExpectedType(expectedType) || diff --git a/compiler/testData/diagnostics/tests/deparenthesize/checkDeparenthesizedType.kt b/compiler/testData/diagnostics/tests/deparenthesize/checkDeparenthesizedType.kt new file mode 100644 index 00000000000..7b85984652f --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/checkDeparenthesizedType.kt @@ -0,0 +1,27 @@ +package m + +fun test(i: Int?) { + if (i != null) { + foo(@l1 i) + foo((i)) + foo(@l2 (i)) + foo((@l3 i)) + } + + val a: Int = @l4 "" + val b: Int = ("") + val c: Int = "": Int + val d: Int = "": Long + + + foo(@l4 "") + foo(("")) + foo("": Int) + foo("": Long) + + use(a, b, c, d) +} + +fun foo(i: Int) = i + +fun use(vararg a: Any?) = a diff --git a/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.kt b/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.kt index 41950e5a44d..1e698add86a 100644 --- a/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.kt +++ b/compiler/testData/diagnostics/tests/regressions/TypeMismatchOnUnaryOperations.kt @@ -8,9 +8,9 @@ fun main(args : Array) { val h : String = v--; val h1 : String = --v; val i : String = !true; - val j : String = @foo true; - val j1 : String = @ true; - val j2 : String = @@ true; + val j : String = @foo true; + val j1 : String = @ true; + val j2 : String = @@ true; val k : String = -1; val l : String = +1; } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 871dfabfad3..cf33fd156f7 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2485,6 +2485,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/deparenthesize/ArrayAccessAssignment.kt"); } + @TestMetadata("checkDeparenthesizedType.kt") + public void testCheckDeparenthesizedType() throws Exception { + doTest("compiler/testData/diagnostics/tests/deparenthesize/checkDeparenthesizedType.kt"); + } + } @TestMetadata("compiler/testData/diagnostics/tests/enum")