Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2015-07-02 13:47:15 +03:00
154 changed files with 1686 additions and 1027 deletions
+1 -1
View File
@@ -172,7 +172,7 @@ def layoutAll(Map args, String home, String out, Paths _paths = null, buildJps =
buildTarGz("idea-${args.buildNumber}", "$paths.artifacts/idea${args.buildNumber}.tar", [paths.distAll, paths.distUnix])
if (p("jdk.bundled.linux") != "false") {
buildTarGz("idea-${args.buildNumber}", "$paths.artifacts/idea${args.buildNumber}-jdk-bundled.tar", [paths.distAll, paths.distUnix, "${paths.sandbox}/bundled.linux.jdk"], ["jre/bin/*"])
buildTarGz("idea-${args.buildNumber}", "$paths.artifacts/idea${args.buildNumber}-jdk-bundled.tar", [paths.distAll, paths.distUnix, "${paths.sandbox}/bundled.linux.jdk"], ["jre/jre/bin/*"])
}
return info
}
-1
View File
@@ -260,7 +260,6 @@ libraryLicense(name: "protobuf", version: "2.5.0", license: "New BSD", url: "htt
libraryLicense(name: "Netty", libraryName: "Netty", version: "4.1.0.Beta3", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Kryo", libraryName: "Kryo", version: "2.22", license: "New BSD License", url: "https://github.com/EsotericSoftware/kryo", licenseUrl: "https://github.com/EsotericSoftware/kryo/blob/master/license.txt")
libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "0.3.1", license: "Apache 2.0", url: "https://github.com/dain/snappy", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Cucumber-Java", libraryName: "cucumber-java", version: "1.2.2", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
libraryLicense(name: "Cucumber-JVM", libraryName: "cucumber-jvm", version: "1.2.2", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
libraryLicense(name: "Cucumber-Groovy", libraryName: "cucumber-groovy", version: "1.2.2", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
libraryLicense(name: "XStream", libraryName: "XStream", version: "1.4.2", license: "BSD License", url: "https://github.com/cucumber/cucumber-jvm-deps/", licenseUrl: "http://xstream.codehaus.org/license.html")
@@ -45,7 +45,6 @@ public class ResumeThreadAction extends DebuggerAction{
final ThreadReferenceProxyImpl thread = threadDescriptor.getThreadReference();
debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) {
public void contextAction() throws Exception {
debugProcess.getSession().getXDebugSession().sessionResumed();
debugProcess.createResumeThreadCommand(getSuspendContext(), thread).run();
debuggerTreeNode.calcValue();
}
@@ -456,6 +456,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
catch (IllegalThreadStateException e) {
LOG.info(e); // undocumented by JDI: may be thrown when querying thread status
}
catch (ObjectCollectedException ignored) {
}
}
requestManager.deleteEventRequests(toDelete);
}
@@ -1694,6 +1696,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
final Set<SuspendContextImpl> suspendingContexts = SuspendManagerUtil.getSuspendingContexts(getSuspendManager(), myThread);
for (SuspendContextImpl suspendContext : suspendingContexts) {
if (suspendContext.getThread() == myThread) {
getSession().getXDebugSession().sessionResumed();
getManagerThread().invoke(createResumeCommand(suspendContext));
}
else {
@@ -28,16 +28,14 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.DocumentUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.EmptyIterable;
@@ -285,13 +283,12 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
if (document == null || lineNumber >= document.getLineCount()) {
return EmptyIterable.getInstance();
}
final int startOffset = document.getLineStartOffset(lineNumber);
final int endOffset = document.getLineEndOffset(lineNumber);
final TextRange lineRange = DocumentUtil.getLineTextRange(document, lineNumber);
return new Iterable<PsiElement>() {
@Override
public Iterator<PsiElement> iterator() {
return new Iterator<PsiElement>() {
PsiElement myElement = file.findElementAt(startOffset);
PsiElement myElement = DebuggerUtilsEx.findElementAt(file, lineRange.getStartOffset());
@Override
public boolean hasNext() {
@@ -303,7 +300,7 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
PsiElement res = myElement;
do {
myElement = PsiTreeUtil.nextLeaf(myElement);
if (myElement == null || myElement.getTextOffset() > endOffset) {
if (myElement == null || myElement.getTextOffset() > lineRange.getEndOffset()) {
myElement = null;
break;
}
@@ -589,7 +589,9 @@ public class DebuggerSession implements AbstractDebuggerSession {
@Override
public void resumed(final SuspendContextImpl suspendContext) {
final SuspendContextImpl currentContext = isSteppingThrough(suspendContext.getThread()) ? null : getProcess().getSuspendManager().getPausedContext();
final SuspendContextImpl currentContext = suspendContext != null && isSteppingThrough(suspendContext.getThread())
? null
: getProcess().getSuspendManager().getPausedContext();
DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() {
@Override
public void run() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -26,6 +26,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.psi.impl.source.PsiClassImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchHelper;
@@ -135,14 +136,15 @@ public class UnusedSymbolUtil {
}
else {
//class maybe used in some weird way, e.g. from XML, therefore the only constructor is used too
if (containingClass != null && method.isConstructor()
boolean isConstructor = method.isConstructor();
if (containingClass != null && isConstructor
&& containingClass.getConstructors().length == 1
&& isClassUsed(project, containingFile, containingClass, progress, helper)) {
return true;
}
if (isImplicitUsage(project, method, progress)) return true;
if (method.findSuperMethods().length != 0) {
if (!isConstructor && FindSuperElementsHelper.findSuperElements(method).length != 0) {
return true;
}
if (!weAreSureThereAreNoUsages(project, containingFile, method, progress, helper)) {
@@ -193,7 +195,7 @@ public class UnusedSymbolUtil {
@NotNull PsiFile containingFile,
@NotNull PsiMember member,
@NotNull ProgressIndicator progress,
final PsiFile ignoreFile,
@Nullable PsiFile ignoreFile,
@NotNull Processor<UsageInfo> usageInfoProcessor) {
String name = member.getName();
if (name == null) {
@@ -247,10 +249,8 @@ public class UnusedSymbolUtil {
}
else if (member instanceof PsiMethod) {
PsiMethod method = (PsiMethod)member;
JavaMethodFindUsagesOptions o = new JavaMethodFindUsagesOptions(project);
//o.isIncludeOverloadUsages = true;
options = o;
options.isSearchForTextOccurrences = method.isConstructor();;
options = new JavaMethodFindUsagesOptions(project);
options.isSearchForTextOccurrences = method.isConstructor();
}
else if (member instanceof PsiVariable) {
options = new JavaVariableFindUsagesOptions(project);
@@ -271,7 +271,7 @@ public class UnusedSymbolUtil {
@NotNull ProgressIndicator progress,
@NotNull GlobalUsageHelper helper) {
final PsiClass containingClass = member.getContainingClass();
if (containingClass == null || !(containingClass instanceof PsiClassImpl)) return true;
if (!(containingClass instanceof PsiClassImpl)) return true;
final PsiMethod valuesMethod = ((PsiClassImpl)containingClass).getValuesMethod();
return valuesMethod == null || isMethodReferenced(project, containingFile, valuesMethod, progress, helper);
}
@@ -0,0 +1,125 @@
/*
* Copyright 2000-2015 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.impl;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiSuperMethodUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.FactoryMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class FindSuperElementsHelper {
@NotNull
public static PsiElement[] findSuperElements(@NotNull PsiElement element) {
if (element instanceof PsiClass) {
PsiClass aClass = (PsiClass) element;
List<PsiClass> allSupers = new ArrayList<PsiClass>(Arrays.asList(aClass.getSupers()));
for (Iterator<PsiClass> iterator = allSupers.iterator(); iterator.hasNext();) {
PsiClass superClass = iterator.next();
if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) iterator.remove();
}
return allSupers.toArray(new PsiClass[allSupers.size()]);
}
if (element instanceof PsiMethod) {
PsiMethod method = (PsiMethod) element;
if (method.isConstructor()) {
PsiMethod constructorInSuper = PsiSuperMethodUtil.findConstructorInSuper(method);
if (constructorInSuper != null) {
return new PsiMethod[]{constructorInSuper};
}
}
else {
PsiMethod[] superMethods = method.findSuperMethods(false);
if (superMethods.length == 0) {
PsiMethod superMethod = getSiblingInheritedViaSubClass(method);
if (superMethod != null) {
superMethods = new PsiMethod[]{superMethod};
}
}
return superMethods;
}
}
return PsiElement.EMPTY_ARRAY;
}
public static PsiMethod getSiblingInheritedViaSubClass(@NotNull PsiMethod method) {
return getSiblingInheritedViaSubClass(method, createSubClassCache());
}
public static PsiMethod getSiblingInheritedViaSubClass(@NotNull final PsiMethod method,
@NotNull Map<PsiClass, PsiClass> subClassCache) {
if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return null;
if (method.hasModifierProperty(PsiModifier.STATIC)) return null;
final PsiClass containingClass = method.getContainingClass();
boolean hasSubClass = containingClass != null && !containingClass.isInterface() && subClassCache.get(containingClass) != null;
if (!hasSubClass) {
return null;
}
final Collection<PsiClass> checkedInterfaces = new THashSet<PsiClass>();
final PsiMethod[] result = new PsiMethod[1];
ClassInheritorsSearch.search(containingClass, true).forEach(new Processor<PsiClass>() {
@Override
public boolean process(PsiClass inheritor) {
for (PsiClassType interfaceType : inheritor.getImplementsListTypes()) {
PsiClassType.ClassResolveResult resolved = interfaceType.resolveGenerics();
PsiClass anInterface = resolved.getElement();
if (anInterface == null || !checkedInterfaces.add(anInterface)) continue;
for (PsiMethod superMethod : anInterface.findMethodsByName(method.getName(), true)) {
PsiClass superInterface = superMethod.getContainingClass();
if (superInterface == null) {
continue;
}
// calculate substitutor of containingClass --> inheritor
PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, inheritor, PsiSubstitutor.EMPTY);
// calculate substitutor of inheritor --> superInterface
substitutor = TypeConversionUtil.getSuperClassSubstitutor(superInterface, inheritor, substitutor);
final MethodSignature superSignature = superMethod.getSignature(substitutor);
final MethodSignature derivedSignature = method.getSignature(PsiSubstitutor.EMPTY);
boolean isOverridden = MethodSignatureUtil.isSubsignature(superSignature, derivedSignature);
if (isOverridden) {
result[0] = superMethod;
return false;
}
}
}
return true;
}
});
return result[0];
}
@NotNull
public static Map<PsiClass, PsiClass> createSubClassCache() {
return new FactoryMap<PsiClass, PsiClass>() {
@Nullable
@Override
protected PsiClass create(PsiClass aClass) {
return ClassInheritorsSearch.search(aClass, false).findFirst();
}
};
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -31,8 +31,8 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.psi.search.searches.AllOverridingMethodsSearch;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
@@ -48,12 +48,12 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JavaLineMarkerProvider implements LineMarkerProvider {
protected final DaemonCodeAnalyzerSettings myDaemonSettings;
protected final EditorColorsManager myColorsManager;
private final DaemonCodeAnalyzerSettings myDaemonSettings;
private final EditorColorsManager myColorsManager;
public JavaLineMarkerProvider(DaemonCodeAnalyzerSettings daemonSettings, EditorColorsManager colorsManager) {
myDaemonSettings = daemonSettings;
@@ -72,19 +72,14 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
method.hasModifierProperty(PsiModifier.ABSTRACT) == superSignature.getMethod().hasModifierProperty(PsiModifier.ABSTRACT);
final Icon icon = overrides ? AllIcons.Gutter.OverridingMethod : AllIcons.Gutter.ImplementingMethod;
final MarkerType type = MarkerType.OVERRIDING_METHOD;
ArrowUpLineMarkerInfo info = new ArrowUpLineMarkerInfo(element, icon, type);
return NavigateAction.setNavigateAction(info, "Go to super method", "GotoSuperMethod");
return createSuperMethodLineMarkerInfo(element, icon, Pass.UPDATE_ALL);
}
}
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(element);
final PsiElement firstChild = element.getFirstChild();
if (interfaceMethod != null && firstChild != null) {
final Icon icon = AllIcons.Gutter.ImplementingMethod;
final MarkerType type = MarkerType.OVERRIDING_METHOD;
ArrowUpLineMarkerInfo info = new ArrowUpLineMarkerInfo(firstChild, icon, type);
return NavigateAction.setNavigateAction(info, "Go to super method", "GotoSuperMethod");
return createSuperMethodLineMarkerInfo(firstChild, AllIcons.Gutter.ImplementingMethod, Pass.UPDATE_ALL);
}
if (myDaemonSettings.SHOW_METHOD_SEPARATORS && firstChild == null) {
@@ -128,6 +123,12 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
return null;
}
@NotNull
private static LineMarkerInfo createSuperMethodLineMarkerInfo(@NotNull PsiElement name, @NotNull Icon icon, int passId) {
ArrowUpLineMarkerInfo info = new ArrowUpLineMarkerInfo(name, icon, MarkerType.OVERRIDING_METHOD, passId);
return NavigateAction.setNavigateAction(info, "Go to super method", IdeActions.ACTION_GOTO_SUPER);
}
private static int getCategory(@NotNull PsiElement element, @NotNull CharSequence documentChars) {
if (element instanceof PsiField || element instanceof PsiTypeParameter) return 1;
if (element instanceof PsiClass || element instanceof PsiClassInitializer) return 2;
@@ -147,37 +148,87 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
@Override
public void collectSlowLineMarkers(@NotNull final List<PsiElement> elements, @NotNull final Collection<LineMarkerInfo> result) {
ApplicationManager.getApplication().assertReadAccessAllowed();
Map<PsiClass, PsiClass> subClassCache = FindSuperElementsHelper.createSubClassCache();
Set<PsiMethod> methods = new HashSet<PsiMethod>();
Collection<PsiMethod> methods = new THashSet<PsiMethod>();
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < elements.size(); i++) {
PsiElement element = elements.get(i);
ProgressManager.checkCanceled();
if (element instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)element;
if (!(element instanceof PsiIdentifier)) continue;
PsiElement parent = element.getParent();
if (parent instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)parent;
if (PsiUtil.canBeOverriden(method)) {
methods.add(method);
}
}
else if (element instanceof PsiClass && !(element instanceof PsiTypeParameter)) {
collectInheritingClasses((PsiClass)element, result);
else if (parent instanceof PsiClass && !(parent instanceof PsiTypeParameter)) {
collectInheritingClasses((PsiClass)parent, result, subClassCache);
}
}
if (!methods.isEmpty()) {
collectOverridingAccessors(methods, result);
collectOverridingMethods(methods, result);
collectSiblingInheritedMethods(methods, result, subClassCache);
}
}
public static void collectInheritingClasses(PsiClass aClass, Collection<LineMarkerInfo> result) {
private static void collectSiblingInheritedMethods(@NotNull final Collection<PsiMethod> methods,
@NotNull Collection<LineMarkerInfo> result,
@NotNull Map<PsiClass, PsiClass> subClassCache) {
for (PsiMethod method : methods) {
ProgressManager.checkCanceled();
PsiClass aClass = method.getContainingClass();
if (aClass == null || aClass.hasModifierProperty(PsiModifier.FINAL) || aClass.isInterface()) continue;
boolean canHaveSiblingSuper = !method.hasModifierProperty(PsiModifier.ABSTRACT) && !method.hasModifierProperty(PsiModifier.STATIC) && method.hasModifierProperty(PsiModifier.PUBLIC)&& !method.hasModifierProperty(PsiModifier.FINAL)&& !method.hasModifierProperty(PsiModifier.NATIVE);
if (!canHaveSiblingSuper) continue;
PsiMethod siblingInheritedViaSubClass = FindSuperElementsHelper.getSiblingInheritedViaSubClass(method, subClassCache);
if (siblingInheritedViaSubClass == null) {
continue;
}
PsiElement range = getMethodRange(method);
LineMarkerInfo info = createSuperMethodLineMarkerInfo(range, AllIcons.Gutter.ImplementingMethod, Pass.UPDATE_OVERRIDEN_MARKERS);
result.add(info);
PsiClass sClass = siblingInheritedViaSubClass.getContainingClass();
String sName = sClass == null ? null : sClass.getQualifiedName();
}
}
@NotNull
private static PsiElement getMethodRange(@NotNull PsiMethod method) {
PsiElement range;
if (method.isPhysical()) {
range = method.getNameIdentifier();
}
else {
final PsiElement navigationElement = method.getNavigationElement();
range = navigationElement instanceof PsiNameIdentifierOwner
? ((PsiNameIdentifierOwner)navigationElement).getNameIdentifier()
: navigationElement;
}
if (range == null) {
range = method;
}
return range;
}
public static void collectInheritingClasses(@NotNull PsiClass aClass,
@NotNull Collection<LineMarkerInfo> result,
@NotNull Map<PsiClass, PsiClass> subClassCache) {
if (aClass.hasModifierProperty(PsiModifier.FINAL)) {
return;
}
if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return; // It's useless to have overridden markers for object.
if (ClassInheritorsSearch.search(aClass, false).findFirst() != null || FunctionalExpressionSearch.search(aClass).findFirst() != null) {
PsiClass subClass = subClassCache.get(aClass);
if (subClass != null || FunctionalExpressionSearch.search(aClass).findFirst() != null) {
final Icon icon = aClass.isInterface() ? AllIcons.Gutter.ImplementedMethod : AllIcons.Gutter.OverridenMethod;
PsiElement range = aClass.getNameIdentifier();
if (range == null) range = aClass;
if (range == null) {
range = aClass;
}
MarkerType type = MarkerType.SUBCLASSED_CLASS;
LineMarkerInfo info = new LineMarkerInfo<PsiElement>(range, range.getTextRange(),
icon, Pass.UPDATE_OVERRIDEN_MARKERS, type.getTooltip(),
@@ -188,7 +239,7 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
}
}
private static void collectOverridingAccessors(final Set<PsiMethod> methods, Collection<LineMarkerInfo> result) {
private static void collectOverridingMethods(@NotNull final Collection<PsiMethod> methods, @NotNull Collection<LineMarkerInfo> result) {
final Set<PsiMethod> overridden = new HashSet<PsiMethod>();
Set<PsiClass> classes = new THashSet<PsiClass>();
for (PsiMethod method : methods) {
@@ -229,22 +280,9 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
ProgressManager.checkCanceled();
boolean overrides = !method.hasModifierProperty(PsiModifier.ABSTRACT);
final Icon icon = overrides ? AllIcons.Gutter.OverridenMethod : AllIcons.Gutter.ImplementedMethod;
PsiElement range;
if (method.isPhysical()) {
range = method.getNameIdentifier();
}
else {
final PsiElement navigationElement = method.getNavigationElement();
if (navigationElement instanceof PsiNameIdentifierOwner) {
range = ((PsiNameIdentifierOwner)navigationElement).getNameIdentifier();
}
else {
range = navigationElement;
}
}
if (range == null) range = method;
PsiElement range = getMethodRange(method);
final MarkerType type = MarkerType.OVERRIDDEN_METHOD;
final Icon icon = overrides ? AllIcons.Gutter.OverridenMethod : AllIcons.Gutter.ImplementedMethod;
LineMarkerInfo<PsiElement> info = new LineMarkerInfo<PsiElement>(range, range.getTextRange(),
icon, Pass.UPDATE_OVERRIDEN_MARKERS, type.getTooltip(),
type.getNavigationHandler(),
@@ -255,8 +293,8 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
}
private static class ArrowUpLineMarkerInfo extends MergeableLineMarkerInfo<PsiElement> {
private ArrowUpLineMarkerInfo(@NotNull PsiElement element, Icon icon, @NotNull MarkerType markerType) {
super(element, element.getTextRange(), icon, Pass.UPDATE_ALL, markerType.getTooltip(),
private ArrowUpLineMarkerInfo(@NotNull PsiElement element, @NotNull Icon icon, @NotNull MarkerType markerType, int passId) {
super(element, element.getTextRange(), icon, passId, markerType.getTooltip(),
markerType.getNavigationHandler(), GutterIconRenderer.Alignment.LEFT);
}
@@ -274,6 +312,7 @@ public class JavaLineMarkerProvider implements LineMarkerProvider {
return myIcon;
}
@NotNull
@Override
public Function<? super PsiElement, String> getCommonTooltip(@NotNull List<MergeableLineMarkerInfo> infos) {
return new Function<PsiElement, String>() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -34,6 +34,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
import com.intellij.psi.search.SearchScope;
@@ -45,6 +46,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -105,9 +107,9 @@ public class MarkerType {
});
@Nullable
public static String calculateOverridingMethodTooltip(PsiMethod method, boolean acceptSelf) {
private static String calculateOverridingMethodTooltip(@NotNull PsiMethod method, boolean acceptSelf) {
PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf);
if (superMethods == null) return null;
if (superMethods.length == 0) return null;
PsiMethod superMethod = superMethods[0];
boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
@@ -121,10 +123,11 @@ public class MarkerType {
else{
key = sameSignature ? "method.overrides" : "method.overrides.in";
}
return composeText(superMethods, "", DaemonBundle.message(key), "GotoSuperMethod");
return composeText(superMethods, "", DaemonBundle.message(key), IdeActions.ACTION_GOTO_SUPER);
}
private static String composeText(PsiElement[] methods, String start, String pattern, String actionId) {
@NotNull
private static String composeText(@NotNull PsiElement[] methods, @NotNull String start, @NotNull String pattern, @NotNull String actionId) {
Shortcut[] shortcuts = ActionManager.getInstance().getAction(actionId).getShortcutSet().getShortcuts();
Shortcut shortcut = ArrayUtil.getFirstElement(shortcuts);
String postfix = "<br><div style='margin-top: 5px'><font size='2'>Click";
@@ -133,9 +136,9 @@ public class MarkerType {
return GutterIconTooltipHelper.composeText(Arrays.asList(methods), start, pattern, postfix);
}
public static void navigateToOverridingMethod(MouseEvent e, PsiMethod method, boolean acceptSelf) {
private static void navigateToOverridingMethod(MouseEvent e, @NotNull PsiMethod method, boolean acceptSelf) {
PsiMethod[] superMethods = composeSuperMethods(method, acceptSelf);
if (superMethods == null) return;
if (superMethods.length == 0) return;
boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(superMethods);
PsiElementListNavigator.openTargets(e, superMethods,
DaemonBundle.message("navigation.title.super.method", method.getName()),
@@ -143,17 +146,23 @@ public class MarkerType {
new MethodCellRenderer(showMethodNames));
}
@Nullable
private static PsiMethod[] composeSuperMethods(PsiMethod method, boolean acceptSelf) {
PsiMethod[] superMethods = method.findSuperMethods(false);
@NotNull
private static PsiMethod[] composeSuperMethods(@NotNull PsiMethod method, boolean acceptSelf) {
PsiElement[] superElements = FindSuperElementsHelper.findSuperElements(method);
PsiMethod[] superMethods = ContainerUtil.map(superElements, new Function<PsiElement, PsiMethod>() {
@Override
public PsiMethod fun(PsiElement element) {
return (PsiMethod)element;
}
}, PsiMethod.EMPTY_ARRAY);
if (acceptSelf) {
superMethods = ArrayUtil.prepend(method, superMethods);
}
if (superMethods.length == 0) return null;
return superMethods;
}
private static PsiElement getParentMethod(PsiElement element) {
private static PsiElement getParentMethod(@NotNull PsiElement element) {
final PsiElement parent = element.getParent();
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(parent);
return interfaceMethod != null ? interfaceMethod : parent;
@@ -179,7 +188,7 @@ public class MarkerType {
}
});
public static String getOverriddenMethodTooltip(final PsiMethod method) {
private static String getOverriddenMethodTooltip(@NotNull PsiMethod method) {
PsiElementProcessor.CollectElementsWithLimit<PsiMethod> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(5);
OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter<PsiMethod>(processor));
@@ -206,7 +215,7 @@ public class MarkerType {
return composeText(overridings, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION);
}
public static void navigateToOverriddenMethod(MouseEvent e, final PsiMethod method) {
private static void navigateToOverriddenMethod(MouseEvent e, @NotNull final PsiMethod method) {
if (DumbService.isDumb(method.getProject())) {
DumbService.getInstance(method.getProject()).showDumbModeNotification(
"Navigation to overriding classes is not possible during index update");
@@ -267,7 +276,7 @@ public class MarkerType {
}
});
public static String getSubclassedClassTooltip(PsiClass aClass) {
private static String getSubclassedClassTooltip(@NotNull PsiClass aClass) {
PsiElementProcessor.CollectElementsWithLimit<PsiClass> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5, new THashSet<PsiClass>());
ClassInheritorsSearch.search(aClass, true).forEach(new PsiElementProcessorAdapter<PsiClass>(processor));
@@ -298,7 +307,7 @@ public class MarkerType {
return composeText(subclasses, start, pattern, IdeActions.ACTION_GOTO_IMPLEMENTATION);
}
public static void navigateToSubclassedClass(MouseEvent e, final PsiClass aClass) {
private static void navigateToSubclassedClass(MouseEvent e, @NotNull final PsiClass aClass) {
if (DumbService.isDumb(aClass.getProject())) {
DumbService.getInstance(aClass.getProject()).showDumbModeNotification("Navigation to overriding methods is not possible during index update");
return;
@@ -331,7 +340,7 @@ public class MarkerType {
private final PsiClass myClass;
private final PsiClassOrFunctionalExpressionListCellRenderer myRenderer;
public SubclassUpdater(PsiClass aClass, PsiClassOrFunctionalExpressionListCellRenderer renderer) {
private SubclassUpdater(@NotNull PsiClass aClass, @NotNull PsiClassOrFunctionalExpressionListCellRenderer renderer) {
super(aClass.getProject(), SEARCHING_FOR_OVERRIDDEN_METHODS);
myClass = aClass;
myRenderer = renderer;
@@ -374,14 +383,13 @@ public class MarkerType {
}
});
}
}
private static class OverridingMethodsUpdater extends ListBackgroundUpdaterTask {
private final PsiMethod myMethod;
private final PsiElementListCellRenderer myRenderer;
public OverridingMethodsUpdater(PsiMethod method, PsiElementListCellRenderer renderer) {
private OverridingMethodsUpdater(@NotNull PsiMethod method, @NotNull PsiElementListCellRenderer renderer) {
super(method.getProject(), SEARCHING_FOR_OVERRIDING_METHODS);
myMethod = method;
myRenderer = renderer;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -29,15 +29,11 @@ import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
public class ShowSiblingsAction extends ShowImplementationsAction {
public ShowSiblingsAction() {
super();
}
@Override
public void performForContext(DataContext dataContext, final boolean invokedByShortcut) {
public void performForContext(@NotNull DataContext dataContext, final boolean invokedByShortcut) {
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
final PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext);
@@ -61,7 +57,7 @@ public class ShowSiblingsAction extends ShowImplementationsAction {
}
final NavigatablePsiElement[] superElements = (NavigatablePsiElement[])findSuperElements(element);
if (superElements == null || superElements.length == 0) return;
if (superElements.length == 0) return;
final boolean isMethod = superElements[0] instanceof PsiMethod;
final JBPopup popup = PsiElementListNavigator.navigateOrCreatePopup(superElements, "Choose super " + (isMethod ? "method" : "class or interface"), "Super " + (isMethod ? "methods" : "classes/interfaces"),
@@ -81,11 +77,11 @@ public class ShowSiblingsAction extends ShowImplementationsAction {
}
private void showSiblings(boolean invokedByShortcut,
Project project,
@NotNull Project project,
Editor editor,
PsiFile file,
boolean invokedFromEditor,
PsiElement element) {
@NotNull PsiElement element) {
final PsiElement[] impls = getSelfAndImplementations(editor, element, createImplementationsSearcher(), false);
final String text = SymbolPresentationUtil.getSymbolPresentableText(element);
showImplementations(impls, project, text, editor, file, element, invokedFromEditor, invokedByShortcut);
@@ -96,11 +92,11 @@ public class ShowSiblingsAction extends ShowImplementationsAction {
return false;
}
@Nullable
@NotNull
private static PsiElement[] findSuperElements(final PsiElement element) {
PsiNameIdentifierOwner parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class);
if (parent == null) {
return null;
return PsiElement.EMPTY_ARRAY;
}
return FindSuperElementsHelper.findSuperElements(parent);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -32,7 +32,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaGotoSuperHandler implements CodeInsightActionHandler {
@Override
@@ -41,7 +40,7 @@ public class JavaGotoSuperHandler implements CodeInsightActionHandler {
int offset = editor.getCaretModel().getOffset();
PsiElement[] superElements = findSuperElements(file, offset);
if (superElements == null || superElements.length == 0) return;
if (superElements.length == 0) return;
if (superElements.length == 1) {
PsiElement superElement = superElements[0].getNavigationElement();
final PsiFile containingFile = superElement.getContainingFile();
@@ -50,24 +49,25 @@ public class JavaGotoSuperHandler implements CodeInsightActionHandler {
if (virtualFile == null) return;
OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile, superElement.getTextOffset());
FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
} else {
if (superElements[0] instanceof PsiMethod) {
boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature((PsiMethod[])superElements);
PsiElementListNavigator.openTargets(editor, (PsiMethod[])superElements,
CodeInsightBundle.message("goto.super.method.chooser.title"),
CodeInsightBundle.message("goto.super.method.findUsages.title", ((PsiMethod)superElements[0]).getName()),
new MethodCellRenderer(showMethodNames));
}
else {
NavigationUtil.getPsiElementPopup(superElements, CodeInsightBundle.message("goto.super.class.chooser.title")).showInBestPositionFor(editor);
}
}
else if (superElements[0] instanceof PsiMethod) {
boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature((PsiMethod[])superElements);
PsiElementListNavigator.openTargets(editor, (PsiMethod[])superElements,
CodeInsightBundle.message("goto.super.method.chooser.title"),
CodeInsightBundle
.message("goto.super.method.findUsages.title", ((PsiMethod)superElements[0]).getName()),
new MethodCellRenderer(showMethodNames));
}
else {
NavigationUtil.getPsiElementPopup(superElements, CodeInsightBundle.message("goto.super.class.chooser.title"))
.showInBestPositionFor(editor);
}
}
@Nullable
private PsiElement[] findSuperElements(PsiFile file, int offset) {
@NotNull
private PsiElement[] findSuperElements(@NotNull PsiFile file, int offset) {
PsiElement element = getElement(file, offset);
if (element == null) return null;
if (element == null) return PsiElement.EMPTY_ARRAY;
final PsiElement psiElement = PsiTreeUtil.getParentOfType(element, PsiFunctionalExpression.class, PsiMember.class);
if (psiElement instanceof PsiFunctionalExpression) {
@@ -79,13 +79,13 @@ public class JavaGotoSuperHandler implements CodeInsightActionHandler {
final PsiNameIdentifierOwner parent = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethod.class, PsiClass.class);
if (parent == null) {
return null;
return PsiElement.EMPTY_ARRAY;
}
return FindSuperElementsHelper.findSuperElements(parent);
}
protected PsiElement getElement(PsiFile file, int offset) {
protected PsiElement getElement(@NotNull PsiFile file, int offset) {
return file.findElementAt(offset);
}
@@ -50,7 +50,7 @@ public class FormatPostfixTemplate extends StringBasedPostfixTemplate {
}
@Override
protected boolean shouldRemoveParent() {
return false;
protected PsiElement getElementToRemove(PsiElement expr) {
return expr;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -26,6 +26,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
@@ -34,6 +35,7 @@ import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -41,20 +43,24 @@ public class SuperMethodWarningUtil {
private SuperMethodWarningUtil() {}
@NotNull
public static PsiMethod[] checkSuperMethods(final PsiMethod method, String actionString) {
return checkSuperMethods(method, actionString, null);
public static PsiMethod[] checkSuperMethods(@NotNull PsiMethod method, @NotNull String actionString) {
return checkSuperMethods(method, actionString, Collections.<PsiElement>emptyList());
}
@NotNull
public static PsiMethod[] checkSuperMethods(final PsiMethod method, String actionString, Collection<PsiElement> ignore) {
public static PsiMethod[] checkSuperMethods(@NotNull PsiMethod method, @NotNull String actionString, @NotNull Collection<PsiElement> ignore) {
PsiClass aClass = method.getContainingClass();
if (aClass == null) return new PsiMethod[]{method};
final Collection<PsiMethod> superMethods = DeepestSuperMethodsSearch.search(method).findAll();
if (ignore != null) {
superMethods.removeAll(ignore);
}
superMethods.removeAll(ignore);
if (superMethods.isEmpty()) {
PsiMethod siblingSuperMethod = FindSuperElementsHelper.getSiblingInheritedViaSubClass(method);
if (siblingSuperMethod != null) {
superMethods.add(siblingSuperMethod);
}
}
if (superMethods.isEmpty()) return new PsiMethod[]{method};
@@ -85,7 +91,7 @@ public class SuperMethodWarningUtil {
}
public static PsiMethod checkSuperMethod(final PsiMethod method, String actionString) {
public static PsiMethod checkSuperMethod(@NotNull PsiMethod method, @NotNull String actionString) {
PsiClass aClass = method.getContainingClass();
if (aClass == null) return method;
@@ -110,10 +116,10 @@ public class SuperMethodWarningUtil {
return null;
}
public static void checkSuperMethod(final PsiMethod method,
final String actionString,
final PsiElementProcessor<PsiMethod> processor,
final Editor editor) {
public static void checkSuperMethod(@NotNull PsiMethod method,
@NotNull String actionString,
@NotNull final PsiElementProcessor<PsiMethod> processor,
@NotNull Editor editor) {
PsiClass aClass = method.getContainingClass();
if (aClass == null) {
processor.execute(method);
@@ -137,7 +143,7 @@ public class SuperMethodWarningUtil {
return;
}
final PsiMethod[] methods = new PsiMethod[]{superMethod, method};
final PsiMethod[] methods = {superMethod, method};
final String renameBase = actionString + " base method";
final String renameCurrent = actionString + " only current method";
final JBList list = new JBList(renameBase, renameCurrent);
@@ -148,6 +154,7 @@ public class SuperMethodWarningUtil {
.setResizable(false)
.setRequestFocus(true)
.setItemChoosenCallback(new Runnable() {
@Override
public void run() {
final Object value = list.getSelectedValue();
if (value instanceof String) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -20,13 +20,14 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.spi.psi.SPIClassProviderReferenceElement;
import org.jetbrains.annotations.NotNull;
/**
* User: anna
*/
public class SPIGotoSuperHandler extends JavaGotoSuperHandler {
@Override
protected PsiElement getElement(PsiFile file, int offset) {
protected PsiElement getElement(@NotNull PsiFile file, int offset) {
final SPIClassProviderReferenceElement
providerElement = PsiTreeUtil.getParentOfType(super.getElement(file, offset), SPIClassProviderReferenceElement.class);
if (providerElement != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -61,7 +61,7 @@ public class JavaAllOverridingMethodsSearcher implements QueryExecutor<Pair<PsiM
PsiSubstitutor substitutor = null;
for (String name : methods.keySet()) {
if (inheritor.findMethodsByName(name, false).length == 0) continue;
if (inheritor.findMethodsByName(name, true).length == 0) continue;
for (PsiMethod method : methods.get(name)) {
if (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) &&
@@ -101,12 +101,14 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
return true;
}
Collection<PsiReferenceList> candidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiReferenceList>>() {
@Override
public Collection<PsiReferenceList> compute() {
return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, project, scope);
}
});
Collection<PsiReferenceList> candidates = MethodUsagesSearcher.resolveInReadAction(project,
new Computable<Collection<PsiReferenceList>>() {
@Override
public Collection<PsiReferenceList> compute() {
return JavaSuperClassNameOccurenceIndex
.getInstance().get(searchKey, project, scope);
}
});
Map<String, List<PsiClass>> classes = new HashMap<String, List<PsiClass>>();
@@ -118,7 +120,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
return referenceList.getParent();
}
});
if (!checkInheritance(p, aClass, candidate)) continue;
if (!checkInheritance(p, aClass, candidate, project)) continue;
String fqn = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
@@ -142,16 +144,19 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
}
if (p.includeAnonymous()) {
Collection<PsiAnonymousClass> anonymousCandidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiAnonymousClass>>() {
@Override
public Collection<PsiAnonymousClass> compute() {
return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, project, scope);
}
});
Collection<PsiAnonymousClass> anonymousCandidates = MethodUsagesSearcher.resolveInReadAction(project,
new Computable<Collection<PsiAnonymousClass>>() {
@Override
public Collection<PsiAnonymousClass> compute() {
return JavaAnonymousClassBaseRefOccurenceIndex
.getInstance()
.get(searchKey, project, scope);
}
});
for (PsiAnonymousClass candidate : anonymousCandidates) {
ProgressIndicatorProvider.checkCanceled();
if (!checkInheritance(p, aClass, candidate)) continue;
if (!checkInheritance(p, aClass, candidate, project)) continue;
if (!consumer.process(candidate)) return false;
}
@@ -190,8 +195,8 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
return true;
}
private static boolean checkInheritance(final DirectClassInheritorsSearch.SearchParameters p, final PsiClass aClass, final PsiClass candidate) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
private static boolean checkInheritance(final DirectClassInheritorsSearch.SearchParameters p, final PsiClass aClass, final PsiClass candidate, Project project) {
return MethodUsagesSearcher.resolveInReadAction(project, new Computable<Boolean>() {
@Override
public Boolean compute() {
return !p.isCheckInheritance() || candidate.isInheritor(aClass, false);
@@ -1,56 +0,0 @@
/*
* Copyright 2000-2012 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.impl;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiSuperMethodUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class FindSuperElementsHelper {
@Nullable
public static PsiElement[] findSuperElements(@NotNull PsiElement element) {
if (element instanceof PsiClass) {
PsiClass aClass = (PsiClass) element;
List<PsiClass> allSupers = new ArrayList<PsiClass>(Arrays.asList(aClass.getSupers()));
for (Iterator<PsiClass> iterator = allSupers.iterator(); iterator.hasNext();) {
PsiClass superClass = iterator.next();
if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) iterator.remove();
}
return allSupers.toArray(new PsiClass[allSupers.size()]);
} else if (element instanceof PsiMethod) {
PsiMethod method = (PsiMethod) element;
if (method.isConstructor()) {
PsiMethod constructorInSuper = PsiSuperMethodUtil.findConstructorInSuper(method);
if (constructorInSuper != null) {
return new PsiMethod[]{constructorInSuper};
}
} else {
return method.findSuperMethods(false);
}
}
return null;
}
}
@@ -0,0 +1,11 @@
package z;
interface I {
void <caret>run();
}
abstract class A {
public void run() {}
}
class Foo extends A implements I {
}
@@ -0,0 +1,11 @@
package z;
interface I {
void run();
}
abstract class A {
public void <caret>run() {}
}
class Foo extends A implements I {
}
@@ -13,20 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.navigation;
package com.intellij.codeInsight.daemon.impl;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
import com.intellij.ide.DataManager;
import com.intellij.lang.CodeInsightActions;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -38,7 +39,7 @@ public class JavaGotoSuperTest extends LightDaemonAnalyzerTestCase {
return JavaTestUtil.getJavaTestDataPath();
}
protected String getBasePath() {
private static String getBasePath() {
return "/codeInsight/gotosuper/";
}
@@ -46,6 +47,13 @@ public class JavaGotoSuperTest extends LightDaemonAnalyzerTestCase {
doTest();
}
private void doTest() {
configureByFile(getBasePath() + getTestName(false) + ".java");
final CodeInsightActionHandler handler = CodeInsightActions.GOTO_SUPER.forLanguage(JavaLanguage.INSTANCE);
handler.invoke(getProject(), getEditor(), getFile());
checkResultByFile(getBasePath() + getTestName(false) + ".after.java");
}
public void testLambdaMarker() throws Exception {
configureByFile(getBasePath() + getTestName(false) + ".java");
int offset = myEditor.getCaretModel().getOffset();
@@ -67,10 +75,52 @@ public class JavaGotoSuperTest extends LightDaemonAnalyzerTestCase {
fail("Gutter expected");
}
private void doTest() throws Throwable {
configureByFile(getBasePath() + getTestName(false) + ".java");
final CodeInsightActionHandler handler = CodeInsightActions.GOTO_SUPER.forLanguage(JavaLanguage.INSTANCE);
handler.invoke(getProject(), getEditor(), getFile());
checkResultByFile(getBasePath() + getTestName(false) + ".after.java");
public void testSiblingInheritance() throws Throwable {
doTest();
}
public void testSiblingInheritanceLineMarkers() throws Throwable {
configureByFile(getBasePath() + "SiblingInheritance.java");
PsiJavaFile file = (PsiJavaFile)getFile();
PsiClass i = JavaPsiFacade.getInstance(getProject()).findClass("z.I", GlobalSearchScope.fileScope(file));
PsiClass a = JavaPsiFacade.getInstance(getProject()).findClass("z.A", GlobalSearchScope.fileScope(file));
PsiMethod iRun = i.getMethods()[0];
assertEquals("run", iRun.getName());
PsiMethod aRun = a.getMethods()[0];
assertEquals("run", aRun.getName());
doHighlighting();
Document document = getEditor().getDocument();
List<LineMarkerInfo> markers = DaemonCodeAnalyzerImpl.getLineMarkers(document, getProject());
assertTrue(markers.size() >= 2);
LineMarkerInfo iMarker = findMarkerWithElement(markers, iRun.getNameIdentifier());
assertSame(MarkerType.OVERRIDDEN_METHOD.getNavigationHandler(), iMarker.getNavigationHandler());
LineMarkerInfo aMarker = findMarkerWithElement(markers, aRun.getNameIdentifier());
assertSame(MarkerType.OVERRIDING_METHOD.getNavigationHandler(), aMarker.getNavigationHandler());
}
private static LineMarkerInfo findMarkerWithElement(List<LineMarkerInfo> markers, PsiElement psiMethod) {
LineMarkerInfo marker = ContainerUtil.find(markers, info -> {
return info.getElement().equals(psiMethod);
});
assertNotNull(markers.toString(), marker);
return marker;
}
public void testSiblingInheritanceGoDown() throws Throwable {
configureByFile(getBasePath() + "SiblingInheritance.after.java");
AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_GOTO_IMPLEMENTATION);
AnActionEvent event = new AnActionEvent(
null,
DataManager.getInstance().getDataContextFromFocus().getResultSync(),
"",
action.getTemplatePresentation(),
ActionManager.getInstance(),
0);
action.update(event);
assertTrue(event.getPresentation().isEnabledAndVisible());
action.actionPerformed(event);
checkResultByFile(getBasePath() + "SiblingInheritance.java");
}
}
@@ -131,7 +131,7 @@ public class RunConfigurableTest extends LightIdeaTestCase {
private void doExpand() {
List<DefaultMutableTreeNode> toExpand = new ArrayList<DefaultMutableTreeNode>();
RunConfigurable.collectNodesRecursively(myRoot, toExpand, FOLDER);
assertEquals(toExpand.size(), 5);
assertEquals(5, toExpand.size());
List<DefaultMutableTreeNode> toExpand2 = new ArrayList<DefaultMutableTreeNode>();
RunConfigurable.collectNodesRecursively(myRoot, toExpand2, CONFIGURATION_TYPE);
toExpand.addAll(toExpand2);
@@ -34,19 +34,12 @@ public class DeclarationParserTest extends JavaParsingTestCase {
public void testPines() { doParserTest("{ class A<T extends List<String>> extends List<List<Integer>> { } }"); }
public void testIncompleteAnnotation() { doParserTest("{ public class Foo { public void testSomething(); @Null } }"); }
public void testClassInit() { doParserTest("{ { /*comment*/ } }"); }
public void testAnnoDeclaration() { doParserTest("{ public @interface Annotation {} }"); }
public void testEnumSmartTypeCompletion() { doParserTest("{ @Preliminary(A.B\n#) public class TimeTravel {}\n" +
" @Preliminary(a=A.B\n#) public class TimeTravel {}\n" +
" @Preliminary(a=A.B\n#, b=c) public class TimeTravel {} }"); }
public void testTypeAnno() {
doParserTest("{ class C<@D T extends @F Object> extends @F Object {\n" +
" @F int @F[] method() throws @F Exception {\n" +
" a = this instanceof @F C;\n" +
" C<@F @G C> c = new @Q C<@F C>();\n" +
" c = (@F Object)c;\n" +
" Class c = @TA String.class;\n" +
" @F C.field++;\n" +
" }\n} }");
public void testEnumSmartTypeCompletion() {
doParserTest(
"{ @Preliminary(A.B\n#) public class TimeTravel {}\n" +
" @Preliminary(a=A.B\n#) public class TimeTravel {}\n" +
" @Preliminary(a=A.B\n#, b=c) public class TimeTravel {} }");
}
public void testEnumBody0() { doParserTest("{ ; }", false, true); }
@@ -59,6 +52,7 @@ public class DeclarationParserTest extends JavaParsingTestCase {
public void testEnumWithInitializedConstants() { doParserTest("{ A(10) { },\n B { void method() {} } }", false, true); }
public void testEnumWithoutConstants() { doParserTest("{ private A }", false, true); }
public void testAnnoDeclaration() { doParserTest("{ public @interface Annotation {} }"); }
public void testAnnoSimple() { doParserTest("{ int foo (); }", true, false); }
public void testAnnoDefault() { doParserTest("{ Class foo() default String.class; }", true, false); }
public void testAnnoNested() { doParserTest("{ @interface Inner { String bar () default \"<unspecified>\"; } }", true, false); }
@@ -66,6 +60,18 @@ public class DeclarationParserTest extends JavaParsingTestCase {
public void testAnnoOtherMembers() { doParserTest("{ int field;\n void m() {}\n class C {}\n interface I {} }", true, false); }
public void testAnnoLoop() { doParserTest("{ @@@ int i; }"); }
public void testTypeAnno() {
doParserTest(
"{ class C<@D T extends @F Object> extends @F Object {\n" +
" @F int @F[] method() throws @F Exception {\n" +
" a = this instanceof @F C;\n" +
" C<@F @G C> c = new @Q C<@F C>();\n" +
" c = (@F Object)c;\n" +
" Class c = @TA String.class;\n" +
" @F C.field++;\n" +
" }\n} }");
}
public void testFieldSimple() { doParserTest("{ int field = 0; }"); }
public void testFieldMulti() { doParserTest("{ int field1 = 0, field2; }"); }
public void testUnclosedBracket() { doParserTest("{ int field[ }"); }
@@ -94,9 +100,13 @@ public class DeclarationParserTest extends JavaParsingTestCase {
public void testConstructorBrackets() { doParserTest("{ A() [] { } }"); }
public void testVarArgBrackets() { doParserTest("{ void foo(int... x[]); }"); }
public void testGenericMethod() { doParserTest("{ public static <E> test();\n" +
" <E> void test1();\n" +
" <E1 extends Integer, E2 extends Runnable> String test2(); }"); }
public void testGenericMethod() {
doParserTest(
"{ public static <E> test();\n" +
" <E> void test1();\n" +
" <E1 extends Integer, E2 extends Runnable> String test2(); }");
}
public void testGenericMethodErrors() { doParserTest("{ <Error sss /> test <error>(); }"); }
public void testErrors() { doParserTest("{ public static <error descr=\"2\">protected int f1 = 0; }"); }
public void testCompletionHack0() { doParserTest("{ <X IntelliJIdeaRulezz>\n String s = \"\"; }"); }
@@ -140,6 +140,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
*
* @return the new marker instance.
*/
@NotNull
Marker precede();
/**
@@ -160,7 +161,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
*
* @param type the type of the node in the AST tree.
*/
void done(IElementType type);
void done(@NotNull IElementType type);
/**
* Like {@linkplain #done(IElementType)}, but collapses all tokens between start and end markers
@@ -168,7 +169,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
*
* @param type the type of the node in the AST tree.
*/
void collapse(IElementType type);
void collapse(@NotNull IElementType type);
/**
* Like {@linkplain #done(IElementType)}, but the marker is completed (end marker inserted)
@@ -178,7 +179,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
* @param type the type of the node in the AST tree.
* @param before marker to complete this one before.
*/
void doneBefore(IElementType type, Marker before);
void doneBefore(@NotNull IElementType type, @NotNull Marker before);
/**
* Like {@linkplain #doneBefore(IElementType, Marker)}, but in addition an error element with given text
@@ -188,7 +189,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
* @param before marker to complete this one before.
* @param errorMessage for error element.
*/
void doneBefore(IElementType type, Marker before, String errorMessage);
void doneBefore(@NotNull IElementType type, @NotNull Marker before, String errorMessage);
/**
* Completes this marker and labels it as error element with specified message. Before calling this method,
@@ -204,7 +205,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
* @param message for error element.
* @param before marker to complete this one before.
*/
void errorBefore(String message, Marker before);
void errorBefore(String message, @NotNull Marker before);
/**
* Allows to define custom edge token binders instead of default ones. If any of parameters is null
@@ -222,6 +223,7 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected {
*
* @return the new marker instance.
*/
@NotNull
Marker mark();
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -38,5 +38,5 @@ public interface PsiParser {
* @return the root of the resulting AST tree.
*/
@NotNull
ASTNode parse(IElementType root, PsiBuilder builder);
ASTNode parse(@NotNull IElementType root, @NotNull PsiBuilder builder);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -16,6 +16,7 @@
package com.intellij.lang;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -31,6 +32,7 @@ public interface WhitespacesAndCommentsBinder {
* Provides an ability for the processor to get a text of any of given tokens.
*/
interface TokenTextGetter {
@NotNull
CharSequence get(int i);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -35,6 +35,7 @@ public abstract class DelegateMarker implements PsiBuilder.Marker {
return myDelegate;
}
@NotNull
@Override
public PsiBuilder.Marker precede() {
return myDelegate.precede();
@@ -51,22 +52,22 @@ public abstract class DelegateMarker implements PsiBuilder.Marker {
}
@Override
public void done(IElementType type) {
public void done(@NotNull IElementType type) {
myDelegate.done(type);
}
@Override
public void collapse(IElementType type) {
public void collapse(@NotNull IElementType type) {
myDelegate.collapse(type);
}
@Override
public void doneBefore(IElementType type, PsiBuilder.Marker before) {
public void doneBefore(@NotNull IElementType type, @NotNull PsiBuilder.Marker before) {
myDelegate.doneBefore(type, before);
}
@Override
public void doneBefore(IElementType type, PsiBuilder.Marker before, String errorMessage) {
public void doneBefore(@NotNull IElementType type, @NotNull PsiBuilder.Marker before, String errorMessage) {
myDelegate.doneBefore(type, before, errorMessage);
}
@@ -76,7 +77,7 @@ public abstract class DelegateMarker implements PsiBuilder.Marker {
}
@Override
public void errorBefore(String message, PsiBuilder.Marker before) {
public void errorBefore(String message, @NotNull PsiBuilder.Marker before) {
myDelegate.errorBefore(message, before);
}
@@ -101,6 +101,7 @@ public class PsiBuilderAdapter implements PsiBuilder {
return myDelegate.getCurrentOffset();
}
@NotNull
@Override
public Marker mark() {
return myDelegate.mark();
@@ -97,28 +97,37 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private IElementType myCachedTokenType;
private final LimitedPool<StartMarker> START_MARKERS = new LimitedPool<StartMarker>(2000, new LimitedPool.ObjectFactory<StartMarker>() {
@NotNull
@Override
public StartMarker create() {
return new StartMarker();
}
@Override
public void cleanup(final StartMarker startMarker) {
public void cleanup(@NotNull final StartMarker startMarker) {
startMarker.clean();
}
});
private final LimitedPool<DoneMarker> DONE_MARKERS = new LimitedPool<DoneMarker>(2000, new LimitedPool.ObjectFactory<DoneMarker>() {
@NotNull
@Override
public DoneMarker create() {
return new DoneMarker();
}
@Override
public void cleanup(final DoneMarker doneMarker) {
public void cleanup(@NotNull final DoneMarker doneMarker) {
doneMarker.clean();
}
});
private static final ArrayFactory<IElementType> myElementTypeArrayFactory = new ArrayFactory<IElementType>() {
@NotNull
@Override
public IElementType[] create(int count) {
return count == 0 ? IElementType.EMPTY_ARRAY : new IElementType[count];
}
};
public static void registerWhitespaceToken(@NotNull IElementType type) {
ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type));
@@ -190,11 +199,10 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
@NotNull final LighterLazyParseableNode chameleon,
@NotNull final CharSequence text) {
this(project, chameleon.getContainingFile(), parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), lexer,
chameleon.getCharTable(), text, null, ((LazyParseableToken)chameleon).myParent, ((LazyParseableToken)chameleon)
);
chameleon.getCharTable(), text, null, ((LazyParseableToken)chameleon).myParent, (LazyParseableToken)chameleon);
}
private void cacheLexemes(LazyParseableToken parentToken) {
private void cacheLexemes(@Nullable LazyParseableToken parentToken) {
int[] lexStarts = null;
IElementType[] lexTypes = null;
int lexemeCount = -1;
@@ -418,6 +426,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
}
@NotNull
@Override
public Marker precede() {
return myBuilder.precede(this);
@@ -434,25 +443,25 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
@Override
public void done(IElementType type) {
public void done(@NotNull IElementType type) {
myType = type;
myBuilder.done(this);
}
@Override
public void collapse(IElementType type) {
public void collapse(@NotNull IElementType type) {
myType = type;
myBuilder.collapse(this);
}
@Override
public void doneBefore(IElementType type, Marker before) {
public void doneBefore(@NotNull IElementType type, @NotNull Marker before) {
myType = type;
myBuilder.doneBefore(this, before);
}
@Override
public void doneBefore(final IElementType type, final Marker before, final String errorMessage) {
public void doneBefore(@NotNull final IElementType type, @NotNull final Marker before, final String errorMessage) {
final StartMarker marker = (StartMarker)before;
myBuilder.myProduction.add(myBuilder.myProduction.lastIndexOf(marker),
new ErrorItem(myBuilder, errorMessage, marker.myLexemeIndex));
@@ -466,7 +475,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
@Override
public void errorBefore(final String message, final Marker before) {
public void errorBefore(final String message, @NotNull final Marker before) {
myType = TokenType.ERROR_ELEMENT;
myBuilder.errorBefore(this, message, before);
}
@@ -509,6 +518,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
}
@NotNull
private Marker precede(final StartMarker marker) {
int idx = myProduction.lastIndexOf(marker);
if (idx < 0) {
@@ -680,7 +690,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private static class DoneWithErrorMarker extends DoneMarker {
private String myMessage;
public DoneWithErrorMarker(final StartMarker marker, final int currentLexeme, final String message) {
private DoneWithErrorMarker(@NotNull StartMarker marker, final int currentLexeme, final String message) {
super(marker, currentLexeme);
myMessage = message;
}
@@ -871,14 +881,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
private void resizeLexemes(final int newSize) {
int count = Math.min(newSize, myLexTypes.length);
int[] newStarts = new int[newSize + 1];
System.arraycopy(myLexStarts, 0, newStarts, 0, count);
myLexStarts = newStarts;
IElementType[] newTypes = new IElementType[newSize];
System.arraycopy(myLexTypes, 0, newTypes, 0, count);
myLexTypes = newTypes;
myLexStarts = ArrayUtil.realloc(myLexStarts, newSize+1);
myLexTypes = ArrayUtil.realloc(myLexTypes, newSize, myElementTypeArrayFactory);
clearCachedTokenType();
}
@@ -886,6 +890,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return myWhitespaces.contains(token) || myComments.contains(token);
}
@NotNull
@Override
public Marker mark() {
if (!myProduction.isEmpty()) {
@@ -897,6 +902,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return marker;
}
@NotNull
private StartMarker createMarker(final int lexemeIndex) {
StartMarker marker = START_MARKERS.alloc();
marker.myLexemeIndex = lexemeIndex;
@@ -917,8 +923,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return myCurrentLexeme >= myLexemeCount;
}
@SuppressWarnings("SuspiciousMethodCalls")
private void rollbackTo(Marker marker) {
private void rollbackTo(@NotNull Marker marker) {
myCurrentLexeme = ((StartMarker)marker).myLexemeIndex;
myTokenTypeChecked = true;
int idx = myProduction.lastIndexOf(marker);
@@ -934,7 +939,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
*
* @return true if there are error elements created and not dropped after marker was created
*/
public boolean hasErrorsAfter(Marker marker) {
public boolean hasErrorsAfter(@NotNull Marker marker) {
assert marker instanceof StartMarker;
int idx = myProduction.lastIndexOf(marker);
if (idx < 0) {
@@ -949,8 +954,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return false;
}
@SuppressWarnings("SuspiciousMethodCalls")
public void drop(Marker marker) {
public void drop(@NotNull Marker marker) {
final DoneMarker doneMarker = ((StartMarker)marker).myDoneMarker;
if (doneMarker != null) {
myProduction.remove(myProduction.lastIndexOf(doneMarker));
@@ -963,7 +967,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
START_MARKERS.recycle((StartMarker)marker);
}
public void error(Marker marker, String message) {
public void error(@NotNull Marker marker, String message) {
doValidityChecks(marker, null);
DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, myCurrentLexeme, message);
@@ -974,10 +978,10 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
myProduction.add(doneMarker);
}
@SuppressWarnings("SuspiciousMethodCalls")
public void errorBefore(Marker marker, String message, Marker before) {
private void errorBefore(@NotNull Marker marker, String message, @NotNull Marker before) {
doValidityChecks(marker, before);
@SuppressWarnings("SuspiciousMethodCalls")
int beforeIndex = myProduction.lastIndexOf(before);
DoneWithErrorMarker doneMarker = new DoneWithErrorMarker((StartMarker)marker, ((StartMarker)before).myLexemeIndex, message);
@@ -988,7 +992,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
myProduction.add(beforeIndex, doneMarker);
}
public void done(final Marker marker) {
public void done(@NotNull Marker marker) {
doValidityChecks(marker, null);
DoneMarker doneMarker = DONE_MARKERS.alloc();
@@ -1002,10 +1006,10 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
myProduction.add(doneMarker);
}
@SuppressWarnings("SuspiciousMethodCalls")
public void doneBefore(Marker marker, Marker before) {
public void doneBefore(@NotNull Marker marker, @NotNull Marker before) {
doValidityChecks(marker, before);
@SuppressWarnings("SuspiciousMethodCalls")
int beforeIndex = myProduction.lastIndexOf(before);
DoneMarker doneMarker = DONE_MARKERS.alloc();
@@ -1027,13 +1031,13 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return true;
}
public void collapse(final Marker marker) {
public void collapse(@NotNull Marker marker) {
done(marker);
((StartMarker)marker).myDoneMarker.myCollapse = true;
}
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "SuspiciousMethodCalls", "ThrowableResultOfMethodCallIgnored"})
private void doValidityChecks(final Marker marker, @Nullable final Marker before) {
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
private void doValidityChecks(@NotNull Marker marker, @Nullable final Marker before) {
final DoneMarker doneMarker = ((StartMarker)marker).myDoneMarker;
if (doneMarker != null) {
LOG.error("Marker already done.");
@@ -1048,6 +1052,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
int endIdx = myProduction.size();
if (before != null) {
//noinspection SuspiciousMethodCalls
endIdx = myProduction.lastIndexOf(before);
if (endIdx < 0) {
LOG.error("'Before' marker has never been added.");
@@ -1330,6 +1335,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
@Override
@NotNull
public CharSequence get(int i) {
return myText.subSequence(myLexStarts[myStart + i], myLexStarts[myStart + i + 1]);
}
@@ -1349,7 +1355,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
}
private void bind(final StartMarker rootMarker, final CompositeElement rootNode) {
private void bind(@NotNull StartMarker rootMarker, @NotNull CompositeElement rootNode) {
StartMarker curMarker = rootMarker;
CompositeElement curNode = rootNode;
@@ -1407,7 +1413,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return curToken;
}
private int collapseLeaves(final CompositeElement ast, final StartMarker startMarker) {
private int collapseLeaves(@NotNull CompositeElement ast, @NotNull StartMarker startMarker) {
final int start = myLexStarts[startMarker.myLexemeIndex];
final int end = myLexStarts[startMarker.myDoneMarker.myLexemeIndex];
final TreeElement leaf = createLeaf(startMarker.myType, start, end);
@@ -1431,7 +1437,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
@Nullable
public static String getErrorMessage(final LighterASTNode node) {
public static String getErrorMessage(@NotNull LighterASTNode node) {
if (node instanceof ErrorItem) return ((ErrorItem)node).myMessage;
if (node instanceof StartMarker) {
final StartMarker marker = (StartMarker)node;
@@ -1448,7 +1454,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
private final MyTreeStructure myTreeStructure;
private MyComparator(TripleFunction<ASTNode, LighterASTNode, FlyweightCapableTreeStructure<LighterASTNode>, ThreeState> custom,
MyTreeStructure treeStructure) {
@NotNull MyTreeStructure treeStructure) {
this.custom = custom;
myTreeStructure = treeStructure;
}
@@ -1570,10 +1576,11 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
if (parentTree == null) {
myPool = new LimitedPool<Token>(1000, new LimitedPool.ObjectFactory<Token>() {
@Override
public void cleanup(final Token token) {
public void cleanup(@NotNull final Token token) {
token.clean();
}
@NotNull
@Override
public Token create() {
return new TokenNode();
@@ -1581,10 +1588,11 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
});
myLazyPool = new LimitedPool<LazyParseableToken>(200, new LimitedPool.ObjectFactory<LazyParseableToken>() {
@Override
public void cleanup(final LazyParseableToken token) {
public void cleanup(@NotNull final LazyParseableToken token) {
token.clean();
}
@NotNull
@Override
public LazyParseableToken create() {
return new LazyParseableToken();
@@ -1727,6 +1735,15 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
return myRoot.myBuilder.myText.subSequence(node.getStartOffset(), node.getEndOffset());
}
@Override
public int getStartOffset(@NotNull LighterASTNode node) {
return node.getStartOffset();
}
@Override
public int getEndOffset(@NotNull LighterASTNode node) {
return node.getEndOffset();
}
}
private static class ASTConverter implements Convertor<Node, ASTNode> {
@@ -178,11 +178,15 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
psiFile = PsiUtilCore.NULL_PSI_FILE;
}
boolean set = myPsiFile.compareAndSet(null, psiFile);
if (!set) {
if (!set && psiFile != PsiUtilCore.NULL_PSI_FILE) {
PsiFile alreadyCreated = myPsiFile.get();
if (alreadyCreated == psiFile) {
LOG.error(this + ".createFile() must create new file instance but got the same: " + psiFile);
}
if (psiFile instanceof PsiFileImpl) {
((PsiFileImpl)psiFile).markInvalidated();
}
psiFile = myPsiFile.get();
psiFile = alreadyCreated;
}
}
return psiFile == PsiUtilCore.NULL_PSI_FILE ? null : psiFile;
@@ -83,4 +83,14 @@ public class ASTStructure implements FlyweightCapableTreeStructure<ASTNode> {
public CharSequence toString(@NotNull ASTNode node) {
return node.getChars();
}
@Override
public int getStartOffset(@NotNull ASTNode node) {
return node.getStartOffset();
}
@Override
public int getEndOffset(@NotNull ASTNode node) {
return node.getStartOffset() + node.getTextLength();
}
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.project.DefaultProjectFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -57,8 +58,7 @@ public class DiffApplication extends ApplicationStarterBase {
if (file1 == null) throw new Exception("Can't find file " + path1);
if (file2 == null) throw new Exception("Can't find file " + path2);
file1.refresh(false, true);
file2.refresh(false, true);
VfsUtil.markDirtyAndRefresh(false, false, false, file1, file2);
DiffRequest request = DiffRequestFactory.getInstance().createFromFiles(null, file1, file2);
Project project = DefaultProjectFactory.getInstance().getDefaultProject();
@@ -26,10 +26,13 @@ import javax.swing.*;
/**
* Interface which should be implemented in order to draw icons in the gutter area and handle events
* for them. Gutter icons are drawn to the left of the folding area and can be used, for example,
* to mark implemented or overridden methods.
* to mark implemented or overridden methods.<p/>
*
* Daemon code analyzer checks newly arrived gutter icon renderer against the old one and if they are equal, does not redraw the icon.
* So it is highly advisable to override hashCode()/equals() methods to avoid icon flickering when old gutter renderer gets replaced with the new.
* So it is highly advisable to override hashCode()/equals() methods to avoid icon flickering when old gutter renderer gets replaced with the new.<p/>
*
* During indexing, click handlers are only invoked for renderers implementing {@link com.intellij.openapi.project.DumbAware}.
*
* @author max
* @see RangeHighlighter#setGutterIconRenderer(GutterIconRenderer)
*/
@@ -312,7 +312,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
}
// we failed to run read action in job launcher thread
// run read action in our thread instead to wait for a write action to complete and resume parallel processing
ApplicationManager.getApplication().runReadAction(EmptyRunnable.getInstance());
DumbService.getInstance(myManager.getProject()).runReadActionInSmartMode(EmptyRunnable.getInstance());
files = failedList;
}
return completed;
@@ -347,7 +347,10 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
ApplicationUtil.tryRunReadAction(new Computable<Void>() {
@Override
public Void compute() {
if (myManager.getProject().isDisposed()) throw new ProcessCanceledException();
final Project project = myManager.getProject();
if (project.isDisposed()) throw new ProcessCanceledException();
if (DumbService.isDumb(project)) throw new ApplicationUtil.CannotRunReadActionException();
List<PsiFile> psiRoots = file.getViewProvider().getAllFiles();
Set<PsiFile> processed = new THashSet<PsiFile>(psiRoots.size() * 2, (float)0.5);
for (final PsiFile psiRoot : psiRoots) {
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ShortcutSet;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.event.MouseEvent;
@@ -28,10 +29,10 @@ import java.awt.event.MouseEvent;
* @author Dmitry Avdeev
*/
public class NavigateAction<T extends PsiElement> extends AnAction {
private LineMarkerInfo<T> myInfo;
private final LineMarkerInfo<T> myInfo;
public NavigateAction(String text,
LineMarkerInfo<T> info,
public NavigateAction(@NotNull String text,
@NotNull LineMarkerInfo<T> info,
@Nullable String originalActionId) {
super(text);
myInfo = info;
@@ -41,7 +42,7 @@ public class NavigateAction<T extends PsiElement> extends AnAction {
}
}
public NavigateAction(LineMarkerInfo<T> info) {
public NavigateAction(@NotNull LineMarkerInfo<T> info) {
myInfo = info;
}
@@ -56,7 +57,8 @@ public class NavigateAction<T extends PsiElement> extends AnAction {
}
}
public static <T extends PsiElement> LineMarkerInfo<T> setNavigateAction(LineMarkerInfo<T> info, String text, @Nullable String originalActionId) {
@NotNull
public static <T extends PsiElement> LineMarkerInfo<T> setNavigateAction(@NotNull LineMarkerInfo<T> info, @NotNull String text, @Nullable String originalActionId) {
NavigateAction<T> action = new NavigateAction<T>(text, info, originalActionId);
info.setNavigateAction(action);
return info;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -37,6 +37,7 @@ import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.usages.UsageView;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -88,12 +89,12 @@ public class PsiElementListNavigator {
}
@Nullable
public static JBPopup navigateOrCreatePopup(final NavigatablePsiElement[] targets,
public static JBPopup navigateOrCreatePopup(@NotNull final NavigatablePsiElement[] targets,
final String title,
final String findUsagesTitle,
final ListCellRenderer listRenderer,
@Nullable final ListBackgroundUpdaterTask listUpdaterTask,
final Consumer<Object[]> consumer) {
@NotNull final Consumer<Object[]> consumer) {
if (targets.length == 0) return null;
if (targets.length == 1) {
consumer.consume(targets);
@@ -33,7 +33,6 @@ import com.intellij.lang.Language;
import com.intellij.lang.LanguageDocumentation;
import com.intellij.lang.documentation.*;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -96,7 +95,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
private Component myPreviouslyFocused;
public static final Key<SmartPsiElementPointer> ORIGINAL_ELEMENT_KEY = Key.create("Original element");
private final ActionManagerEx myActionManagerEx;
private final ActionManager myActionManager;
private final TargetElementUtil myTargetElementUtil;
@@ -161,9 +160,9 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return ServiceManager.getService(project, DocumentationManager.class);
}
public DocumentationManager(final Project project, ActionManagerEx managerEx, TargetElementUtil targetElementUtil) {
public DocumentationManager(final Project project, ActionManager manager, TargetElementUtil targetElementUtil) {
super(project);
myActionManagerEx = managerEx;
myActionManager = manager;
final AnActionListener actionListener = new AnActionListener() {
@Override
public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
@@ -174,11 +173,11 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return;
}
if (action instanceof ListScrollingUtil.ListScrollAction) return;
if (action == myActionManagerEx.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN)) return;
if (action == myActionManagerEx.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP)) return;
if (action == myActionManagerEx.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_PAGE_DOWN)) return;
if (action == myActionManagerEx.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_PAGE_UP)) return;
if (action == ActionManagerEx.getInstanceEx().getAction(IdeActions.ACTION_EDITOR_ESCAPE)) return;
if (action == myActionManager.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN)) return;
if (action == myActionManager.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP)) return;
if (action == myActionManager.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_PAGE_DOWN)) return;
if (action == myActionManager.getAction(IdeActions.ACTION_EDITOR_MOVE_CARET_PAGE_UP)) return;
if (action == ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_ESCAPE)) return;
if (ActionPlaces.JAVADOC_INPLACE_SETTINGS.equals(event.getPlace())) return;
if (action instanceof BaseNavigateToSourceAction) return;
closeDocHint();
@@ -198,7 +197,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
public void afterActionPerformed(final AnAction action, final DataContext dataContext, AnActionEvent event) {
}
};
myActionManagerEx.addAnActionListener(actionListener, project);
myActionManager.addAnActionListener(actionListener, project);
myUpdateDocAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD,myProject);
myTargetElementUtil = targetElementUtil;
}
@@ -463,7 +462,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
};
List<Pair<ActionListener, KeyStroke>> actions = ContainerUtil.newSmartList();
AnAction quickDocAction = ActionManagerEx.getInstanceEx().getAction(IdeActions.ACTION_QUICK_JAVADOC);
AnAction quickDocAction = ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC);
for (Shortcut shortcut : quickDocAction.getShortcutSet().getShortcuts()) {
if (!(shortcut instanceof KeyboardShortcut)) continue;
actions.add(Pair.create(actionListener, ((KeyboardShortcut)shortcut).getFirstKeyStroke()));
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -105,7 +105,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
}
protected Editor getEditor(DataContext dataContext) {
protected static Editor getEditor(@NotNull DataContext dataContext) {
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
if (editor == null) {
@@ -123,7 +123,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
return editor;
}
public void performForContext(DataContext dataContext, boolean invokedByShortcut) {
public void performForContext(@NotNull DataContext dataContext, boolean invokedByShortcut) {
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null) return;
PsiDocumentManager.getInstance(project).commitAllDocuments();
@@ -185,7 +185,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
showImplementations(impls, project, text, editor, file, element, isInvokedFromEditor, invokedByShortcut);
}
protected static PsiElement getElement(Project project, PsiFile file, Editor editor, PsiElement element) {
protected static PsiElement getElement(@NotNull Project project, PsiFile file, Editor editor, PsiElement element) {
if (element == null && editor != null) {
element = TargetElementUtil.findTargetElement(editor, TargetElementUtil.getInstance().getAllAccepted());
final PsiElement adjustedElement =
@@ -200,6 +200,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
return element;
}
@NotNull
protected static ImplementationSearcher createImplementationsSearcher() {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return new ImplementationSearcher() {
@@ -209,18 +210,16 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
}
};
}
else {
return new ImplementationSearcher.FirstImplementationsSearcher() {
@Override
protected PsiElement[] filterElements(PsiElement element, PsiElement[] targetElements, final int offset) {
return ShowImplementationsAction.filterElements(targetElements);
}
};
}
return new ImplementationSearcher.FirstImplementationsSearcher() {
@Override
protected PsiElement[] filterElements(PsiElement element, PsiElement[] targetElements, final int offset) {
return ShowImplementationsAction.filterElements(targetElements);
}
};
}
protected void updateElementImplementations(final PsiElement element, final Editor editor, final Project project, final PsiFile file) {
PsiElement[] impls = null;
private void updateElementImplementations(final PsiElement element, final Editor editor, @NotNull Project project, final PsiFile file) {
PsiElement[] impls = {};
String text = "";
if (element != null) {
// if (element instanceof PsiPackage) return;
@@ -234,10 +233,15 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
showImplementations(impls, project, text, editor, file, element, false, false);
}
protected void showImplementations(final PsiElement[] impls, final Project project, final String text, final Editor editor, final PsiFile file,
protected void showImplementations(@NotNull PsiElement[] impls,
@NotNull final Project project,
final String text,
final Editor editor,
final PsiFile file,
final PsiElement element,
boolean invokedFromEditor, boolean invokedByShortcut) {
if (impls == null || impls.length == 0) return;
boolean invokedFromEditor,
boolean invokedByShortcut) {
if (impls.length == 0) return;
FeatureUsageTracker.getInstance().triggerFeatureUsed(CODEASSISTS_QUICKDEFINITION_FEATURE);
if (LookupManager.getInstance(project).getActiveLookup() != null) {
@@ -317,7 +321,7 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
}
}
private static boolean cancelTask(ImplementationsUpdaterTask task) {
private static boolean cancelTask(@Nullable ImplementationsUpdaterTask task) {
if (task != null) {
ProgressIndicator indicator = task.myIndicator;
if (indicator != null) {
@@ -330,9 +334,10 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
private void updateInBackground(Editor editor,
@Nullable PsiElement element,
ImplementationViewComponent component,
@NotNull ImplementationViewComponent component,
String title,
AbstractPopup popup, Ref<UsageView> usageView) {
@NotNull AbstractPopup popup,
@NotNull Ref<UsageView> usageView) {
final ImplementationsUpdaterTask updaterTask = SoftReference.dereference(myTaskRef);
cancelTask(updaterTask);
@@ -348,15 +353,17 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
return true;
}
@NotNull
private static PsiElement[] getSelfAndImplementations(Editor editor,
PsiElement element,
final ImplementationSearcher handler) {
@NotNull PsiElement element,
@NotNull ImplementationSearcher handler) {
return getSelfAndImplementations(editor, element, handler, !(element instanceof PomTargetPsiElement));
}
@NotNull
protected static PsiElement[] getSelfAndImplementations(Editor editor,
PsiElement element,
final ImplementationSearcher handler,
@NotNull PsiElement element,
@NotNull ImplementationSearcher handler,
final boolean includeSelfAlways) {
int offset = editor == null ? 0 : editor.getCaretModel().getOffset();
final PsiElement[] handlerImplementations = handler.searchImplementations(element, editor, offset, includeSelfAlways, true);
@@ -367,17 +374,18 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
// Magically, it's null for ant property declarations.
element = element.getNavigationElement();
psiFile = element.getContainingFile();
if (psiFile == null) return PsiElement.EMPTY_ARRAY;
if (psiFile == null) {
return PsiElement.EMPTY_ARRAY;
}
}
if (psiFile.getVirtualFile() != null && (element.getTextRange() != null || element instanceof PsiFile)) {
return new PsiElement[]{element};
}
else {
return PsiElement.EMPTY_ARRAY;
}
return PsiElement.EMPTY_ARRAY;
}
private static PsiElement[] filterElements(final PsiElement[] targetElements) {
@NotNull
private static PsiElement[] filterElements(@NotNull final PsiElement[] targetElements) {
final Set<PsiElement> unique = new LinkedHashSet<PsiElement>(Arrays.asList(targetElements));
for (final PsiElement elt : targetElements) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -410,12 +418,13 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
private static class ImplementationsUpdaterTask extends BackgroundUpdaterTask<ImplementationViewComponent> {
private final String myCaption;
private final Editor myEditor;
@NotNull
private final PsiElement myElement;
private final boolean myIncludeSelf;
private PsiElement[] myElements;
private volatile ProgressIndicator myIndicator;
public ImplementationsUpdaterTask(final PsiElement element, final Editor editor, final String caption, boolean includeSelf) {
private ImplementationsUpdaterTask(@NotNull PsiElement element, final Editor editor, final String caption, boolean includeSelf) {
super(element.getProject(), ImplementationSearcher.SEARCHING_FOR_IMPLEMENTATIONS);
myCaption = caption;
myEditor = editor;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -21,8 +21,6 @@ import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupAdapter;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.ui.popup.AbstractPopup;
@@ -69,7 +67,7 @@ public abstract class BackgroundUpdaterTask<T> extends Task.Backgroundable {
super(project, title, canBeCancelled, backgroundOption);
}
public void init(@NotNull AbstractPopup popup, T component, Ref<UsageView> usageView) {
public void init(@NotNull AbstractPopup popup, @NotNull T component, @NotNull Ref<UsageView> usageView) {
myPopup = popup;
myComponent = component;
myUsageView = usageView;
@@ -37,7 +37,7 @@ public abstract class StringBasedPostfixTemplate extends PostfixTemplateWithExpr
public final void expandForChooseExpression(@NotNull PsiElement expr, @NotNull Editor editor) {
Project project = expr.getProject();
Document document = editor.getDocument();
PsiElement elementForRemoving = shouldRemoveParent() ? expr.getParent() : expr;
PsiElement elementForRemoving = getElementToRemove(expr);
document.deleteString(elementForRemoving.getTextRange().getStartOffset(), elementForRemoving.getTextRange().getEndOffset());
TemplateManager manager = TemplateManager.getInstance(project);
@@ -78,7 +78,16 @@ public abstract class StringBasedPostfixTemplate extends PostfixTemplateWithExpr
return true;
}
/** @deprecated use {@link StringBasedPostfixTemplate#getElementToRemove(PsiElement)} (idea 16 to remove) */
protected boolean shouldRemoveParent() {
return true;
}
protected PsiElement getElementToRemove(PsiElement expr) {
if (shouldRemoveParent()) {
return expr.getParent();
} else {
return expr;
}
}
}
@@ -19,6 +19,7 @@ package com.intellij.find.impl;
import com.intellij.find.FindManager;
import com.intellij.find.findUsages.FindUsagesManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.usages.impl.UsageViewImpl;
@@ -45,7 +46,7 @@ public class ShowRecentFindUsagesGroup extends ActionGroup {
public AnAction[] getChildren(@Nullable final AnActionEvent e) {
if (e == null) return EMPTY_ARRAY;
Project project = e.getData(CommonDataKeys.PROJECT);
if (project == null) return EMPTY_ARRAY;
if (project == null || DumbService.isDumb(project)) return EMPTY_ARRAY;
final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager();
List<ConfigurableUsageTarget> history = new ArrayList<ConfigurableUsageTarget>(findUsagesManager.getHistory().getAll());
Collections.reverse(history);
@@ -122,7 +122,6 @@ public class FileBasedIndexImpl extends FileBasedIndex {
private static final int OK = 1;
private static final int REQUIRES_REBUILD = 2;
private static final int REBUILD_IN_PROGRESS = 3;
private static final Map<ID<?, ?>, AtomicInteger> ourRebuildStatus = new THashMap<ID<?, ?>, AtomicInteger>();
private final MessageBusConnection myConnection;
@@ -679,7 +678,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
for (ID<?, ?> indexId : myIndices.keySet()) {
final UpdatableIndex<?, ?, FileContent> index = getIndex(indexId);
assert index != null;
checkRebuild(indexId, true); // if the index was scheduled for rebuild, only clean it
if(ourRebuildStatus.get(indexId).get() != OK) {
doClearIndex(indexId); // if the index was scheduled for rebuild, only clean it
}
index.dispose();
}
@@ -825,7 +826,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myChangedFilesCollector.tryToEnsureAllInvalidateTasksCompleted();
if (isUpToDateCheckEnabled()) {
try {
checkRebuild(indexId, false);
if (ourRebuildStatus.get(indexId).get() != OK) {
throw new ProcessCanceledException();
}
myChangedFilesCollector.forceUpdate(project, filter, restrictedFile);
indexUnsavedDocuments(indexId, project, filter, restrictedFile);
}
@@ -1225,65 +1228,6 @@ public class FileBasedIndexImpl extends FileBasedIndex {
@Override
public <K> void scheduleRebuild(@NotNull final ID<K, ?> indexId, @NotNull final Throwable e) {
requestRebuild(indexId, new Throwable(e));
try {
checkRebuild(indexId, false);
}
catch (ProcessCanceledException ignored) {
}
}
private void checkRebuild(@NotNull final ID<?, ?> indexId, final boolean cleanupOnly) {
final AtomicInteger status = ourRebuildStatus.get(indexId);
if (status.get() == OK) {
return;
}
if (status.compareAndSet(REQUIRES_REBUILD, REBUILD_IN_PROGRESS)) {
cleanupProcessedFlag();
advanceIndexVersion(indexId);
final Runnable rebuildRunnable = new Runnable() {
@Override
public void run() {
try {
doClearIndex(indexId);
if (!cleanupOnly) {
scheduleIndexRebuild("checkRebuild");
}
}
catch (StorageException e) {
requestRebuild(indexId);
LOG.info(e);
}
finally {
status.compareAndSet(REBUILD_IN_PROGRESS, OK);
}
}
};
if (cleanupOnly || myIsUnitTestMode) {
rebuildRunnable.run();
}
else {
//noinspection SSBasedInspection
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
new Task.Modal(null, "Updating index", false) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
indicator.setIndeterminate(true);
rebuildRunnable.run();
}
}.queue();
}
}, ModalityState.NON_MODAL);
}
}
if (status.get() == REBUILD_IN_PROGRESS) {
throw new ProcessCanceledException();
}
}
private static void scheduleIndexRebuild(String reason) {
@@ -1547,9 +1491,11 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
@Override
public void requestRebuild(ID<?, ?> indexId, Throwable throwable) {
public void requestRebuild(final ID<?, ?> indexId, final Throwable throwable) {
cleanupProcessedFlag();
boolean requiresRebuildWasSet = ourRebuildStatus.get(indexId).compareAndSet(OK, REQUIRES_REBUILD);
final AtomicInteger status = ourRebuildStatus.get(indexId);
boolean requiresRebuildWasSet = status.compareAndSet(OK, REQUIRES_REBUILD);
if (requiresRebuildWasSet) {
String message = "Rebuild requested for index " + indexId;
Application app = ApplicationManager.getApplication();
@@ -1560,6 +1506,47 @@ public class FileBasedIndexImpl extends FileBasedIndex {
} else {
LOG.info(message, throwable);
}
cleanupProcessedFlag();
advanceIndexVersion(indexId);
final Runnable rebuildRunnable = new Runnable() {
@Override
public void run() {
try {
doClearIndex(indexId);
scheduleIndexRebuild("checkRebuild");
}
catch (StorageException e) {
requestRebuild(indexId);
LOG.info(e);
}
finally {
status.compareAndSet(REQUIRES_REBUILD, OK);
}
}
};
if (myIsUnitTestMode) {
rebuildRunnable.run();
}
else {
// we do invoke later since we can have read lock acquired
//noinspection SSBasedInspection
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
new Task.Modal(null, "Updating index", false) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
indicator.setIndeterminate(true);
rebuildRunnable.run();
}
}.queue();
}
}, ModalityState.NON_MODAL);
}
}
}
@@ -1636,6 +1623,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
try {
PsiFile psiFile = null;
FileContentImpl fc = null;
int inputId = -1;
final List<ID<?, ?>> affectedIndexCandidates = getAffectedIndexCandidates(file);
//noinspection ForLoopReplaceableByForEach
@@ -1671,11 +1659,12 @@ public class FileBasedIndexImpl extends FileBasedIndex {
psiFile = content.getUserData(IndexingDataKeys.PSI_FILE);
initFileContent(fc, project, psiFile);
inputId = Math.abs(getFileId(file));
}
try {
ProgressManager.checkCanceled();
updateSingleIndex(indexId, file, fc);
updateSingleIndex(indexId, inputId, fc);
}
catch (ProcessCanceledException e) {
cleanFileContent(fc, psiFile);
@@ -1727,14 +1716,13 @@ public class FileBasedIndexImpl extends FileBasedIndex {
fc.putUserData(IndexingDataKeys.PROJECT, project);
}
private void updateSingleIndex(@NotNull ID<?, ?> indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC)
private void updateSingleIndex(@NotNull ID<?, ?> indexId, final int inputId, @Nullable FileContent currentFC)
throws StorageException {
if (ourRebuildStatus.get(indexId).get() == REQUIRES_REBUILD) {
return; // the index is scheduled for rebuild, no need to update
}
myLocalModCount++;
final int inputId = Math.abs(getFileId(file));
final UpdatableIndex<?, ?, FileContent> index = getIndex(indexId);
assert index != null;
@@ -1749,7 +1737,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
try {
scheduleUpdate(indexId,
createUpdateComputableWithBufferingDisabled(update),
createIndexedStampUpdateRunnable(indexId, file, currentFC != null)
createIndexedStampUpdateRunnable(indexId, inputId, currentFC != null)
);
} catch (RuntimeException exception) {
Throwable causeToRebuildIndex = getCauseToRebuildIndex(exception);
@@ -1766,21 +1754,18 @@ public class FileBasedIndexImpl extends FileBasedIndex {
@NotNull
private Runnable createIndexedStampUpdateRunnable(@NotNull final ID<?, ?> indexId,
@NotNull final VirtualFile file,
final int fileId,
final boolean hasContent) {
return new Runnable() {
@Override
public void run() {
if (file.isValid()) {
int fileId = getIdMaskingNonIdBasedFile(file);
if (hasContent) {
IndexingStamp.setFileIndexedStateCurrent(fileId, indexId);
}
else {
IndexingStamp.setFileIndexedStateUnindexed(fileId, indexId);
}
if (myNotRequiringContentIndices.contains(indexId)) IndexingStamp.flushCache(fileId);
if (hasContent) {
IndexingStamp.setFileIndexedStateCurrent(fileId, indexId);
}
else {
IndexingStamp.setFileIndexedStateUnindexed(fileId, indexId);
}
if (myNotRequiringContentIndices.contains(indexId)) IndexingStamp.flushCache(fileId);
}
};
}
@@ -1947,13 +1932,15 @@ public class FileBasedIndexImpl extends FileBasedIndex {
boolean fileIsDirectory = file.isDirectory();
if (!contentChange) {
FileContent fileContent = null;
int inputId = -1;
for (ID<?, ?> indexId : fileIsDirectory ? myIndicesForDirectories : myNotRequiringContentIndices) {
if (getInputFilter(indexId).acceptInput(file)) {
try {
if (fileContent == null) {
fileContent = new FileContentImpl(file);
inputId = Math.abs(getFileId(file));
}
updateSingleIndex(indexId, file, fileContent);
updateSingleIndex(indexId, inputId, fileContent);
}
catch (StorageException e) {
LOG.info(e);
@@ -2048,16 +2035,16 @@ public class FileBasedIndexImpl extends FileBasedIndex {
private void invalidateIndicesForFile(@NotNull final VirtualFile file, boolean markForReindex) {
cleanProcessedFlag(file);
IndexingStamp.flushCache(file);
final int fileId = getIdMaskingNonIdBasedFile(file);
final int fileId = Math.abs(getIdMaskingNonIdBasedFile(file));
IndexingStamp.flushCache(fileId);
List<ID<?, ?>> nontrivialFileIndexedStates = IndexingStamp.getNontrivialFileIndexedStates(fileId);
if (!markForReindex) { // markForReindex really means content changed
for (ID<?, ?> indexId : nontrivialFileIndexedStates) {
if (myNotRequiringContentIndices.contains(indexId)) {
try {
updateSingleIndex(indexId, file, null);
updateSingleIndex(indexId, fileId, null);
}
catch (StorageException e) {
LOG.info(e);
@@ -2093,19 +2080,19 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myFutureInvalidations.offer(new InvalidationTask(file) {
@Override
public void run() {
removeFileDataFromIndices(finalFileIndexedStatesToUpdate, getSubj());
removeFileDataFromIndices(finalFileIndexedStatesToUpdate, fileId);
}
});
}
IndexingStamp.flushCache(file);
IndexingStamp.flushCache(fileId);
}
private void removeFileDataFromIndices(@NotNull Collection<ID<?, ?>> affectedIndices, @NotNull VirtualFile file) {
private void removeFileDataFromIndices(@NotNull Collection<ID<?, ?>> affectedIndices, int inputId) {
Throwable unexpectedError = null;
for (ID<?, ?> indexId : affectedIndices) {
try {
updateSingleIndex(indexId, file, null);
updateSingleIndex(indexId, inputId, null);
}
catch (StorageException e) {
LOG.info(e);
@@ -2121,7 +2108,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
}
}
IndexingStamp.flushCache(file);
IndexingStamp.flushCache(inputId);
if (unexpectedError != null) {
LOG.error(unexpectedError);
}
@@ -2241,7 +2228,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
try {
if (isTooLarge(file)) {
List<ID<?, ?>> nontrivialFileIndexedStates = IndexingStamp.getNontrivialFileIndexedStates(fileId);
removeFileDataFromIndices(ContainerUtil.intersection(nontrivialFileIndexedStates, myRequiringContentIndices), file);
removeFileDataFromIndices(ContainerUtil.intersection(nontrivialFileIndexedStates, myRequiringContentIndices), Math.abs(fileId));
}
else {
doIndexFileContent(project, fileContent);
@@ -2263,10 +2250,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myContentlessIndicesUpdateQueue.ensureUpToDate();
for (VFileEvent event : events) {
Object requestor = event.getRequestor();
if (requestor instanceof FileDocumentManager ||
requestor instanceof PsiManager ||
requestor == LocalHistory.VFS_EVENT_REQUESTOR) {
if (memoryStorageCleaningNeeded(event)) {
cleanupMemoryStorage();
break;
}
@@ -2276,6 +2260,13 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
}
private boolean memoryStorageCleaningNeeded(VFileEvent event) {
Object requestor = event.getRequestor();
return requestor instanceof FileDocumentManager ||
requestor instanceof PsiManager ||
requestor == LocalHistory.VFS_EVENT_REQUESTOR;
}
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
myContentlessIndicesUpdateQueue.ensureUpToDate();
@@ -2390,14 +2381,16 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
}
FileContent fileContent = null;
int inputId = -1;
for (ID<?, ?> indexId : myNotRequiringContentIndices) {
if (shouldIndexFile(file, indexId)) {
oldStuff = false;
try {
if (fileContent == null) {
fileContent = new FileContentImpl(file);
inputId = Math.abs(getFileId(file));
}
updateSingleIndex(indexId, file, fileContent);
updateSingleIndex(indexId, inputId, fileContent);
}
catch (StorageException e) {
LOG.info(e);
@@ -32,10 +32,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VFileProperty;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.*;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -301,7 +298,7 @@ public class VirtualFileDiffElement extends DiffElement<VirtualFile> {
}.execute();
}
virtualFile.refresh(true, true);
VfsUtil.markDirtyAndRefresh(true, true, true, virtualFile);
}
}
}
@@ -43,7 +43,13 @@ public class ComplementaryFontsRegistry {
private static FontInfo ourSharedDefaultFont;
private static final TIntHashSet ourUndisplayableChars = new TIntHashSet();
private static boolean ourOldUseAntialiasing;
// This matches style detection in JDK (class sun.font.Font2D)
private static final String[] BOLD_NAMES = {"bold", "demibold", "demi-bold", "demi bold", "negreta", "demi" };
private static final String[] ITALIC_NAMES = {"italic", "cursiva", "oblique", "inclined"};
private static final String[] BOLD_ITALIC_NAMES = {"bolditalic", "bold-italic", "bold italic", "boldoblique", "bold-oblique",
"bold oblique", "demibold italic", "negreta cursiva","demi oblique"};
static {
final UISettings settings = UISettings.getInstance();
ourOldUseAntialiasing = settings.ANTIALIASING_IN_EDITOR;
@@ -121,44 +127,36 @@ public class ComplementaryFontsRegistry {
Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
for (Font font : allFonts) {
String name = font.getName();
int style;
if (name.endsWith("-Italic")) {
style = Font.ITALIC;
}
else if (name.endsWith("-Bold")) {
style = Font.BOLD;
}
else if (name.endsWith("-BoldItalic")) {
style = Font.BOLD | Font.ITALIC;
}
else {
style = Font.PLAIN;
}
int style = getFontStyle(name);
if (style != Font.PLAIN) {
String baseName = name.substring(0, name.lastIndexOf('-'));
Pair<String, Integer>[] entry = ourStyledFontMap.get(baseName);
String familyName = font.getFamily();
Pair<String, Integer>[] entry = ourStyledFontMap.get(familyName);
if (entry == null) {
//noinspection unchecked
entry = new Pair[4];
for (int i = 1; i < 4; i++) {
entry[i] = Pair.create(baseName, i);
entry[i] = Pair.create(familyName, i);
}
ourStyledFontMap.put(baseName, entry);
ourStyledFontMap.put(familyName, entry);
}
entry[style] = Pair.create(name, Font.PLAIN);
}
}
}
private static Pair<String, Integer> fontFamily(String familyName, int style) {
if (SystemInfo.isMac && style > 0 && style < 4) {
Pair<String, Integer>[] replacement = ourStyledFontMap.get(familyName);
if (replacement != null) {
familyName = replacement[style].first;
style = replacement[style].second;
}
@JdkConstants.FontStyle
private static int getFontStyle(String fontName) {
fontName = fontName.toLowerCase(Locale.getDefault());
for (String name : BOLD_ITALIC_NAMES) {
if (fontName.contains(name)) return Font.BOLD | Font.ITALIC;
}
return Pair.create(familyName, style);
for (String name : ITALIC_NAMES) {
if (fontName.contains(name)) return Font.ITALIC;
}
for (String name : BOLD_NAMES) {
if (fontName.contains(name)) return Font.BOLD;
}
return Font.PLAIN;
}
@NotNull
@@ -200,11 +198,17 @@ public class ComplementaryFontsRegistry {
@Nullable
private static FontInfo doGetFontAbleToDisplay(char c, int size, @JdkConstants.FontStyle int style, @NotNull String defaultFontFamily) {
synchronized (lock) {
Pair<String, Integer> p = fontFamily(defaultFontFamily, style);
if (SystemInfo.isMac && style > 0 && style < 4) {
Pair<String, Integer>[] replacement = ourStyledFontMap.get(defaultFontFamily);
if (replacement != null) {
defaultFontFamily = replacement[style].first;
style = replacement[style].second;
}
}
if (ourSharedKeyInstance.mySize == size &&
ourSharedKeyInstance.myStyle == p.getSecond() &&
ourSharedKeyInstance.myStyle == style &&
ourSharedKeyInstance.myFamilyName != null &&
ourSharedKeyInstance.myFamilyName.equals(p.getFirst()) &&
ourSharedKeyInstance.myFamilyName.equals(defaultFontFamily) &&
ourSharedDefaultFont != null &&
( c < 128 ||
ourSharedDefaultFont.canDisplay(c)
@@ -213,13 +217,13 @@ public class ComplementaryFontsRegistry {
return ourSharedDefaultFont;
}
ourSharedKeyInstance.myFamilyName = p.getFirst();
ourSharedKeyInstance.myFamilyName = defaultFontFamily;
ourSharedKeyInstance.mySize = size;
ourSharedKeyInstance.myStyle = p.getSecond();
ourSharedKeyInstance.myStyle = style;
FontInfo defaultFont = ourUsedFonts.get(ourSharedKeyInstance);
if (defaultFont == null) {
defaultFont = new FontInfo(p.getFirst(), size, p.getSecond());
defaultFont = new FontInfo(defaultFontFamily, size, style);
ourUsedFonts.put(ourSharedKeyInstance, defaultFont);
ourSharedKeyInstance = new FontKey("", 0, 0);
}
@@ -45,7 +45,7 @@ import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
@@ -1379,31 +1379,32 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
GutterIconRenderer renderer = getGutterRenderer(e);
final Project project = myEditor.getProject();
if (project != null && DumbService.isDumb(project) && !DumbService.isDumbAware(renderer)) {
DumbService.getInstance(project).showDumbModeNotification("Navigation is not available during indexing");
return;
}
AnAction clickAction = null;
if (renderer != null && e.getButton() < 4) {
clickAction = (InputEvent.BUTTON2_MASK & e.getModifiers()) > 0
? renderer.getMiddleButtonClickAction()
: renderer.getClickAction();
}
try {
if (clickAction != null) {
clickAction.actionPerformed(new AnActionEvent(e, myEditor.getDataContext(), "ICON_NAVIGATION", clickAction.getTemplatePresentation(),
ActionManager.getInstance(),
e.getModifiers()));
e.consume();
repaint();
}
else {
ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e);
if (lineRenderer != null) {
lineRenderer.doAction(myEditor, e);
} else {
fireEventToTextAnnotationListeners(e);
}
}
if (clickAction != null) {
clickAction.actionPerformed(new AnActionEvent(e, myEditor.getDataContext(), "ICON_NAVIGATION", clickAction.getTemplatePresentation(),
ActionManager.getInstance(),
e.getModifiers()));
e.consume();
repaint();
}
catch (IndexNotReadyException e1) {
DumbService.getInstance(myEditor.getProject()).showDumbModeNotification("Navigation is not available during indexing");
else {
ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e);
if (lineRenderer != null) {
lineRenderer.doAction(myEditor, e);
} else {
fireEventToTextAnnotationListeners(e);
}
}
}
@@ -47,7 +47,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
private JComponent myCenterPanel;
private final String myDimensionKey;
private final boolean myShowApplyButton;
private boolean myChangesWereApplied;
private boolean mySaveAllOnClose;
public SingleConfigurableEditor(@Nullable Project project,
Configurable configurable,
@@ -166,18 +166,16 @@ public class SingleConfigurableEditor extends DialogWrapper {
@Override
public void doCancelAction() {
if (myChangesWereApplied) {
ApplicationManager.getApplication().saveAll();
}
super.doCancelAction();
}
@Override
protected void doOKAction() {
try {
if (myConfigurable.isModified()) myConfigurable.apply();
ApplicationManager.getApplication().saveAll();
if (myConfigurable.isModified()) {
myConfigurable.apply();
mySaveAllOnClose = true;
}
}
catch (ConfigurationException e) {
if (e.getMessage() != null) {
@@ -237,7 +235,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
myPerformAction = true;
if (myConfigurable.isModified()) {
myConfigurable.apply();
myChangesWereApplied = true;
mySaveAllOnClose = true;
setCancelButtonText(CommonBundle.getCloseButtonText());
}
}
@@ -275,5 +273,9 @@ public class SingleConfigurableEditor extends DialogWrapper {
super.dispose();
myConfigurable.disposeUIResources();
myConfigurable = null;
if (mySaveAllOnClose) {
ApplicationManager.getApplication().saveAll();
}
}
}
@@ -108,9 +108,9 @@ public class ProgressManagerImpl extends CoreProgressManager implements Disposab
@Override
@NotNull
public Future<?> runProcessWithProgressAsynchronously(@NotNull final Task.Backgroundable task,
@NotNull final ProgressIndicator progressIndicator,
@Nullable final Runnable continuation,
@NotNull final ModalityState modalityState) {
@NotNull final ProgressIndicator progressIndicator,
@Nullable final Runnable continuation,
@NotNull final ModalityState modalityState) {
if (progressIndicator instanceof Disposable) {
Disposer.register(ApplicationManager.getApplication(), (Disposable)progressIndicator);
}
@@ -17,6 +17,7 @@ package com.intellij.openapi.progress.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.DialogWrapperPeer;
@@ -221,13 +222,17 @@ class ProgressDialog implements Disposable {
}
void cancel() {
enableCancelButtonIfNeeded(false);
}
void enableCancelButtonIfNeeded(final boolean enable) {
if (myProgressWindow.myShouldShowCancel) {
SwingUtilities.invokeLater(new Runnable() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
myCancelButton.setEnabled(false);
myCancelButton.setEnabled(enable);
}
});
}, ModalityState.any());
}
}
@@ -241,6 +241,22 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro
}
}
@Override
public void startNonCancelableSection() {
if (isCancelable()) {
enableCancel(false);
}
super.startNonCancelableSection();
}
@Override
public void finishNonCancelableSection() {
super.finishNonCancelableSection();
if (isCancelable()) {
enableCancel(true);
}
}
@Override
public void setIndeterminate(boolean indeterminate) {
super.setIndeterminate(indeterminate);
@@ -384,4 +400,8 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro
public boolean isPopupWasShown() {
return myDialog != null && myDialog.myPopup != null && myDialog.myPopup.isShowing();
}
protected void enableCancel(boolean enable) {
myDialog.enableCancelButtonIfNeeded(enable);
}
}
@@ -60,13 +60,13 @@ public class FileNameCache {
private static int calcStripeIdFromNameId(int id) {
int h = id;
h -= (h<<6);
h ^= (h>>17);
h -= (h<<9);
h ^= (h<<4);
h -= (h<<3);
h ^= (h<<10);
h ^= (h>>15);
h -= h<<6;
h ^= h>>17;
h -= h<<9;
h ^= h<<4;
h -= h<<3;
h ^= h<<10;
h ^= h>>15;
return h % ourNameCache.length;
}
@@ -18,6 +18,7 @@ package com.intellij.openapi.vfs.newvfs.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -32,6 +33,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl;
import com.intellij.psi.impl.PsiCachedValue;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.UriUtil;
@@ -547,6 +549,15 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
@Override
protected boolean changeUserMap(KeyFMap oldMap, KeyFMap newMap) {
checkLeaks(newMap);
return myData.changeUserMap(oldMap, UserDataInterner.internUserData(newMap));
}
static void checkLeaks(KeyFMap newMap) {
for (Key key : newMap.getKeys()) {
if (key != null && newMap.get(key) instanceof PsiCachedValue) {
throw new AssertionError("Don't store CachedValue in VFS user data, since it leads to memory leaks");
}
}
}
}
@@ -142,6 +142,7 @@ public class VirtualFileImpl extends VirtualFileSystemEntry {
@Override
protected boolean changeUserMap(KeyFMap oldMap, KeyFMap newMap) {
VirtualDirectoryImpl.checkLeaks(newMap);
return mySegment.changeUserMap(Math.abs(getId()), oldMap, UserDataInterner.internUserData(newMap));
}
@@ -106,7 +106,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
final boolean insideBalloon = isInsideBalloon(me);
if (myHideOnMouse && id == MouseEvent.MOUSE_PRESSED) {
if (!insideBalloon && !hasModalDialog(me)) {
if (!insideBalloon && !hasModalDialog(me) && !isWithinChildWindow(me)) {
hide();
}
return;
@@ -159,6 +159,21 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
}
};
private boolean isWithinChildWindow(MouseEvent event) {
Component owner = UIUtil.getWindow(myContent);
if (owner != null) {
Component child = UIUtil.getWindow(event.getComponent());
if (child != owner) {
for (; child != null; child = child.getParent()) {
if (child == owner) {
return true;
}
}
}
}
return false;
}
private static boolean hasModalDialog(MouseEvent e) {
final Component c = e.getComponent();
final DialogWrapper dialog = DialogWrapper.findInstance(c);
@@ -492,4 +492,8 @@ public class SheetController {
public String getResult() {
return myResult;
}
public void dispose() {
mySheetPanel.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0));
}
}
@@ -228,6 +228,7 @@ public class SheetMessage {
if (restoreFullScreenButton) {
FullScreenUtilities.setWindowCanFullScreen(myParent, true);
}
myController.dispose();
myWindow.dispose();
}
}
@@ -352,6 +352,7 @@ patch.apply.conflict.patched.version=Patched Version
patch.apply.select.title=Select Patch File
patch.apply.select.base.directory.title=Select Base Directory
shelve.changes.action=Shelve Changes
shelve.changes.progress.title=Shelving Changes...
patch.apply.already.applied=All of the changes in the specified patch are already contained in the code
patch.apply.partially.applied=Some of the changes in the specified patch were skipped because they are already contained in the code
patch.apply.success.applied.text=Patch successfully applied
@@ -105,12 +105,14 @@
<action id="EmmetNextEditPoint" class="com.intellij.codeInsight.template.emmet.actions.GoToEditPointAction$Forward"
text="Next Emmet Edit Point" description="Go to next Emmet edit point">
<keyboard-shortcut first-keystroke="alt shift CLOSE_BRACKET" keymap="$default"/>
<keyboard-shortcut first-keystroke="control alt RIGHT" keymap="Mac OS X" replace-all="true"/>
<keyboard-shortcut first-keystroke="control alt RIGHT" keymap="Mac OS X 10.5+" replace-all="true"/>
</action>
<action id="EmmetPreviousEditPoint" class="com.intellij.codeInsight.template.emmet.actions.GoToEditPointAction$Backward"
text="Previous Emmet Edit Point" description="Go to previous Emmet edit point">
<keyboard-shortcut first-keystroke="alt shift OPEN_BRACKET" keymap="$default"/>
<keyboard-shortcut first-keystroke="control alt LEFT" keymap="Mac OS X" replace-all="true"/>
<keyboard-shortcut first-keystroke="control alt LEFT" keymap="Mac OS X 10.5+" replace-all="true"/>
</action>
</group>
@@ -19,4 +19,5 @@ com.jetbrains.plugins.ini4idea
com.jetbrains.plugins.meteor
AWSCloudFormation
Dart
IdeaVIM
IdeaVIM
IDETalk
@@ -28,11 +28,13 @@ import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
import com.intellij.execution.testframework.sm.runner.TestProxyFilterProvider;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.project.Project;
import com.intellij.pom.Navigatable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.File;
public class ImportedTestConsoleProperties extends SMTRunnerConsoleProperties implements SMCustomMessagesParsing {
@@ -111,4 +113,11 @@ public class ImportedTestConsoleProperties extends SMTRunnerConsoleProperties im
public AbstractRerunFailedTestsAction createRerunFailedTestsAction(ConsoleView consoleView) {
return myProperties == null ? null : myProperties.createRerunFailedTestsAction(consoleView);
}
@Override
public void appendAdditionalActions(DefaultActionGroup actionGroup, JComponent parent, TestConsoleProperties target) {
if (myProperties != null) {
myProperties.appendAdditionalActions(actionGroup, parent, this);
}
}
}
@@ -52,7 +52,12 @@ public class ImportedTestContentHandler extends DefaultHandler {
myCurrentTest = name;
myDuration = attributes.getValue(TestResultsXmlFormatter.ATTR_DURATION);
myStatus = attributes.getValue(TestResultsXmlFormatter.ATTR_STATUS);
myProcessor.onTestStarted(new TestStartedEvent(name, attributes.getValue(TestResultsXmlFormatter.ATTR_LOCATION)));
final String isConfig = attributes.getValue(TestResultsXmlFormatter.ATTR_CONFIG);
final TestStartedEvent startedEvent = new TestStartedEvent(name, attributes.getValue(TestResultsXmlFormatter.ATTR_LOCATION));
if (isConfig != null && Boolean.valueOf(isConfig)) {
startedEvent.setConfig(true);
}
myProcessor.onTestStarted(startedEvent);
currentValue.setLength(0);
}
else if (TestResultsXmlFormatter.ELEM_OUTPUT.equals(qName)) {
@@ -18,6 +18,7 @@ package com.intellij.execution.testframework.sm.runner.history.actions;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.ExecutorRegistry;
import com.intellij.execution.RunnerRegistry;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
@@ -26,6 +27,7 @@ import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.testframework.export.TestResultsXmlFormatter;
import com.intellij.execution.testframework.sm.runner.history.ImportedTestRunnableState;
import com.intellij.execution.testframework.sm.runner.SMRunnerConsolePropertiesProvider;
@@ -115,7 +117,14 @@ public abstract class AbstractImportTestsAction extends AnAction {
}
final Executor executor = properties != null ? properties.getExecutor()
: ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID);
ExecutionEnvironmentBuilder.create(project, executor, profile).buildAndExecute();
ExecutionEnvironmentBuilder builder = ExecutionEnvironmentBuilder.create(project, executor, profile);
final RunConfiguration initialConfiguration = profile.getInitialConfiguration();
final ProgramRunner runner =
initialConfiguration != null ? RunnerRegistry.getInstance().getRunner(executor.getId(), initialConfiguration) : null;
if (runner != null) {
builder = builder.runner(runner);
}
builder.buildAndExecute();
}
catch (ExecutionException e1) {
Messages.showErrorDialog(project, e1.getMessage(), "Import Failed");
@@ -214,6 +223,10 @@ public abstract class AbstractImportTestsAction extends AnAction {
return myProperties;
}
public RunConfiguration getInitialConfiguration() {
return mySettings != null ? mySettings.getConfiguration() : null;
}
public Project getProject() {
return myProject;
}
@@ -319,6 +319,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
}
fireOnTestingFinished();
if (testsRoot.wasTerminated() && myStatusLine.getStatusColor() == ColorProgressBar.GREEN) {
myStatusLine.setStatusColor(JBColor.LIGHT_GRAY);
}
if (testsRoot.isEmptySuite() &&
testsRoot.isTestsReporterAttached() &&
@@ -773,12 +777,14 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
private static class MySaveHistoryTask extends Task.Backgroundable {
private final TestConsoleProperties myConsoleProperties;
private SMTestProxy.SMRootTestProxy myRoot;
private RunConfiguration myConfiguration;
private String myOutput;
public MySaveHistoryTask(TestConsoleProperties consoleProperties, SMTestProxy.SMRootTestProxy root, RunConfiguration configuration) {
super(consoleProperties.getProject(), "Save Test Results", true);
myConsoleProperties = consoleProperties;
myRoot = root;
myConfiguration = configuration;
}
@@ -796,7 +802,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
final SMTestProxy.SMRootTestProxy root = myRoot;
final RunConfiguration configuration = myConfiguration;
if (root != null && configuration != null) {
TestResultsXmlFormatter.execute(root, configuration, handler);
TestResultsXmlFormatter.execute(root, configuration, myConsoleProperties, handler);
}
myOutput = w.toString();
}
@@ -594,7 +594,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
if (ourTestCount++ % 100 == 0) {
// some tests are written in Groovy, and running all of them may result in some 40M of memory wasted on bean infos
// so let's clear the cache every now and then to ensure it doesn't grow too large
GCUtil.tryClearBeanInfoCache();
GCUtil.clearBeanInfoCache();
}
}
@@ -15,14 +15,13 @@
*/
package com.intellij.util;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.TestOnly;
import java.beans.Introspector;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class GCUtil {
@@ -79,25 +78,12 @@ public class GCUtil {
return o == null ? 0 : Math.abs(o.hashCode()) % 10;
}
private static final boolean ourHasBeanInfoCache = SystemInfo.isJavaVersionAtLeast("1.7");
/**
* Using java beans (e.g. Groovy does it) results in all referenced class infos being cached in ThreadGroupContext. A valid fix
* would be to hold BeanInfo objects on soft references, but that should be done in JDK. So let's clear this cache manually for now,
* in clients that are known to create bean infos.
*/
public static void tryClearBeanInfoCache() {
if (ourHasBeanInfoCache) {
try {
Class<?> aClass = Class.forName("java.beans.ThreadGroupContext");
Method getContextMethod = aClass.getDeclaredMethod("getContext");
getContextMethod.setAccessible(true);
Object contextForThreadGroup = getContextMethod.invoke(null);
Method clearBeanInfoCacheMethod = contextForThreadGroup.getClass().getDeclaredMethod("clearBeanInfoCache");
clearBeanInfoCacheMethod.setAccessible(true);
clearBeanInfoCacheMethod.invoke(contextForThreadGroup);
}
catch (Throwable ignore) {}
}
public static void clearBeanInfoCache() {
Introspector.flushCaches();
}
}
@@ -127,10 +127,18 @@ public abstract class Filter<T extends AbstractTestProxy> {
}
});
public static final Filter SUCCESSFUL_CONFIGS = new Filter() {
public static final Filter HIDE_SUCCESSFUL_CONFIGS = new Filter() {
@Override
public boolean shouldAccept(AbstractTestProxy test) {
return !test.isConfig() || !test.isPassed();
final List<? extends AbstractTestProxy> children = test.getChildren();
if (!children.isEmpty()) {
for (AbstractTestProxy proxy : children) {
if (!proxy.isConfig() || !proxy.isPassed()) return true;
}
return false;
}
return !(test.isConfig() && test.isPassed());
}
};
@@ -195,7 +195,7 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp
myUsePredefinedMessageFilter = usePredefinedMessageFilter;
}
protected void appendAdditionalActions(DefaultActionGroup actionGroup, JComponent parent) { }
public void appendAdditionalActions(DefaultActionGroup actionGroup, JComponent parent, TestConsoleProperties target) { }
@Nullable
protected AnAction createImportAction() {
@@ -203,16 +203,16 @@ public abstract class TestConsoleProperties extends StoringPropertyContainer imp
}
@NotNull
protected ToggleBooleanProperty createIncludeNonStartedInRerun() {
protected ToggleBooleanProperty createIncludeNonStartedInRerun(TestConsoleProperties target) {
String text = ExecutionBundle.message("junit.runing.info.include.non.started.in.rerun.failed.action.name");
return new ToggleBooleanProperty(text, null, null, this, INCLUDE_NON_STARTED_IN_RERUN_FAILED);
return new ToggleBooleanProperty(text, null, null, target, INCLUDE_NON_STARTED_IN_RERUN_FAILED);
}
@NotNull
protected ToggleBooleanProperty createHideSuccessfulConfig() {
protected ToggleBooleanProperty createHideSuccessfulConfig(TestConsoleProperties target) {
String text = ExecutionBundle.message("junit.runing.info.hide.successful.config.action.name");
setIfUndefined(HIDE_SUCCESSFUL_CONFIG, true);
return new ToggleBooleanProperty(text, null, null, this, HIDE_SUCCESSFUL_CONFIG);
return new ToggleBooleanProperty(text, null, null, target, HIDE_SUCCESSFUL_CONFIG);
}
@JdkConstants.TreeSelectionMode
@@ -23,7 +23,6 @@ package com.intellij.execution.testframework;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.actions.ScrollToTestSourceAction;
import com.intellij.execution.testframework.actions.ShowStatisticsAction;
import com.intellij.execution.testframework.actions.TestFrameworkActions;
@@ -155,7 +154,7 @@ public class ToolbarPanel extends JPanel implements OccurenceNavigator, Disposab
secondaryGroup.addSeparator();
secondaryGroup.add(new ToggleBooleanProperty(ExecutionBundle.message("junit.runing.info.select.first.failed.action.name"),
null, null, properties, TestConsoleProperties.SELECT_FIRST_DEFECT));
properties.appendAdditionalActions(secondaryGroup, parent);
properties.appendAdditionalActions(secondaryGroup, parent, properties);
actionGroup.add(secondaryGroup);
add(ActionManager.getInstance().
@@ -56,7 +56,7 @@ public class TestFrameworkActions {
}
final boolean hideSuccessfulConfigs = TestConsoleProperties.HIDE_SUCCESSFUL_CONFIG.value(properties);
final Filter hideConfigsFilter = hideSuccessfulConfigs ? Filter.SUCCESSFUL_CONFIGS : Filter.NO_FILTER;
final Filter hideConfigsFilter = hideSuccessfulConfigs ? Filter.HIDE_SUCCESSFUL_CONFIGS : Filter.NO_FILTER;
return hidePassedFilter.and(hideIgnoredFilter).and(hideConfigsFilter);
}
@@ -307,7 +307,7 @@ public class ExportTestResultsAction extends DumbAwareAction {
StringWriter w = new StringWriter();
handler.setResult(new StreamResult(w));
try {
TestResultsXmlFormatter.execute(myModel.getRoot(), myRunConfiguration, handler);
TestResultsXmlFormatter.execute(myModel.getRoot(), myRunConfiguration, myModel.getProperties(), handler);
}
catch (ProcessCanceledException e) {
return null;
@@ -18,12 +18,10 @@ package com.intellij.execution.testframework.export;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.filters.*;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.Printable;
import com.intellij.execution.testframework.Printer;
import com.intellij.execution.testframework.TestProxyRoot;
import com.intellij.execution.testframework.*;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.extensions.Extensions;
@@ -59,6 +57,7 @@ public class TestResultsXmlFormatter {
public static final String ATTR_STATUS = "status";
public static final String TOTAL_STATUS = "total";
private static final String ATTR_FOORTER_TEXT = "footerText";
public static final String ATTR_CONFIG = "isConfig";
public static final String STATUS_PASSED = "passed";
public static final String STATUS_FAILED = "failed";
public static final String STATUS_ERROR = "error";
@@ -72,16 +71,21 @@ public class TestResultsXmlFormatter {
private final RunConfiguration myRuntimeConfiguration;
private final ContentHandler myResultHandler;
private final AbstractTestProxy myTestRoot;
private final boolean myHidePassedConfig;
public static void execute(AbstractTestProxy root, RunConfiguration runtimeConfiguration, ContentHandler resultHandler)
public static void execute(AbstractTestProxy root, RunConfiguration runtimeConfiguration, TestConsoleProperties properties, ContentHandler resultHandler)
throws SAXException {
new TestResultsXmlFormatter(root, runtimeConfiguration, resultHandler).execute();
new TestResultsXmlFormatter(root, runtimeConfiguration, properties, resultHandler).execute();
}
private TestResultsXmlFormatter(AbstractTestProxy root, RunConfiguration runtimeConfiguration, ContentHandler resultHandler) {
private TestResultsXmlFormatter(AbstractTestProxy root,
RunConfiguration runtimeConfiguration,
TestConsoleProperties properties,
ContentHandler resultHandler) {
myRuntimeConfiguration = runtimeConfiguration;
myTestRoot = root;
myResultHandler = resultHandler;
myHidePassedConfig = TestConsoleProperties.HIDE_SUCCESSFUL_CONFIG.value(properties);
}
private void execute() throws SAXException {
@@ -205,6 +209,9 @@ public class TestResultsXmlFormatter {
if (locationUrl != null) {
attrs.put(ATTR_LOCATION, locationUrl);
}
if (node.isConfig()) {
attrs.put(ATTR_CONFIG, "true");
}
String elemName = node.isLeaf() ? ELEM_TEST : ELEM_SUITE;
startElement(elemName, attrs);
if (node.isLeaf()) {
@@ -250,7 +257,7 @@ public class TestResultsXmlFormatter {
}
else {
for (AbstractTestProxy child : node.getChildren()) {
if (child.isConfig() && child.isPassed()) {
if (myHidePassedConfig && child.isConfig() && child.isPassed()) {
//ignore configurations during export
continue;
}
@@ -18,14 +18,40 @@ package com.intellij.usages.actions;
import com.intellij.usages.Usage;
import com.intellij.usages.UsageView;
import java.util.List;
/**
* @author Manuel Stadelmann
*/
public class RemoveUsageAction extends IncludeExcludeActionBase {
@Override
protected void process(Usage[] usages, UsageView usageView) {
Usage nextToSelect = null;
for (Usage usage : usages) {
Usage toSelect = getNextToSelect(usageView, usage);
usageView.removeUsage(usage);
nextToSelect = toSelect;
}
if (nextToSelect != null) {
usageView.selectUsages(new Usage[]{nextToSelect});
}
}
private Usage getNextToSelect(UsageView usageView, Usage toDelete) {
List<Usage> sortedUsages = usageView.getSortedUsages();
int curIndex = sortedUsages.indexOf(toDelete);
int selectIndex = 0;
if (curIndex < sortedUsages.size() - 1) {
selectIndex = curIndex + 1;
}
else if (curIndex > 0) {
selectIndex = curIndex - 1;
}
return sortedUsages.get(selectIndex);
}
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.util.ProgressWrapper;
import com.intellij.openapi.progress.util.TooManyUsagesStatus;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
@@ -654,7 +655,15 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
@NotNull
private AnAction showSettings() {
final ConfigurableUsageTarget configurableUsageTarget = getConfigurableTarget(myTargets);
String description = configurableUsageTarget == null ? "Show find usages settings dialog" : "Show settings for "+configurableUsageTarget.getLongDescriptiveName();
String description = null;
try {
description = configurableUsageTarget == null ? null : "Show settings for "+configurableUsageTarget.getLongDescriptiveName();
}
catch (IndexNotReadyException ignored) {
}
if (description == null) {
description = "Show find usages settings dialog";
}
return new AnAction("Settings...", description, AllIcons.General.ProjectSettings) {
{
KeyboardShortcut shortcut = configurableUsageTarget == null ? getShowUsagesWithSettingsShortcut() : configurableUsageTarget.getShortcut();
@@ -1612,7 +1621,8 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
final JButton button = new JButton(UIUtil.replaceMnemonicAmpersand(text));
DialogUtil.registerMnemonic(button);
DumbService.getInstance(myProject).makeDumbAware(button, UsageViewImpl.this);
button.setFocusable(false);
button.addActionListener(new ActionListener() {
@Override
@@ -16,8 +16,8 @@
package com.intellij.util.diff;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ThreeState;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -34,6 +34,10 @@ public class DiffTree<OT, NT> {
private final ShallowNodeComparator<OT, NT> myComparator;
private final List<Ref<OT[]>> myOldChildrenLists = new ArrayList<Ref<OT[]>>();
private final List<Ref<NT[]>> myNewChildrenLists = new ArrayList<Ref<NT[]>>();
private final CharSequence myOldText;
private final CharSequence myNewText;
private final int myOldTreeStart;
private final int myNewTreeStart;
private DiffTree(@NotNull FlyweightCapableTreeStructure<OT> oldTree,
@NotNull FlyweightCapableTreeStructure<NT> newTree,
@@ -41,6 +45,10 @@ public class DiffTree<OT, NT> {
myOldTree = oldTree;
myNewTree = newTree;
myComparator = comparator;
myOldText = oldTree.toString(oldTree.getRoot());
myOldTreeStart = oldTree.getStartOffset(oldTree.getRoot());
myNewText = newTree.toString(newTree.getRoot());
myNewTreeStart = newTree.getStartOffset(newTree.getRoot());
}
public static <OT, NT> void diff(@NotNull FlyweightCapableTreeStructure<OT> oldTree,
@@ -263,10 +271,12 @@ public class DiffTree<OT, NT> {
CompareResult c11 = looksEqual(myComparator, oldChild, newChild);
if (c11 == CompareResult.DRILL_DOWN_NEEDED) {
CharSequence oldText = myOldTree.toString(oldChild);
CharSequence newText = myNewTree.toString(newChild);
int oldStart = myOldTree.getStartOffset(oldChild) - myOldTreeStart;
int oldEnd = myOldTree.getEndOffset(oldChild) - myOldTreeStart;
int newStart = myNewTree.getStartOffset(newChild) - myNewTreeStart;
int newEnd = myNewTree.getEndOffset(newChild) - myNewTreeStart;
// drill down only if node texts match, but when they do, match all the way down unconditionally
c11 = StringUtil.equals(oldText, newText)
c11 = CharArrayUtil.regionMatches(myOldText, oldStart, oldEnd, myNewText, newStart, newEnd)
? build(oldChild, newChild, level + 1, DiffTree.<OT, NT>emptyConsumer())
: CompareResult.NOT_EQUAL;
}
@@ -39,4 +39,7 @@ public interface FlyweightCapableTreeStructure<T> {
@NotNull
CharSequence toString(@NotNull T node);
int getStartOffset(@NotNull T node);
int getEndOffset(@NotNull T node);
}
@@ -15,15 +15,36 @@
*/
package com.intellij.util.text;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
public class ByteArrayCharSequence implements CharSequence {
private int hash;
private final byte[] myChars;
public ByteArrayCharSequence(@NotNull byte... chars) {
private ByteArrayCharSequence(@NotNull byte[] chars) {
myChars = chars;
}
@Override
public int hashCode() {
int h = hash;
if (h == 0) {
byte[] chars = myChars;
for (byte aChar : chars) {
h = 31 * h + aChar;
}
hash = h;
}
return h;
}
@Override
public boolean equals(Object obj) {
return obj instanceof CharSequence && StringUtil.equals(this, (CharSequence)obj);
}
@Override
public final int length() {
return myChars.length;
@@ -63,6 +84,7 @@ public class ByteArrayCharSequence implements CharSequence {
//noinspection RedundantStringConstructorCall
return new String(name.toString()); // So we don't hold whole char[] buffer of a lengthy path on JDK 6
}
bytes[i] = (byte)c;
}
return new ByteArrayCharSequence(bytes);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -288,27 +288,36 @@ public class CharArrayUtil {
return offset;
}
public static boolean regionMatches(@NotNull char[] buffer, int offset, int bufferEnd, @NotNull CharSequence s) {
public static boolean regionMatches(@NotNull char[] buffer, int start, int end, @NotNull CharSequence s) {
final int len = s.length();
if (offset + len > bufferEnd) return false;
if (offset < 0) return false;
if (start + len > end) return false;
if (start < 0) return false;
for (int i = 0; i < len; i++) {
if (buffer[offset + i] != s.charAt(i)) return false;
if (buffer[start + i] != s.charAt(i)) return false;
}
return true;
}
public static boolean regionMatches(@NotNull CharSequence buffer, int offset, int bufferEnd, @NotNull CharSequence s) {
public static boolean regionMatches(@NotNull CharSequence buffer, int start, int end, @NotNull CharSequence s) {
final int len = s.length();
if (offset + len > bufferEnd) return false;
if (offset < 0) return false;
if (start + len > end) return false;
if (start < 0) return false;
//if (buffer instanceof String && s instanceof String) {
// return ((String)buffer).regionMatches(offset, (String)s, 0, len);
//}
for (int i = 0; i < len; i++) {
if (buffer.charAt(offset + i) != s.charAt(i)) return false;
if (buffer.charAt(start + i) != s.charAt(i)) return false;
}
return true;
}
public static boolean regionMatches(@NotNull CharSequence s1, int start1, int end1, @NotNull CharSequence s2, int start2, int end2) {
if (end1-start1 != end2-start2) return false;
for (int i = start1,j=start2; i < end1; i++,j++) {
if (s1.charAt(i) != s2.charAt(j)) return false;
}
return true;
}
@@ -63,7 +63,7 @@ public class ThreeStateCheckBox extends JCheckBox {
@Override
public boolean isSelected() {
return myState == State.SELECTED;
return myState == State.SELECTED || (UIUtil.isUnderAquaLookAndFeel() && myState == State.DONT_CARE);
}
});
@@ -101,6 +101,10 @@ public class ThreeStateCheckBox extends JCheckBox {
public void setState(State state) {
myState = state;
String value = state == State.DONT_CARE ? "indeterminate" : null;
putClientProperty("JButton.selectedState", value);
repaint();
}
@@ -111,12 +115,11 @@ public class ThreeStateCheckBox extends JCheckBox {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (UIUtil.isUnderAquaLookAndFeel()) {
paintIndeterminateIcon(g);
return;
}
super.paintComponent(g);
switch (getState()) {
case DONT_CARE:
Icon icon = getIcon();
@@ -155,19 +158,4 @@ public class ThreeStateCheckBox extends JCheckBox {
break;
}
}
protected void paintIndeterminateIcon(Graphics g) {
State initial = getState();
try {
if (getState() == State.DONT_CARE) {
setSelected(true);
putClientProperty("JButton.selectedState", "indeterminate");
} else {
putClientProperty("JButton.selectedState", null);
}
super.paintComponent(g);
} finally {
setState(initial);
}
}
}
@@ -16,6 +16,9 @@
package com.intellij.util.diff;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.ThreeState;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
@@ -30,11 +33,13 @@ import java.util.List;
@SuppressWarnings({"HardCodedStringLiteral"})
public class DiffTreeTest extends TestCase {
private static class Node {
private final int myStartOffset;
@NotNull
private final Node[] myChildren;
private final int myId;
public Node(final int id, @NotNull Node... children) {
public Node(final int id, int startOffset, @NotNull Node... children) {
myStartOffset = startOffset;
myChildren = children;
myId = id;
}
@@ -55,7 +60,17 @@ public class DiffTreeTest extends TestCase {
@Override
public String toString() {
return String.valueOf(myId);
return getChildren().length == 0 ? String.valueOf(myId) : StringUtil.join(myChildren, new Function<Node, String>() {
@Override
public String fun(Node node) {
return node.toString();
}
}, "");
}
public TextRange getTextRange() {
int endOffset = myChildren.length == 0 ? myStartOffset + toString().length() : myChildren[myChildren.length-1].getTextRange().getEndOffset();
return new TextRange(myStartOffset, endOffset);
}
}
@@ -98,6 +113,16 @@ public class DiffTreeTest extends TestCase {
public CharSequence toString(@NotNull Node node) {
return node.toString();
}
@Override
public int getStartOffset(@NotNull Node node) {
return node.getTextRange().getStartOffset();
}
@Override
public int getEndOffset(@NotNull Node node) {
return node.getTextRange().getEndOffset();
}
}
private static class NodeComparator implements ShallowNodeComparator<Node, Node> {
@@ -123,17 +148,17 @@ public class DiffTreeTest extends TestCase {
@Override
public void nodeReplaced(@NotNull final Node oldNode, @NotNull final Node newNode) {
myResults.add("REPLACED: " + oldNode + " to " + newNode);
myResults.add("REPLACED: " + oldNode.getId() + " to " + newNode.getId());
}
@Override
public void nodeDeleted(@NotNull final Node parent, @NotNull final Node child) {
myResults.add("DELETED from " + parent + ": " + child);
myResults.add("DELETED from " + parent.getId() + ": " + child.getId());
}
@Override
public void nodeInserted(@NotNull final Node oldParent, @NotNull final Node node, final int pos) {
myResults.add("INSERTED to " + oldParent + ": " + node + " at " + pos);
myResults.add("INSERTED to " + oldParent.getId() + ": " + node.getId() + " at " + pos);
}
public List<String> getEvents() {
@@ -142,32 +167,32 @@ public class DiffTreeTest extends TestCase {
}
public void testEmptyEqualRoots() throws Exception {
Node r1 = new Node(0);
Node r2 = new Node(0);
Node r1 = new Node(0,0);
Node r2 = new Node(0,0);
final String expected = "";
performTest(r1, r2, expected);
}
public void testSingleChildEqualRoots() throws Exception {
Node r1 = new Node(0, new Node(1));
Node r2 = new Node(0, new Node(1));
Node r1 = new Node(0,0, new Node(1,0));
Node r2 = new Node(0,0, new Node(1,0));
final String expected = "";
performTest(r1, r2, expected);
}
public void testTheOnlyChildRemoved() throws Exception {
Node r1 = new Node(0, new Node(1));
Node r2 = new Node(0);
Node r1 = new Node(0,0, new Node(1,0));
Node r2 = new Node(0,0);
String expected = "DELETED from 0: 1";
performTest(r1, r2, expected);
}
public void testTheOnlyChildAdded() throws Exception {
Node r1 = new Node(0);
Node r2 = new Node(0, new Node(1));
Node r1 = new Node(0,0);
Node r2 = new Node(0,0, new Node(1,0));
String expected = "INSERTED to 0: 1 at 0";
performTest(r1, r2, expected);
@@ -175,56 +200,56 @@ public class DiffTreeTest extends TestCase {
}
public void testTheOnlyChildReplaced() throws Exception {
Node r1 = new Node(0, new Node(1));
Node r2 = new Node(0, new Node(2));
Node r1 = new Node(0,0, new Node(1,0));
Node r2 = new Node(0,0, new Node(2,0));
String expected = "REPLACED: 1 to 2";
performTest(r1, r2, expected);
}
public void testInsertedIntoTheMiddle() throws Exception {
Node r1 = new Node(0, new Node(1, new Node(21), new Node(23)));
Node r2 = new Node(0, new Node(1, new Node(21), new Node(22), new Node(23)));
String expected = "INSERTED to 1: 22 at 1";
Node r1 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1)));
Node r2 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(4,1), new Node(3,2)));
String expected = "INSERTED to 1: 4 at 1";
performTest(r1, r2, expected);
}
public void testInsertedFirst() throws Exception {
Node r1 = new Node(0, new Node(1, new Node(22), new Node(23)));
Node r2 = new Node(0, new Node(1, new Node(21), new Node(22), new Node(23)));
String expected = "INSERTED to 1: 21 at 0";
Node r1 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(4,1)));
Node r2 = new Node(0,0, new Node(1,0, new Node(3,0), new Node(2,1), new Node(4,2)));
String expected = "INSERTED to 1: 3 at 0";
performTest(r1, r2, expected);
}
public void testInsertedLast() throws Exception {
Node r1 = new Node(0, new Node(1, new Node(21), new Node(22)));
Node r2 = new Node(0, new Node(1, new Node(21), new Node(22), new Node(23)));
String expected = "INSERTED to 1: 23 at 2";
Node r1 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1)));
Node r2 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1), new Node(4,2)));
String expected = "INSERTED to 1: 4 at 2";
performTest(r1, r2, expected);
}
public void testInsertedTwoLast() throws Exception {
Node r1 = new Node(0, new Node(1, new Node(21), new Node(22)));
Node r2 = new Node(0, new Node(1, new Node(21), new Node(22), new Node(23), new Node(24)));
Node r1 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1)));
Node r2 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1), new Node(4,2), new Node(5,3)));
performTest(r1, r2, "INSERTED to 1: 24 at 2", "INSERTED to 1: 23 at 2");
performTest(r1, r2, "INSERTED to 1: 5 at 2", "INSERTED to 1: 4 at 2");
}
public void testSubtreeAppears() throws Exception {
Node r1 = new Node(0, new Node(1, new Node(21), new Node(22), new Node(23)));
Node r2 = new Node(0, new Node(1, new Node(21), new Node(22, new Node(221)), new Node(23)));
Node r1 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1), new Node(4,2)));
Node r2 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1, new Node(6,1)), new Node(4,2)));
performTest(r1, r2, "INSERTED to 22: 221 at 0");
performTest(r1, r2, "INSERTED to 3: 6 at 0");
}
public void testSubtreeChanges() throws Exception {
Node r1 = new Node(0, new Node(1, new Node(21), new Node(22, new Node(221)), new Node(23)));
Node r2 = new Node(0, new Node(1, new Node(21), new Node(250, new Node(222)), new Node(23)));
Node r1 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(3,1, new Node(6,1)), new Node(4,2)));
Node r2 = new Node(0,0, new Node(1,0, new Node(2,0), new Node(5,1, new Node(6,1)), new Node(4,2)));
performTest(r1, r2, "REPLACED: 22 to 250");
performTest(r1, r2, "REPLACED: 3 to 5");
}
private static void performTest(final Node r1, final Node r2, final String... expected) {
@@ -29,14 +29,15 @@ import com.intellij.openapi.diff.impl.patch.IdeaTextPatchBuilder;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsApplicationSettings;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
@@ -54,7 +55,7 @@ import java.util.List;
*/
public class CreatePatchCommitExecutor extends LocalCommitExecutor implements ProjectComponent, JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.patch.CreatePatchCommitExecutor");
private final Project myProject;
private final ChangeListManager myChangeListManager;
@@ -139,24 +140,13 @@ public class CreatePatchCommitExecutor extends LocalCommitExecutor implements Pr
myPanel.setFileName(ShelveChangesManager.suggestPatchName(myProject, commitMessage, new File(PATCH_PATH), null));
myPanel.setReversePatch(false);
boolean dvcsIsUsed = false;
if (ProjectLevelVcsManager.getInstance(myProject).dvcsUsedInProject()) {
for (Change change : changes) {
final AbstractVcs vcs = ChangesUtil.getVcsForChange(change, myProject);
if (vcs != null && VcsType.distributed.equals(vcs.getType())) {
dvcsIsUsed = true;
break;
}
myPanel.setChanges(ContainerUtil.filter(changes, new Condition<Change>() {
@Override
public boolean value(Change change) {
return change.getBeforeRevision() != null && change.getAfterRevision() != null;
}
}
final List<Change> modified = new ArrayList<Change>();
for (Change change : changes) {
if (change.getBeforeRevision() == null || change.getAfterRevision() == null) continue;
modified.add(change);
}
myPanel.setChanges(modified);
myPanel.showTextStoreOption(dvcsIsUsed);
}));
myPanel.showTextStoreOption();
return myPanel.getPanel();
}
@@ -258,7 +248,8 @@ public class CreatePatchCommitExecutor extends LocalCommitExecutor implements Pr
LOG.info(ex);
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
public void run() {
Messages.showErrorDialog(myProject, VcsBundle.message("create.patch.error.title", ex.getMessage()), CommonBundle.getErrorTitle());
Messages.showErrorDialog(myProject, VcsBundle.message("create.patch.error.title", ex.getMessage()),
CommonBundle.getErrorTitle());
}
}, null, myProject);
}
@@ -66,7 +66,6 @@ public class CreatePatchConfigurationPanel {
private JCheckBox myIncludeBaseRevisionTextCheckBox;
private Consumer<Boolean> myOkEnabledListener;
private final Project myProject;
private boolean myDvcsIsUsed;
private List<Change> myChanges;
private Collection<Change> myIncludedChanges;
private SelectFilesToAddTextsToPatchPanel mySelectFilesToAddTextsToPatchPanel;
@@ -173,8 +172,7 @@ public class CreatePatchConfigurationPanel {
myPanelWithSelectedFiles.add(myHideableTitledPanel, BorderLayout.CENTER);
}
public void showTextStoreOption(final boolean dvcsIsUsed) {
myDvcsIsUsed = dvcsIsUsed;
public void showTextStoreOption() {
if (myChanges.size() > 0) {
myIncludeBaseRevisionTextCheckBox.setVisible(true);
@@ -34,6 +34,7 @@ import com.intellij.openapi.diff.impl.patch.apply.ApplyFilePatchBase;
import com.intellij.openapi.diff.impl.patch.formove.CustomBinaryPatchApplier;
import com.intellij.openapi.diff.impl.patch.formove.PatchApplier;
import com.intellij.openapi.progress.AsynchronousExecution;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectEx;
@@ -146,6 +147,10 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
public ShelvedChangeList shelveChanges(final Collection<Change> changes, final String commitMessage, final boolean rollback)
throws IOException, VcsException {
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
if (progressIndicator != null) {
progressIndicator.setText(VcsBundle.message("shelve.changes.progress.title"));
}
final List<Change> textChanges = new ArrayList<Change>();
final List<ShelvedBinaryFile> binaryFiles = new ArrayList<ShelvedBinaryFile>();
for (Change change : changes) {
@@ -180,12 +185,15 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
patchPath, commitContext);
changeList = new ShelvedChangeList(patchPath.toString(), commitMessage.replace('\n', ' '), binaryFiles);
myShelvedChangeLists.add(changeList);
ProgressManager.checkCanceled();
myShelvedChangeLists.add(changeList);
if (rollback) {
final String operationName = UIUtil.removeMnemonic(RollbackChangesDialog.operationNameByChanges(myProject, changes));
boolean modalContext = ApplicationManager.getApplication().isDispatchThread() && LaterInvocator.isInModalContext();
if (progressIndicator != null) {
progressIndicator.startNonCancelableSection();
}
new RollbackWorker(myProject, operationName, modalContext).
doRollback(changes, true, null, VcsBundle.message("shelve.changes.action"));
}
@@ -203,13 +203,15 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
final int idx = myList.locationToIndex(e.getPoint());
if (idx >= 0) {
final Rectangle baseRect = myList.getCellBounds(idx, idx);
baseRect.setSize(checkboxWidth, baseRect.height);
if (baseRect.contains(e.getPoint())) {
toggleSelection();
return true;
if (myShowCheckboxes) {
final Rectangle baseRect = myList.getCellBounds(idx, idx);
baseRect.setSize(checkboxWidth, baseRect.height);
if (baseRect.contains(e.getPoint())) {
toggleSelection();
return true;
}
}
else if (clickCount == 2) {
if (clickCount == 2) {
myDoubleClickHandler.run();
return true;
}
@@ -228,9 +230,11 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
final int row = myTree.getRowForLocation(e.getPoint().x, e.getPoint().y);
if (row >= 0) {
final Rectangle baseRect = myTree.getRowBounds(row);
baseRect.setSize(checkboxWidth, baseRect.height);
if (baseRect.contains(e.getPoint())) return false;
if (myShowCheckboxes) {
final Rectangle baseRect = myTree.getRowBounds(row);
baseRect.setSize(checkboxWidth, baseRect.height);
if (baseRect.contains(e.getPoint())) return false;
}
}
myDoubleClickHandler.run();
@@ -24,6 +24,7 @@ import com.intellij.openapi.actionSystem.DataSink;
import com.intellij.openapi.actionSystem.TypeSafeDataProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProgressManager;
@@ -68,6 +69,7 @@ import java.util.List;
public class CommitChangeListDialog extends DialogWrapper implements CheckinProjectPanel, TypeSafeDataProvider {
private final static String outCommitHelpId = "reference.dialogs.vcs.commit";
private static final int LAYOUT_VERSION = 2;
private static final Logger LOG = Logger.getInstance(CommitChangeListDialog.class);
private final CommitContext myCommitContext;
private final CommitMessage myCommitMessageArea;
private Splitter mySplitter;
@@ -651,12 +653,13 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
return;
}
boolean isOK = true;
if (SessionDialog.createConfigurationUI(session, getIncludedChanges(), getCommitMessage())!= null) {
final JComponent configurationUI = SessionDialog.createConfigurationUI(session, getIncludedChanges(), getCommitMessage());
if (configurationUI != null) {
DialogWrapper sessionDialog = new SessionDialog(commitExecutor.getActionText(),
getProject(),
session,
getIncludedChanges(),
getCommitMessage());
getCommitMessage(), configurationUI);
isOK = sessionDialog.showAndGet();
}
if (isOK) {
@@ -692,7 +695,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
commitExecutor.getActionText());
for (CheckinHandler handler : myHandlers) {
handler.checkinFailed(Arrays.asList(new VcsException(e)));
handler.checkinFailed(Collections.singletonList(new VcsException(e)));
}
}
finally {
@@ -707,8 +710,6 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
}
}
}, commitExecutor);
}
else {
session.executionCanceled();
@@ -41,17 +41,24 @@ public class SessionDialog extends DialogWrapper {
public SessionDialog(String title, Project project,
CommitSession session, List<Change> changes,
String commitMessage) {
String commitMessage, @Nullable JComponent configurationComponent) {
super(project, true);
mySession = session;
myChanges = changes;
myCommitMessage = commitMessage;
myConfigurationComponent = createConfigurationUI(mySession, myChanges, myCommitMessage);
myConfigurationComponent =
configurationComponent == null ? createConfigurationUI(mySession, myChanges, myCommitMessage) : configurationComponent;
setTitle(CommitChangeListDialog.trimEllipsis(title));
init();
updateButtons();
}
public SessionDialog(String title, Project project,
CommitSession session, List<Change> changes,
String commitMessage) {
this(title, project, session, changes, commitMessage, null);
}
public static JComponent createConfigurationUI(final CommitSession session, final List<Change> changes, final String commitMessage) {
try {
return session.getAdditionalConfigurationUI(changes, commitMessage);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -17,6 +17,8 @@ package com.siyeh.ig.abstraction;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.intellij.util.ArrayUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -28,10 +30,10 @@ import com.siyeh.ig.ui.ExternalizableStringSet;
import org.jetbrains.annotations.NotNull;
public class PublicMethodNotExposedInInterfaceInspectionBase extends BaseInspection {
@SuppressWarnings({"PublicField"})
@SuppressWarnings("PublicField")
public final ExternalizableStringSet ignorableAnnotations =
new ExternalizableStringSet();
@SuppressWarnings({"PublicField"})
@SuppressWarnings("PublicField")
public boolean onlyWarnIfContainingClassImplementsAnInterface = false;
@Override
@@ -115,7 +117,11 @@ public class PublicMethodNotExposedInInterfaceInspectionBase extends BaseInspect
}
private boolean exposedInInterface(PsiMethod method) {
final PsiMethod[] superMethods = method.findSuperMethods();
PsiMethod[] superMethods = method.findSuperMethods();
PsiMethod siblingInherited = FindSuperElementsHelper.getSiblingInheritedViaSubClass(method);
if (siblingInherited != null && !ArrayUtil.contains(siblingInherited, superMethods)) {
superMethods = ArrayUtil.append(superMethods, siblingInherited);
}
for (final PsiMethod superMethod : superMethods) {
final PsiClass superClass = superMethod.getContainingClass();
if (superClass == null) {
@@ -18,6 +18,7 @@ package com.siyeh.ig.classlayout;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.impl.FindSuperElementsHelper;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -67,6 +68,10 @@ public class NoopMethodInAbstractClassInspection extends BaseInspection {
if (!MethodUtils.isEmpty(method)) {
return;
}
if (FindSuperElementsHelper.getSiblingInheritedViaSubClass(method) != null) {
// it may be an explicit intention to have non-abstract method here in order to sibling-inherit the method in subclass
return;
}
registerMethodError(method);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,11 +48,11 @@ public class EqualityToEqualsFix extends InspectionGadgetsFix {
@Override
public void doFix(Project project, ProblemDescriptor descriptor) {
final PsiElement comparisonToken = descriptor.getPsiElement();
final PsiBinaryExpression expression = (PsiBinaryExpression)
comparisonToken.getParent();
if (expression == null) {
final PsiElement parent = comparisonToken.getParent();
if (!(parent instanceof PsiBinaryExpression)) {
return;
}
final PsiBinaryExpression expression = (PsiBinaryExpression)parent;
boolean negated = false;
final IElementType tokenType = expression.getOperationTokenType();
if (JavaTokenType.NE.equals(tokenType)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -27,6 +27,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.FinalUtils;
import com.siyeh.ig.psiutils.PsiElementOrderComparator;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
@@ -352,6 +353,9 @@ public class TryFinallyCanBeTryWithResourcesInspection extends BaseInspection {
}
static boolean isVariableUsedOutsideContext(PsiVariable variable, PsiElement context) {
if (!FinalUtils.canBeFinal(variable)) {
return true;
}
final VariableUsedOutsideContextVisitor visitor = new VariableUsedOutsideContextVisitor(variable, context);
final PsiElement declarationScope = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
if (declarationScope == null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -17,6 +17,7 @@ package com.siyeh.ig.psiutils;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -29,10 +30,29 @@ import org.jetbrains.annotations.Nullable;
public final class DefiniteAssignmentUtil {
public static void checkVariable(PsiVariable variable, DefiniteAssignment definiteAssignment) {
if (variable.getInitializer() != null) {
throw new IllegalArgumentException("variable has initializer, check for assignment to the field");
}
if (variable instanceof PsiField) {
final PsiField field = (PsiField)variable;
checkField(field, definiteAssignment);
}
else if (variable instanceof PsiParameter) {
throw new IllegalArgumentException("parameter has implicit initializer, check for assignment to the parameter");
}
else if (variable instanceof PsiLocalVariable) {
final PsiLocalVariable localVariable = (PsiLocalVariable)variable;
final PsiElement parent = localVariable.getParent();
assert parent instanceof PsiDeclarationStatement;
PsiStatement statement = (PsiStatement)parent;
while (statement != null) {
checkStatement(statement, definiteAssignment);
statement = PsiTreeUtil.getNextSiblingOfType(statement, PsiStatement.class);
}
}
else {
assert false;
}
}
private static void checkField(PsiField field, DefiniteAssignment definiteAssignment) {
@@ -44,42 +64,22 @@ public final class DefiniteAssignmentUtil {
return;
}
final PsiElement[] children = aClass.getChildren();
if (field.hasModifierProperty(PsiModifier.STATIC)) {
for (PsiElement child : children) {
if (child instanceof PsiField) {
final PsiField otherField = (PsiField)child;
if (!otherField.hasModifierProperty(PsiModifier.STATIC)) {
continue;
}
final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
for (PsiElement child : children) {
if (child instanceof PsiField) {
final PsiField otherField = (PsiField)child;
if (otherField.hasModifierProperty(PsiModifier.STATIC) == isStatic) {
checkExpression(otherField.getInitializer(), definiteAssignment, BooleanExpressionValue.UNDEFINED);
}
else if (child instanceof PsiClassInitializer) {
final PsiClassInitializer classInitializer = (PsiClassInitializer)child;
if (!classInitializer.hasModifierProperty(PsiModifier.STATIC)) {
continue;
}
}
else if (child instanceof PsiClassInitializer) {
final PsiClassInitializer classInitializer = (PsiClassInitializer)child;
if (classInitializer.hasModifierProperty(PsiModifier.STATIC) == isStatic) {
checkCodeBlock(classInitializer.getBody(), definiteAssignment);
}
}
}
else {
for (PsiElement child : children) {
if (child instanceof PsiField) {
final PsiField otherField = (PsiField)child;
if (otherField.hasModifierProperty(PsiModifier.STATIC)) {
continue;
}
checkExpression(otherField.getInitializer(), definiteAssignment, BooleanExpressionValue.UNDEFINED);
}
else if (child instanceof PsiClassInitializer) {
final PsiClassInitializer classInitializer = (PsiClassInitializer)child;
if (classInitializer.hasModifierProperty(PsiModifier.STATIC)) {
continue;
}
checkCodeBlock(classInitializer.getBody(), definiteAssignment);
}
if (definiteAssignment.stop()) return;
}
if (!isStatic) {
final PsiMethod[] constructors = aClass.getConstructors();
if (constructors.length != 0) { // missing from spec?
final boolean da = definiteAssignment.isDefinitelyAssigned();
@@ -481,14 +481,9 @@ public final class DefiniteAssignmentUtil {
}
if (PsiType.BOOLEAN.equals(expression.getType())) {
final Object result = ExpressionUtils.computeConstantExpression(expression);
if (Boolean.TRUE == result) {
if (BooleanExpressionValue.WHEN_FALSE == value) {
definiteAssignment.set(true, true);
}
return;
}
else if (Boolean.FALSE == result) {
if (BooleanExpressionValue.WHEN_TRUE == value) {
if (result != null) {
if (Boolean.TRUE == result && BooleanExpressionValue.WHEN_FALSE == value ||
Boolean.FALSE == result && BooleanExpressionValue.WHEN_TRUE == value) {
definiteAssignment.set(true, true);
}
return;
@@ -1,5 +1,5 @@
/*
* Copyright 2009-2013 Bas Leijdekkers
* Copyright 2009-2015 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,10 @@ public class FinalUtils {
private FinalUtils() {}
public static boolean canBeFinal(@NotNull PsiVariable variable) {
if (variable.getInitializer() != null || variable instanceof PsiParameter) {
// parameters have an implicit initializer
return !VariableAccessUtils.variableIsAssigned(variable);
}
final FinalDefiniteAssignment definiteAssignment = new FinalDefiniteAssignment(variable);
DefiniteAssignmentUtil.checkVariable(variable, definiteAssignment);
return definiteAssignment.isDefinitelyAssigned() &&
@@ -16,7 +16,10 @@
package com.siyeh.ig.psiutils;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -79,6 +82,30 @@ public class VariableAccessUtils {
return visitor.isPassed();
}
public static boolean variableIsAssigned(@NotNull PsiVariable variable) {
if (variable instanceof PsiField) {
if (variable.hasModifierProperty(PsiModifier.PRIVATE)) {
final PsiClass aClass = PsiUtil.getTopLevelClass(variable);
return variableIsAssigned(variable, aClass);
}
return !ReferencesSearch.search(variable, variable.getUseScope()).forEach(new Processor<PsiReference>() {
@Override
public boolean process(PsiReference reference) {
final PsiElement element = reference.getElement();
if (!(element instanceof PsiExpression)) {
return true;
}
final PsiExpression expression = (PsiExpression)element;
return !PsiUtil.isAccessedForWriting(expression);
}
});
}
final PsiElement context =
PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class, PsiMethod.class, PsiLambdaExpression.class,
PsiCatchSection.class, PsiForStatement.class, PsiForeachStatement.class);
return variableIsAssigned(variable, context);
}
public static boolean variableIsAssigned(
@NotNull PsiVariable variable, @Nullable PsiElement context) {
if (context == null) {
@@ -1,5 +1,6 @@
package com.siyeh.igtest.migration.try_finally_can_be_try_with_resources;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -33,4 +34,19 @@ class TryFinallyCanBeTryWithResources {
stream.close();
}
}
public void write3() throws IOException {
InputStream in = true ? new FileInputStream("null") : null;
try {
byte[] magicNumber = new byte[2];
in.mark(2);
in.read(magicNumber);
in.reset();
if (false) {
in = new FileInputStream("in"); // var can't be (implicitly final) resource var, because it is reassigned here
}
} finally {
in.close();
}
}
}
@@ -886,6 +886,18 @@ class T58 {
x = 3;
}
}
class T59 {
private int i = 0;
{
assert true : i++;
}
}
class T60 {
private int i = 1;
{
if (false) i = 2;
}
}
class Foo {
public interface Accessor<T> {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -31,6 +31,9 @@ import com.intellij.cvsSupport2.cvsoperations.cvsAdd.ui.AbstractAddOptionsDialog
import com.intellij.cvsSupport2.ui.CvsTabbedWindow;
import com.intellij.cvsSupport2.ui.Options;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.actions.VcsContext;
@@ -100,14 +103,26 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
LOG.error(filesToAdd);
}
if (showDialog) {
final AbstractAddOptionsDialog dialog = AbstractAddOptionsDialog.createDialog(project, roots, dialogOptions);
if (!dialog.showAndGet()) {
return CvsHandler.NULL;
if (!showDialog) {
return CommandCvsHandler.createAddFilesHandler(project, roots);
}
final CvsHandler[] handler = new CvsHandler[1];
final Runnable runnable = new Runnable() {
@Override
public void run() {
final AbstractAddOptionsDialog dialog = AbstractAddOptionsDialog.createDialog(project, roots, dialogOptions);
handler[0] = !dialog.showAndGet() ? CvsHandler.NULL : CommandCvsHandler.createAddFilesHandler(project, roots);
}
};
final Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
runnable.run();
}
else {
application.invokeAndWait(runnable, ModalityState.any());
}
return CommandCvsHandler.createAddFilesHandler(project, roots);
return handler[0];
}
@Override
@@ -31,6 +31,8 @@ public class SettingsProviderComponent {
}
public List<OutPair> getOutPairs(Project project, String filePath) {
if (filePath == null) return Collections.emptyList();
final List<OutPair> outPairs;
try {
final Set<String> rootDirs = getRootDirs(project);
@@ -15,20 +15,16 @@
*/
package org.jetbrains.java.generate;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.codeInsight.generation.actions.BaseGenerateAction;
/**
* The IDEA action for this plugin.
* <p/>
* This action handles the generation of a <code>toString()</code> method that dumps the fields
* of the class.
*/
public class GenerateToStringAction extends EditorAction {
public class GenerateToStringAction extends BaseGenerateAction {
/**
* Constructor.
*/
public GenerateToStringAction() {
super(new GenerateToStringActionHandlerImpl()); // register our action handler
super(new GenerateToStringActionHandlerImpl());
}
}
@@ -15,16 +15,14 @@
*/
package org.jetbrains.java.generate;
import com.intellij.codeInsight.CodeInsightActionHandler;
import com.intellij.codeInsight.generation.PsiElementClassMember;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.ide.util.MemberChooser;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.ShowSettingsUtil;
@@ -56,14 +54,17 @@ import java.util.List;
/**
* The action-handler that does the code generation.
*/
public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler implements GenerateToStringActionHandler {
public class GenerateToStringActionHandlerImpl implements GenerateToStringActionHandler, CodeInsightActionHandler {
private static final Logger logger = Logger.getInstance("#GenerateToStringActionHandlerImpl");
public void executeWriteAction(Editor editor, DataContext dataContext) {
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
assert project != null;
@Override
public boolean startInWriteAction() {
return true;
}
PsiClass clazz = getSubjectClass(editor, dataContext);
@Override
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
PsiClass clazz = getSubjectClass(editor, file);
assert clazz != null;
doExecuteAction(project, clazz, editor);
@@ -145,14 +146,8 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler
return GenerationUtil.combineToClassMemberList(filteredFields, filteredMethods);
}
@Override
public boolean isEnabled(Editor editor, DataContext dataContext) {
return getSubjectClass(editor, dataContext) != null;
}
@Nullable
private static PsiClass getSubjectClass(Editor editor, DataContext dataContext) {
PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext);
private static PsiClass getSubjectClass(Editor editor, final PsiFile file) {
if (file == null) return null;
int offset = editor.getCaretModel().getOffset();
@@ -15,6 +15,10 @@
*/
package git4idea.stash;
import com.intellij.openapi.command.impl.UndoManagerImpl;
import com.intellij.openapi.command.undo.DocumentReference;
import com.intellij.openapi.command.undo.DocumentReferenceManager;
import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.AsynchronousExecution;
import com.intellij.openapi.project.Project;
@@ -25,10 +29,14 @@ import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryFile;
import com.intellij.openapi.vcs.changes.shelf.ShelvedChange;
import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.continuation.ContinuationContext;
import com.intellij.util.continuation.TaskDescriptor;
import com.intellij.util.continuation.Where;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -60,7 +68,7 @@ public class GitShelveUtils {
VirtualFile baseDir = project.getBaseDir();
assert baseDir != null;
final String projectPath = baseDir.getPath() + "/";
final List<ShelvedChange> changes = shelvedChangeList.getChanges(project);
context.next(new TaskDescriptor("Refreshing files before unshelve", Where.POOLED) {
@Override
public void run(ContinuationContext context) {
@@ -76,11 +84,36 @@ public class GitShelveUtils {
public void run(ContinuationContext context) {
LOG.info("Unshelving in UI thread. shelvedChangeList: " + shelvedChangeList);
// we pass null as target change list for Patch Applier to do NOTHING with change lists
shelveManager.scheduleUnshelveChangeList(shelvedChangeList, shelvedChangeList.getChanges(project),
shelveManager.scheduleUnshelveChangeList(shelvedChangeList, changes,
shelvedChangeList.getBinaryFiles(), null, false, context, true,
true, leftConflictTitle, rightConflictTitle);
}
}, new TaskDescriptor("", Where.AWT) {
@Override
public void run(ContinuationContext context) {
markUnshelvedFilesNonUndoable(project, changes);
}
});
}
@CalledInAwt
private static void markUnshelvedFilesNonUndoable(@NotNull final Project project,
@NotNull List<ShelvedChange> changes) {
final UndoManagerImpl undoManager = (UndoManagerImpl)UndoManager.getInstance(project);
if (undoManager != null && !changes.isEmpty()) {
ContainerUtil.process(changes, new Processor<ShelvedChange>() {
@Override
public boolean process(ShelvedChange change) {
final VirtualFile vfUnderProject = VfsUtil.findFileByIoFile(new File(project.getBasePath(), change.getAfterPath()), false);
if (vfUnderProject != null) {
final DocumentReference documentReference = DocumentReferenceManager.getInstance().create(vfUnderProject);
undoManager.nonundoableActionPerformed(documentReference, false);
undoManager.invalidateActionsFor(documentReference);
}
return true;
}
});
}
}
public static void refreshFilesBeforeUnshelve(final Project project, ShelvedChangeList shelvedChangeList, String projectPath) {
@@ -46,7 +46,7 @@ public class UploadApplicationAction extends AnAction {
public void update(AnActionEvent e) {
final Project project = e.getProject();
e.getPresentation().setEnabledAndVisible(
project != null && !ProjectFacetManager.getInstance(project).getFacets(AppEngineFacet.ID).isEmpty());
project != null && ProjectFacetManager.getInstance(project).hasFacets(AppEngineFacet.ID));
if (project != null) {
String text;
@@ -15,12 +15,12 @@
<tr>
<td valign="top"><nobr><font face="verdana" size="-2" color="#f45252"><b>${NAME}</b></font></nobr></td>
<td width="10">&nbsp;</td>
<td valign="top"><font face="verdana" size="-1">name of the created method.</font></td>
<td width="100%" valign="top"><font face="verdana" size="-1">name of the created method.</font></td>
</tr>
<tr>
<td valign="top"><nobr><font face="verdana" size="-2" color="#f45252"><b>${BODY}</b></font></nobr></td>
<td width="10">&nbsp;</td>
<td valign="top"><font face="verdana" size="-1">generated method body.</font></td>
<td width="100%" valign="top"><font face="verdana" size="-1">generated method body.</font></td>
</tr>
</table>
</body>

Some files were not shown because too many files have changed in this diff Show More