mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
move operator assignment check for object to javac quirks inspection with fix (IDEA-154209)
This commit is contained in:
+1
-2
@@ -436,8 +436,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
if (rExpression == null) return null;
|
||||
final PsiType rType = rExpression.getType();
|
||||
HighlightInfo errorResult = null;
|
||||
if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true) ||
|
||||
PsiType.getJavaLangObject(containingFile.getManager(), assignment.getResolveScope()).equals(lType)) {
|
||||
if (!TypeConversionUtil.isBinaryOperatorApplicable(opSign, lType, rType, true)) {
|
||||
String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
|
||||
String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
|
||||
JavaHighlightUtil.formatType(lType),
|
||||
|
||||
+60
-3
@@ -16,16 +16,21 @@
|
||||
package com.intellij.codeInspection.compiler;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
|
||||
@@ -73,6 +78,28 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression assignment) {
|
||||
super.visitAssignmentExpression(assignment);
|
||||
final PsiType lType = assignment.getLExpression().getType();
|
||||
PsiJavaToken operationSign = assignment.getOperationSign();
|
||||
IElementType eqOpSign = operationSign.getTokenType();
|
||||
IElementType opSign = TypeConversionUtil.convertEQtoOperation(eqOpSign);
|
||||
if (opSign == null) return;
|
||||
final PsiExpression rExpression = assignment.getRExpression();
|
||||
if (rExpression == null) return;
|
||||
if (JavaSdkVersion.JDK_1_6.equals(JavaVersionService.getInstance().getJavaSdkVersion(assignment)) &&
|
||||
PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()).equals(lType)) {
|
||||
String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
|
||||
String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
|
||||
JavaHighlightUtil.formatType(lType),
|
||||
JavaHighlightUtil.formatType(rExpression.getType()));
|
||||
|
||||
myHolder.registerProblem(assignment, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new ReplaceAssignmentOperatorWithAssignmentFix(operationSign.getText()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitIdentifier(PsiIdentifier identifier) {
|
||||
super.visitIdentifier(identifier);
|
||||
@@ -83,4 +110,34 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
|
||||
myHolder.registerProblem(identifier, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReplaceAssignmentOperatorWithAssignmentFix implements LocalQuickFix {
|
||||
private final String myOperationSign;
|
||||
|
||||
public ReplaceAssignmentOperatorWithAssignmentFix(String operationSign) {
|
||||
myOperationSign = operationSign;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Replace ''" + myOperationSign + "'' with ''=''";
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Replace Operator Assignment with Assignment";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (element instanceof PsiAssignmentExpression) {
|
||||
PsiReplacementUtil.replaceOperatorAssignmentWithAssignmentExpression((PsiAssignmentExpression)element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class a {
|
||||
ia[~i | (i+=(!b?2:i))] -= i + 3.3;
|
||||
|
||||
// Object += String
|
||||
<error descr="Operator '+' cannot be applied to 'java.lang.Object', 'java.lang.String'">o += o + "string"</error>;
|
||||
o += o + "string";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Test {
|
||||
{
|
||||
Object o = "";
|
||||
<warning descr="Operator '+' cannot be applied to 'java.lang.Object', 'java.lang.String'">o += ""</warning>;
|
||||
System.out.println(o);
|
||||
}
|
||||
}
|
||||
+4
@@ -61,4 +61,8 @@ public class LightAdvHighlightingJdk6Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testUnreachableAssignments() { doTest(false, false); }
|
||||
public void testCompileTypeConstantsAccessibleFromStaticFieldInitializers() { doTest(false, false);}
|
||||
public void testInheritUnrelatedConcreteMethodsWithSameSignature() { doTest(false, false);}
|
||||
|
||||
public void testAssignmentFromStringToObject() {
|
||||
doTest(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -26,6 +26,8 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.FileTypeUtils;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -148,4 +150,48 @@ public class PsiReplacementUtil {
|
||||
getElementText(child, elementToReplace, replacement, out);
|
||||
}
|
||||
}
|
||||
|
||||
public static void replaceOperatorAssignmentWithAssignmentExpression(@NotNull PsiAssignmentExpression assignmentExpression) {
|
||||
final PsiJavaToken sign = assignmentExpression.getOperationSign();
|
||||
final PsiExpression lhs = assignmentExpression.getLExpression();
|
||||
final PsiExpression rhs = assignmentExpression.getRExpression();
|
||||
final String operator = sign.getText();
|
||||
final String newOperator = operator.substring(0, operator.length() - 1);
|
||||
final String lhsText = lhs.getText();
|
||||
final String rhsText = (rhs == null) ? "" : rhs.getText();
|
||||
final boolean parentheses = ParenthesesUtils.areParenthesesNeeded(sign, rhs);
|
||||
final String cast = getCastString(lhs, rhs);
|
||||
final StringBuilder newExpression = new StringBuilder(lhsText);
|
||||
newExpression.append('=').append(cast);
|
||||
if (!cast.isEmpty()) {
|
||||
newExpression.append('(');
|
||||
}
|
||||
newExpression.append(lhsText).append(newOperator);
|
||||
if (parentheses) {
|
||||
newExpression.append('(').append(rhsText).append(')');
|
||||
}
|
||||
else {
|
||||
newExpression.append(rhsText);
|
||||
}
|
||||
if (!cast.isEmpty()) {
|
||||
newExpression.append(')');
|
||||
}
|
||||
replaceExpression(assignmentExpression, newExpression.toString());
|
||||
}
|
||||
|
||||
private static String getCastString(PsiExpression lhs, PsiExpression rhs) {
|
||||
if (lhs == null || rhs == null) {
|
||||
return "";
|
||||
}
|
||||
final PsiType lType = lhs.getType();
|
||||
PsiType rType = rhs.getType();
|
||||
if (TypeConversionUtil.isNumericType(rType)) {
|
||||
rType = TypeConversionUtil.binaryNumericPromotion(lType, rType);
|
||||
}
|
||||
if (lType == null || rType == null ||
|
||||
TypeConversionUtil.isAssignable(lType, rType) || !TypeConversionUtil.areTypesConvertible(lType, rType)) {
|
||||
return "";
|
||||
}
|
||||
return '(' + lType.getCanonicalText() + ')';
|
||||
}
|
||||
}
|
||||
|
||||
+4
-45
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package com.siyeh.ipp.opassign;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.PsiAssignmentExpression;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaToken;
|
||||
import com.siyeh.IntentionPowerPackBundle;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ipp.base.MutablyNamedIntention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -42,47 +42,6 @@ public class ReplaceOperatorAssignmentWithAssignmentIntention extends MutablyNam
|
||||
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element) {
|
||||
final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)element;
|
||||
final PsiJavaToken sign = assignmentExpression.getOperationSign();
|
||||
final PsiExpression lhs = assignmentExpression.getLExpression();
|
||||
final PsiExpression rhs = assignmentExpression.getRExpression();
|
||||
final String operator = sign.getText();
|
||||
final String newOperator = operator.substring(0, operator.length() - 1);
|
||||
final String lhsText = lhs.getText();
|
||||
final String rhsText = (rhs == null) ? "" : rhs.getText();
|
||||
final boolean parentheses = ParenthesesUtils.areParenthesesNeeded(sign, rhs);
|
||||
final String cast = getCastString(lhs, rhs);
|
||||
final StringBuilder newExpression = new StringBuilder(lhsText);
|
||||
newExpression.append('=').append(cast);
|
||||
if (!cast.isEmpty()) {
|
||||
newExpression.append('(');
|
||||
}
|
||||
newExpression.append(lhsText).append(newOperator);
|
||||
if (parentheses) {
|
||||
newExpression.append('(').append(rhsText).append(')');
|
||||
}
|
||||
else {
|
||||
newExpression.append(rhsText);
|
||||
}
|
||||
if (!cast.isEmpty()) {
|
||||
newExpression.append(')');
|
||||
}
|
||||
PsiReplacementUtil.replaceExpression(assignmentExpression, newExpression.toString());
|
||||
}
|
||||
|
||||
private static String getCastString(PsiExpression lhs, PsiExpression rhs) {
|
||||
if (lhs == null || rhs == null) {
|
||||
return "";
|
||||
}
|
||||
final PsiType lType = lhs.getType();
|
||||
PsiType rType = rhs.getType();
|
||||
if (TypeConversionUtil.isNumericType(rType)) {
|
||||
rType = TypeConversionUtil.binaryNumericPromotion(lType, rType);
|
||||
}
|
||||
if (lType == null || rType == null ||
|
||||
TypeConversionUtil.isAssignable(lType, rType) || !TypeConversionUtil.areTypesConvertible(lType, rType)) {
|
||||
return "";
|
||||
}
|
||||
return '(' + lType.getCanonicalText() + ')';
|
||||
PsiReplacementUtil.replaceOperatorAssignmentWithAssignmentExpression((PsiAssignmentExpression)element);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user