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:
@@ -90,7 +90,7 @@ public class JetPsiUtil {
|
|||||||
boolean deparenthesizeBinaryExpressionWithTypeRHS
|
boolean deparenthesizeBinaryExpressionWithTypeRHS
|
||||||
) {
|
) {
|
||||||
return deparenthesizeWithResolutionStrategy(
|
return deparenthesizeWithResolutionStrategy(
|
||||||
expression, deparenthesizeBinaryExpressionWithTypeRHS, /* deparenthesizeRecursively = */ true, null);
|
expression, deparenthesizeBinaryExpressionWithTypeRHS, /* deparenthesizeRecursively = */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -98,50 +98,58 @@ public class JetPsiUtil {
|
|||||||
@Nullable JetExpression expression,
|
@Nullable JetExpression expression,
|
||||||
boolean deparenthesizeBinaryExpressionWithTypeRHS
|
boolean deparenthesizeBinaryExpressionWithTypeRHS
|
||||||
) {
|
) {
|
||||||
return deparenthesizeWithResolutionStrategy(
|
return deparenthesizeOnce(expression, deparenthesizeBinaryExpressionWithTypeRHS, null);
|
||||||
expression, deparenthesizeBinaryExpressionWithTypeRHS, /* deparenthesizeRecursively = */ false, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetExpression deparenthesizeWithResolutionStrategy(
|
public static JetExpression deparenthesizeWithResolutionStrategy(
|
||||||
@Nullable JetExpression expression,
|
@Nullable JetExpression expression,
|
||||||
boolean deparenthesizeBinaryExpressionWithTypeRHS,
|
|
||||||
@Nullable Function<JetTypeReference, Void> typeResolutionStrategy
|
@Nullable Function<JetTypeReference, Void> typeResolutionStrategy
|
||||||
) {
|
) {
|
||||||
return deparenthesizeWithResolutionStrategy(expression, true, true, typeResolutionStrategy);
|
return deparenthesizeWithResolutionStrategy(expression, true, typeResolutionStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static JetExpression deparenthesizeWithResolutionStrategy(
|
private static JetExpression deparenthesizeWithResolutionStrategy(
|
||||||
@Nullable JetExpression expression,
|
@Nullable JetExpression expression,
|
||||||
boolean deparenthesizeBinaryExpressionWithTypeRHS,
|
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
|
@Nullable Function<JetTypeReference, Void> typeResolutionStrategy
|
||||||
) {
|
) {
|
||||||
if (deparenthesizeBinaryExpressionWithTypeRHS && expression instanceof JetBinaryExpressionWithTypeRHS) {
|
if (deparenthesizeBinaryExpressionWithTypeRHS && expression instanceof JetBinaryExpressionWithTypeRHS) {
|
||||||
JetBinaryExpressionWithTypeRHS binaryExpression = (JetBinaryExpressionWithTypeRHS) expression;
|
JetBinaryExpressionWithTypeRHS binaryExpression = (JetBinaryExpressionWithTypeRHS) expression;
|
||||||
JetSimpleNameExpression operationSign = binaryExpression.getOperationReference();
|
JetSimpleNameExpression operationSign = binaryExpression.getOperationReference();
|
||||||
if (JetTokens.COLON.equals(operationSign.getReferencedNameElementType())) {
|
if (JetTokens.COLON.equals(operationSign.getReferencedNameElementType())) {
|
||||||
expression = binaryExpression.getLeft();
|
|
||||||
JetTypeReference typeReference = binaryExpression.getRight();
|
JetTypeReference typeReference = binaryExpression.getRight();
|
||||||
if (typeResolutionStrategy != null && typeReference != null) {
|
if (typeResolutionStrategy != null && typeReference != null) {
|
||||||
typeResolutionStrategy.apply(typeReference);
|
typeResolutionStrategy.apply(typeReference);
|
||||||
}
|
}
|
||||||
|
return binaryExpression.getLeft();
|
||||||
}
|
}
|
||||||
|
return expression;
|
||||||
}
|
}
|
||||||
else if (expression instanceof JetLabeledExpression) {
|
else if (expression instanceof JetLabeledExpression) {
|
||||||
JetExpression baseExpression = ((JetLabeledExpression) expression).getBaseExpression();
|
return ((JetLabeledExpression) expression).getBaseExpression();
|
||||||
if (baseExpression != null) {
|
|
||||||
expression = baseExpression;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (expression instanceof JetExpressionWrapper) {
|
else if (expression instanceof JetExpressionWrapper) {
|
||||||
expression = ((JetExpressionWrapper) expression).getBaseExpression();
|
return ((JetExpressionWrapper) expression).getBaseExpression();
|
||||||
}
|
}
|
||||||
if (expression instanceof JetParenthesizedExpression) {
|
else if (expression instanceof JetParenthesizedExpression) {
|
||||||
JetExpression innerExpression = ((JetParenthesizedExpression) expression).getExpression();
|
return ((JetParenthesizedExpression) expression).getExpression();
|
||||||
return innerExpression != null && deparenthesizeRecursively ? deparenthesizeWithResolutionStrategy(
|
|
||||||
innerExpression, deparenthesizeBinaryExpressionWithTypeRHS, true, typeResolutionStrategy) : innerExpression;
|
|
||||||
}
|
}
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public fun Call.getValueArgumentForExpression(expression: JetExpression): ValueA
|
|||||||
// Get call / resolved call from binding context
|
// Get call / resolved call from binding context
|
||||||
|
|
||||||
public fun JetElement?.getCalleeExpressionIfAny(): JetExpression? {
|
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) {
|
return when (element) {
|
||||||
is JetSimpleNameExpression -> element
|
is JetSimpleNameExpression -> element
|
||||||
is JetCallElement -> element.getCalleeExpression()
|
is JetCallElement -> element.getCalleeExpression()
|
||||||
|
|||||||
+1
-1
@@ -337,7 +337,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
|||||||
final ExpressionTypingContext context =
|
final ExpressionTypingContext context =
|
||||||
contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(scope).replaceContextDependency(INDEPENDENT);
|
contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(scope).replaceContextDependency(INDEPENDENT);
|
||||||
JetExpression leftOperand = expression.getLeft();
|
JetExpression leftOperand = expression.getLeft();
|
||||||
JetExpression left = deparenthesizeWithResolutionStrategy(leftOperand, true, new Function<JetTypeReference, Void>() {
|
JetExpression left = deparenthesizeWithResolutionStrategy(leftOperand, new Function<JetTypeReference, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void apply(JetTypeReference reference) {
|
public Void apply(JetTypeReference reference) {
|
||||||
components.typeResolver.resolveType(context.scope, reference, context.trace, true);
|
components.typeResolver.resolveType(context.scope, reference, context.trace, true);
|
||||||
|
|||||||
@@ -82,4 +82,15 @@ class C {
|
|||||||
}
|
}
|
||||||
a<!UNSAFE_CALL!>.<!>compareTo("2")
|
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
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
internal final fun notContainsBreak(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.String?): kotlin.Unit
|
internal final fun notContainsBreak(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.String?): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
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
|
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 object TestClass {
|
||||||
public fun main(args: Array<String>) {
|
public fun main(args: Array<String>) {
|
||||||
var i = 1
|
var i = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user