get rid of 'unwrapFromBlock'

do the logic in 'deparenthesize' method
This commit is contained in:
Svetlana Isakova
2013-09-17 18:56:54 +04:00
parent 4bf5bb18e9
commit 73c5cb07d8
10 changed files with 93 additions and 48 deletions
@@ -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<JetElement> getStatements() {
return Collections.<JetElement>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<JetElement> getStatements() {
return Collections.<JetElement>singletonList(expression);
}
@Override
public JetExpression getBaseExpression() {
return expression;
}
}
}
@@ -53,6 +53,10 @@ public class JetPsiUtil {
private JetPsiUtil() {
}
public interface JetExpressionWrapper {
JetExpression getBaseExpression();
}
public static <D> void visitChildren(@NotNull JetElement element, @NotNull JetTreeVisitor<D> 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<JetElement> 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;
}
@@ -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);
}
@@ -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<JetType> 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<ReceiverValue> variants =
AutoCastUtils.getAutoCastVariants(context.trace.getBindingContext(), context.dataFlowInfo, receiverToCast);
for (ReceiverValue receiverValue : variants) {
@@ -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();
@@ -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) {
@@ -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) ||
@@ -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 <!TYPE_MISMATCH!>""<!>
val b: Int = (<!TYPE_MISMATCH!>""<!>)
val c: Int = <!TYPE_MISMATCH!>""<!>: Int
val d: Int = <!TYPE_MISMATCH!><!TYPE_MISMATCH!>""<!>: Long<!>
foo(@l4 <!TYPE_MISMATCH!>""<!>)
foo((<!TYPE_MISMATCH!>""<!>))
foo(<!TYPE_MISMATCH!>""<!>: Int)
foo(<!TYPE_MISMATCH!><!TYPE_MISMATCH!>""<!>: Long<!>)
use(a, b, c, d)
}
fun foo(i: Int) = i
fun use(vararg a: Any?) = a
@@ -8,9 +8,9 @@ fun main(args : Array<String>) {
val <!UNUSED_VARIABLE!>h<!> : String = <!TYPE_MISMATCH!>v--<!>;
val <!UNUSED_VARIABLE!>h1<!> : String = <!TYPE_MISMATCH!>--v<!>;
val <!UNUSED_VARIABLE!>i<!> : String = <!TYPE_MISMATCH!>!true<!>;
val <!UNUSED_VARIABLE!>j<!> : String = <!TYPE_MISMATCH!>@foo <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!><!>;
val <!UNUSED_VARIABLE!>j1<!> : String = <!TYPE_MISMATCH!>@ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!><!>;
val <!UNUSED_VARIABLE!>j2<!> : String = <!TYPE_MISMATCH!>@@ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!><!>;
val <!UNUSED_VARIABLE!>j<!> : String = @foo <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!>;
val <!UNUSED_VARIABLE!>j1<!> : String = @ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!>;
val <!UNUSED_VARIABLE!>j2<!> : String = @@ <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!>;
val <!UNUSED_VARIABLE!>k<!> : String = <!TYPE_MISMATCH!>-1<!>;
val <!UNUSED_VARIABLE!>l<!> : String = <!TYPE_MISMATCH!>+1<!>;
}
@@ -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")