mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java] value breaks: PSI improvements (IDEA-CR-40172)
This commit is contained in:
+6
-2
@@ -783,17 +783,19 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
@Nullable
|
||||
static HighlightInfo checkValueBreakExpression(@NotNull PsiBreakStatement statement, @Nullable PsiExpression expression) {
|
||||
PsiElement enclosing = PsiImplUtil.findEnclosingSwitchOrLoop(statement);
|
||||
boolean plainRef = PsiImplUtil.isPlainReference(expression);
|
||||
|
||||
if (enclosing instanceof PsiSwitchExpression) {
|
||||
if (expression == null) {
|
||||
String message = JavaErrorMessages.message("value.break.missing");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create();
|
||||
}
|
||||
if (PsiTreeUtil.isAncestor(statement.findExitedElement(), enclosing, true)) {
|
||||
if (plainRef && PsiTreeUtil.isAncestor(((PsiReferenceExpression)expression).resolve(), enclosing, true)) {
|
||||
String message = JavaErrorMessages.message("break.outside.switch.expr");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create();
|
||||
}
|
||||
}
|
||||
else if (expression != null && (!PsiImplUtil.isPlainReference(expression) || ((PsiReferenceExpression)expression).resolve() instanceof PsiVariable)) {
|
||||
else if (expression != null && !plainRef) {
|
||||
String message = JavaErrorMessages.message("value.break.unexpected");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create();
|
||||
}
|
||||
@@ -814,6 +816,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
@Nullable
|
||||
static HighlightInfo checkContinueTarget(@NotNull PsiContinueStatement statement, @NotNull PsiIdentifier label, @NotNull LanguageLevel level) {
|
||||
PsiStatement continuedStatement = statement.findContinuedStatement();
|
||||
|
||||
if (continuedStatement == null) {
|
||||
String message = JavaErrorMessages.message("unresolved.label", label.getText());
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(label).descriptionAndTooltip(message).create();
|
||||
@@ -822,6 +825,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
String message = JavaErrorMessages.message("not.loop.label", label.getText());
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message).create();
|
||||
}
|
||||
|
||||
if (level.isAtLeast(LanguageLevel.JDK_12_PREVIEW)) {
|
||||
PsiElement enclosing = PsiImplUtil.findEnclosingSwitchOrLoop(statement);
|
||||
if (enclosing instanceof PsiSwitchExpression && PsiTreeUtil.isAncestor(continuedStatement, enclosing, true)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -8,14 +9,21 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface PsiBreakStatement extends PsiStatement {
|
||||
/**
|
||||
* Returns the label identifier iff it is present and the statement is not inside a switch expression, {@code null} otherwise.
|
||||
*
|
||||
* @see #getExpression()
|
||||
* Returns the label expression iff it is present, is an unqualified reference, and the statement is not inside a switch expression,
|
||||
* {@code null} otherwise.
|
||||
*/
|
||||
@Nullable PsiIdentifier getLabelIdentifier();
|
||||
@Nullable PsiReferenceExpression getLabelExpression();
|
||||
|
||||
/**
|
||||
* Returns the label/value expression, or {@code null} if the statement is empty.
|
||||
* Returns the value expression iff it is present and the statement is inside a switch expression, {@code null} otherwise.
|
||||
*/
|
||||
@Nullable PsiExpression getValueExpression();
|
||||
|
||||
/**
|
||||
* Returns the label or value expression, or {@code null} if the statement is empty.
|
||||
*
|
||||
* @see #getLabelExpression()
|
||||
* @see #getValueExpression()
|
||||
*/
|
||||
@Nullable PsiExpression getExpression();
|
||||
|
||||
@@ -25,7 +33,15 @@ public interface PsiBreakStatement extends PsiStatement {
|
||||
*/
|
||||
@Nullable PsiElement findExitedElement();
|
||||
|
||||
/** @deprecated doesn't support "switch" expressions; use {@link #findExitedElement()} instead */
|
||||
/** @deprecated doesn't support switch expressions; use {@link #getLabelExpression()}} instead */
|
||||
@Deprecated
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
default PsiIdentifier getLabelIdentifier() {
|
||||
PsiReferenceExpression expression = getLabelExpression();
|
||||
return expression != null ? PsiTreeUtil.getChildOfType(expression, PsiIdentifier.class) : null;
|
||||
}
|
||||
|
||||
/** @deprecated doesn't support switch expressions; use {@link #findExitedElement()} instead */
|
||||
@Deprecated
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
default PsiStatement findExitedStatement() {
|
||||
|
||||
+17
-18
@@ -8,7 +8,6 @@ import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.psi.tree.ChildRoleBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiBreakStatementImpl extends CompositePsiElement implements PsiBreakStatement {
|
||||
@@ -19,9 +18,17 @@ public class PsiBreakStatementImpl extends CompositePsiElement implements PsiBre
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiIdentifier getLabelIdentifier() {
|
||||
PsiIdentifier labelId = labelId();
|
||||
return labelId != null && !(findExitedElement() instanceof PsiSwitchExpression) ? labelId : null;
|
||||
public PsiReferenceExpression getLabelExpression() {
|
||||
PsiExpression expression = getExpression();
|
||||
boolean isLabel = PsiImplUtil.isPlainReference(expression) && !(PsiImplUtil.findEnclosingSwitchOrLoop(this) instanceof PsiSwitchExpression);
|
||||
return isLabel ? (PsiReferenceExpression)expression : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression getValueExpression() {
|
||||
PsiExpression expression = getExpression();
|
||||
boolean isValue = expression != null && PsiImplUtil.findEnclosingSwitchOrLoop(this) instanceof PsiSwitchExpression;
|
||||
return isValue ? expression : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,29 +38,21 @@ public class PsiBreakStatementImpl extends CompositePsiElement implements PsiBre
|
||||
|
||||
@Override
|
||||
public PsiElement findExitedElement() {
|
||||
PsiIdentifier label = labelId();
|
||||
if (label == null) {
|
||||
return PsiImplUtil.findEnclosingSwitchOrLoop(this);
|
||||
PsiElement enclosing = PsiImplUtil.findEnclosingSwitchOrLoop(this);
|
||||
PsiExpression expression = getExpression();
|
||||
|
||||
if (enclosing == null || enclosing instanceof PsiSwitchExpression || !PsiImplUtil.isPlainReference(expression)) {
|
||||
return enclosing;
|
||||
}
|
||||
|
||||
PsiLabeledStatement labeled = PsiImplUtil.findEnclosingLabeledStatement(this, label.getText());
|
||||
PsiLabeledStatement labeled = PsiImplUtil.findEnclosingLabeledStatement(enclosing, expression.getText());
|
||||
if (labeled != null) {
|
||||
return labeled.getStatement();
|
||||
}
|
||||
|
||||
PsiElement enclosing = PsiImplUtil.findEnclosingSwitchOrLoop(this);
|
||||
if (enclosing instanceof PsiSwitchExpression) {
|
||||
return enclosing;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private PsiIdentifier labelId() {
|
||||
PsiExpression expr = getExpression();
|
||||
return PsiImplUtil.isPlainReference(expr) ? PsiTreeUtil.getChildOfType(expr, PsiIdentifier.class) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode findChildByRole(int role) {
|
||||
LOG.assertTrue(ChildRole.isUnique(role));
|
||||
|
||||
Reference in New Issue
Block a user