mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IG: use normalize declaration fix and expand activation area when no highlight
for "C-style array declaration" inspection
This commit is contained in:
+88
-40
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2018 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2019 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,59 +18,107 @@ package com.siyeh.ig.fixes;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.JavaSharedImplUtil;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.DeclarationSearchUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class NormalizeDeclarationFix extends InspectionGadgetsFix {
|
||||
|
||||
private final boolean myCStyleDeclaration;
|
||||
|
||||
public NormalizeDeclarationFix(boolean cStyleDeclaration) {
|
||||
myCStyleDeclaration = cStyleDeclaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return InspectionGadgetsBundle.message("normalize.declaration.quickfix");
|
||||
return myCStyleDeclaration
|
||||
? InspectionGadgetsBundle.message("c.style.array.declaration.replace.quickfix")
|
||||
: InspectionGadgetsBundle.message("normalize.declaration.quickfix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement variableNameElement = descriptor.getPsiElement();
|
||||
final PsiVariable parent =
|
||||
(PsiVariable)variableNameElement.getParent();
|
||||
if (parent == null) {
|
||||
return;
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
if (!(element instanceof PsiVariable) && !(element instanceof PsiMethod)) {
|
||||
element = element.getParent();
|
||||
}
|
||||
if (parent instanceof PsiField) {
|
||||
parent.normalizeDeclaration();
|
||||
return;
|
||||
if (element instanceof PsiLocalVariable) {
|
||||
final PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof PsiDeclarationStatement)) {
|
||||
return;
|
||||
}
|
||||
PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)parent;
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiForStatement) {
|
||||
splitMultipleDeclarationInForStatementInitialization(declarationStatement);
|
||||
return;
|
||||
}
|
||||
final PsiElement[] elements = declarationStatement.getDeclaredElements();
|
||||
final PsiVariable variable = (PsiVariable)elements[0];
|
||||
variable.normalizeDeclaration();
|
||||
for (int i = 1; i < elements.length; i++) {
|
||||
declarationStatement = PsiTreeUtil.getNextSiblingOfType(declarationStatement, PsiDeclarationStatement.class);
|
||||
assert declarationStatement != null;
|
||||
JavaSharedImplUtil.normalizeBrackets((PsiVariable)declarationStatement.getDeclaredElements()[0]);
|
||||
}
|
||||
}
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (!(grandParent instanceof PsiDeclarationStatement)) {
|
||||
return;
|
||||
else if (element instanceof PsiField) {
|
||||
PsiField field = DeclarationSearchUtils.findFirstFieldInDeclaration((PsiField)element);
|
||||
PsiField nextField = field;
|
||||
int count = 0;
|
||||
while (nextField != null) {
|
||||
count++;
|
||||
nextField = DeclarationSearchUtils.findNextFieldInDeclaration(nextField);
|
||||
}
|
||||
field.normalizeDeclaration();
|
||||
for (int i = 1; i < count; i++) {
|
||||
field = PsiTreeUtil.getNextSiblingOfType(field, PsiField.class);
|
||||
assert field != null;
|
||||
JavaSharedImplUtil.normalizeBrackets(field);
|
||||
}
|
||||
}
|
||||
final PsiElement greatGrandParent = grandParent.getParent();
|
||||
if (greatGrandParent instanceof PsiForStatement) {
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement)grandParent;
|
||||
splitMultipleDeclarationInForStatementInitialization(
|
||||
declarationStatement);
|
||||
return;
|
||||
else if (element instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
|
||||
if (returnTypeElement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiType returnType = method.getReturnType();
|
||||
if (returnType == null) {
|
||||
return;
|
||||
}
|
||||
PsiElement child = method.getParameterList();
|
||||
while (!(child instanceof PsiCodeBlock)) {
|
||||
final PsiElement elementToDelete = child;
|
||||
child = child.getNextSibling();
|
||||
if (elementToDelete instanceof PsiJavaToken) {
|
||||
final IElementType tokenType = ((PsiJavaToken)elementToDelete).getTokenType();
|
||||
if (JavaTokenType.LBRACKET.equals(tokenType) || JavaTokenType.RBRACKET.equals(tokenType)) {
|
||||
elementToDelete.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiTypeElement typeElement = JavaPsiFacade.getElementFactory(project).createTypeElement(returnType);
|
||||
returnTypeElement.replace(typeElement);
|
||||
}
|
||||
parent.normalizeDeclaration();
|
||||
}
|
||||
|
||||
private static void splitMultipleDeclarationInForStatementInitialization(
|
||||
PsiDeclarationStatement declarationStatement) {
|
||||
private static void splitMultipleDeclarationInForStatementInitialization(PsiDeclarationStatement declarationStatement) {
|
||||
final PsiElement forStatement = declarationStatement.getParent();
|
||||
final PsiElement[] declaredElements =
|
||||
declarationStatement.getDeclaredElements();
|
||||
final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
|
||||
final Project project = forStatement.getProject();
|
||||
final PsiElementFactory factory =
|
||||
JavaPsiFacade.getElementFactory(project);
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiElement greatGreatGrandParent = forStatement.getParent();
|
||||
final PsiBlockStatement blockStatement;
|
||||
final PsiCodeBlock codeBlock;
|
||||
if (!(greatGreatGrandParent instanceof PsiCodeBlock)) {
|
||||
blockStatement = (PsiBlockStatement)
|
||||
factory.createStatementFromText("{}", forStatement);
|
||||
blockStatement = (PsiBlockStatement)factory.createStatementFromText("{}", forStatement);
|
||||
codeBlock = blockStatement.getCodeBlock();
|
||||
}
|
||||
else {
|
||||
@@ -85,19 +133,14 @@ public class NormalizeDeclarationFix extends InspectionGadgetsFix {
|
||||
final PsiVariable variable = (PsiVariable)declaredElement;
|
||||
final PsiType type = variable.getType();
|
||||
final String typeText = type.getCanonicalText();
|
||||
final StringBuilder newStatementText =
|
||||
new StringBuilder(typeText);
|
||||
newStatementText.append(' ');
|
||||
newStatementText.append(variable.getName());
|
||||
final StringBuilder newStatementText = new StringBuilder(typeText);
|
||||
newStatementText.append(' ').append(variable.getName());
|
||||
final PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null) {
|
||||
newStatementText.append('=');
|
||||
newStatementText.append(initializer.getText());
|
||||
newStatementText.append('=').append(initializer.getText());
|
||||
}
|
||||
newStatementText.append(';');
|
||||
final PsiStatement newStatement =
|
||||
factory.createStatementFromText(
|
||||
newStatementText.toString(), forStatement);
|
||||
final PsiStatement newStatement = factory.createStatementFromText(newStatementText.toString(), forStatement);
|
||||
if (codeBlock == null) {
|
||||
greatGreatGrandParent.addBefore(newStatement, forStatement);
|
||||
}
|
||||
@@ -105,12 +148,17 @@ public class NormalizeDeclarationFix extends InspectionGadgetsFix {
|
||||
codeBlock.add(newStatement);
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < declaredElements.length; i++) {
|
||||
for (int i = 0; i < declaredElements.length; i++) {
|
||||
final PsiElement declaredElement = declaredElements[i];
|
||||
if (!(declaredElement instanceof PsiVariable)) {
|
||||
continue;
|
||||
}
|
||||
declaredElement.delete();
|
||||
if (i == 0) {
|
||||
((PsiVariable)declaredElement).normalizeDeclaration();
|
||||
}
|
||||
else {
|
||||
declaredElement.delete();
|
||||
}
|
||||
}
|
||||
if (codeBlock != null) {
|
||||
codeBlock.add(forStatement);
|
||||
|
||||
+15
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2017 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2019 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,16 +30,12 @@ public class DeclarationSearchUtils {
|
||||
|
||||
private DeclarationSearchUtils() {}
|
||||
|
||||
public static boolean variableNameResolvesToTarget(
|
||||
@NotNull String variableName, @NotNull PsiVariable target,
|
||||
@NotNull PsiElement context) {
|
||||
|
||||
public static boolean variableNameResolvesToTarget(@NotNull String variableName, @NotNull PsiVariable target,
|
||||
@NotNull PsiElement context) {
|
||||
final Project project = context.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
final PsiResolveHelper resolveHelper = psiFacade.getResolveHelper();
|
||||
final PsiVariable variable =
|
||||
resolveHelper.resolveAccessibleReferencedVariable(
|
||||
variableName, context);
|
||||
final PsiVariable variable = resolveHelper.resolveAccessibleReferencedVariable(variableName, context);
|
||||
return target.equals(variable);
|
||||
}
|
||||
|
||||
@@ -98,4 +94,15 @@ public class DeclarationSearchUtils {
|
||||
}
|
||||
return cost == PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES;
|
||||
}
|
||||
|
||||
public static PsiField findFirstFieldInDeclaration(PsiField field) {
|
||||
final PsiTypeElement typeElement = field.getTypeElement();
|
||||
if (typeElement == null) return field; // e.g. enum constant
|
||||
return (PsiField)typeElement.getParent();
|
||||
}
|
||||
|
||||
public static PsiField findNextFieldInDeclaration(PsiField field) {
|
||||
final PsiField nextField = PsiTreeUtil.getNextSiblingOfType(field, PsiField.class);
|
||||
return nextField != null && field.getTypeElement() == nextField.getTypeElement() ? nextField : null;
|
||||
}
|
||||
}
|
||||
+28
-52
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2018 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2019 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,16 +16,15 @@
|
||||
package com.siyeh.ig.style;
|
||||
|
||||
import com.intellij.codeInspection.CleanupLocalInspectionTool;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.fixes.NormalizeDeclarationFix;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -61,53 +60,7 @@ public class CStyleArrayDeclarationInspection extends BaseInspection implements
|
||||
|
||||
@Override
|
||||
public InspectionGadgetsFix buildFix(Object... infos) {
|
||||
return new CStyleArrayDeclarationFix();
|
||||
}
|
||||
|
||||
private static class CStyleArrayDeclarationFix
|
||||
extends InspectionGadgetsFix {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"c.style.array.declaration.replace.quickfix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement().getParent();
|
||||
if (element instanceof PsiVariable) {
|
||||
final PsiVariable variable = (PsiVariable)element;
|
||||
variable.normalizeDeclaration();
|
||||
CodeStyleManager.getInstance(project).reformat(variable);
|
||||
}
|
||||
else if (element instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
|
||||
if (returnTypeElement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiType returnType = method.getReturnType();
|
||||
if (returnType == null) {
|
||||
return;
|
||||
}
|
||||
PsiElement child = method.getParameterList();
|
||||
while (!(child instanceof PsiCodeBlock)) {
|
||||
final PsiElement element1 = child;
|
||||
child = child.getNextSibling();
|
||||
if (element1 instanceof PsiJavaToken) {
|
||||
final PsiJavaToken token = (PsiJavaToken)element1;
|
||||
final IElementType tokenType = token.getTokenType();
|
||||
if (JavaTokenType.LBRACKET.equals(tokenType) || JavaTokenType.RBRACKET.equals(tokenType)) {
|
||||
token.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiTypeElement typeElement = JavaPsiFacade.getElementFactory(project).createTypeElement(returnType);
|
||||
returnTypeElement.replace(typeElement);
|
||||
}
|
||||
}
|
||||
return new NormalizeDeclarationFix(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -135,7 +88,12 @@ public class CStyleArrayDeclarationInspection extends BaseInspection implements
|
||||
if (elementType.equals(declaredType)) {
|
||||
return;
|
||||
}
|
||||
registerVariableError(variable, variable);
|
||||
if (InspectionProjectProfileManager.isInformationLevel(getShortName(), variable)) {
|
||||
registerError(variable, variable);
|
||||
}
|
||||
else {
|
||||
registerVariableError(variable, variable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,6 +111,24 @@ public class CStyleArrayDeclarationInspection extends BaseInspection implements
|
||||
if (type.equals(returnType)) {
|
||||
return;
|
||||
}
|
||||
if (InspectionProjectProfileManager.isInformationLevel(getShortName(), method)) {
|
||||
registerError(typeElement, method);
|
||||
PsiElement child = method.getParameterList();
|
||||
PsiJavaToken first = null;
|
||||
PsiJavaToken last = null;
|
||||
while (!(child instanceof PsiCodeBlock)) {
|
||||
if (child instanceof PsiJavaToken) {
|
||||
PsiJavaToken token = (PsiJavaToken)child;
|
||||
final IElementType tokenType = token.getTokenType();
|
||||
if (JavaTokenType.LBRACKET.equals(tokenType) || JavaTokenType.RBRACKET.equals(tokenType)) {
|
||||
if (first == null) first = token;
|
||||
last = token;
|
||||
}
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
if (first != null) registerErrorAtRange(first, last, method);
|
||||
}
|
||||
registerMethodError(method, method);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
class FieldWithWhitespace {
|
||||
|
||||
String[] s;
|
||||
String[] s;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class InForLoop {
|
||||
void x(int i) {
|
||||
if (true) {
|
||||
int[] is = {};
|
||||
for (int[] ii = {0}; i < 10; i++) {}
|
||||
}
|
||||
}}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
class InForLoop {
|
||||
void x(int i) {
|
||||
if (true) for (int ii[] = {0}, is<caret>[] = {}; i < 10; i++) {}
|
||||
}}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class X {
|
||||
|
||||
int[] array;
|
||||
int[][] array2;
|
||||
int[][][] array3;
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
class X {
|
||||
|
||||
int[] array, array2<caret>[], array3[][];
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class X {{
|
||||
|
||||
int[] array;
|
||||
int[][] array2;
|
||||
int[][][] array3;
|
||||
}}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
class X {{
|
||||
|
||||
int[] array, array2<caret>[], array3[][];
|
||||
}}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
public class SimpleMethod {
|
||||
|
||||
public String[] ohGod(String[] a) {
|
||||
public String[]/*2*/ ohGod(String[] a)/*1*/ {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
public class SimpleMethod {
|
||||
|
||||
public String ohGo<caret>d(String[] a)[] {
|
||||
public String/*2*/ ohGo<caret>d(String[] a)/*1*/[] {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
+4
-15
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2019 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.siyeh.ig.fixes.style;
|
||||
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
@@ -26,6 +12,9 @@ public class CStyleArrayDeclarationFixTest extends IGQuickFixesTestCase {
|
||||
|
||||
public void testSimpleMethod() { doTest(); }
|
||||
public void testFieldWithWhitespace() { doTest(); }
|
||||
public void testInForLoop() { doTest(); }
|
||||
public void testMultipleVariablesSingleDeclaration() { doTest(); }
|
||||
public void testMultipleFieldsSingleDeclaration() { doTest(); }
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user