mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -262,4 +262,7 @@ public abstract class QuickFixFactory {
|
||||
@NotNull Collection<String> missedElements);
|
||||
@NotNull
|
||||
public abstract IntentionAction createSurroundWithQuotesAnnotationParameterValueFix(@NotNull PsiAnnotationMemberValue value, @NotNull PsiType expectedType);
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall);
|
||||
}
|
||||
|
||||
+2
-12
@@ -26,18 +26,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
* - work with PSI or document only and
|
||||
* - don't provide {@link com.intellij.codeInsight.intention.IntentionAction} for quick fixes/suppression, making do with {@link LocalQuickFix} only.
|
||||
*/
|
||||
public abstract class BaseJavaBatchLocalInspectionTool extends AbstractBaseJavaLocalInspectionTool implements BatchSuppressableTool {
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
return BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(getShortName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressedFor(@NotNull PsiElement element) {
|
||||
return isSuppressedFor(element, this);
|
||||
}
|
||||
|
||||
public abstract class BaseJavaBatchLocalInspectionTool extends AbstractBaseJavaLocalInspectionTool {
|
||||
@Deprecated
|
||||
public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
|
||||
BatchSuppressManager manager = BatchSuppressManager.SERVICE.getInstance();
|
||||
String alternativeId;
|
||||
|
||||
+1
-5
@@ -42,11 +42,7 @@ public abstract class BaseJavaLocalInspectionTool extends AbstractBaseJavaLocalI
|
||||
return SuppressManager.getInstance().createSuppressActions(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressedFor(@NotNull PsiElement element) {
|
||||
return isSuppressedFor(element, this);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
|
||||
return BaseJavaBatchLocalInspectionTool.isSuppressedFor(element, tool);
|
||||
}
|
||||
|
||||
+1
-11
@@ -26,7 +26,7 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class GlobalJavaBatchInspectionTool extends GlobalInspectionTool implements BatchSuppressableTool {
|
||||
public abstract class GlobalJavaBatchInspectionTool extends GlobalInspectionTool {
|
||||
@Override
|
||||
public boolean queryExternalUsagesRequests(@NotNull final InspectionManager manager,
|
||||
@NotNull final GlobalInspectionContext globalContext,
|
||||
@@ -38,14 +38,4 @@ public abstract class GlobalJavaBatchInspectionTool extends GlobalInspectionTool
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
return BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(getShortName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressedFor(@NotNull final PsiElement element) {
|
||||
return BatchSuppressManager.SERVICE.getInstance().isSuppressedFor(element, getShortName());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -26,7 +26,7 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool implements CustomSuppressableInspectionTool {
|
||||
public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool {
|
||||
@Override
|
||||
public boolean queryExternalUsagesRequests(@NotNull final InspectionManager manager,
|
||||
@NotNull final GlobalInspectionContext globalContext,
|
||||
@@ -38,10 +38,10 @@ public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool impl
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@Nullable
|
||||
public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
|
||||
return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
return BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(HighlightDisplayKey.find(getShortName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
@@ -670,6 +670,7 @@ public class HighlightMethodUtil {
|
||||
registerChangeParameterClassFix(methodCall, list, highlightInfo);
|
||||
if (methodCandidates.length == 0) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.createStaticImportMethodFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.addMethodQualifierFix(methodCall));
|
||||
}
|
||||
for (IntentionAction action : QUICK_FIX_FACTORY.getVariableTypeFromCallFixes(methodCall, list)) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, action);
|
||||
|
||||
+6
@@ -602,4 +602,10 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
|
||||
@NotNull PsiType expectedType) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-1
@@ -583,7 +583,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (dfaLeft instanceof DfaVariableValue) {
|
||||
DfaVariableValue dfaVar = (DfaVariableValue)dfaLeft;
|
||||
if (isUnknownState(dfaVar)) return true;
|
||||
|
||||
|
||||
if (!dfaRelation.isInstanceOf()) {
|
||||
if (((DfaTypeValue)dfaRight).isNotNull() && isNull(dfaVar)) {
|
||||
return isNegated;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isNegated) {
|
||||
DfaVariableState newState = getVariableState(dfaVar).withNotInstanceofValue((DfaTypeValue)dfaRight);
|
||||
if (newState != null) {
|
||||
|
||||
+4
-1
@@ -52,7 +52,6 @@ public class DfaRelationValue extends DfaValue {
|
||||
}
|
||||
|
||||
public DfaRelationValue createRelation(DfaValue dfaLeft, DfaValue dfaRight, IElementType relation, boolean negated) {
|
||||
if (dfaRight instanceof DfaTypeValue && INSTANCEOF_KEYWORD != relation) return null;
|
||||
if (PLUS == relation) return null;
|
||||
|
||||
if (dfaLeft instanceof DfaVariableValue || dfaLeft instanceof DfaBoxedValue || dfaLeft instanceof DfaUnboxedValue
|
||||
@@ -169,6 +168,10 @@ public class DfaRelationValue extends DfaValue {
|
||||
return myRelation == EQEQ && myIsNegated || myRelation == GT && !myIsNegated || myRelation == GE && myIsNegated;
|
||||
}
|
||||
|
||||
public boolean isInstanceOf() {
|
||||
return myRelation == INSTANCEOF_KEYWORD;
|
||||
}
|
||||
|
||||
@NonNls public String toString() {
|
||||
return (isNegated() ? "not " : "") + myLeftOperand + " " + myRelation + " " + myRightOperand;
|
||||
}
|
||||
|
||||
+2
-23
@@ -15,14 +15,11 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.unusedSymbol;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspectionTool implements CustomSuppressableInspectionTool {
|
||||
public class UnusedSymbolLocalInspectionBase extends BaseJavaLocalInspectionTool {
|
||||
@NonNls public static final String SHORT_NAME = HighlightInfoType.UNUSED_SYMBOL_SHORT_NAME;
|
||||
@NonNls public static final String DISPLAY_NAME = HighlightInfoType.UNUSED_SYMBOL_DISPLAY_NAME;
|
||||
@NonNls public static final String UNUSED_PARAMETERS_SHORT_NAME = "UnusedParameters";
|
||||
@@ -33,22 +30,4 @@ public class UnusedSymbolLocalInspectionBase extends AbstractBaseJavaLocalInspec
|
||||
public boolean CLASS = true;
|
||||
public boolean PARAMETER = true;
|
||||
public boolean REPORT_PARAMETER_FOR_PUBLIC_METHODS = true;
|
||||
|
||||
@Override
|
||||
public boolean isSuppressedFor(@NotNull PsiElement element) {
|
||||
return isSuppressedFor(element, this);
|
||||
}
|
||||
public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
|
||||
return BaseJavaBatchLocalInspectionTool.isSuppressedFor(element, tool);
|
||||
}
|
||||
@Override
|
||||
public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
|
||||
String shortName = getShortName();
|
||||
HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
|
||||
if (key == null) {
|
||||
throw new AssertionError("HighlightDisplayKey.find(" + shortName + ") is null. Inspection: "+getClass());
|
||||
}
|
||||
SuppressQuickFix[] batchSuppressActions = BatchSuppressManager.SERVICE.getInstance().createBatchSuppressActions(key);
|
||||
return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionActions(batchSuppressActions);
|
||||
}
|
||||
}
|
||||
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.ui.popup.list.ListPopupImpl;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class AddMethodQualifierFix implements IntentionAction {
|
||||
private static final boolean UNIT_TEST_MODE = ApplicationManager.getApplication().isUnitTestMode();
|
||||
|
||||
private final SmartPsiElementPointer<PsiMethodCallExpression> myMethodCall;
|
||||
private List<PsiVariable> myCandidates = null;
|
||||
|
||||
public AddMethodQualifierFix(final PsiMethodCallExpression methodCallExpression) {
|
||||
myMethodCall = SmartPointerManager.getInstance(methodCallExpression.getProject()).createSmartPsiElementPointer(methodCallExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
String text = QuickFixBundle.message("add.method.qualifier.fix.text", myCandidates.size() > 1 ? "" : myCandidates.get(0).getName());
|
||||
if (myCandidates.size() > 1) {
|
||||
text += "...";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
|
||||
final PsiMethodCallExpression element = myMethodCall.getElement();
|
||||
if (element == null || !element.isValid()) {
|
||||
return false;
|
||||
}
|
||||
if (myCandidates == null) {
|
||||
findCandidates();
|
||||
}
|
||||
return myCandidates.size() != 0;
|
||||
}
|
||||
|
||||
private void findCandidates() {
|
||||
myCandidates = new ArrayList<PsiVariable>();
|
||||
final PsiMethodCallExpression methodCallElement = myMethodCall.getElement();
|
||||
final String methodName = methodCallElement.getMethodExpression().getReferenceName();
|
||||
if (methodName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final PsiVariable var : CreateFromUsageUtils.guessMatchingVariables(methodCallElement)) {
|
||||
final PsiType type = var.getType();
|
||||
if (!(type instanceof PsiClassType)) {
|
||||
continue;
|
||||
}
|
||||
final PsiClass resolvedClass = ((PsiClassType)type).resolve();
|
||||
if (resolvedClass == null) {
|
||||
continue;
|
||||
}
|
||||
if (resolvedClass.findMethodsByName(methodName, true).length > 0) {
|
||||
myCandidates.add(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public List<PsiVariable> getCandidates() {
|
||||
return myCandidates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
|
||||
if (myCandidates.size() == 1 || UNIT_TEST_MODE) {
|
||||
qualify(myCandidates.get(0), editor);
|
||||
}
|
||||
else {
|
||||
chooseAndQualify(editor);
|
||||
}
|
||||
}
|
||||
|
||||
private void chooseAndQualify(final Editor editor) {
|
||||
final BaseListPopupStep<PsiVariable> step =
|
||||
new BaseListPopupStep<PsiVariable>(QuickFixBundle.message("add.qualifier"), myCandidates) {
|
||||
@Override
|
||||
public PopupStep onChosen(final PsiVariable selectedValue, final boolean finalChoice) {
|
||||
if (selectedValue != null && finalChoice) {
|
||||
WriteCommandAction.runWriteCommandAction(selectedValue.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
qualify(selectedValue, editor);
|
||||
}
|
||||
});
|
||||
}
|
||||
return FINAL_CHOICE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getTextFor(final PsiVariable value) {
|
||||
return ObjectUtils.assertNotNull(value.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIconFor(final PsiVariable aValue) {
|
||||
return aValue.getIcon(0);
|
||||
}
|
||||
};
|
||||
|
||||
final ListPopupImpl popup = new ListPopupImpl(step);
|
||||
popup.showInBestPositionFor(editor);
|
||||
}
|
||||
|
||||
private void qualify(final PsiVariable qualifier, final Editor editor) {
|
||||
final String qualifierPresentableText = qualifier.getName();
|
||||
final PsiMethodCallExpression oldExpression = myMethodCall.getElement();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(qualifier.getProject());
|
||||
final PsiExpression expression = elementFactory
|
||||
.createExpressionFromText(qualifierPresentableText + "." + oldExpression.getMethodExpression().getReferenceName() + "()", null);
|
||||
final PsiElement replacedExpression = oldExpression.replace(expression);
|
||||
editor.getCaretModel().moveToOffset(replacedExpression.getTextOffset() + replacedExpression.getTextLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+6
@@ -762,6 +762,12 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
return new SurroundWithQuotesAnnotationParameterValueFix(value, expectedType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall) {
|
||||
return new AddMethodQualifierFix(methodCall);
|
||||
}
|
||||
|
||||
private static boolean timeToOptimizeImports(@NotNull PsiFile file) {
|
||||
if (!CodeInsightSettings.getInstance().OPTIMIZE_IMPORTS_ON_THE_FLY) return false;
|
||||
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class FieldDependenciesManager {
|
||||
private final Map<PsiField, Set<PsiField>> myFieldDependencies;
|
||||
private final Map<PsiField, ArrangementEntryDependencyInfo> myFieldInfosMap = ContainerUtil.newHashMap();
|
||||
|
||||
public FieldDependenciesManager(@NotNull Map<PsiField, Set<PsiField>> fieldDependencies, @NotNull Map<PsiField, JavaElementArrangementEntry> fields) {
|
||||
myFieldDependencies = fieldDependencies;
|
||||
for (PsiField field : fields.keySet()) {
|
||||
JavaElementArrangementEntry entry = fields.get(field);
|
||||
myFieldInfosMap.put(field, new ArrangementEntryDependencyInfo(entry));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ArrangementEntryDependencyInfo> getRoots() {
|
||||
List<ArrangementEntryDependencyInfo> list = ContainerUtil.newArrayList();
|
||||
|
||||
for (Map.Entry<PsiField, Set<PsiField>> entry : myFieldDependencies.entrySet()) {
|
||||
ArrangementEntryDependencyInfo currentInfo = myFieldInfosMap.get(entry.getKey());
|
||||
|
||||
for (PsiField usedInInitialization : entry.getValue()) {
|
||||
ArrangementEntryDependencyInfo fieldInfo = myFieldInfosMap.get(usedInInitialization);
|
||||
if (fieldInfo != null)
|
||||
currentInfo.addDependentEntryInfo(fieldInfo);
|
||||
}
|
||||
|
||||
list.add(currentInfo);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
+20
-62
@@ -27,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -36,28 +34,22 @@ import java.util.HashSet;
|
||||
*/
|
||||
public class JavaArrangementParseInfo {
|
||||
|
||||
@NotNull private final List<JavaElementArrangementEntry> myEntries = new ArrayList<JavaElementArrangementEntry>();
|
||||
private final List<JavaElementArrangementEntry> myEntries = new ArrayList<JavaElementArrangementEntry>();
|
||||
|
||||
@NotNull private final Map<Pair<String/* property name */, String/* class name */>, JavaArrangementPropertyInfo> myProperties
|
||||
= new HashMap<Pair<String, String>, JavaArrangementPropertyInfo>();
|
||||
private final Map<Pair<String/* property name */, String/* class name */>, JavaArrangementPropertyInfo> myProperties = new HashMap<Pair<String, String>, JavaArrangementPropertyInfo>();
|
||||
|
||||
@NotNull private final List<ArrangementEntryDependencyInfo> myMethodDependencyRoots
|
||||
= new ArrayList<ArrangementEntryDependencyInfo>();
|
||||
private final List<ArrangementEntryDependencyInfo> myMethodDependencyRoots = new ArrayList<ArrangementEntryDependencyInfo>();
|
||||
private final Map<PsiMethod /* anchor */, Set<PsiMethod /* dependencies */>> myMethodDependencies = new HashMap<PsiMethod, Set<PsiMethod>>();
|
||||
|
||||
@NotNull private final Map<PsiMethod /* anchor */, Set<PsiMethod /* dependencies */>> myMethodDependencies
|
||||
= new HashMap<PsiMethod, Set<PsiMethod>>();
|
||||
private final Map<PsiMethod, JavaElementArrangementEntry> myMethodEntriesMap = new HashMap<PsiMethod, JavaElementArrangementEntry>();
|
||||
private final Map<PsiClass, List<Pair<PsiMethod/*overridden*/, PsiMethod/*overriding*/>>> myOverriddenMethods = new LinkedHashMap<PsiClass, List<Pair<PsiMethod, PsiMethod>>>();
|
||||
|
||||
@NotNull private final Map<PsiMethod, JavaElementArrangementEntry> myMethodEntriesMap =
|
||||
new HashMap<PsiMethod, JavaElementArrangementEntry>();
|
||||
|
||||
@NotNull private final Map<PsiClass, List<Pair<PsiMethod/*overridden*/, PsiMethod/*overriding*/>>> myOverriddenMethods
|
||||
= new LinkedHashMap<PsiClass, List<Pair<PsiMethod, PsiMethod>>>();
|
||||
|
||||
@NotNull private final Set<PsiMethod> myTmpMethodDependencyRoots = new LinkedHashSet<PsiMethod>();
|
||||
@NotNull private final Set<PsiMethod> myDependentMethods = new HashSet<PsiMethod>();
|
||||
private final Set<PsiMethod> myTmpMethodDependencyRoots = new LinkedHashSet<PsiMethod>();
|
||||
private final Set<PsiMethod> myDependentMethods = new HashSet<PsiMethod>();
|
||||
private boolean myRebuildMethodDependencies;
|
||||
|
||||
@NotNull private FieldDependenciesManager myFieldDependenciesManager = new FieldDependenciesManager();
|
||||
private final HashMap<PsiField, JavaElementArrangementEntry> myFields = ContainerUtil.newLinkedHashMap();
|
||||
private final Map<PsiField, Set<PsiField>> myFieldDependencies = ContainerUtil.newHashMap();
|
||||
|
||||
@NotNull
|
||||
public List<JavaElementArrangementEntry> getEntries() {
|
||||
@@ -96,8 +88,7 @@ public class JavaArrangementParseInfo {
|
||||
|
||||
@Nullable
|
||||
private ArrangementEntryDependencyInfo buildMethodDependencyInfo(@NotNull final PsiMethod method,
|
||||
@NotNull Map<PsiMethod, ArrangementEntryDependencyInfo> cache)
|
||||
{
|
||||
@NotNull Map<PsiMethod, ArrangementEntryDependencyInfo> cache) {
|
||||
JavaElementArrangementEntry entry = myMethodEntriesMap.get(method);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
@@ -158,7 +149,7 @@ public class JavaArrangementParseInfo {
|
||||
}
|
||||
|
||||
public void onFieldEntryCreated(@NotNull PsiField field, @NotNull JavaElementArrangementEntry entry) {
|
||||
myFieldDependenciesManager.registerFieldAndEntry(field, entry);
|
||||
myFields.put(field, entry);
|
||||
}
|
||||
|
||||
public void onOverriddenMethod(@NotNull PsiMethod baseMethod, @NotNull PsiMethod overridingMethod) {
|
||||
@@ -201,7 +192,7 @@ public class JavaArrangementParseInfo {
|
||||
result.add(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -226,49 +217,16 @@ public class JavaArrangementParseInfo {
|
||||
}
|
||||
|
||||
public void registerFieldInitializationDependency(@NotNull PsiField fieldToInitialize, @NotNull PsiField usedInInitialization) {
|
||||
myFieldDependenciesManager.registerInitializationDependency(fieldToInitialize, usedInInitialization);
|
||||
Set<PsiField> fields = myFieldDependencies.get(fieldToInitialize);
|
||||
if (fields == null) {
|
||||
fields = ContainerUtil.newHashSet();
|
||||
myFieldDependencies.put(fieldToInitialize, fields);
|
||||
}
|
||||
fields.add(usedInInitialization);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ArrangementEntryDependencyInfo> getFieldDependencyRoots() {
|
||||
return myFieldDependenciesManager.getRoots();
|
||||
}
|
||||
|
||||
private static class FieldDependenciesManager {
|
||||
private final Map<PsiField, Set<PsiField>> myFieldDependencies = ContainerUtil.newHashMap();
|
||||
private final Map<PsiField, ArrangementEntryDependencyInfo> myFieldInfosMap = ContainerUtil.newHashMap();
|
||||
|
||||
|
||||
public void registerFieldAndEntry(@NotNull PsiField field, @NotNull JavaElementArrangementEntry entry) {
|
||||
myFieldInfosMap.put(field, new ArrangementEntryDependencyInfo(entry));
|
||||
}
|
||||
|
||||
public void registerInitializationDependency(@NotNull PsiField fieldToInitialize, @NotNull PsiField usedInInitialization) {
|
||||
Set<PsiField> fields = myFieldDependencies.get(fieldToInitialize);
|
||||
if (fields == null) {
|
||||
fields = new HashSet<PsiField>();
|
||||
myFieldDependencies.put(fieldToInitialize, fields);
|
||||
}
|
||||
fields.add(usedInInitialization);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ArrangementEntryDependencyInfo> getRoots() {
|
||||
List<ArrangementEntryDependencyInfo> list = ContainerUtil.newArrayList();
|
||||
|
||||
for (Map.Entry<PsiField, Set<PsiField>> entry : myFieldDependencies.entrySet()) {
|
||||
ArrangementEntryDependencyInfo currentInfo = myFieldInfosMap.get(entry.getKey());
|
||||
|
||||
for (PsiField usedInInitialization : entry.getValue()) {
|
||||
ArrangementEntryDependencyInfo fieldInfo = myFieldInfosMap.get(usedInInitialization);
|
||||
if (fieldInfo != null)
|
||||
currentInfo.addDependentEntryInfo(fieldInfo);
|
||||
}
|
||||
|
||||
list.add(currentInfo);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
return new FieldDependenciesManager(myFieldDependencies, myFields).getRoots();
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
public A() {
|
||||
|
||||
MyElement localElement1 = getElement();
|
||||
|
||||
getProje<caret>ct();
|
||||
|
||||
MyElement localElement2 = getElement();
|
||||
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
public void m() {
|
||||
fieldElement.getProject();
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
public void m() {
|
||||
getProje<caret>ct();
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import java.lang.Object;
|
||||
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
public void m(MyElement paramElement) {
|
||||
|
||||
Object o = new Object() {
|
||||
|
||||
private final MyElement nestedField;
|
||||
|
||||
public void targetMethod(MyElement nestedParamElement) {
|
||||
|
||||
final MyElement localElement1 = getElement();
|
||||
|
||||
getProje<caret>ct ();
|
||||
|
||||
MyElement localElement2 = getElement();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
public void targetMethod(MyElement paramElement) {
|
||||
|
||||
MyElement localElement1 = getElement();
|
||||
|
||||
getProje<caret>ct();
|
||||
|
||||
MyElement localElement2 = getElement();
|
||||
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
static {
|
||||
|
||||
MyElement localElement1 = getElement();
|
||||
|
||||
getProje<caret>ct();
|
||||
|
||||
MyElement localElement2 = getElement();
|
||||
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
public class A {
|
||||
|
||||
Project p;
|
||||
MyElement fieldElement;
|
||||
|
||||
static MyElement staticElement;
|
||||
|
||||
public static void targetMethod(MyElement paramElement) {
|
||||
|
||||
MyElement localElement1 = getElement();
|
||||
|
||||
getProje<caret>ct();
|
||||
|
||||
MyElement localElement2 = getElement();
|
||||
|
||||
}
|
||||
|
||||
interface Project {
|
||||
|
||||
}
|
||||
|
||||
interface MyElement {
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class Bar3 {
|
||||
|
||||
public void foo(@Nullable Object element) {
|
||||
final String elementType = element != null ? element.toString() : null;
|
||||
if (elementType == "") {
|
||||
System.out.println(element.hashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class Bar3 {
|
||||
|
||||
public void foo(@Nullable Object element) {
|
||||
final String elementType = element != null ? element.toString() : null;
|
||||
if (elementType == nullableString()) {
|
||||
System.out.println(<warning descr="Method invocation 'element.hashCode()' may produce 'java.lang.NullPointerException'">element.hashCode()</warning>);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable String nullableString() { return null; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class Bar3 {
|
||||
|
||||
public void foo(@Nullable Object element) {
|
||||
final String elementType = element != null ? element.toString() : null;
|
||||
if (elementType == someString()) {
|
||||
System.out.println(<warning descr="Method invocation 'element.hashCode()' may produce 'java.lang.NullPointerException'">element.hashCode()</warning>);
|
||||
}
|
||||
}
|
||||
|
||||
String someString() { return <warning descr="'null' is returned by the method which is not declared as @Nullable">null</warning>; }
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AddMethodQualifierFix;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class AddMethodQualifierTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/quickFix/addMethodCallQualifier/";
|
||||
}
|
||||
|
||||
public void testNonStaticMethod() {
|
||||
doTest("fieldElement", "staticElement", "localElement1", "paramElement");
|
||||
}
|
||||
|
||||
public void testStaticMethod() {
|
||||
doTest("staticElement", "localElement1", "paramElement");
|
||||
}
|
||||
|
||||
public void testNestedMethod() {
|
||||
doTest("fieldElement", "localElement1", "nestedField", "nestedParamElement", "staticElement", "paramElement");
|
||||
}
|
||||
|
||||
public void testConstructor() {
|
||||
doTest("fieldElement", "staticElement", "localElement1");
|
||||
}
|
||||
|
||||
public void testStaticInitializer() {
|
||||
doTest("staticElement", "localElement1");
|
||||
}
|
||||
|
||||
public void testFix() {
|
||||
doTestFix();
|
||||
}
|
||||
|
||||
private void doTestFix() {
|
||||
myFixture.configureByFile(getTestName(false) + "Before.java");
|
||||
final AddMethodQualifierFix quickFix = getQuickFix();
|
||||
assertNotNull(quickFix);
|
||||
myFixture.launchAction(quickFix);
|
||||
myFixture.checkResultByFile(getTestName(false) + "After.java");
|
||||
}
|
||||
|
||||
private void doTest(final String... candidatesNames) {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
final AddMethodQualifierFix addMethodQualifierFix = getQuickFix();
|
||||
if (candidatesNames.length == 0) {
|
||||
assertNull(addMethodQualifierFix);
|
||||
return;
|
||||
}
|
||||
assertNotNull(addMethodQualifierFix);
|
||||
final Set<String> actualCandidatesNames = new TreeSet<String>(ContainerUtil.map(addMethodQualifierFix.getCandidates(), new Function<PsiNamedElement, String>() {
|
||||
@Override
|
||||
public String fun(final PsiNamedElement psiNamedElement) {
|
||||
final String name = psiNamedElement.getName();
|
||||
assertNotNull(name);
|
||||
return name;
|
||||
}
|
||||
}));
|
||||
final Set<String> expectedCandidatesNames = new TreeSet<String>(ContainerUtil.list(candidatesNames));
|
||||
assertEquals(expectedCandidatesNames, actualCandidatesNames);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private AddMethodQualifierFix getQuickFix() {
|
||||
final List<IntentionAction> availableIntentions = myFixture.getAvailableIntentions();
|
||||
AddMethodQualifierFix addMethodQualifierFix = null;
|
||||
for (final IntentionAction availableIntention : availableIntentions) {
|
||||
if (availableIntention instanceof AddMethodQualifierFix) {
|
||||
addMethodQualifierFix = (AddMethodQualifierFix)availableIntention;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return addMethodQualifierFix;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,6 +71,9 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testGeneratedEquals() throws Throwable { doTest(); }
|
||||
|
||||
public void testIDEA84489() throws Throwable { doTest(); }
|
||||
public void testComparingNullToNotNull() { doTest(); }
|
||||
public void testComparingNullableToNullable() { doTest(); }
|
||||
public void testComparingNullableToUnknown() { doTest(); }
|
||||
public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
|
||||
public void testComparingToNullableShouldNotAffectNullity() throws Throwable { doTest(); }
|
||||
public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ResourceUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xmlb.SerializationFilter;
|
||||
@@ -46,7 +47,7 @@ import java.util.Set;
|
||||
* @since 28-Nov-2005
|
||||
*/
|
||||
@SuppressWarnings("JavadocReference")
|
||||
public abstract class InspectionProfileEntry {
|
||||
public abstract class InspectionProfileEntry implements BatchSuppressableTool{
|
||||
public static final String GENERAL_GROUP_NAME = InspectionsBundle.message("inspection.general.tools.group.name");
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry");
|
||||
@@ -56,6 +57,42 @@ public abstract class InspectionProfileEntry {
|
||||
private static final Object BLACK_LIST_LOCK = new Object();
|
||||
private Boolean myUseNewSerializer = null;
|
||||
|
||||
@NonNls
|
||||
@Nullable
|
||||
public String getAlternativeID() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressedFor(@NotNull PsiElement element) {
|
||||
InspectionSuppressor suppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage());
|
||||
if (suppressor != null) {
|
||||
String toolId = getSuppressId();
|
||||
if (suppressor.isSuppressedFor(element, toolId)) {
|
||||
return true;
|
||||
}
|
||||
final String alternativeId = getAlternativeID();
|
||||
return alternativeId != null && !alternativeId.equals(toolId) && suppressor.isSuppressedFor(element, alternativeId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected String getSuppressId() {
|
||||
return getShortName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
if (element != null) {
|
||||
InspectionSuppressor suppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage());
|
||||
if (suppressor != null) {
|
||||
return suppressor.getSuppressActions(element, getShortName());
|
||||
}
|
||||
}
|
||||
return SuppressQuickFix.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public void cleanup(Project project) {
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,11 @@ public abstract class LocalInspectionTool extends InspectionProfileEntry {
|
||||
return getShortName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSuppressId() {
|
||||
return getID();
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@Nullable
|
||||
public String getAlternativeID() {
|
||||
|
||||
@@ -830,33 +830,23 @@ public class HighlightInfo implements Segment {
|
||||
throw new AssertionError("unknown tool: " + toolWrapper+"; key: "+myKey);
|
||||
}
|
||||
|
||||
SuppressQuickFix[] suppressFixes = null;
|
||||
if (wrappedTool instanceof CustomSuppressableInspectionTool) {
|
||||
suppressFixes = SuppressQuickFix.EMPTY_ARRAY;
|
||||
final IntentionAction[] suppressActions = ((CustomSuppressableInspectionTool)wrappedTool).getSuppressActions(element);
|
||||
if (suppressActions != null) {
|
||||
ContainerUtil.addAll(newOptions, suppressActions);
|
||||
}
|
||||
}
|
||||
if (wrappedTool instanceof BatchSuppressableTool) {
|
||||
suppressFixes = ((BatchSuppressableTool)wrappedTool).getBatchSuppressActions(element);
|
||||
}
|
||||
|
||||
if (suppressFixes == null) {
|
||||
final InspectionSuppressor suppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage());
|
||||
if (suppressor != null) {
|
||||
suppressFixes = suppressor.getSuppressActions(element, wrappedTool.getShortName());
|
||||
} else {
|
||||
SuppressQuickFix[] suppressFixes = wrappedTool.getBatchSuppressActions(element);
|
||||
if (suppressFixes.length > 0) {
|
||||
ContainerUtil.addAll(newOptions, ContainerUtil.map(suppressFixes, new Function<SuppressQuickFix, IntentionAction>() {
|
||||
@Override
|
||||
public IntentionAction fun(SuppressQuickFix fix) {
|
||||
return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(fix);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (suppressFixes != null) {
|
||||
ContainerUtil.addAll(newOptions, ContainerUtil.map(suppressFixes, new Function<SuppressQuickFix, IntentionAction>() {
|
||||
@Override
|
||||
public IntentionAction fun(SuppressQuickFix fix) {
|
||||
return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction(fix);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (myProblemGroup instanceof SuppressableProblemGroup) {
|
||||
final IntentionAction[] suppressActions = ((SuppressableProblemGroup)myProblemGroup).getSuppressActions(element);
|
||||
|
||||
@@ -194,24 +194,6 @@ public class SuppressionUtil extends SuppressionUtilCore {
|
||||
}
|
||||
|
||||
public static boolean inspectionResultSuppressed(@NotNull PsiElement place, @NotNull LocalInspectionTool tool) {
|
||||
if (tool instanceof CustomSuppressableInspectionTool) {
|
||||
return ((CustomSuppressableInspectionTool)tool).isSuppressedFor(place);
|
||||
}
|
||||
if (tool instanceof BatchSuppressableTool) {
|
||||
return ((BatchSuppressableTool)tool).isSuppressedFor(place);
|
||||
}
|
||||
|
||||
final InspectionSuppressor suppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(place.getLanguage());
|
||||
if (suppressor != null) {
|
||||
return suppressor.isSuppressedFor(place, tool.getID());
|
||||
}
|
||||
|
||||
String alternativeId;
|
||||
String id;
|
||||
|
||||
return isSuppressed(place, id = tool.getID()) ||
|
||||
(alternativeId = tool.getAlternativeID()) != null &&
|
||||
!alternativeId.equals(id) &&
|
||||
isSuppressed(place, alternativeId);
|
||||
return tool.isSuppressedFor(place);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,16 +90,13 @@ public class InspectionManagerEx extends InspectionManagerBase {
|
||||
if (tool instanceof CustomSuppressableInspectionTool) {
|
||||
return ((CustomSuppressableInspectionTool)tool).getSuppressActions(null);
|
||||
}
|
||||
if (tool instanceof BatchSuppressableTool) {
|
||||
LocalQuickFix[] actions = ((BatchSuppressableTool)tool).getBatchSuppressActions(null);
|
||||
return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, new Function<LocalQuickFix, SuppressIntentionAction>() {
|
||||
@Override
|
||||
public SuppressIntentionAction fun(final LocalQuickFix fix) {
|
||||
return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction((SuppressQuickFix)fix);
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
LocalQuickFix[] actions = tool.getBatchSuppressActions(null);
|
||||
return ContainerUtil.map2Array(actions, SuppressIntentionAction.class, new Function<LocalQuickFix, SuppressIntentionAction>() {
|
||||
@Override
|
||||
public SuppressIntentionAction fun(final LocalQuickFix fix) {
|
||||
return SuppressIntentionActionFromFix.convertBatchToSuppressIntentionAction((SuppressQuickFix)fix);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class PowerSaveModeNotifier implements StartupActivity {
|
||||
private static final NotificationGroup POWER_SAVE_MODE = NotificationGroup.balloonGroup("Power Save Mode");
|
||||
private static final String IGNORE_POWER_SAVE_MODE = "ignore.power.save.mode";
|
||||
|
||||
@Override
|
||||
public void runActivity(@NotNull Project project) {
|
||||
if (PowerSaveMode.isEnabled()) {
|
||||
notifyOnPowerSaveMode(project);
|
||||
}
|
||||
}
|
||||
|
||||
static void notifyOnPowerSaveMode(Project project) {
|
||||
if (PropertiesComponent.getInstance().getBoolean(IGNORE_POWER_SAVE_MODE, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String message = "Code insight and other background tasks are disabled." +
|
||||
"<br/><a href=\"ignore\">Do not show again</a>" +
|
||||
"<br/><a href=\"turnOff\">Disable Power Save Mode</a>";
|
||||
POWER_SAVE_MODE.createNotification("Power save mode is on", message, NotificationType.WARNING, new NotificationListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
|
||||
final String description = event.getDescription();
|
||||
if ("ignore".equals(description)) {
|
||||
PropertiesComponent.getInstance().setValue(IGNORE_POWER_SAVE_MODE, "true");
|
||||
notification.expire();
|
||||
}
|
||||
else if ("turnOff".equals(description)) {
|
||||
PowerSaveMode.setEnabled(false);
|
||||
notification.expire();
|
||||
}
|
||||
}
|
||||
}).notify(project);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
|
||||
@@ -32,5 +33,8 @@ public class TogglePowerSaveAction extends ToggleAction implements DumbAware {
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
PowerSaveMode.setEnabled(state);
|
||||
if (state) {
|
||||
PowerSaveModeNotifier.notifyOnPowerSaveMode(e.getData(CommonDataKeys.PROJECT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-13
@@ -59,7 +59,7 @@ public class PushedFilePropertiesUpdater {
|
||||
private final Project myProject;
|
||||
private final FilePropertyPusher[] myPushers;
|
||||
private final FilePropertyPusher[] myFilePushers;
|
||||
private final Queue<DumbModeTask> myTasks = new ConcurrentLinkedQueue<DumbModeTask>();
|
||||
private final Queue<Runnable> myTasks = new ConcurrentLinkedQueue<Runnable>();
|
||||
private final MessageBusConnection myConnection;
|
||||
|
||||
public static PushedFilePropertiesUpdater getInstance(Project project) {
|
||||
@@ -84,7 +84,6 @@ public class PushedFilePropertiesUpdater {
|
||||
myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
|
||||
@Override
|
||||
public void rootsChanged(final ModuleRootEvent event) {
|
||||
pushAll(myPushers);
|
||||
for (FilePropertyPusher pusher : myPushers) {
|
||||
pusher.afterRootsChanged(project);
|
||||
}
|
||||
@@ -123,8 +122,6 @@ public class PushedFilePropertiesUpdater {
|
||||
}
|
||||
|
||||
public void initializeProperties() {
|
||||
pushAll(myPushers);
|
||||
|
||||
for (final FilePropertyPusher pusher : myPushers) {
|
||||
pusher.initExtra(myProject, myProject.getMessageBus(), new FilePropertyPusher.Engine() {
|
||||
@Override
|
||||
@@ -140,13 +137,18 @@ public class PushedFilePropertiesUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
public void pushAllPropertiesNow() {
|
||||
performPushTasks();
|
||||
doPushAll(myPushers);
|
||||
}
|
||||
|
||||
private void schedulePushRecursively(final VirtualFile dir, final FilePropertyPusher... pushers) {
|
||||
if (pushers.length == 0) return;
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
if (!fileIndex.isInContent(dir)) return;
|
||||
queueTask(new DumbModeTask() {
|
||||
queueTask(new Runnable() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull final ProgressIndicator indicator) {
|
||||
public void run() {
|
||||
doPushRecursively(dir, pushers, fileIndex);
|
||||
}
|
||||
});
|
||||
@@ -162,25 +164,25 @@ public class PushedFilePropertiesUpdater {
|
||||
});
|
||||
}
|
||||
|
||||
private void queueTask(DumbModeTask task) {
|
||||
private void queueTask(Runnable task) {
|
||||
myTasks.offer(task);
|
||||
DumbService.getInstance(myProject).queueTask(new DumbModeTask() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
performPushTasks(indicator);
|
||||
performPushTasks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void performPushTasks(ProgressIndicator indicator) {
|
||||
private void performPushTasks() {
|
||||
boolean hadTasks = false;
|
||||
while (true) {
|
||||
DumbModeTask task = myTasks.poll();
|
||||
Runnable task = myTasks.poll();
|
||||
if (task == null) {
|
||||
break;
|
||||
}
|
||||
hadTasks = true;
|
||||
task.performInDumbMode(indicator);
|
||||
task.run();
|
||||
}
|
||||
|
||||
if (hadTasks && !myProject.isDisposed()) {
|
||||
@@ -213,9 +215,9 @@ public class PushedFilePropertiesUpdater {
|
||||
}
|
||||
|
||||
public void pushAll(final FilePropertyPusher... pushers) {
|
||||
queueTask(new DumbModeTask() {
|
||||
queueTask(new Runnable() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
public void run() {
|
||||
doPushAll(pushers);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -51,7 +51,7 @@ public class UnindexedFilesUpdater extends DumbModeTask {
|
||||
}
|
||||
|
||||
private void updateUnindexedFiles(ProgressIndicator indicator) {
|
||||
PushedFilePropertiesUpdater.getInstance(myProject).performPushTasks(indicator);
|
||||
PushedFilePropertiesUpdater.getInstance(myProject).pushAllPropertiesNow();
|
||||
|
||||
indicator.setIndeterminate(true);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
|
||||
|
||||
@@ -268,6 +268,8 @@ public class JBScrollPane extends JScrollPane {
|
||||
}
|
||||
|
||||
private static boolean isOverlaidScrollbar(@Nullable JScrollBar scrollbar) {
|
||||
if (!ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return false;
|
||||
|
||||
ScrollBarUI vsbUI = scrollbar == null ? null : scrollbar.getUI();
|
||||
return vsbUI instanceof ButtonlessScrollBarUI && !((ButtonlessScrollBarUI)vsbUI).alwaysShowTrack();
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ public class FormBuilder {
|
||||
final int index = UIUtil.getDisplayMnemonicIndex(labelText);
|
||||
if (index != -1) {
|
||||
label.setDisplayedMnemonic(labelText.charAt(index + 1));
|
||||
label.setDisplayedMnemonicIndex(index);
|
||||
}
|
||||
label.setLabelFor(component);
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
|
||||
public void initComponent() {
|
||||
checkJvm();
|
||||
startDiskSpaceMonitoring();
|
||||
checkPowerSaveMode();
|
||||
}
|
||||
|
||||
private void checkJvm() {
|
||||
@@ -210,25 +209,4 @@ public class SystemHealthMonitor extends ApplicationComponent.Adapter {
|
||||
}, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void checkPowerSaveMode() {
|
||||
if (PowerSaveMode.isEnabled()) {
|
||||
final String ignoreKey = "ignore.power.save.mode";
|
||||
String message = "Power save mode is on. Code insight and other background tasks are disabled." +
|
||||
"<br/><a href=\"ignore\">Do not show again</a>" +
|
||||
"<br/><a href=\"turnOff\">Disable Power Save Mode</a>";
|
||||
|
||||
showNotification(ignoreKey, message, new HyperlinkAdapter() {
|
||||
@Override
|
||||
protected void hyperlinkActivated(HyperlinkEvent e) {
|
||||
final String description = e.getDescription();
|
||||
if ("ignore".equals(description)) {
|
||||
myProperties.setValue(ignoreKey, "true");
|
||||
}
|
||||
else if ("turnOff".equals(description)) {
|
||||
PowerSaveMode.setEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.caches.CacheUpdater;
|
||||
import com.intellij.ide.caches.FileContent;
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -40,7 +41,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class CacheUpdateRunner {
|
||||
public class CacheUpdateRunner extends DumbModeTask {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.CacheUpdateRunner");
|
||||
private static final Key<Boolean> FAILED_TO_INDEX = Key.create("FAILED_TO_INDEX");
|
||||
private static final int PROC_COUNT = Runtime.getRuntime().availableProcessors();
|
||||
@@ -58,15 +59,11 @@ public class CacheUpdateRunner {
|
||||
return new ArrayList<CacheUpdater>(myUpdaters).toString();
|
||||
}
|
||||
|
||||
public int queryNeededFiles(@NotNull ProgressIndicator indicator) {
|
||||
private int queryNeededFiles(@NotNull ProgressIndicator indicator) {
|
||||
// can be queried twice in DumbService
|
||||
return getSession(indicator).getFilesToUpdate().size();
|
||||
}
|
||||
|
||||
public int getNumberOfPendingUpdateJobs(@NotNull ProgressIndicator indicator) {
|
||||
return getSession(indicator).getNumberOfPendingUpdateJobs();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CacheUpdateSession getSession(@NotNull ProgressIndicator indicator) {
|
||||
CacheUpdateSession session = mySession;
|
||||
@@ -76,7 +73,7 @@ public class CacheUpdateRunner {
|
||||
return session;
|
||||
}
|
||||
|
||||
public void processFiles(@NotNull final ProgressIndicator indicator, boolean processInReadAction) {
|
||||
private void processFiles(@NotNull final ProgressIndicator indicator, boolean processInReadAction) {
|
||||
try {
|
||||
Collection<VirtualFile> files = mySession.getFilesToUpdate();
|
||||
|
||||
@@ -134,7 +131,7 @@ public class CacheUpdateRunner {
|
||||
}
|
||||
}
|
||||
|
||||
public void updatingDone() {
|
||||
private void updatingDone() {
|
||||
try {
|
||||
mySession.updatingDone();
|
||||
}
|
||||
@@ -217,6 +214,21 @@ public class CacheUpdateRunner {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
indicator.checkCanceled();
|
||||
indicator.setIndeterminate(true);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
|
||||
int count = queryNeededFiles(indicator);
|
||||
|
||||
indicator.setIndeterminate(false);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.updating"));
|
||||
if (count > 0) {
|
||||
processFiles(indicator, true);
|
||||
}
|
||||
updatingDone();
|
||||
}
|
||||
|
||||
private static class MyRunnable implements Runnable {
|
||||
private final ProgressIndicatorBase myInnerIndicator;
|
||||
private final FileContentQueue myQueue;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.caches.CacheUpdater;
|
||||
import com.intellij.ide.caches.FileContent;
|
||||
import com.intellij.ide.util.DelegatingProgressIndicator;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -29,8 +28,8 @@ import com.intellij.openapi.progress.*;
|
||||
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.ShutDownTracker;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.AppIconScheme;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -48,21 +47,15 @@ import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DumbServiceImpl extends DumbService {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.project.DumbServiceImpl");
|
||||
private volatile boolean myDumb = false;
|
||||
private final DumbModeListener myPublisher;
|
||||
private final Queue<IndexUpdateRunnable> myUpdatesQueue = new Queue<IndexUpdateRunnable>(5);
|
||||
private final Queue<DumbModeTask> myUpdatesQueue = new Queue<DumbModeTask>(5);
|
||||
private final Queue<Runnable> myRunWhenSmartQueue = new Queue<Runnable>(5);
|
||||
private final Project myProject;
|
||||
private final CacheUpdateRunner NULL_ACTION;
|
||||
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass"})
|
||||
public static DumbServiceImpl getInstance(@NotNull Project project) {
|
||||
@@ -71,45 +64,12 @@ public class DumbServiceImpl extends DumbService {
|
||||
|
||||
@Override
|
||||
public void queueTask(final DumbModeTask task) {
|
||||
CacheUpdater wrapper = new CacheUpdater() {
|
||||
@Override
|
||||
public int getNumberOfPendingUpdateJobs() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator) {
|
||||
task.performInDumbMode(indicator);
|
||||
return new VirtualFile[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processFile(@NotNull FileContent fileContent) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatingDone() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void canceled() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return task.toString();
|
||||
}
|
||||
};
|
||||
queueCacheUpdateInDumbMode(Arrays.asList(wrapper));
|
||||
scheduleCacheUpdate(task, true);
|
||||
}
|
||||
|
||||
public DumbServiceImpl(Project project, MessageBus bus) {
|
||||
myProject = project;
|
||||
myPublisher = bus.syncPublisher(DUMB_MODE);
|
||||
NULL_ACTION = new CacheUpdateRunner(project, Collections.<CacheUpdater>emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,87 +105,48 @@ public class DumbServiceImpl extends DumbService {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void queueCacheUpdate(@NotNull Collection<CacheUpdater> updaters) {
|
||||
scheduleCacheUpdate(updaters, false);
|
||||
scheduleCacheUpdate(new CacheUpdateRunner(myProject, new ArrayList<CacheUpdater>(updaters)), false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void queueCacheUpdateInDumbMode(@NotNull Collection<CacheUpdater> updaters) {
|
||||
scheduleCacheUpdate(updaters, true);
|
||||
scheduleCacheUpdate(new CacheUpdateRunner(myProject, new ArrayList<CacheUpdater>(updaters)), true);
|
||||
}
|
||||
|
||||
private void scheduleCacheUpdate(@NotNull Collection<CacheUpdater> updaters, boolean forceDumbMode) {
|
||||
// prevent concurrent modifications
|
||||
final CacheUpdateRunner runner = new CacheUpdateRunner(myProject, new ArrayList<CacheUpdater>(updaters));
|
||||
|
||||
private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
|
||||
if (application.isUnitTestMode() || application.isHeadlessEnvironment()) {
|
||||
// no dumb mode for tests
|
||||
EmptyProgressIndicator i = new EmptyProgressIndicator();
|
||||
final int size = runner.queryNeededFiles(i);
|
||||
if (application.isUnitTestMode() ||
|
||||
application.isHeadlessEnvironment() ||
|
||||
!forceDumbMode && !myDumb && application.isReadAccessAllowed()) {
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (indicator != null) {
|
||||
indicator.pushState();
|
||||
}
|
||||
try {
|
||||
HeavyProcessLatch.INSTANCE.processStarted();
|
||||
if (size > 0) {
|
||||
runner.processFiles(i, false);
|
||||
}
|
||||
runner.updatingDone();
|
||||
task.performInDumbMode(indicator != null ? indicator : new EmptyProgressIndicator());
|
||||
}
|
||||
finally {
|
||||
HeavyProcessLatch.INSTANCE.processFinished();
|
||||
if (indicator != null) {
|
||||
indicator.popState();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forceDumbMode && !myDumb && application.isReadAccessAllowed()) {
|
||||
// if there are not so many files to process, process them on the spot without entering dumb mode
|
||||
final ProgressIndicator currentIndicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
final ProgressIndicator indicator;
|
||||
if (currentIndicator != null) {
|
||||
indicator = currentIndicator;
|
||||
currentIndicator.pushState();
|
||||
}
|
||||
else {
|
||||
indicator = new EmptyProgressIndicator();
|
||||
}
|
||||
try {
|
||||
final int size = runner.queryNeededFiles(indicator);
|
||||
if (size + runner.getNumberOfPendingUpdateJobs(indicator) < 50) {
|
||||
// If not that many files found, process them on the spot, avoiding entering dumb mode
|
||||
// Consider number of pending tasks as well, because they may take noticeable time to process even if the number of files is small
|
||||
try {
|
||||
HeavyProcessLatch.INSTANCE.processStarted();
|
||||
if (size > 0) {
|
||||
runner.processFiles(indicator, false);
|
||||
}
|
||||
runner.updatingDone();
|
||||
}
|
||||
finally {
|
||||
HeavyProcessLatch.INSTANCE.processFinished();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (currentIndicator != null) {
|
||||
currentIndicator.popState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final IndexUpdateRunnable updateRunnable = new IndexUpdateRunnable(runner);
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
myUpdatesQueue.addLast(task);
|
||||
// ok to test and set the flag like this, because the change is always done from dispatch thread
|
||||
if (myDumb) {
|
||||
myUpdatesQueue.addLast(updateRunnable);
|
||||
}
|
||||
else {
|
||||
if (!myDumb) {
|
||||
// always change dumb status inside write action.
|
||||
// This will ensure all active read actions are completed before the app goes dumb
|
||||
boolean startSuccess =
|
||||
@@ -239,14 +160,13 @@ public class DumbServiceImpl extends DumbService {
|
||||
catch (Throwable e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
updateRunnable.run();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error("Failed to start background index update task", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
startBackgroundProcess();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.error("Failed to start background index update task", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -365,140 +285,101 @@ public class DumbServiceImpl extends DumbService {
|
||||
}, modalityState, myProject.getDisposed());
|
||||
}
|
||||
|
||||
private class IndexUpdateRunnable implements Runnable {
|
||||
private final CacheUpdateRunner myAction;
|
||||
private void startBackgroundProcess() {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
|
||||
|
||||
public IndexUpdateRunnable(@NotNull CacheUpdateRunner action) {
|
||||
myAction = action;
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
if (indicator instanceof ProgressIndicatorEx) {
|
||||
((ProgressIndicatorEx)indicator).addStateDelegate(new AppIconProgress());
|
||||
}
|
||||
|
||||
final ProgressIndicator proxy = new DelegatingProgressIndicator(indicator);
|
||||
|
||||
final ShutDownTracker shutdownTracker = ShutDownTracker.getInstance();
|
||||
final Thread self = Thread.currentThread();
|
||||
try {
|
||||
HeavyProcessLatch.INSTANCE.processStarted();
|
||||
shutdownTracker.registerStopperThread(self);
|
||||
runTasks(proxy);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
LOG.error(e);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
shutdownTracker.unregisterStopperThread(self);
|
||||
HeavyProcessLatch.INSTANCE.processFinished();
|
||||
}
|
||||
}
|
||||
|
||||
private void runTasks(ProgressIndicator indicator) {
|
||||
while (true) {
|
||||
DumbModeTask task = getNextTask();
|
||||
if (task == null) break;
|
||||
|
||||
try {
|
||||
if (ApplicationManager.getApplication().isInternal()) LOG.info("Running dumb mode task: " + task);
|
||||
indicator.checkCanceled();
|
||||
indicator.setIndeterminate(true);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
|
||||
task.performInDumbMode(indicator);
|
||||
}
|
||||
catch (ProcessCanceledException ignored) {
|
||||
}
|
||||
catch (Throwable unexpected) {
|
||||
LOG.error(unexpected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DumbModeTask getNextTask() {
|
||||
final Ref<DumbModeTask> nextTask = Ref.create();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
if (myUpdatesQueue.isEmpty()) {
|
||||
updateFinished();
|
||||
} else {
|
||||
nextTask.set(myUpdatesQueue.pullFirst());
|
||||
}
|
||||
}
|
||||
});
|
||||
return nextTask.get();
|
||||
}
|
||||
|
||||
private class AppIconProgress extends ProgressIndicatorBase {
|
||||
double lastFraction;
|
||||
|
||||
@Override
|
||||
public void setFraction(final double fraction) {
|
||||
if (fraction - lastFraction < 0.01d) return;
|
||||
lastFraction = fraction;
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AppIcon.getInstance().setProgress(myProject, "indexUpdate", AppIconScheme.Progress.INDEXING, fraction, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
|
||||
|
||||
public void finish(@NotNull TaskInfo task) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
if (indicator instanceof ProgressIndicatorEx) {
|
||||
((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() {
|
||||
double lastFraction;
|
||||
|
||||
@Override
|
||||
public void setFraction(final double fraction) {
|
||||
if (fraction - lastFraction < 0.01d) return;
|
||||
lastFraction = fraction;
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AppIcon.getInstance().setProgress(myProject, "indexUpdate", AppIconScheme.Progress.INDEXING, fraction, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(@NotNull TaskInfo task) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AppIcon appIcon = AppIcon.getInstance();
|
||||
if (appIcon.hideProgress(myProject, "indexUpdate")) {
|
||||
appIcon.requestAttention(myProject, false);
|
||||
appIcon.setOkBadge(myProject, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final ProgressIndicator proxy = new DelegatingProgressIndicator(indicator);
|
||||
|
||||
final ShutDownTracker shutdownTracker = ShutDownTracker.getInstance();
|
||||
final Thread self = Thread.currentThread();
|
||||
try {
|
||||
HeavyProcessLatch.INSTANCE.processStarted();
|
||||
shutdownTracker.registerStopperThread(self);
|
||||
runAction(proxy, myAction);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
LOG.error(e);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
shutdownTracker.unregisterStopperThread(self);
|
||||
HeavyProcessLatch.INSTANCE.processFinished();
|
||||
}
|
||||
}
|
||||
|
||||
private void runAction(ProgressIndicator indicator, CacheUpdateRunner updateRunner) {
|
||||
while (updateRunner != null) {
|
||||
try {
|
||||
if (ApplicationManager.getApplication().isInternal()) LOG.info("Running dumb mode task: " + updateRunner);
|
||||
indicator.checkCanceled();
|
||||
indicator.setIndeterminate(true);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
|
||||
int count = updateRunner.queryNeededFiles(indicator);
|
||||
|
||||
indicator.setIndeterminate(false);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.updating"));
|
||||
if (count > 0) {
|
||||
updateRunner.processFiles(indicator, true);
|
||||
}
|
||||
updateRunner.updatingDone();
|
||||
}
|
||||
catch (ProcessCanceledException ignored) {
|
||||
}
|
||||
catch (Throwable unexpected) {
|
||||
LOG.error(unexpected);
|
||||
}
|
||||
updateRunner = getNextUpdateRunner();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CacheUpdateRunner getNextUpdateRunner() {
|
||||
final BlockingQueue<CacheUpdateRunner> actionQueue = new LinkedBlockingQueue<CacheUpdateRunner>();
|
||||
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IndexUpdateRunnable nextRunnable = getNextUpdateFromQueue();
|
||||
try {
|
||||
actionQueue.offer(nextRunnable == null ? NULL_ACTION : nextRunnable.myAction);
|
||||
}
|
||||
finally {
|
||||
if (nextRunnable == null) {
|
||||
updateFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// try to obtain the next action or terminate if no actions left
|
||||
while (!myProject.isDisposed()) {
|
||||
try {
|
||||
CacheUpdateRunner ref = actionQueue.poll(500L, TimeUnit.MILLISECONDS);
|
||||
if (ref != null) {
|
||||
return ref == NULL_ACTION ? null : ref;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IndexUpdateRunnable getNextUpdateFromQueue() {
|
||||
try {
|
||||
return myUpdatesQueue.isEmpty()? null : myUpdatesQueue.pullFirst();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.info(e);
|
||||
return null;
|
||||
public void run() {
|
||||
AppIcon appIcon = AppIcon.getInstance();
|
||||
if (appIcon.hideProgress(myProject, "indexUpdate")) {
|
||||
appIcon.requestAttention(myProject, false);
|
||||
appIcon.setOkBadge(myProject, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -283,6 +283,7 @@
|
||||
serviceImplementation="com.intellij.ide.TypePresentationServiceImpl"/>
|
||||
|
||||
<postStartupActivity implementation="com.intellij.ide.TipOfTheDayManager"/>
|
||||
<postStartupActivity implementation="com.intellij.ide.actions.PowerSaveModeNotifier"/>
|
||||
<postStartupActivity implementation="com.intellij.openapi.actionSystem.impl.ActionPreloader"/>
|
||||
<postStartupActivity id="OpenFilesActivity" implementation="com.intellij.openapi.fileEditor.impl.OpenFilesActivity"/>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public class OneElementFMap<V> implements KeyFMap {
|
||||
private final Key myKey;
|
||||
private final V myValue;
|
||||
|
||||
public OneElementFMap(Key key, @NotNull V value) {
|
||||
public OneElementFMap(@NotNull Key key, @NotNull V value) {
|
||||
myKey = key;
|
||||
myValue = value;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class OneElementFMap<V> implements KeyFMap {
|
||||
|
||||
OneElementFMap map = (OneElementFMap)o;
|
||||
|
||||
if (!myKey.equals(map.myKey)) return false;
|
||||
if (myKey != map.myKey) return false;
|
||||
if (!myValue.equals(map.myValue)) return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -24,7 +24,7 @@ class PairElementsFMap implements KeyFMap {
|
||||
private final Object value1;
|
||||
private final Object value2;
|
||||
|
||||
PairElementsFMap(Key key1, @NotNull Object value1, Key key2, @NotNull Object value2) {
|
||||
PairElementsFMap(@NotNull Key key1, @NotNull Object value1, @NotNull Key key2, @NotNull Object value2) {
|
||||
this.key1 = key1;
|
||||
this.value1 = value1;
|
||||
this.key2 = key2;
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.util.ui.tree;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.containers.ComparatorUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -49,7 +48,6 @@ public class WideSelectionTreeUI extends BasicTreeUI {
|
||||
@NotNull private final Condition<Integer> myWideSelectionCondition;
|
||||
private boolean myWideSelection;
|
||||
private boolean myOldRepaintAllRowValue;
|
||||
private boolean invertLineColor;
|
||||
private boolean myForceDontPaintLines = false;
|
||||
private boolean mySkinny = false;
|
||||
|
||||
@@ -281,17 +279,15 @@ public class WideSelectionTreeUI extends BasicTreeUI {
|
||||
final boolean isExpanded,
|
||||
final boolean hasBeenExpanded,
|
||||
final boolean isLeaf) {
|
||||
if (!shouldPaintLines()) return;
|
||||
if (!UIUtil.isUnderAquaBasedLookAndFeel() && !UIUtil.isUnderDarcula() && !UIUtil.isUnderIntelliJLaF()) {
|
||||
if (UIUtil.isUnderAlloyIDEALookAndFeel()) {
|
||||
invertLineColor = tree.getSelectionModel().isRowSelected(row) && tree.hasFocus();
|
||||
}
|
||||
if (shouldPaintLines()) {
|
||||
super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf);
|
||||
invertLineColor = false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldPaintLines() {
|
||||
if (UIUtil.isUnderAquaBasedLookAndFeel() || UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF()) {
|
||||
return false;
|
||||
}
|
||||
return myForceDontPaintLines || !"None".equals(tree.getClientProperty("JTree.lineStyle"));
|
||||
}
|
||||
|
||||
@@ -302,41 +298,26 @@ public class WideSelectionTreeUI extends BasicTreeUI {
|
||||
|
||||
@Override
|
||||
protected void paintVerticalPartOfLeg(final Graphics g, final Rectangle clipBounds, final Insets insets, final TreePath path) {
|
||||
if (!UIUtil.isUnderAquaBasedLookAndFeel() && !UIUtil.isUnderDarcula() && !UIUtil.isUnderIntelliJLaF() && shouldPaintLines()) {
|
||||
invertLineColor = UIUtil.isUnderAlloyIDEALookAndFeel() && tree.hasFocus() && tree.getSelectionModel().isPathSelected(path);
|
||||
if (shouldPaintLines()) {
|
||||
super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
|
||||
invertLineColor = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintVerticalLine(Graphics g, JComponent c, int x, int top, int bottom) {
|
||||
if (!shouldPaintLines()) return;
|
||||
if (tree.hasFocus() && UIUtil.isUnderAlloyIDEALookAndFeel()) {
|
||||
int y0, y1 = top;
|
||||
while (y1 < bottom) {
|
||||
y0 = y1;
|
||||
final int row = tree.getRowForPath(tree.getClosestPathForLocation(x, y0 + 1));
|
||||
invertLineColor = tree.isRowSelected(row);
|
||||
g.setColor(getHashColor());
|
||||
final Rectangle bounds = tree.getRowBounds(row);
|
||||
y1 = bounds.y + bounds.height;
|
||||
super.paintVerticalLine(g, c, x, y0, Math.min(bottom, y1));
|
||||
}
|
||||
invertLineColor = false;
|
||||
} else {
|
||||
if (shouldPaintLines()) {
|
||||
super.paintVerticalLine(g, c, x, top, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getHashColor() {
|
||||
if (invertLineColor && !ComparatorUtil.equalsNullable(UIUtil.getTreeSelectionForeground(), UIUtil.getTreeForeground())) {
|
||||
final Color c = UIUtil.getTreeSelectionForeground();
|
||||
if (c != null) {
|
||||
return c.darker();
|
||||
}
|
||||
}
|
||||
//if (invertLineColor && !ComparatorUtil.equalsNullable(UIUtil.getTreeSelectionForeground(), UIUtil.getTreeForeground())) {
|
||||
// final Color c = UIUtil.getTreeSelectionForeground();
|
||||
// if (c != null) {
|
||||
// return c.darker();
|
||||
// }
|
||||
//}
|
||||
return super.getHashColor();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.TreeSpeedSearch;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.TransferToEDTQueue;
|
||||
import com.intellij.util.ui.TextTransferable;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
|
||||
@@ -56,6 +57,8 @@ import java.util.List;
|
||||
* @author nik
|
||||
*/
|
||||
public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposable {
|
||||
private final TransferToEDTQueue<Runnable> myLaterInvocator = TransferToEDTQueue.createRunnableMerger("XDebuggerTree later invocator", 100);
|
||||
|
||||
private static final DataKey<XDebuggerTree> XDEBUGGER_TREE_KEY = DataKey.create("xdebugger.tree");
|
||||
private static final Convertor<TreePath, String> SPEED_SEARCH_CONVERTER = new Convertor<TreePath, String>() {
|
||||
@Override
|
||||
@@ -324,4 +327,8 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
|
||||
public static XDebuggerTree getTree(DataContext context) {
|
||||
return XDEBUGGER_TREE_KEY.getData(context);
|
||||
}
|
||||
|
||||
public TransferToEDTQueue<Runnable> getLaterInvocator() {
|
||||
return myLaterInvocator;
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -189,4 +189,8 @@ public abstract class XDebuggerTreeNode implements TreeNode, TreeSpeedSearch.Pat
|
||||
component.append(link.getLinkText(), link.getTextAttributes(), link);
|
||||
}
|
||||
}
|
||||
|
||||
void invokeNodeUpdate(Runnable runnable) {
|
||||
myTree.getLaterInvocator().offer(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -22,7 +22,6 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SortedList;
|
||||
import com.intellij.xdebugger.frame.*;
|
||||
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
|
||||
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
|
||||
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
|
||||
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -75,7 +74,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
|
||||
|
||||
@Override
|
||||
public void addChildren(@NotNull final XValueChildrenList children, final boolean last) {
|
||||
DebuggerUIUtil.invokeLater(new Runnable() {
|
||||
invokeNodeUpdate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myValueChildren == null) {
|
||||
@@ -125,7 +124,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
|
||||
|
||||
@Override
|
||||
public void tooManyChildren(final int remaining) {
|
||||
DebuggerUIUtil.invokeLater(new Runnable() {
|
||||
invokeNodeUpdate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setTemporaryMessageNode(MessageTreeNode.createEllipsisNode(myTree, XValueContainerNode.this, remaining));
|
||||
@@ -162,7 +161,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
|
||||
@Override
|
||||
public void setMessage(@NotNull final String message,
|
||||
final Icon icon, @NotNull final SimpleTextAttributes attributes, @Nullable final XDebuggerTreeNodeHyperlink link) {
|
||||
DebuggerUIUtil.invokeLater(new Runnable() {
|
||||
invokeNodeUpdate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setMessageNodes(MessageTreeNode.createMessages(myTree, XValueContainerNode.this, message, link,
|
||||
|
||||
+8
-2
@@ -94,12 +94,18 @@ public final class XValueNodePresentationConfigurator {
|
||||
node.applyPresentation(icon, presentation, hasChildren);
|
||||
}
|
||||
else {
|
||||
application.invokeLater(new Runnable() {
|
||||
Runnable updater = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
node.applyPresentation(icon, presentation, hasChildren);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (node instanceof XDebuggerTreeNode) {
|
||||
((XDebuggerTreeNode)node).invokeNodeUpdate(updater);
|
||||
}
|
||||
else {
|
||||
application.invokeLater(updater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-13
@@ -44,14 +44,7 @@ import java.util.regex.Matcher;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class GroovySuppressableInspectionTool extends LocalInspectionTool implements BatchSuppressableTool {
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
return getSuppressActions(getShortName());
|
||||
|
||||
}
|
||||
|
||||
public abstract class GroovySuppressableInspectionTool extends LocalInspectionTool {
|
||||
public static SuppressQuickFix[] getSuppressActions(String name) {
|
||||
final HighlightDisplayKey displayKey = HighlightDisplayKey.find(name);
|
||||
return new SuppressQuickFix[] {
|
||||
@@ -61,11 +54,6 @@ public abstract class GroovySuppressableInspectionTool extends LocalInspectionTo
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressedFor(@NotNull final PsiElement element) {
|
||||
return isElementToolSuppressedIn(element, getID());
|
||||
}
|
||||
|
||||
public static boolean isElementToolSuppressedIn(final PsiElement place, final String toolId) {
|
||||
return getElementToolSuppressedIn(place, toolId) != null;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.jetbrains.rest.inspections;
|
||||
|
||||
import com.intellij.codeInspection.CustomSuppressableInspectionTool;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.SuppressIntentionAction;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.rest.RestBundle;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
@@ -27,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* User : catherine
|
||||
*/
|
||||
public abstract class RestInspection extends LocalInspectionTool implements CustomSuppressableInspectionTool {
|
||||
public abstract class RestInspection extends LocalInspectionTool {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -46,9 +44,10 @@ public abstract class RestInspection extends LocalInspectionTool implements Cust
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressIntentionAction[] getSuppressActions(@Nullable PsiElement element) {
|
||||
return null;
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
return SuppressQuickFix.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.SuppressIntentionAction;
|
||||
import com.intellij.codeInspection.SuppressQuickFix;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -230,9 +230,10 @@ public class PyDocstringInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressIntentionAction[] getSuppressActions(@Nullable PsiElement element) {
|
||||
List<SuppressIntentionAction> result = new ArrayList<SuppressIntentionAction>();
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
List<SuppressQuickFix> result = new ArrayList<SuppressQuickFix>();
|
||||
if (element != null) {
|
||||
if (PsiTreeUtil.getParentOfType(element, PyFunction.class) != null) {
|
||||
result.add(new PySuppressInspectionFix(getShortName().replace("Inspection", ""), "Suppress for function", PyFunction.class));
|
||||
@@ -241,6 +242,6 @@ public class PyDocstringInspection extends PyInspection {
|
||||
result.add(new PySuppressInspectionFix(getShortName().replace("Inspection", ""), "Suppress for class", PyClass.class));
|
||||
}
|
||||
}
|
||||
return result.toArray(new SuppressIntentionAction[result.size()]);
|
||||
return result.toArray(new SuppressQuickFix[result.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.CustomSuppressableInspectionTool;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.SuppressIntentionAction;
|
||||
import com.intellij.codeInspection.SuppressionUtil;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -41,7 +38,7 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class PyInspection extends LocalInspectionTool implements CustomSuppressableInspectionTool {
|
||||
public abstract class PyInspection extends LocalInspectionTool {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -60,12 +57,13 @@ public abstract class PyInspection extends LocalInspectionTool implements Custom
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SuppressIntentionAction[] getSuppressActions(@Nullable final PsiElement element) {
|
||||
List<SuppressIntentionAction> result = new ArrayList<SuppressIntentionAction>();
|
||||
public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
|
||||
List<SuppressQuickFix> result = new ArrayList<SuppressQuickFix>();
|
||||
result.add(new PySuppressInspectionFix(getSuppressId(), "Suppress for statement", PyStatement.class) {
|
||||
@Override
|
||||
protected PsiElement getContainer(PsiElement context) {
|
||||
public PsiElement getContainer(PsiElement context) {
|
||||
if (PsiTreeUtil.getParentOfType(context, PyStatementList.class, false, ScopeOwner.class) != null ||
|
||||
PsiTreeUtil.getParentOfType(context, PyFunction.class, PyClass.class) == null) {
|
||||
return super.getContainer(context);
|
||||
@@ -75,7 +73,7 @@ public abstract class PyInspection extends LocalInspectionTool implements Custom
|
||||
});
|
||||
result.add(new PySuppressInspectionFix(getSuppressId(), "Suppress for function", PyFunction.class));
|
||||
result.add(new PySuppressInspectionFix(getSuppressId(), "Suppress for class", PyClass.class));
|
||||
return result.toArray(new SuppressIntentionAction[result.size()]);
|
||||
return result.toArray(new SuppressQuickFix[result.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,7 +129,7 @@ public abstract class PyInspection extends LocalInspectionTool implements Custom
|
||||
return m.matches() && SuppressionUtil.isInspectionToolIdMentioned(m.group(1), getSuppressId());
|
||||
}
|
||||
|
||||
private String getSuppressId() {
|
||||
protected String getSuppressId() {
|
||||
return getShortName().replace("Inspection", "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.jetbrains.python.inspections.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.actions.AbstractBatchSuppressByNoInspectionCommentFix;
|
||||
import com.intellij.codeInsight.daemon.impl.actions.AbstractSuppressByNoInspectionCommentFix;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -23,7 +24,7 @@ import com.jetbrains.python.psi.PyElement;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PySuppressInspectionFix extends AbstractSuppressByNoInspectionCommentFix {
|
||||
public class PySuppressInspectionFix extends AbstractBatchSuppressByNoInspectionCommentFix {
|
||||
private final Class<? extends PyElement> myContainerClass;
|
||||
|
||||
public PySuppressInspectionFix(final String ID, final String text, final Class<? extends PyElement> containerClass) {
|
||||
@@ -33,7 +34,7 @@ public class PySuppressInspectionFix extends AbstractSuppressByNoInspectionComme
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiElement getContainer(PsiElement context) {
|
||||
public PsiElement getContainer(PsiElement context) {
|
||||
return PsiTreeUtil.getParentOfType(context, myContainerClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,8 +259,8 @@ public class PyPIPackageUtil {
|
||||
return packages;
|
||||
}
|
||||
|
||||
public Collection<String> getPackageNames() throws IOException {
|
||||
Map<String, String> pyPIPackages = loadAndGetPackages();
|
||||
public Collection<String> getPackageNames() {
|
||||
Map<String, String> pyPIPackages = getPyPIPackages();
|
||||
ArrayList<String> list = Lists.newArrayList(pyPIPackages.keySet());
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
|
||||
@@ -30,8 +30,10 @@ import com.jetbrains.python.packaging.PyRequirement;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -51,13 +53,7 @@ public class PyPackageUsagesCollector extends AbstractApplicationUsagesCollector
|
||||
public void run() {
|
||||
List<PyRequirement> requirements = PyPackageManagerImpl.getRequirements(m);
|
||||
if (requirements != null) {
|
||||
Collection<String> packages;
|
||||
try {
|
||||
packages = new HashSet<String>(PyPIPackageUtil.INSTANCE.getPackageNames());
|
||||
}
|
||||
catch (IOException e) {
|
||||
return;
|
||||
}
|
||||
Collection<String> packages = new HashSet<String>(PyPIPackageUtil.INSTANCE.getPackageNames());
|
||||
for (PyRequirement requirement : requirements) {
|
||||
String name = requirement.getName();
|
||||
if (packages.contains(name)) {
|
||||
|
||||
@@ -281,4 +281,6 @@ wrap.array.to.arrays.as.list.single.parameter.text=Wrap using ''Arrays.asList''
|
||||
|
||||
annotations.fix=Annotations
|
||||
add.missing.annotation.parameters.fix=Add missing annotation parameters - {0}
|
||||
add.missing.annotation.single.parameter.fix=Add missing annotation parameter ''{0}''
|
||||
add.missing.annotation.single.parameter.fix=Add missing annotation parameter ''{0}''
|
||||
|
||||
add.method.qualifier.fix.text=Add Qualifier {0} to Method
|
||||
@@ -40,7 +40,7 @@ import java.awt.*;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class SpellCheckingInspection extends LocalInspectionTool implements BatchSuppressableTool {
|
||||
public class SpellCheckingInspection extends LocalInspectionTool {
|
||||
public static final String SPELL_CHECKING_INSPECTION_TOOL_NAME = "SpellCheckingInspection";
|
||||
|
||||
@Override
|
||||
@@ -66,12 +66,8 @@ public class SpellCheckingInspection extends LocalInspectionTool implements Batc
|
||||
if(strategy instanceof SuppressibleSpellcheckingStrategy) {
|
||||
return ((SuppressibleSpellcheckingStrategy)strategy).getSuppressActions(element, getShortName());
|
||||
}
|
||||
final InspectionSuppressor suppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(language);
|
||||
if (suppressor != null) {
|
||||
return suppressor.getSuppressActions(element, getShortName());
|
||||
}
|
||||
}
|
||||
return SuppressQuickFix.EMPTY_ARRAY;
|
||||
return super.getBatchSuppressActions(element);
|
||||
}
|
||||
|
||||
private static SpellcheckingStrategy getSpellcheckingStrategy(@NotNull PsiElement element, @NotNull Language language) {
|
||||
@@ -90,8 +86,7 @@ public class SpellCheckingInspection extends LocalInspectionTool implements Batc
|
||||
if (strategy instanceof SuppressibleSpellcheckingStrategy) {
|
||||
return ((SuppressibleSpellcheckingStrategy)strategy).isSuppressedFor(element, getShortName());
|
||||
}
|
||||
final InspectionSuppressor suppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(language);
|
||||
return suppressor != null && suppressor.isSuppressedFor(element, getShortName());
|
||||
return super.isSuppressedFor(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user