Rework deparenthesize-like methods

- Extract private `deparenthesizeOnce` and repeat it until get the same expression

- Drop redundant parameter `deparenthesizeRecursively`

- Drop some usages of `safeDeparenthesize` in `deparenthesize`
  because even if `deparenthesize` returns null (i.e. something was not parsed)
  there is no sense in working with such expressions

Note, that `deparenthesize` now unwraps nested labels' declaration (see changes in testData),
but it seems to be reasonable
This commit is contained in:
Denis Zharkov
2015-05-05 12:20:26 +03:00
parent b72a3de86e
commit 9101505eca
6 changed files with 38 additions and 19 deletions
@@ -90,7 +90,7 @@ public class JetPsiUtil {
boolean deparenthesizeBinaryExpressionWithTypeRHS
) {
return deparenthesizeWithResolutionStrategy(
expression, deparenthesizeBinaryExpressionWithTypeRHS, /* deparenthesizeRecursively = */ true, null);
expression, deparenthesizeBinaryExpressionWithTypeRHS, /* deparenthesizeRecursively = */ null);
}
@Nullable
@@ -98,50 +98,58 @@ public class JetPsiUtil {
@Nullable JetExpression expression,
boolean deparenthesizeBinaryExpressionWithTypeRHS
) {
return deparenthesizeWithResolutionStrategy(
expression, deparenthesizeBinaryExpressionWithTypeRHS, /* deparenthesizeRecursively = */ false, null);
return deparenthesizeOnce(expression, deparenthesizeBinaryExpressionWithTypeRHS, null);
}
@Nullable
public static JetExpression deparenthesizeWithResolutionStrategy(
@Nullable JetExpression expression,
boolean deparenthesizeBinaryExpressionWithTypeRHS,
@Nullable Function<JetTypeReference, Void> typeResolutionStrategy
) {
return deparenthesizeWithResolutionStrategy(expression, true, true, typeResolutionStrategy);
return deparenthesizeWithResolutionStrategy(expression, true, typeResolutionStrategy);
}
@Nullable
private static JetExpression deparenthesizeWithResolutionStrategy(
@Nullable JetExpression expression,
boolean deparenthesizeBinaryExpressionWithTypeRHS,
boolean deparenthesizeRecursively,
@Nullable Function<JetTypeReference, Void> typeResolutionStrategy
) {
while (true) {
JetExpression baseExpression =
deparenthesizeOnce(expression, deparenthesizeBinaryExpressionWithTypeRHS, typeResolutionStrategy);
if (baseExpression == expression) return baseExpression;
expression = baseExpression;
}
}
@Nullable
private static JetExpression deparenthesizeOnce(
@Nullable JetExpression expression,
boolean deparenthesizeBinaryExpressionWithTypeRHS,
@Nullable Function<JetTypeReference, Void> typeResolutionStrategy
) {
if (deparenthesizeBinaryExpressionWithTypeRHS && expression instanceof JetBinaryExpressionWithTypeRHS) {
JetBinaryExpressionWithTypeRHS binaryExpression = (JetBinaryExpressionWithTypeRHS) expression;
JetSimpleNameExpression operationSign = binaryExpression.getOperationReference();
if (JetTokens.COLON.equals(operationSign.getReferencedNameElementType())) {
expression = binaryExpression.getLeft();
JetTypeReference typeReference = binaryExpression.getRight();
if (typeResolutionStrategy != null && typeReference != null) {
typeResolutionStrategy.apply(typeReference);
}
return binaryExpression.getLeft();
}
return expression;
}
else if (expression instanceof JetLabeledExpression) {
JetExpression baseExpression = ((JetLabeledExpression) expression).getBaseExpression();
if (baseExpression != null) {
expression = baseExpression;
}
return ((JetLabeledExpression) expression).getBaseExpression();
}
else if (expression instanceof JetExpressionWrapper) {
expression = ((JetExpressionWrapper) expression).getBaseExpression();
return ((JetExpressionWrapper) expression).getBaseExpression();
}
if (expression instanceof JetParenthesizedExpression) {
JetExpression innerExpression = ((JetParenthesizedExpression) expression).getExpression();
return innerExpression != null && deparenthesizeRecursively ? deparenthesizeWithResolutionStrategy(
innerExpression, deparenthesizeBinaryExpressionWithTypeRHS, true, typeResolutionStrategy) : innerExpression;
else if (expression instanceof JetParenthesizedExpression) {
return ((JetParenthesizedExpression) expression).getExpression();
}
return expression;
}
@@ -101,7 +101,7 @@ public fun Call.getValueArgumentForExpression(expression: JetExpression): ValueA
// Get call / resolved call from binding context
public fun JetElement?.getCalleeExpressionIfAny(): JetExpression? {
val element = if (this is JetExpression) JetPsiUtil.safeDeparenthesize(this, false) else this
val element = if (this is JetExpression) JetPsiUtil.deparenthesize(this, false) else this
return when (element) {
is JetSimpleNameExpression -> element
is JetCallElement -> element.getCalleeExpression()
@@ -337,7 +337,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
final ExpressionTypingContext context =
contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(scope).replaceContextDependency(INDEPENDENT);
JetExpression leftOperand = expression.getLeft();
JetExpression left = deparenthesizeWithResolutionStrategy(leftOperand, true, new Function<JetTypeReference, Void>() {
JetExpression left = deparenthesizeWithResolutionStrategy(leftOperand, new Function<JetTypeReference, Void>() {
@Override
public Void apply(JetTypeReference reference) {
components.typeResolver.resolveType(context.scope, reference, context.trace, true);
@@ -82,4 +82,15 @@ class C {
}
a<!UNSAFE_CALL!>.<!>compareTo("2")
}
fun twoLabelsOnLoop() {
label1@ label2@ for (i in 1..100) {
if (i > 0) {
break@label1
}
else {
break@label2
}
}
}
}
@@ -12,5 +12,6 @@ internal final class C {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final fun notContainsBreak(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.String?): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final fun twoLabelsOnLoop(): kotlin.Unit
internal final fun unresolvedBreak(/*0*/ a: kotlin.String?, /*1*/ array: kotlin.Array<kotlin.Int>): kotlin.Unit
}
@@ -1,4 +1,3 @@
// ERROR: The label '@OuterLoop1' does not denote a loop
public object TestClass {
public fun main(args: Array<String>) {
var i = 1