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:
+35
-33
@@ -55,7 +55,14 @@ public class ContractInference {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<List<MethodContract>> compute() {
|
||||
return Result.create(new ContractInferenceInterpreter(method).inferContracts(), method);
|
||||
List<MethodContract> result = RecursionManager.doPreventingRecursion(method, true, new Computable<List<MethodContract>>() {
|
||||
@Override
|
||||
public List<MethodContract> compute() {
|
||||
return new ContractInferenceInterpreter(method).inferContracts();
|
||||
}
|
||||
});
|
||||
if (result == null) result = Collections.emptyList();
|
||||
return Result.create(result, method);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -134,47 +141,42 @@ class ContractInferenceInterpreter {
|
||||
if (targetMethod == null) return Collections.emptyList();
|
||||
|
||||
final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
|
||||
return RecursionManager.doPreventingRecursion(myMethod, true, new Computable<List<MethodContract>>() {
|
||||
final boolean notNull = NullableNotNullManager.isNotNull(targetMethod);
|
||||
List<MethodContract> fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction<MethodContract, MethodContract>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public List<MethodContract> compute() {
|
||||
final boolean notNull = NullableNotNullManager.isNotNull(targetMethod);
|
||||
List<MethodContract> fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction<MethodContract, MethodContract>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public MethodContract fun(MethodContract delegateContract) {
|
||||
ValueConstraint[] answer = myEmptyConstraints;
|
||||
for (int i = 0; i < delegateContract.arguments.length; i++) {
|
||||
if (i >= arguments.length) return null;
|
||||
public MethodContract fun(MethodContract delegateContract) {
|
||||
ValueConstraint[] answer = myEmptyConstraints;
|
||||
for (int i = 0; i < delegateContract.arguments.length; i++) {
|
||||
if (i >= arguments.length) return null;
|
||||
|
||||
ValueConstraint argConstraint = delegateContract.arguments[i];
|
||||
if (argConstraint != ANY_VALUE) {
|
||||
int paramIndex = resolveParameter(arguments[i]);
|
||||
if (paramIndex < 0) {
|
||||
if (argConstraint != getLiteralConstraint(arguments[i])) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
answer = withConstraint(answer, paramIndex, argConstraint);
|
||||
if (answer == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
ValueConstraint argConstraint = delegateContract.arguments[i];
|
||||
if (argConstraint != ANY_VALUE) {
|
||||
int paramIndex = resolveParameter(arguments[i]);
|
||||
if (paramIndex < 0) {
|
||||
if (argConstraint != getLiteralConstraint(arguments[i])) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue;
|
||||
if (notNull && returnValue != THROW_EXCEPTION) {
|
||||
returnValue = NOT_NULL_VALUE;
|
||||
else {
|
||||
answer = withConstraint(answer, paramIndex, argConstraint);
|
||||
if (answer == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return answer == null ? null : new MethodContract(answer, returnValue);
|
||||
}
|
||||
});
|
||||
if (notNull) {
|
||||
return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE)));
|
||||
}
|
||||
return fromDelegate;
|
||||
ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue;
|
||||
if (notNull && returnValue != THROW_EXCEPTION) {
|
||||
returnValue = NOT_NULL_VALUE;
|
||||
}
|
||||
return answer == null ? null : new MethodContract(answer, returnValue);
|
||||
}
|
||||
});
|
||||
if (notNull) {
|
||||
return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE)));
|
||||
}
|
||||
return fromDelegate;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+2
-2
@@ -1510,11 +1510,11 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findContractAnnotation(PsiMethod method) {
|
||||
public static PsiAnnotation findContractAnnotation(@NotNull PsiMethod method) {
|
||||
return AnnotationUtil.findAnnotationInHierarchy(method, Collections.singleton(ORG_JETBRAINS_ANNOTATIONS_CONTRACT));
|
||||
}
|
||||
|
||||
public static boolean isPure(PsiMethod method) {
|
||||
public static boolean isPure(@NotNull PsiMethod method) {
|
||||
PsiAnnotation anno = findContractAnnotation(method);
|
||||
return anno != null && Boolean.TRUE.equals(AnnotationUtil.getBooleanAttributeValue(anno, "pure"));
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ public class JavaCompletionUtil {
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (method.getSignature(plainSub).equals(method.getSignature(castSub)) &&
|
||||
returnType != null &&
|
||||
castSub.substitute(returnType).isAssignableFrom(plainSub.substitute(returnType)) &&
|
||||
toRaw(castSub.substitute(returnType)).isAssignableFrom(toRaw(plainSub.substitute(returnType))) &&
|
||||
processor.isAccessible(plainClass.findMethodBySignature(method, true))
|
||||
) {
|
||||
return item;
|
||||
@@ -494,6 +494,10 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiType toRaw(@NotNull PsiType type) {
|
||||
return type instanceof PsiClassType ? ((PsiClassType)type).rawType() : type;
|
||||
}
|
||||
|
||||
public static LookupElement highlightIfNeeded(PsiType qualifierType, LookupElement item, Object object) {
|
||||
return containsMember(qualifierType, object) ? highlight(item) : item;
|
||||
|
||||
@@ -192,7 +192,7 @@ public class AnnotationUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiAnnotation findAnnotationInHierarchy(final PsiModifierListOwner listOwner, @NotNull Set<String> annotationNames) {
|
||||
public static PsiAnnotation findAnnotationInHierarchy(@NotNull final PsiModifierListOwner listOwner, @NotNull Set<String> annotationNames) {
|
||||
PsiAnnotation directAnnotation = findAnnotation(listOwner, annotationNames);
|
||||
if (directAnnotation != null) return directAnnotation;
|
||||
|
||||
|
||||
+27
-6
@@ -13,13 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.JavaCodeFragmentFactory;
|
||||
package com.intellij.codeInsight.completion
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.JavaCodeFragmentFactory
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiExpression
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.PairFunction
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -97,5 +100,23 @@ public class FragmentCompletionTest extends LightCodeInsightFixtureTestCase {
|
||||
myFixture.checkResult("o instanceof String && ((String) o).substring(<caret>)");
|
||||
}
|
||||
|
||||
public void testNoGenericQualifierCastingWithRuntimeType() throws Throwable {
|
||||
final ctxText = "import java.util.*; class Bar {{ Map<Integer,Integer> map = new HashMap<Integer,Integer>(); map=null; }}"
|
||||
final ctxFile = createLightFile(StdFileTypes.JAVA, ctxText)
|
||||
final context = ctxFile.findElementAt(ctxText.indexOf("map="))
|
||||
assert context
|
||||
|
||||
PsiFile file = JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment("map.entry<caret>", context, null, true);
|
||||
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
|
||||
myFixture.file.putCopyableUserData(JavaCompletionUtil.DYNAMIC_TYPE_EVALUATOR, new PairFunction<PsiExpression, CompletionParameters, PsiType>() {
|
||||
@Override
|
||||
PsiType fun(PsiExpression t, CompletionParameters v) {
|
||||
return JavaPsiFacade.getElementFactory(t.project).createTypeByFQClassName(CommonClassNames.JAVA_UTIL_HASH_MAP)
|
||||
}
|
||||
})
|
||||
assert !myFixture.completeBasic()
|
||||
myFixture.checkResult("map.entrySet()<caret>");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
package com.intellij.openapi.options;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link ConfigurableProvider#canCreateConfigurable()} instead
|
||||
* to specify configurables which should not be visible
|
||||
* (a provider usually does not instantiate a configurable and related classes)
|
||||
*
|
||||
* @author yole
|
||||
*/
|
||||
@Deprecated
|
||||
public interface OptionalConfigurable {
|
||||
boolean needDisplay();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public interface SearchableConfigurable extends Configurable {
|
||||
/**
|
||||
* @deprecated use {@link ConfigurableProvider#canCreateConfigurable()} instead
|
||||
* to specify configurables which should not be visible
|
||||
* (a provider usually does not instantiate a configurable and related classes)
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isVisible();
|
||||
|
||||
@@ -36,6 +36,7 @@ public abstract class ProjectSetProcessor {
|
||||
|
||||
public static class Context {
|
||||
public VirtualFile directory;
|
||||
public String directoryName;
|
||||
public Project project;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -130,8 +130,9 @@ public class ConfigurableExtensionPointUtil {
|
||||
}
|
||||
|
||||
private static boolean isSuppressed(Configurable each, ConfigurableFilter filter) {
|
||||
OptionalConfigurable optional = ConfigurableWrapper.cast(OptionalConfigurable.class, each);
|
||||
return each instanceof Configurable.Assistant
|
||||
|| each instanceof OptionalConfigurable && !((OptionalConfigurable) each).needDisplay()
|
||||
|| optional != null && !optional.needDisplay()
|
||||
|| filter != null && !filter.isIncluded(each);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ProjectSetReader {
|
||||
processors.put(extension.getId(), extension);
|
||||
}
|
||||
|
||||
JsonElement parse = null;
|
||||
JsonElement parse;
|
||||
try {
|
||||
parse = new JsonParser().parse(descriptor);
|
||||
}
|
||||
@@ -51,6 +51,7 @@ public class ProjectSetReader {
|
||||
}
|
||||
Iterator<Map.Entry<String, JsonElement>> iterator = parse.getAsJsonObject().entrySet().iterator();
|
||||
ProjectSetProcessor.Context context = new ProjectSetProcessor.Context();
|
||||
context.directoryName = "";
|
||||
context.directory = forTests;
|
||||
runProcessor(processors, context, iterator);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ org.jetbrains.kannotator 0.2.420
|
||||
org.jetbrains.kotlin 0.7.1360 0.7.1376 0.8.7
|
||||
SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0
|
||||
"JSTestDriver Plugin" 138.317 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
|
||||
AngularJS 134.1094 0.1.8 0.1.9
|
||||
AngularJS 134.1243 134.1341 134.1444 135.1063 135.565 135.831 135.937 138.1242 138.1988 134.1094 0.1.8 0.1.9
|
||||
com.jetbrains.plugins.ini4idea 0.4 0.5 0.6 0.7 0.8 0.8.1 0.9 0.9.1 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5
|
||||
org.jetbrains.plugins.vagrant 0.1 0.2
|
||||
org.intellij.clojure 0.2.1.178
|
||||
net.nicoulaj.idea.markdown 0.9.5 0.9.4 0.9.3 0.9.2 0.9.1 0.8.3 0.8.2 0.8.1 0.8 0.7 0.6.1 0.6 0.5.1 0.5 0.4 0.3 0.2 0.1
|
||||
|
||||
+18
-14
@@ -59,13 +59,15 @@ public class UsageViewContext {
|
||||
|
||||
public void configure(@NotNull UsageViewPresentation presentation) {
|
||||
final String pattern = myConfiguration.getMatchOptions().getSearchPattern();
|
||||
presentation.setScopeText(myConfiguration.getMatchOptions().getScope().getDisplayName());
|
||||
final String scopeText = myConfiguration.getMatchOptions().getScope().getDisplayName();
|
||||
presentation.setScopeText(scopeText);
|
||||
final String usagesString = SSRBundle.message("occurrences.of", pattern);
|
||||
presentation.setUsagesString(usagesString);
|
||||
presentation.setTabText(StringUtil.shortenTextWithEllipsis(usagesString, 60, 0, false));
|
||||
presentation.setUsagesWord(SSRBundle.message("occurrence"));
|
||||
presentation.setCodeUsagesString(SSRBundle.message("found.occurrences"));
|
||||
presentation.setCodeUsagesString(SSRBundle.message("found.occurrences", scopeText));
|
||||
presentation.setTargetsNodeText(SSRBundle.message("targets.node.text"));
|
||||
presentation.setCodeUsages(false);
|
||||
}
|
||||
|
||||
protected void configureActions() {}
|
||||
@@ -75,17 +77,7 @@ public class UsageViewContext {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableText() {
|
||||
final MatchOptions matchOptions = myConfiguration.getMatchOptions();
|
||||
final String pattern = matchOptions.getSearchPattern();
|
||||
final String scope = matchOptions.getScope().getDisplayName();
|
||||
if (myConfiguration instanceof ReplaceConfiguration) {
|
||||
final ReplaceConfiguration replaceConfiguration = (ReplaceConfiguration)myConfiguration;
|
||||
final String replacement = replaceConfiguration.getOptions().getReplacement();
|
||||
return SSRBundle.message("replace.occurrences.of.0.with.1.in.2", pattern, replacement, scope);
|
||||
}
|
||||
else {
|
||||
return SSRBundle.message("occurrences.of.0.in.1", pattern, scope);
|
||||
}
|
||||
return myConfiguration.getMatchOptions().getSearchPattern();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,7 +166,19 @@ public class UsageViewContext {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getLongDescriptiveName() {
|
||||
return StringUtil.shortenTextWithEllipsis(getPresentableText(), 150, 0, true);
|
||||
final MatchOptions matchOptions = myConfiguration.getMatchOptions();
|
||||
final String pattern = matchOptions.getSearchPattern();
|
||||
final String scope = matchOptions.getScope().getDisplayName();
|
||||
final String result;
|
||||
if (myConfiguration instanceof ReplaceConfiguration) {
|
||||
final ReplaceConfiguration replaceConfiguration = (ReplaceConfiguration)myConfiguration;
|
||||
final String replacement = replaceConfiguration.getOptions().getReplacement();
|
||||
result = SSRBundle.message("replace.occurrences.of.0.with.1.in.2", pattern, replacement, scope);
|
||||
}
|
||||
else {
|
||||
result = SSRBundle.message("occurrences.of.0.in.1", pattern, scope);
|
||||
}
|
||||
return StringUtil.shortenTextWithEllipsis(result, 150, 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.intellij.openapi.vcs;
|
||||
import com.intellij.ide.impl.ProjectUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.projectImport.ProjectSetProcessor;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -35,13 +37,17 @@ public class OpenProjectSetProcessor extends ProjectSetProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEntries(@NotNull List<Pair<String, String>> entries, @NotNull Context context, @NotNull Runnable runNext) {
|
||||
for (Pair<String, String> entry : entries) {
|
||||
public void processEntries(@NotNull List<Pair<String, String>> entries, @NotNull final Context context, @NotNull Runnable runNext) {
|
||||
for (final Pair<String, String> entry : entries) {
|
||||
if ("project".equals(entry.getFirst())) {
|
||||
Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||
Project project = ProjectUtil.openProject(context.directory.getPath() + entry.getSecond(), ArrayUtil.getFirstElement(projects), false);
|
||||
if (project == null) return;
|
||||
context.project = project;
|
||||
final Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||
context.project = UIUtil.invokeAndWaitIfNeeded(new Computable<Project>() {
|
||||
@Override
|
||||
public Project compute() {
|
||||
return ProjectUtil.openProject(context.directory.getPath() + "/" + context.directoryName + "/" + entry.getSecond(), ArrayUtil.getFirstElement(projects), false);
|
||||
}
|
||||
});
|
||||
if (context.project == null) return;
|
||||
runNext.run();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +44,9 @@ public class VcsProjectSetProcessor extends ProjectSetProcessor {
|
||||
@NotNull final Context context,
|
||||
@NotNull final Runnable runNext) {
|
||||
|
||||
final VirtualFile directory;
|
||||
if (context.directory != null) {
|
||||
directory = context.directory;
|
||||
}
|
||||
else {
|
||||
directory = getDirectory();
|
||||
if (directory == null) return;
|
||||
if (context.directory == null) {
|
||||
context.directory = getDirectory();
|
||||
if (context.directory == null) return;
|
||||
}
|
||||
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(null, "Hey", true) {
|
||||
@@ -66,7 +62,8 @@ public class VcsProjectSetProcessor extends ProjectSetProcessor {
|
||||
|
||||
String url = pair.getSecond();
|
||||
final String[] split = splitUrl(url);
|
||||
if (!processor.checkout(split[0], directory, split[1])) return;
|
||||
context.directoryName = split[1];
|
||||
if (!processor.checkout(split[0], context.directory, context.directoryName)) return;
|
||||
}
|
||||
runNext.run();
|
||||
}
|
||||
|
||||
+5
-8
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SideEffectChecker {
|
||||
@@ -60,14 +60,11 @@ public class SideEffectChecker {
|
||||
return;
|
||||
}
|
||||
super.visitMethodCallExpression(expression);
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if ((methodName.startsWith("is") || methodName.startsWith("get")) && expression.getArgumentList().getExpressions().length == 0) {
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (PropertyUtil.isSimpleGetter(method)) {
|
||||
return;
|
||||
}
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (method != null && ControlFlowAnalyzer.isPure(method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mayHaveSideEffects = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,8 +149,8 @@ if.to.assertion.intention.name=Replace 'if' with 'assert' statement
|
||||
expand.to.normal.annotation.intention.family.name=Expand Annotation to Normal Form
|
||||
expand.to.normal.annotation.intention.name=Add 'value=' to annotation attribute
|
||||
annotate.overridden.methods.intention.family.name=Annotate overriding methods and their parameters
|
||||
annotate.overridden.methods.intention.method.name=Annotate overriding methods as ''@{0}''
|
||||
annotate.overridden.methods.intention.parameters.name=Annotate same parameter of overriding methods as ''@{0}''
|
||||
annotate.overridden.methods.intention.method.name=Annotate overriding methods as ''{0}''
|
||||
annotate.overridden.methods.intention.parameters.name=Annotate same parameter of overriding methods as ''{0}''
|
||||
split.multi.catch.intention.name=Split multi-catch into separate 'catch' blocks
|
||||
split.multi.catch.intention.family.name=Split Multi-Catch into Separate Catch Blocks
|
||||
replace.arm.with.try.finally.intention.name=Replace 'try-with-resources' with 'try finally'
|
||||
|
||||
+36
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 Bas Leijdekkers
|
||||
* Copyright 2011-2014 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,22 +15,24 @@
|
||||
*/
|
||||
package com.siyeh.ipp.annotation;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.IntentionPowerPackBundle;
|
||||
import com.siyeh.ipp.base.MutablyNamedIntention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
@NotNull
|
||||
@@ -42,32 +44,37 @@ public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
@Override
|
||||
protected String getTextForElement(PsiElement element) {
|
||||
final PsiAnnotation annotation = (PsiAnnotation)element;
|
||||
final String qualifiedName = annotation.getQualifiedName();
|
||||
if (qualifiedName == null) {
|
||||
return null;
|
||||
}
|
||||
final String annotationName = ClassUtil.extractClassName(qualifiedName);
|
||||
final String annotationText = annotation.getText();
|
||||
final PsiElement grandParent = element.getParent().getParent();
|
||||
if (grandParent instanceof PsiMethod) {
|
||||
return IntentionPowerPackBundle.message(
|
||||
"annotate.overridden.methods.intention.method.name",
|
||||
annotationName);
|
||||
return IntentionPowerPackBundle.message("annotate.overridden.methods.intention.method.name", annotationText);
|
||||
}
|
||||
else {
|
||||
return IntentionPowerPackBundle.message(
|
||||
"annotate.overridden.methods.intention.parameters.name",
|
||||
annotationName);
|
||||
return IntentionPowerPackBundle.message("annotate.overridden.methods.intention.parameters.name", annotationText);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element)
|
||||
throws IncorrectOperationException {
|
||||
protected void processIntention(@NotNull PsiElement element) {
|
||||
final PsiAnnotation annotation = (PsiAnnotation)element;
|
||||
final String annotationName = annotation.getQualifiedName();
|
||||
if (annotationName == null) {
|
||||
return;
|
||||
}
|
||||
final Project project = element.getProject();
|
||||
final NullableNotNullManager notNullManager = NullableNotNullManager.getInstance(project);
|
||||
final List<String> notNulls = notNullManager.getNotNulls();
|
||||
final List<String> nullables = notNullManager.getNullables();
|
||||
final List<String> annotationsToRemove;
|
||||
if (notNulls.contains(annotationName)) {
|
||||
annotationsToRemove = nullables;
|
||||
}
|
||||
else if (nullables.contains(annotationName)) {
|
||||
annotationsToRemove = notNulls;
|
||||
}
|
||||
else {
|
||||
annotationsToRemove = Collections.emptyList();
|
||||
}
|
||||
final PsiElement parent = annotation.getParent();
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
final PsiMethod method;
|
||||
@@ -95,7 +102,6 @@ public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
parameterIndex = -1;
|
||||
method = (PsiMethod)grandParent;
|
||||
}
|
||||
final Project project = element.getProject();
|
||||
final Collection<PsiMethod> overridingMethods =
|
||||
OverridingMethodsSearch.search(method,
|
||||
GlobalSearchScope.allScope(project), true).findAll();
|
||||
@@ -103,14 +109,14 @@ public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
annotation.getParameterList().getAttributes();
|
||||
for (PsiMethod overridingMethod : overridingMethods) {
|
||||
if (parameterIndex == -1) {
|
||||
annotate(overridingMethod, annotationName, attributes, element);
|
||||
annotate(overridingMethod, annotationName, attributes, element, annotationsToRemove);
|
||||
}
|
||||
else {
|
||||
final PsiParameterList parameterList =
|
||||
overridingMethod.getParameterList();
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final PsiParameter parameter = parameters[parameterIndex];
|
||||
annotate(parameter, annotationName, attributes, element);
|
||||
annotate(parameter, annotationName, attributes, element, annotationsToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +124,8 @@ public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
private static void annotate(PsiModifierListOwner modifierListOwner,
|
||||
String annotationName,
|
||||
PsiNameValuePair[] attributes,
|
||||
PsiElement context) {
|
||||
PsiElement context,
|
||||
List<String> annotationsToRemove) {
|
||||
final Project project = context.getProject();
|
||||
final ExternalAnnotationsManager annotationsManager =
|
||||
ExternalAnnotationsManager.getInstance(project);
|
||||
@@ -138,6 +145,9 @@ public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
final PsiFile fromFile = context.getContainingFile();
|
||||
if (annotationAnnotationPlace ==
|
||||
ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) {
|
||||
for (String annotationToRemove : annotationsToRemove) {
|
||||
annotationsManager.deannotate(modifierListOwner, annotationToRemove);
|
||||
}
|
||||
annotationsManager.annotateExternally(modifierListOwner,
|
||||
annotationName, fromFile, attributes);
|
||||
}
|
||||
@@ -147,6 +157,12 @@ public class AnnotateOverriddenMethodsIntention extends MutablyNamedIntention {
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(containingFile)) {
|
||||
return;
|
||||
}
|
||||
for (String annotationToRemove : annotationsToRemove) {
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotation(modifierListOwner, annotationToRemove);
|
||||
if (annotation != null) {
|
||||
annotation.delete();
|
||||
}
|
||||
}
|
||||
final PsiAnnotation inserted =
|
||||
modifierList.addAnnotation(annotationName);
|
||||
for (PsiNameValuePair pair : attributes) {
|
||||
|
||||
@@ -299,13 +299,20 @@ public class XPathEvalAction extends XPathAction {
|
||||
|
||||
public static void showUsageView(@NotNull final Project project, MyUsageTarget usageTarget, Factory<UsageSearcher> searcherFactory, final EditExpressionAction editAction) {
|
||||
final UsageViewPresentation presentation = new UsageViewPresentation();
|
||||
presentation.setTargetsNodeText("Expression");
|
||||
presentation.setTargetsNodeText("XPath Expression");
|
||||
presentation.setCodeUsages(false);
|
||||
presentation.setCodeUsagesString("Result");
|
||||
presentation.setCodeUsagesString("Found Matches");
|
||||
presentation.setNonCodeUsagesString("Result");
|
||||
presentation.setUsagesString("XPath Result");
|
||||
presentation.setUsagesWord("match");
|
||||
presentation.setTabText("XPath");
|
||||
final ItemPresentation targetPresentation = usageTarget.getPresentation();
|
||||
if (targetPresentation != null) {
|
||||
presentation
|
||||
.setTabText(StringUtil.shortenTextWithEllipsis("XPath '" + targetPresentation.getPresentableText() + '\'', 60, 0, true));
|
||||
}
|
||||
else {
|
||||
presentation.setTabText("XPath");
|
||||
}
|
||||
presentation.setScopeText("XML Files");
|
||||
|
||||
presentation.setOpenInNewTab(XPathAppComponent.getInstance().getConfig().OPEN_NEW_TAB);
|
||||
|
||||
+5
-4
@@ -25,6 +25,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.usages.*;
|
||||
import org.intellij.plugins.xpathView.Config;
|
||||
import org.intellij.plugins.xpathView.XPathAppComponent;
|
||||
@@ -78,13 +79,13 @@ public class FindByXPathAction extends AnAction {
|
||||
}
|
||||
|
||||
final UsageViewPresentation presentation = new UsageViewPresentation();
|
||||
presentation.setTargetsNodeText(settings.MATCH_RECURSIVELY ? "Pattern" : "Expression");
|
||||
presentation.setTargetsNodeText(settings.MATCH_RECURSIVELY ? "XPath Pattern" : "XPath Expression");
|
||||
presentation.setCodeUsages(false);
|
||||
presentation.setCodeUsagesString("Result");
|
||||
presentation.setCodeUsagesString("Found Matches in " + scope.getName());
|
||||
presentation.setNonCodeUsagesString("Result");
|
||||
presentation.setUsagesString("XPath Result");
|
||||
presentation.setUsagesString("results matching '" + expression + '\'');
|
||||
presentation.setUsagesWord("match");
|
||||
presentation.setTabText("XPath");
|
||||
presentation.setTabText(StringUtil.shortenTextWithEllipsis("XPath '" + expression + '\'', 60, 0, true));
|
||||
presentation.setScopeText(scope.getName());
|
||||
|
||||
presentation.setOpenInNewTab(settings.OPEN_NEW_TAB);
|
||||
|
||||
@@ -92,7 +92,7 @@ public final class SearchScope {
|
||||
case DIRECTORY:
|
||||
return "Directory '" + getPath() + "'";
|
||||
case CUSTOM:
|
||||
return "Scope '" + getScopeName() + "'";
|
||||
return getScopeName();
|
||||
}
|
||||
assert false;
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user