mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -333,9 +333,6 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
|
||||
String fullName = args.fullName != null ? args.fullName : p("component.names.fullname")
|
||||
|
||||
String vmOptions = "-Dfile.encoding=UTF-8 ${vmOptions()} -Xverify:none"
|
||||
if (isEap() && !args.mac_no_yjp) {
|
||||
vmOptions += " ${yjpOptions(args.system_selector)}"
|
||||
}
|
||||
|
||||
String minor = p("component.version.minor")
|
||||
String version = isEap() && !minor.contains("RC") && !minor.contains("Beta") ? "EAP $args.buildNumber" : "${p("component.version.major")}.${minor}"
|
||||
@@ -354,7 +351,11 @@ binding.setVariable("layoutMacApp", { String path, String ch, Map args ->
|
||||
}
|
||||
|
||||
new File("$path/bin/idea.properties").text = effectiveProperties.toString()
|
||||
new File("$path/bin/idea.vmoptions").text = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
|
||||
String ideaVmOptions = "$mem64 -XX:+UseCompressedOops".split(" ").join("\n")
|
||||
if (isEap() && !args.mac_no_yjp) {
|
||||
ideaVmOptions += " ${yjpOptions(args.system_selector)}"
|
||||
}
|
||||
new File("$path/bin/idea.vmoptions").text = ideaVmOptions
|
||||
|
||||
String classPath = classPathLibs.collect {"\$APP_PACKAGE/Contents/lib/${it}" }.join(":")
|
||||
|
||||
|
||||
@@ -1157,7 +1157,12 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
public ArrayReference newInstance(final ArrayType arrayType,
|
||||
final int dimension)
|
||||
throws EvaluateException {
|
||||
return arrayType.newInstance(dimension);
|
||||
try {
|
||||
return arrayType.newInstance(dimension);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -291,30 +291,37 @@ public abstract class DebuggerUtils {
|
||||
}
|
||||
|
||||
if (subType instanceof ClassType) {
|
||||
result = getSuperType(((ClassType)subType).superclass(), superType);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List ifaces = ((ClassType)subType).allInterfaces();
|
||||
for (Object iface : ifaces) {
|
||||
InterfaceType interfaceType = (InterfaceType)iface;
|
||||
if (typeEquals(interfaceType, superType)) {
|
||||
return interfaceType;
|
||||
try {
|
||||
final ClassType clsType = (ClassType)subType;
|
||||
result = getSuperType(clsType.superclass(), superType);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (InterfaceType iface : clsType.allInterfaces()) {
|
||||
if (typeEquals(iface, superType)) {
|
||||
return iface;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotPreparedException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (subType instanceof InterfaceType) {
|
||||
List ifaces = ((InterfaceType)subType).superinterfaces();
|
||||
for (Object iface : ifaces) {
|
||||
InterfaceType interfaceType = (InterfaceType)iface;
|
||||
result = getSuperType(interfaceType, superType);
|
||||
if (result != null) {
|
||||
return result;
|
||||
try {
|
||||
for (InterfaceType iface : ((InterfaceType)subType).superinterfaces()) {
|
||||
result = getSuperType(iface, superType);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotPreparedException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
else if (subType instanceof ArrayType) {
|
||||
if (superType.endsWith("[]")) {
|
||||
@@ -324,7 +331,7 @@ public abstract class DebuggerUtils {
|
||||
return instanceOf(subTypeItem, superTypeItem) ? subType : null;
|
||||
}
|
||||
catch (ClassNotLoadedException e) {
|
||||
LOG.debug(e);
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,9 +504,21 @@ public class RedundantCastUtil {
|
||||
return;
|
||||
}
|
||||
if (parent instanceof PsiForeachStatement) {
|
||||
if (InheritanceUtil.isInheritor(PsiUtil.resolveClassInType(opType), false, CommonClassNames.JAVA_LANG_ITERABLE)) {
|
||||
addToResults(typeCast);
|
||||
return;
|
||||
final PsiClassType.ClassResolveResult castResolveResult = PsiUtil.resolveGenericsClassInType(opType);
|
||||
final PsiClass psiClass = castResolveResult.getElement();
|
||||
if (psiClass != null) {
|
||||
final PsiClass iterableClass = JavaPsiFacade.getInstance(parent.getProject()).findClass(CommonClassNames.JAVA_LANG_ITERABLE, psiClass.getResolveScope());
|
||||
if (iterableClass != null && InheritanceUtil.isInheritorOrSelf(psiClass, iterableClass, true)) {
|
||||
final PsiTypeParameter[] iterableTypeParameters = iterableClass.getTypeParameters();
|
||||
if (iterableTypeParameters.length == 1) {
|
||||
final PsiType resultedParamType = TypeConversionUtil.getSuperClassSubstitutor(iterableClass, psiClass, castResolveResult.getSubstitutor()).substitute(iterableTypeParameters[0]);
|
||||
if (resultedParamType != null &&
|
||||
TypeConversionUtil.isAssignable(((PsiForeachStatement)parent).getIterationParameter().getType(), resultedParamType)) {
|
||||
addToResults(typeCast);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent instanceof PsiThrowStatement) {
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems/>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class SomeClass {
|
||||
public void test() {
|
||||
List<?> objects = new ArrayList<>();
|
||||
for (String value : (Iterable<? extends String>) objects) {
|
||||
System.out.println(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ public class RedundantCast15Test extends InspectionTestCase {
|
||||
public void testGetClassProcessing() throws Exception { doTest();}
|
||||
public void testInstanceOfChecks() throws Exception { doTest();}
|
||||
public void testForEachValue() throws Exception { doTest();}
|
||||
public void testForEachValueIDEA126166() throws Exception { doTest();}
|
||||
public void testCaseThrowable() throws Exception { doTest();}
|
||||
public void testSafeTempVarName() throws Exception { doTest();}
|
||||
|
||||
|
||||
@@ -216,6 +216,9 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
|
||||
}
|
||||
});
|
||||
SelectTemplateSettings.getInstance().setLastTemplate(null, null);
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
Thread.sleep(2000); //wait for JBCardLayout release timers
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public interface EditorColors {
|
||||
TextAttributesKey FOLDED_TEXT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("FOLDED_TEXT_ATTRIBUTES");
|
||||
TextAttributesKey DELETED_TEXT_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("DELETED_TEXT_ATTRIBUTES");
|
||||
|
||||
ColorKey GUTTER_BACKGROUND = ColorKey.createColorKey("GUTTER_BACKGROUND");
|
||||
ColorKey GUTTER_BACKGROUND = ColorKey.createColorKey("GUTTER_BACKGROUND", new JBColor(0xf0f0f0, 0x313335));
|
||||
@Deprecated ColorKey LEFT_GUTTER_BACKGROUND = GUTTER_BACKGROUND;
|
||||
ColorKey NOTIFICATION_BACKGROUND = ColorKey.createColorKey("NOTIFICATION_BACKGROUND");
|
||||
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ public final class SingleConfigurationConfigurable<Config extends RunConfigurati
|
||||
settings.setSingleton(mySingleton);
|
||||
settings.setFolderName(myFolderName);
|
||||
super.apply();
|
||||
RunManagerImpl.getInstanceImpl(getConfiguration().getProject()).fireRunConfigurationChanged(settings);
|
||||
runManager.addConfiguration(settings, myStoreProjectConfiguration, runManager.getBeforeRunTasks(settings.getConfiguration()), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -32,58 +32,48 @@ import com.intellij.psi.PsiManager;
|
||||
public class ReloadFromDiskAction extends AnAction implements DumbAware {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
DataContext dataContext = e.getDataContext();
|
||||
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
if (editor == null) return;
|
||||
final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (psiFile == null) return;
|
||||
final Project project = e.getProject();
|
||||
final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
|
||||
if (project == null || editor == null) return;
|
||||
final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (file == null) return;
|
||||
|
||||
int res = Messages.showOkCancelDialog(
|
||||
project,
|
||||
IdeBundle.message("prompt.reload.file.from.disk", psiFile.getVirtualFile().getPresentableUrl()),
|
||||
IdeBundle.message("title.reload.file"),
|
||||
Messages.getWarningIcon()
|
||||
);
|
||||
String message = IdeBundle.message("prompt.reload.file.from.disk", file.getVirtualFile().getPresentableUrl());
|
||||
int res = Messages.showOkCancelDialog(project, message, IdeBundle.message("title.reload.file"), Messages.getWarningIcon());
|
||||
if (res != Messages.OK) return;
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(
|
||||
project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PsiManager.getInstance(project).reloadFromDisk(psiFile);
|
||||
Runnable command = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!project.isDisposed()) {
|
||||
file.getVirtualFile().refresh(false, false);
|
||||
PsiManager.getInstance(project).reloadFromDisk(file);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
IdeBundle.message("command.reload.from.disk"),
|
||||
null
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(project, command, IdeBundle.message("command.reload.from.disk"), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent event){
|
||||
Presentation presentation = event.getPresentation();
|
||||
DataContext dataContext = event.getDataContext();
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (project == null){
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
if (editor == null){
|
||||
presentation.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
Document document = editor.getDocument();
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
|
||||
if (psiFile == null || psiFile.getVirtualFile() == null){
|
||||
presentation.setEnabled(false);
|
||||
public void update(AnActionEvent event) {
|
||||
boolean enabled = false;
|
||||
|
||||
Project project = event.getProject();
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(event.getDataContext());
|
||||
if (project != null && editor != null) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (file != null && file.getVirtualFile() != null) {
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
event.getPresentation().setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.actionSystem.ex.AnActionListener;
|
||||
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
@@ -155,8 +156,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
private static AtomicBoolean ourOtherKeyWasPressed = new AtomicBoolean(false);
|
||||
private static AtomicLong ourLastTimePressed = new AtomicLong(0);
|
||||
private static AtomicBoolean showAll = new AtomicBoolean(false);
|
||||
private ArrayList<VirtualFile> myAlreadyAddedFiles = new ArrayList<VirtualFile>();
|
||||
private ArrayList<AnAction> myAlreadyAddedActions = new ArrayList<AnAction>();
|
||||
private volatile ActionCallback myCurrentWorker = ActionCallback.DONE;
|
||||
private int myHistoryIndex = 0;
|
||||
boolean mySkipFocusGain = false;
|
||||
@@ -255,7 +254,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
}, null);
|
||||
}
|
||||
|
||||
private JBPopup myBalloon;
|
||||
private volatile JBPopup myBalloon;
|
||||
private int myPopupActualWidth;
|
||||
private Component myFocusOwner;
|
||||
private ChooseByNamePopup myFileChooseByName;
|
||||
@@ -497,7 +496,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
public void run() {
|
||||
if (myCalcThread != null) {
|
||||
myCalcThread.cancel();
|
||||
myCalcThread = null;
|
||||
//myCalcThread = null;
|
||||
}
|
||||
myAlarm.cancelAllRequests();
|
||||
if (myBalloon != null && !myBalloon.isDisposed() && myPopup != null && !myPopup.isDisposed()) {
|
||||
@@ -1199,9 +1198,12 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
private class CalcThread implements Runnable {
|
||||
private final Project project;
|
||||
private final String pattern;
|
||||
private ProgressIndicator myProgressIndicator = new ProgressIndicatorBase();
|
||||
private final ProgressIndicator myProgressIndicator = new ProgressIndicatorBase();
|
||||
private final ActionCallback myDone = new ActionCallback();
|
||||
private SearchListModel myListModel = new SearchListModel();
|
||||
private final SearchListModel myListModel = new SearchListModel();
|
||||
private final ArrayList<VirtualFile> myAlreadyAddedFiles = new ArrayList<VirtualFile>();
|
||||
private final ArrayList<AnAction> myAlreadyAddedActions = new ArrayList<AnAction>();
|
||||
|
||||
|
||||
public CalcThread(Project project, String pattern) {
|
||||
this.project = project;
|
||||
@@ -1293,9 +1295,10 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
protected void check() {
|
||||
myProgressIndicator.checkCanceled();
|
||||
if (myDone.isRejected()) throw new ProcessCanceledException();
|
||||
if (myBalloon == null || myBalloon.isDisposed()) throw new ProcessCanceledException();
|
||||
}
|
||||
|
||||
private void buildToolWindows(String pattern) {
|
||||
private synchronized void buildToolWindows(String pattern) {
|
||||
if (myActions == null) {
|
||||
if (myActionModel == null) {
|
||||
myActionModel = createActionModel();
|
||||
@@ -1331,7 +1334,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
});
|
||||
}
|
||||
|
||||
private void buildActionsAndSettings(String pattern) {
|
||||
private synchronized void buildActionsAndSettings(String pattern) {
|
||||
final Set<Object> actions = new HashSet<Object>();
|
||||
final Set<Object> settings = new HashSet<Object>();
|
||||
final MinusculeMatcher matcher = new MinusculeMatcher("*" +pattern, NameUtil.MatchingCaseSensitivity.NONE);
|
||||
@@ -1384,7 +1387,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
});
|
||||
}
|
||||
|
||||
private void buildFiles(final String pattern) {
|
||||
private synchronized void buildFiles(final String pattern) {
|
||||
int filesCounter = 0;
|
||||
final Set<Object> elements = new LinkedHashSet<Object>();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
|
||||
@@ -1445,7 +1448,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
}
|
||||
}
|
||||
|
||||
private void buildSymbols(final String pattern) {
|
||||
private synchronized void buildSymbols(final String pattern) {
|
||||
check();
|
||||
int symbolsCounter = 0;
|
||||
final Set<Object> elements = new LinkedHashSet<Object>();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
|
||||
@@ -1508,7 +1512,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
return null;
|
||||
}
|
||||
|
||||
private void buildRunConfigurations(String pattern) {
|
||||
private synchronized void buildRunConfigurations(String pattern) {
|
||||
final List<Object> runConfigurations = new ArrayList<Object>();
|
||||
MinusculeMatcher matcher = new MinusculeMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
|
||||
final ChooseRunConfigurationPopup.ItemWrapper[] wrappers =
|
||||
@@ -1541,7 +1545,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
|
||||
}
|
||||
|
||||
private void buildClasses(final String pattern, boolean includeLibraries) {
|
||||
private synchronized void buildClasses(final String pattern, boolean includeLibraries) {
|
||||
if (pattern.indexOf('.') != -1) {
|
||||
//todo[kb] it's not a mistake. If we search for "*.png" or "index.xml" in SearchEverywhere
|
||||
//todo[kb] we don't want to see Java classes started with Png or Xml. This approach should be reworked someday.
|
||||
@@ -1593,7 +1597,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
}
|
||||
}
|
||||
|
||||
private void buildRecentFiles(String pattern) {
|
||||
private synchronized void buildRecentFiles(String pattern) {
|
||||
final MinusculeMatcher matcher = new MinusculeMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
|
||||
final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
|
||||
final List<VirtualFile> selected = Arrays.asList(FileEditorManager.getInstance(project).getSelectedFiles());
|
||||
@@ -1626,7 +1630,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
return myProgressIndicator.isCanceled() || myDone.isRejected();
|
||||
}
|
||||
|
||||
private void buildTopHit(String pattern) {
|
||||
private synchronized void buildTopHit(String pattern) {
|
||||
final List<Object> elements = new ArrayList<Object>();
|
||||
final HistoryItem history = myHistoryItem;
|
||||
if (history != null) {
|
||||
@@ -1719,6 +1723,26 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
@Override
|
||||
public void run() {
|
||||
if (isCanceled()) return;
|
||||
|
||||
|
||||
for (Object element : elements.toArray()) {
|
||||
if (element instanceof AnAction) {
|
||||
final AnAction action = (AnAction)element;
|
||||
final AnActionEvent e = new AnActionEvent(myActionEvent.getInputEvent(),
|
||||
myActionEvent.getDataContext(),
|
||||
myActionEvent.getPlace(),
|
||||
action.getTemplatePresentation(),
|
||||
myActionEvent.getActionManager(),
|
||||
myActionEvent.getModifiers());
|
||||
ActionUtil.performDumbAwareUpdate(action, e, false);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
if (!presentation.isEnabled() || !presentation.isVisible() || StringUtil.isEmpty(presentation.getText())) {
|
||||
elements.remove(element);
|
||||
}
|
||||
if (isCanceled()) return;
|
||||
}
|
||||
}
|
||||
if (isCanceled() || elements.isEmpty()) return;
|
||||
myListModel.myTitleIndexes.topHit = myListModel.size();
|
||||
for (Object element : elements) {
|
||||
myListModel.addElement(element);
|
||||
@@ -1894,39 +1918,48 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void resetFields() {
|
||||
protected void resetFields() {
|
||||
if (myBalloon!= null) {
|
||||
myBalloon.cancel();
|
||||
myBalloon = null;
|
||||
}
|
||||
myFileModel = null;
|
||||
if (myFileChooseByName != null) {
|
||||
myFileChooseByName.close(false);
|
||||
myFileChooseByName = null;
|
||||
}
|
||||
if (myClassChooseByName != null) {
|
||||
myClassChooseByName.close(false);
|
||||
myClassChooseByName = null;
|
||||
}
|
||||
if (mySymbolsChooseByName != null) {
|
||||
mySymbolsChooseByName.close(false);
|
||||
mySymbolsChooseByName = null;
|
||||
}
|
||||
myClassModel = null;
|
||||
myActionModel = null;
|
||||
myActions = null;
|
||||
mySymbolsModel = null;
|
||||
myConfigurables.clear();
|
||||
myFocusComponent = null;
|
||||
myContextComponent = null;
|
||||
myFocusOwner = null;
|
||||
myRenderer.myProject = null;
|
||||
myCalcThread = null;
|
||||
myPopup = null;
|
||||
myHistoryIndex = 0;
|
||||
myPopupActualWidth = 0;
|
||||
myCurrentWorker = ActionCallback.DONE;
|
||||
showAll.set(false);
|
||||
myCurrentWorker.doWhenProcessed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myFileModel = null;
|
||||
if (myFileChooseByName != null) {
|
||||
myFileChooseByName.close(false);
|
||||
myFileChooseByName = null;
|
||||
}
|
||||
if (myClassChooseByName != null) {
|
||||
myClassChooseByName.close(false);
|
||||
myClassChooseByName = null;
|
||||
}
|
||||
if (mySymbolsChooseByName != null) {
|
||||
mySymbolsChooseByName.close(false);
|
||||
mySymbolsChooseByName = null;
|
||||
}
|
||||
if (myCalcThread != null) {
|
||||
synchronized (myCalcThread) {
|
||||
myClassModel = null;
|
||||
myActionModel = null;
|
||||
myActions = null;
|
||||
mySymbolsModel = null;
|
||||
myConfigurables.clear();
|
||||
myFocusComponent = null;
|
||||
myContextComponent = null;
|
||||
myFocusOwner = null;
|
||||
myRenderer.myProject = null;
|
||||
myPopup = null;
|
||||
myHistoryIndex = 0;
|
||||
myPopupActualWidth = 0;
|
||||
myCurrentWorker = ActionCallback.DONE;
|
||||
showAll.set(false);
|
||||
myCalcThread = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
mySkipFocusGain = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.ex.MarkupModelEx;
|
||||
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
|
||||
@@ -335,11 +336,15 @@ public class Bookmark implements Navigatable {
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
g.setColor(ICON_BACKGROUND_COLOR);
|
||||
g.fillRect(x, y, getIconWidth(), getIconHeight());
|
||||
g.setColor(JBColor.GRAY);
|
||||
g.drawRect(x, y, getIconWidth(), getIconHeight());
|
||||
myIcon.paintIcon(c, g, x, y);
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
try {
|
||||
Color gutterBackground = EditorColors.GUTTER_BACKGROUND.getDefaultColor();
|
||||
g2.setColor(gutterBackground);
|
||||
g2.fillRoundRect(x, y, getIconWidth(), getIconHeight(), 4, 4);
|
||||
myIcon.paintIcon(c, g2, x, y);
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -312,7 +312,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
|
||||
@Override
|
||||
@NotNull
|
||||
public String[] getNames(boolean checkBoxState) {
|
||||
final ArrayList<String> result = new ArrayList<String>();
|
||||
final LinkedHashSet<String> result = new LinkedHashSet<String>();
|
||||
result.add(INTENTIONS_KEY);
|
||||
for (AnAction action : myActionsMap.keySet()) {
|
||||
result.add(getActionId(action));
|
||||
|
||||
@@ -220,17 +220,17 @@ public class JBScrollPane extends JScrollPane {
|
||||
|
||||
if (extendViewportUnderVScrollbar) {
|
||||
viewportBounds.x = Math.min(viewportBounds.x, vsb.getX());
|
||||
viewportBounds.width = Math.max(viewportBounds.width, vsb.getX() + vsb.getWidth());
|
||||
viewportBounds.width = vsb.getX() + vsb.getWidth() - viewportBounds.x;
|
||||
}
|
||||
if (extendViewportUnderHScrollbar) {
|
||||
viewportBounds.y = Math.min(viewportBounds.y, hsb.getY());
|
||||
viewportBounds.height = Math.max(viewportBounds.height, hsb.getY() + hsb.getHeight());
|
||||
viewportBounds.height = hsb.getY() + hsb.getHeight() - viewportBounds.y;
|
||||
}
|
||||
|
||||
if (extendViewportUnderVScrollbar) {
|
||||
if (hsb != null) {
|
||||
Rectangle scrollbarBounds = hsb.getBounds();
|
||||
scrollbarBounds.width = viewportBounds.width - scrollbarBounds.x;
|
||||
scrollbarBounds.width = viewportBounds.x + viewportBounds.width - scrollbarBounds.x;
|
||||
hsb.setBounds(scrollbarBounds);
|
||||
}
|
||||
if (colHead != null) {
|
||||
@@ -244,7 +244,7 @@ public class JBScrollPane extends JScrollPane {
|
||||
if (extendViewportUnderHScrollbar) {
|
||||
if (vsb != null) {
|
||||
Rectangle scrollbarBounds = vsb.getBounds();
|
||||
scrollbarBounds.height = viewportBounds.height - scrollbarBounds.y;
|
||||
scrollbarBounds.height = viewportBounds.y + viewportBounds.height - scrollbarBounds.y;
|
||||
vsb.setBounds(scrollbarBounds);
|
||||
}
|
||||
if (rowHead != null) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.LogUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
@@ -24,13 +25,21 @@ import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.ui.EditorNotifications;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class FileChangedNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel> {
|
||||
private static final Logger LOG = Logger.getInstance(FileChangedNotificationProvider.class);
|
||||
private static final Key<EditorNotificationPanel> KEY = Key.create("file.changed.notification.panel");
|
||||
@@ -51,6 +60,23 @@ public class FileChangedNotificationProvider extends EditorNotifications.Provide
|
||||
}
|
||||
}
|
||||
}, project);
|
||||
|
||||
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(myProject);
|
||||
connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
|
||||
@Override
|
||||
public void after(@NotNull List<? extends VFileEvent> events) {
|
||||
if (!myProject.isDisposed() && !GeneralSettings.getInstance().isSyncOnFrameActivation()) {
|
||||
Set<VirtualFile> openFiles = ContainerUtil.newHashSet(FileEditorManager.getInstance(myProject).getSelectedFiles());
|
||||
EditorNotifications notifications = EditorNotifications.getInstance(myProject);
|
||||
for (VFileEvent event : events) {
|
||||
VirtualFile file = event.getFile();
|
||||
if (openFiles.contains(file)) {
|
||||
notifications.updateNotifications(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+89
-63
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide.plugins;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
@@ -73,9 +74,9 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
final MyPluginManagerColumnInfo infoColumn = new MyPluginManagerColumnInfo();
|
||||
final EnabledPluginInfo enabledColumn = new EnabledPluginInfo();
|
||||
final Spacer spacer = new Spacer();
|
||||
super.columns = SystemInfo.isMac ? new ColumnInfo[]{infoColumn, enabledColumn, spacer}
|
||||
columns = SystemInfo.isMac ? new ColumnInfo[]{infoColumn, enabledColumn, spacer}
|
||||
:new ColumnInfo[]{infoColumn, enabledColumn};
|
||||
view = new ArrayList<IdeaPluginDescriptor>(Arrays.asList(PluginManager.getPlugins()));
|
||||
view = new ArrayList<IdeaPluginDescriptor>(Arrays.asList(PluginManagerCore.getPlugins()));
|
||||
view.addAll(myInstalled);
|
||||
reset(view);
|
||||
|
||||
@@ -122,11 +123,12 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNameColumn() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void reset(final List<IdeaPluginDescriptor> list) {
|
||||
private void reset(@NotNull List<IdeaPluginDescriptor> list) {
|
||||
for (IdeaPluginDescriptor ideaPluginDescriptor : list) {
|
||||
setEnabled(ideaPluginDescriptor);
|
||||
}
|
||||
@@ -134,13 +136,16 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
updatePluginDependencies();
|
||||
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(null, "Load custom plugin repositories data...") {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
updateRepositoryPlugins();
|
||||
}
|
||||
});
|
||||
if (!ApplicationManager.getApplication().isDisposed()) {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(null, "Load custom plugin repositories data...") {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
updateRepositoryPlugins();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
SwingUtilities.invokeLater(runnable);
|
||||
@@ -168,7 +173,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
|
||||
private void setEnabled(IdeaPluginDescriptor ideaPluginDescriptor,
|
||||
final boolean enabled) {
|
||||
final Collection<String> disabledPlugins = PluginManager.getDisabledPlugins();
|
||||
final Collection<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
|
||||
final PluginId pluginId = ideaPluginDescriptor.getPluginId();
|
||||
if (!enabled && !disabledPlugins.contains(pluginId.toString())) {
|
||||
myEnabled.put(pluginId, null);
|
||||
@@ -192,37 +197,40 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
if (descriptor instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)descriptor).isDeleted()) continue;
|
||||
final Boolean enabled = myEnabled.get(pluginId);
|
||||
if (enabled == null || enabled.booleanValue()) {
|
||||
PluginManager.checkDependants(descriptor, new Function<PluginId, IdeaPluginDescriptor>() {
|
||||
@Nullable
|
||||
public IdeaPluginDescriptor fun(final PluginId pluginId) {
|
||||
return PluginManager.getPlugin(pluginId);
|
||||
}
|
||||
}, new Condition<PluginId>() {
|
||||
public boolean value(final PluginId dependantPluginId) {
|
||||
final Boolean enabled = myEnabled.get(dependantPluginId);
|
||||
if ((enabled == null && !updatedPlugins.contains(dependantPluginId)) ||
|
||||
(enabled != null && !enabled.booleanValue())) {
|
||||
Set<PluginId> required = myDependentToRequiredListMap.get(pluginId);
|
||||
if (required == null) {
|
||||
required = new HashSet<PluginId>();
|
||||
myDependentToRequiredListMap.put(pluginId, required);
|
||||
}
|
||||
PluginManagerCore.checkDependants(descriptor, new Function<PluginId, IdeaPluginDescriptor>() {
|
||||
@Override
|
||||
@Nullable
|
||||
public IdeaPluginDescriptor fun(final PluginId pluginId) {
|
||||
return PluginManager.getPlugin(pluginId);
|
||||
}
|
||||
}, new Condition<PluginId>() {
|
||||
@Override
|
||||
public boolean value(final PluginId dependantPluginId) {
|
||||
final Boolean enabled = myEnabled.get(dependantPluginId);
|
||||
if ((enabled == null && !updatedPlugins.contains(dependantPluginId)) ||
|
||||
(enabled != null && !enabled.booleanValue())) {
|
||||
Set<PluginId> required = myDependentToRequiredListMap.get(pluginId);
|
||||
if (required == null) {
|
||||
required = new HashSet<PluginId>();
|
||||
myDependentToRequiredListMap.put(pluginId, required);
|
||||
}
|
||||
|
||||
required.add(dependantPluginId);
|
||||
//return false;
|
||||
}
|
||||
required.add(dependantPluginId);
|
||||
//return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
);
|
||||
if (enabled == null && !myDependentToRequiredListMap.containsKey(pluginId) && !PluginManager.isIncompatible(descriptor)) {
|
||||
if (enabled == null && !myDependentToRequiredListMap.containsKey(pluginId) && !PluginManagerCore.isIncompatible(descriptor)) {
|
||||
myEnabled.put(pluginId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePluginsList(List<IdeaPluginDescriptor> list) {
|
||||
// For each downloadable plugin we need to know whether its counterpart
|
||||
// is already installed, and if yes compare the difference in versions:
|
||||
@@ -277,7 +285,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
installedPlugins.add(idString);
|
||||
}
|
||||
final PluginManagerUISettings updateSettings = PluginManagerUISettings.getInstance();
|
||||
if (state > 0 && !PluginManager.isIncompatible(descr) && !updatedPlugins.contains(descr.getPluginId())) {
|
||||
if (state > 0 && !PluginManagerCore.isIncompatible(descr) && !updatedPlugins.contains(descr.getPluginId())) {
|
||||
NewVersions2Plugins.put(pluginId, 1);
|
||||
if (!updateSettings.myOutdatedPlugins.contains(idString)) {
|
||||
updateSettings.myOutdatedPlugins.add(idString);
|
||||
@@ -312,6 +320,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
private void hideNotApplicablePlugins(Boolean value, final IdeaPluginDescriptor... ideaPluginDescriptors) {
|
||||
if (!value && ENABLED.equals(myEnabledFilter) || (value && DISABLED.equals(myEnabledFilter))) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (IdeaPluginDescriptor ideaPluginDescriptor : ideaPluginDescriptors) {
|
||||
view.remove(ideaPluginDescriptor);
|
||||
@@ -375,10 +384,12 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
super("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object valueOf(IdeaPluginDescriptor ideaPluginDescriptor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(final IdeaPluginDescriptor ideaPluginDescriptor) {
|
||||
return false;
|
||||
}
|
||||
@@ -389,6 +400,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
return new DefaultTableCellRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getColumnClass() {
|
||||
return Spacer.class;
|
||||
}
|
||||
@@ -400,22 +412,27 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
super(/*IdeBundle.message("plugin.manager.enable.column.title")*/"");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean valueOf(IdeaPluginDescriptor ideaPluginDescriptor) {
|
||||
return myEnabled.get(ideaPluginDescriptor.getPluginId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(final IdeaPluginDescriptor ideaPluginDescriptor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getColumnClass() {
|
||||
return Boolean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableCellEditor getEditor(final IdeaPluginDescriptor o) {
|
||||
return new BooleanTableCellEditor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableCellRenderer getRenderer(final IdeaPluginDescriptor ideaPluginDescriptor) {
|
||||
return new BooleanTableCellRenderer() {
|
||||
@Override
|
||||
@@ -430,6 +447,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(final IdeaPluginDescriptor ideaPluginDescriptor, Boolean value) {
|
||||
final PluginId currentPluginId = ideaPluginDescriptor.getPluginId();
|
||||
final Boolean enabled = myEnabled.get(currentPluginId) == null ? Boolean.FALSE : value;
|
||||
@@ -439,8 +457,10 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
hideNotApplicablePlugins(value, ideaPluginDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<IdeaPluginDescriptor> getComparator() {
|
||||
return new Comparator<IdeaPluginDescriptor>() {
|
||||
@Override
|
||||
public int compare(final IdeaPluginDescriptor o1, final IdeaPluginDescriptor o2) {
|
||||
final Boolean enabled1 = myEnabled.get(o1.getPluginId());
|
||||
final Boolean enabled2 = myEnabled.get(o2.getPluginId());
|
||||
@@ -486,34 +506,39 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
}
|
||||
|
||||
for (final IdeaPluginDescriptor ideaPluginDescriptor : descriptorsToCheckDependencies) {
|
||||
PluginManager.checkDependants(ideaPluginDescriptor, new Function<PluginId, IdeaPluginDescriptor>() {
|
||||
@Nullable
|
||||
public IdeaPluginDescriptor fun(final PluginId pluginId) {
|
||||
return PluginManager.getPlugin(pluginId);
|
||||
}
|
||||
}, new Condition<PluginId>() {
|
||||
public boolean value(final PluginId pluginId) {
|
||||
Boolean enabled = myEnabled.get(pluginId);
|
||||
if (enabled == null) {
|
||||
return false;
|
||||
}
|
||||
if (newVal && !enabled.booleanValue()) {
|
||||
deps.add(pluginId);
|
||||
}
|
||||
PluginManagerCore.checkDependants(ideaPluginDescriptor, new Function<PluginId, IdeaPluginDescriptor>() {
|
||||
@Override
|
||||
@Nullable
|
||||
public IdeaPluginDescriptor fun(final PluginId pluginId) {
|
||||
return PluginManager.getPlugin(pluginId);
|
||||
}
|
||||
}, new Condition<PluginId>() {
|
||||
@Override
|
||||
public boolean value(final PluginId pluginId) {
|
||||
Boolean enabled = myEnabled.get(pluginId);
|
||||
if (enabled == null) {
|
||||
return false;
|
||||
}
|
||||
if (newVal && !enabled.booleanValue()) {
|
||||
deps.add(pluginId);
|
||||
}
|
||||
|
||||
if (!newVal) {
|
||||
if (ideaPluginDescriptor instanceof IdeaPluginDescriptorImpl && ((IdeaPluginDescriptorImpl)ideaPluginDescriptor).isDeleted()) return true;
|
||||
final PluginId pluginDescriptorId = ideaPluginDescriptor.getPluginId();
|
||||
for (IdeaPluginDescriptor descriptor : ideaPluginDescriptors) {
|
||||
if (pluginId.equals(descriptor.getPluginId())) {
|
||||
deps.add(pluginDescriptorId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!newVal) {
|
||||
if (ideaPluginDescriptor instanceof IdeaPluginDescriptorImpl &&
|
||||
((IdeaPluginDescriptorImpl)ideaPluginDescriptor).isDeleted()) {
|
||||
return true;
|
||||
}
|
||||
final PluginId pluginDescriptorId = ideaPluginDescriptor.getPluginId();
|
||||
for (IdeaPluginDescriptor descriptor : ideaPluginDescriptors) {
|
||||
if (pluginId.equals(descriptor.getPluginId())) {
|
||||
deps.add(pluginDescriptorId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
if (!deps.isEmpty()) {
|
||||
@@ -525,6 +550,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
}, ", ");
|
||||
final Set<IdeaPluginDescriptor> pluginDependencies = new HashSet<IdeaPluginDescriptor>();
|
||||
final String listOfDependencies = StringUtil.join(deps, new Function<PluginId, String>() {
|
||||
@Override
|
||||
public String fun(final PluginId pluginId) {
|
||||
final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(pluginId);
|
||||
assert pluginDescriptor != null;
|
||||
@@ -564,13 +590,13 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
|
||||
@Override
|
||||
public Comparator<IdeaPluginDescriptor> getComparator() {
|
||||
final Comparator<IdeaPluginDescriptor> comparator = super.getColumnComparator();
|
||||
final Comparator<IdeaPluginDescriptor> comparator = getColumnComparator();
|
||||
return new Comparator<IdeaPluginDescriptor>() {
|
||||
@Override
|
||||
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
|
||||
if (isSortByStatus()) {
|
||||
final boolean incompatible1 = PluginManager.isIncompatible(o1);
|
||||
final boolean incompatible2 = PluginManager.isIncompatible(o2);
|
||||
final boolean incompatible1 = PluginManagerCore.isIncompatible(o1);
|
||||
final boolean incompatible2 = PluginManagerCore.isIncompatible(o2);
|
||||
if (incompatible1) {
|
||||
if (incompatible2) return comparator.compare(o1, o2);
|
||||
return -1;
|
||||
|
||||
@@ -90,7 +90,7 @@ public class IdeaApplication {
|
||||
}
|
||||
|
||||
if (Main.isCommandLine()) {
|
||||
new CommandLineApplication(isInternal, false, headless);
|
||||
new CommandLineApplication(isInternal, isUnitTest, headless);
|
||||
}
|
||||
else {
|
||||
Splash splash = null;
|
||||
|
||||
+7
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -106,6 +106,12 @@ public class AbbreviationManagerImpl extends AbbreviationManager implements
|
||||
final String abbrValue = abbr.getAttributeValue("name");
|
||||
if (abbrValue != null) {
|
||||
values.add(abbrValue);
|
||||
List<String> actionIds = myAbbreviation2ActionId.get(abbrValue);
|
||||
if (actionIds == null) {
|
||||
actionIds = new ArrayList<String>();
|
||||
myAbbreviation2ActionId.put(abbrValue, actionIds);
|
||||
}
|
||||
actionIds.add(actionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+186
-145
@@ -19,6 +19,7 @@ import com.intellij.BundleBase;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.diagnostic.PerformanceWatcher;
|
||||
import com.intellij.diagnostic.PluginException;
|
||||
import com.intellij.diagnostic.ThreadDumper;
|
||||
import com.intellij.ide.*;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
@@ -80,7 +81,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"})
|
||||
public class ApplicationImpl extends PlatformComponentManagerImpl implements ApplicationEx {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.application.impl.ApplicationImpl");
|
||||
private final ModalityState MODALITY_STATE_NONE = ModalityState.NON_MODAL;
|
||||
@@ -96,7 +96,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
private IApplicationStore myComponentStore;
|
||||
|
||||
private boolean myTestModeFlag;
|
||||
private final boolean myTestModeFlag;
|
||||
private final boolean myHeadlessMode;
|
||||
private final boolean myCommandLineMode;
|
||||
|
||||
@@ -107,12 +107,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
private volatile Runnable myExceptionalThreadWithReadAccessRunnable;
|
||||
|
||||
private int myInEditorPaintCounter = 0;
|
||||
private long myStartTime = 0;
|
||||
private int myInEditorPaintCounter; // EDT only
|
||||
private final long myStartTime;
|
||||
@Nullable
|
||||
private final Splash mySplash;
|
||||
private boolean myDoNotSave;
|
||||
private volatile boolean myDisposeInProgress = false;
|
||||
private volatile boolean myDisposeInProgress;
|
||||
|
||||
private final Disposable myLastDisposable = Disposer.newDisposable(); // will be disposed last
|
||||
|
||||
@@ -171,7 +171,30 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
private Boolean myActive;
|
||||
|
||||
private static final ThreadLocal<Integer> ourEdtSafe = new ThreadLocal<Integer>();
|
||||
private static final int IS_EDT_FLAG = 1<<30; // we don't mess with sign bit since we want to do arithmetic
|
||||
private static final int IS_READ_LOCK_ACQUIRED_FLAG = 1<<29;
|
||||
private static final int IS_EXCEPTIONAL_THREAD_FLAG = 1<<28;
|
||||
private static class Status {
|
||||
// higher three bits are for IS_* flags
|
||||
// lower bits are for edtSafe counter
|
||||
private int flags;
|
||||
}
|
||||
|
||||
private static final ThreadLocal<Status> status = new ThreadLocal<Status>(){
|
||||
@Override
|
||||
protected Status initialValue() {
|
||||
Status status = new Status();
|
||||
status.flags = BitUtil.set(status.flags, IS_EDT_FLAG, EventQueue.isDispatchThread());
|
||||
return status;
|
||||
}
|
||||
};
|
||||
private static Status getStatus() {
|
||||
return status.get();
|
||||
}
|
||||
private static void setReadLockAcquired(Status status, boolean acquired) {
|
||||
status.flags = BitUtil.set(status.flags, IS_READ_LOCK_ACQUIRED_FLAG, acquired);
|
||||
}
|
||||
|
||||
@NonNls private static final ModalityState ANY = new ModalityState() {
|
||||
@Override
|
||||
public boolean dominates(@NotNull ModalityState anotherState) {
|
||||
@@ -201,7 +224,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeComponent(Object component, boolean service) {
|
||||
public void initializeComponent(@NotNull Object component, boolean service) {
|
||||
getStateStore().initComponent(component, service);
|
||||
}
|
||||
|
||||
@@ -233,7 +256,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
myHeadlessMode = isHeadless;
|
||||
myCommandLineMode = isCommandLine;
|
||||
|
||||
myDoNotSave = myTestModeFlag || myHeadlessMode;
|
||||
myDoNotSave = isUnitTestMode || isHeadless;
|
||||
|
||||
loadApplicationComponents();
|
||||
|
||||
@@ -353,7 +376,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public boolean holdsReadLock() {
|
||||
return myLock.getReadHoldCount() != 0;
|
||||
return holdsReadLock(getStatus());
|
||||
}
|
||||
|
||||
private static boolean holdsReadLock(Status status) {
|
||||
return BitUtil.isSet(status.flags, IS_READ_LOCK_ACQUIRED_FLAG);
|
||||
}
|
||||
|
||||
private void loadApplicationComponents() {
|
||||
@@ -367,7 +394,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized Object createComponent(Class componentInterface) {
|
||||
protected synchronized Object createComponent(@NotNull Class componentInterface) {
|
||||
Object component = super.createComponent(componentInterface);
|
||||
if (mySplash != null) {
|
||||
mySplash.showProgress("", 0.65f + getPercentageOfComponentsLoaded() * 0.35f);
|
||||
@@ -375,6 +402,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
return component;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected MutablePicoContainer createPicoContainer() {
|
||||
return Extensions.getRootArea().getPicoContainer();
|
||||
@@ -395,10 +423,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
return myTestModeFlag;
|
||||
}
|
||||
|
||||
public void setUnitTestMode(boolean testModeFlag) {
|
||||
myTestModeFlag = testModeFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHeadlessEnvironment() {
|
||||
return myHeadlessMode;
|
||||
@@ -415,6 +439,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
return ourThreadExecutorsService.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isReadAccessAllowed()) {
|
||||
assert false : describe(Thread.currentThread());
|
||||
}
|
||||
try {
|
||||
action.run();
|
||||
}
|
||||
@@ -427,6 +454,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
finally {
|
||||
//ReflectionUtil.resetThreadLocals();
|
||||
Thread.interrupted(); // reset interrupted status
|
||||
if (isReadAccessAllowed()) {
|
||||
assert false : describe(Thread.currentThread());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -438,6 +468,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
return ourThreadExecutorsService.submit(new Callable<T>() {
|
||||
@Override
|
||||
public T call() {
|
||||
if (isReadAccessAllowed()) {
|
||||
assert false : describe(Thread.currentThread());
|
||||
}
|
||||
try {
|
||||
return action.call();
|
||||
}
|
||||
@@ -450,17 +483,22 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
finally {
|
||||
//ReflectionUtil.resetThreadLocals();
|
||||
Thread.interrupted(); // reset interrupted status
|
||||
if (isReadAccessAllowed()) {
|
||||
assert false : describe(Thread.currentThread());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Thread ourDispatchThread = null;
|
||||
|
||||
@Override
|
||||
public boolean isDispatchThread() {
|
||||
return EventQueue.isDispatchThread();
|
||||
return isDispatchThread(getStatus());
|
||||
}
|
||||
|
||||
private static boolean isDispatchThread(Status status) {
|
||||
return BitUtil.isSet(status.flags, IS_EDT_FLAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -535,7 +573,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> T getComponentFromContainer(final Class<T> interfaceClass) {
|
||||
protected <T> T getComponentFromContainer(@NotNull final Class<T> interfaceClass) {
|
||||
if (myIsFiringLoadingEvent) {
|
||||
return null;
|
||||
}
|
||||
@@ -567,13 +605,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
Disposer.dispose(myLastDisposable); // dispose it last
|
||||
}
|
||||
|
||||
private final Object lock = new Object();
|
||||
private void makeChangesVisibleToEDT() {
|
||||
synchronized (lock) {
|
||||
lock.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runProcessWithProgressSynchronously(@NotNull final Runnable process,
|
||||
@NotNull String progressTitle,
|
||||
@@ -629,7 +660,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
@Override
|
||||
public void run() {
|
||||
if (myExceptionalThreadWithReadAccessRunnable != process) {
|
||||
LOG.error("myExceptionalThreadWithReadAccessRunnable != process, process = " + myExceptionalThreadWithReadAccessRunnable);
|
||||
LOG.error("myExceptionalThreadWithReadAccessRunnable != process, process = " + myExceptionalThreadWithReadAccessRunnable);
|
||||
}
|
||||
|
||||
executeOnPooledThread(new Runnable() {
|
||||
@@ -639,9 +670,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
LOG.error("myExceptionalThreadWithReadAccessRunnable != process, process = " + myExceptionalThreadWithReadAccessRunnable);
|
||||
}
|
||||
|
||||
final boolean old = setExceptionalThreadWithReadAccessFlag(true);
|
||||
LOG.assertTrue(isReadAccessAllowed());
|
||||
setExceptionalThreadWithReadAccessFlag(true);
|
||||
try {
|
||||
LOG.assertTrue(isReadAccessAllowed());
|
||||
ProgressManager.getInstance().runProcess(process, progress);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
@@ -653,8 +684,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
setExceptionalThreadWithReadAccessFlag(old);
|
||||
makeChangesVisibleToEDT();
|
||||
setExceptionalThreadWithReadAccessFlag(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -669,7 +699,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
finally {
|
||||
myExceptionalThreadWithReadAccessRunnable = null;
|
||||
makeChangesVisibleToEDT();
|
||||
}
|
||||
|
||||
return !progress.isCanceled();
|
||||
@@ -677,12 +706,13 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public void invokeAndWait(@NotNull Runnable runnable, @NotNull ModalityState modalityState) {
|
||||
if (isDispatchThread()) {
|
||||
Status status = getStatus();
|
||||
if (isDispatchThread(status)) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isExceptionalThreadWithReadAccess() && holdsReadLock()) {
|
||||
if (!isExceptionalThreadWithReadAccess(status) && holdsReadLock(status)) {
|
||||
LOG.error("Calling invokeAndWait from read-action leads to possible deadlock.");
|
||||
}
|
||||
|
||||
@@ -712,13 +742,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
@Override
|
||||
@NotNull
|
||||
public ModalityState getDefaultModalityState() {
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
if (isDispatchThread()) {
|
||||
return getCurrentModalityState();
|
||||
}
|
||||
else {
|
||||
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
return progress == null ? getNoneModalityState() : progress.getModalityState();
|
||||
}
|
||||
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
|
||||
return progress == null ? getNoneModalityState() : progress.getModalityState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -769,7 +797,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
private static volatile boolean exiting = false;
|
||||
|
||||
public void exit(final boolean force, final boolean allowListenersToCancel, final boolean restart) {
|
||||
|
||||
if (exiting) return;
|
||||
|
||||
exiting = true;
|
||||
@@ -788,19 +815,19 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
getMessageBus().syncPublisher(AppLifecycleListener.TOPIC).appClosing();
|
||||
myDisposeInProgress = true;
|
||||
if (!doExit(allowListenersToCancel, restart)) {
|
||||
myDisposeInProgress = false;
|
||||
}
|
||||
doExit(allowListenersToCancel, restart);
|
||||
myDisposeInProgress = false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!isDispatchThread()) {
|
||||
invokeLater(runnable, ModalityState.NON_MODAL);
|
||||
}
|
||||
else {
|
||||
if (isDispatchThread()) {
|
||||
runnable.run();
|
||||
}
|
||||
} finally {
|
||||
else {
|
||||
invokeLater(runnable, ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
exiting = false;
|
||||
}
|
||||
}
|
||||
@@ -857,6 +884,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDoNotShowMessage() {
|
||||
return "Do not ask me again";
|
||||
@@ -896,13 +924,15 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public void runReadAction(@NotNull final Runnable action) {
|
||||
if (isReadAccessAllowed()) {
|
||||
Status status = getStatus();
|
||||
if (isReadAccessAllowed(status)) {
|
||||
action.run();
|
||||
}
|
||||
else {
|
||||
assertReadActionAllowed();
|
||||
assertNoPsiLock();
|
||||
try {
|
||||
myLock.readLock().lockInterruptibly();
|
||||
setReadLockAcquired(status, true);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeInterruptedException(e);
|
||||
@@ -911,70 +941,66 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
action.run();
|
||||
}
|
||||
finally {
|
||||
setReadLockAcquired(status, false);
|
||||
myLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public <T> T runReadAction(@NotNull final Computable<T> computation) {
|
||||
if (isReadAccessAllowed()) {
|
||||
Status status = getStatus();
|
||||
if (isReadAccessAllowed(status)) {
|
||||
return computation.compute();
|
||||
}
|
||||
else {
|
||||
assertReadActionAllowed();
|
||||
try {
|
||||
myLock.readLock().lockInterruptibly();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeInterruptedException(e);
|
||||
}
|
||||
try {
|
||||
return computation.compute();
|
||||
}
|
||||
finally {
|
||||
myLock.readLock().unlock();
|
||||
}
|
||||
assertNoPsiLock();
|
||||
try {
|
||||
myLock.readLock().lockInterruptibly();
|
||||
setReadLockAcquired(status, true);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeInterruptedException(e);
|
||||
}
|
||||
try {
|
||||
return computation.compute();
|
||||
}
|
||||
finally {
|
||||
setReadLockAcquired(status, false);
|
||||
myLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> T runReadAction(@NotNull ThrowableComputable<T, E> computation) throws E {
|
||||
if (isReadAccessAllowed()) {
|
||||
Status status = getStatus();
|
||||
if (isReadAccessAllowed(status)) {
|
||||
return computation.compute();
|
||||
}
|
||||
else {
|
||||
assertReadActionAllowed();
|
||||
try {
|
||||
myLock.readLock().lockInterruptibly();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeInterruptedException(e);
|
||||
}
|
||||
try {
|
||||
return computation.compute();
|
||||
}
|
||||
finally {
|
||||
myLock.readLock().unlock();
|
||||
}
|
||||
assertNoPsiLock();
|
||||
try {
|
||||
myLock.readLock().lockInterruptibly();
|
||||
setReadLockAcquired(status, true);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeInterruptedException(e);
|
||||
}
|
||||
try {
|
||||
return computation.compute();
|
||||
}
|
||||
finally {
|
||||
setReadLockAcquired(status, false);
|
||||
myLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static final ThreadLocal<Boolean> exceptionalThreadWithReadAccessFlag = new ThreadLocal<Boolean>();
|
||||
|
||||
private static boolean isExceptionalThreadWithReadAccess() {
|
||||
Boolean flag = exceptionalThreadWithReadAccessFlag.get();
|
||||
return flag == Boolean.TRUE;
|
||||
private static boolean isExceptionalThreadWithReadAccess(Status status) {
|
||||
return BitUtil.isSet(status.flags, IS_EXCEPTIONAL_THREAD_FLAG);
|
||||
}
|
||||
|
||||
public static boolean setExceptionalThreadWithReadAccessFlag(boolean flag) {
|
||||
boolean old = isExceptionalThreadWithReadAccess();
|
||||
if (flag) {
|
||||
exceptionalThreadWithReadAccessFlag.set(Boolean.TRUE);
|
||||
}
|
||||
else {
|
||||
exceptionalThreadWithReadAccessFlag.remove();
|
||||
}
|
||||
return old;
|
||||
public static void setExceptionalThreadWithReadAccessFlag(boolean flag) {
|
||||
Status status = getStatus();
|
||||
assert !isDispatchThread(status) : "exceptional thread must not be EDT";
|
||||
assert flag != isReadAccessAllowed(status) : "must not start exceptional thread from inside read action";
|
||||
status.flags = BitUtil.set(status.flags, IS_EXCEPTIONAL_THREAD_FLAG, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1012,7 +1038,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public boolean hasWriteAction(@Nullable Class<?> actionClass) {
|
||||
assertCanRunWriteAction();
|
||||
assertCanRunWriteAction(getStatus());
|
||||
|
||||
for (int i = myWriteActionsStack.size() - 1; i >= 0; i--) {
|
||||
Class action = myWriteActionsStack.get(i);
|
||||
@@ -1028,7 +1054,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
LOG.error(
|
||||
"Read access is allowed from event dispatch thread or inside read-action only" +
|
||||
" (see com.intellij.openapi.application.Application.runReadAction())",
|
||||
"Current thread: " + describe(Thread.currentThread()), "Our dispatch thread:" + describe(ourDispatchThread),
|
||||
"Current thread: " + describe(Thread.currentThread()), "; dispatch thread: " + EventQueue.isDispatchThread() +"; isDispatchThread(): "+isDispatchThread(),
|
||||
"SystemEventQueueThread: " + describe(getEventQueueThread()));
|
||||
}
|
||||
}
|
||||
@@ -1039,7 +1065,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
return o + " " + System.identityHashCode(o);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Thread getEventQueueThread() {
|
||||
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
|
||||
try {
|
||||
@@ -1047,63 +1072,63 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
method.setAccessible(true);
|
||||
return (Thread)method.invoke(eventQueue);
|
||||
}
|
||||
catch (Exception e1) {
|
||||
// ok
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadAccessAllowed() {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
return ourDispatchThread == currentThread ||
|
||||
isExceptionalThreadWithReadAccess() ||
|
||||
holdsReadLock() ||
|
||||
isDispatchThread();
|
||||
return isReadAccessAllowed(getStatus());
|
||||
}
|
||||
|
||||
private static void assertCanRunWriteAction() {
|
||||
assertIsDispatchThread("Write access is allowed from event dispatch thread only");
|
||||
private static boolean isReadAccessAllowed(Status status) {
|
||||
return (status.flags & (IS_EDT_FLAG | IS_EXCEPTIONAL_THREAD_FLAG | IS_READ_LOCK_ACQUIRED_FLAG)) != 0;
|
||||
}
|
||||
|
||||
private static void assertCanRunWriteAction(Status status) {
|
||||
assertIsDispatchThread(status, "Write access is allowed from event dispatch thread only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assertIsDispatchThread() {
|
||||
if (ShutDownTracker.isShutdownHookRunning()) return;
|
||||
Integer safeCounter = ourEdtSafe.get();
|
||||
if (safeCounter != null && safeCounter > 0) return;
|
||||
assertIsDispatchThread("Access is allowed from event dispatch thread only.");
|
||||
assertIsDispatchThread(getStatus());
|
||||
}
|
||||
|
||||
private static void assertIsDispatchThread(@NotNull String message) {
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
if (ourDispatchThread == currentThread) return;
|
||||
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
ourDispatchThread = currentThread;
|
||||
private static void assertIsDispatchThread(Status status) {
|
||||
if (isDispatchThread(status)) return;
|
||||
if (ShutDownTracker.isShutdownHookRunning()) return;
|
||||
int safeCounter = getSafeCounter(status);
|
||||
if (safeCounter == 0) {
|
||||
assertIsDispatchThread(status, "Access is allowed from event dispatch thread only.");
|
||||
}
|
||||
if (ourDispatchThread == currentThread) return;
|
||||
}
|
||||
|
||||
private static int getSafeCounter(Status status) {
|
||||
return status.flags & 0x1fffffff;
|
||||
}
|
||||
|
||||
private static void assertIsDispatchThread(Status status, @NotNull String message) {
|
||||
if (isDispatchThread(status)) return;
|
||||
LOG.error(message,
|
||||
"EventQueue.isDispatchThread()="+EventQueue.isDispatchThread(),
|
||||
"isDispatchThread()="+isDispatchThread(getStatus()),
|
||||
"Toolkit.getEventQueue()="+Toolkit.getDefaultToolkit().getSystemEventQueue(),
|
||||
"Current thread: " + describe(Thread.currentThread()),
|
||||
"Our dispatch thread:" + describe(ourDispatchThread),
|
||||
"SystemEventQueueThread: " + describe(getEventQueueThread()));
|
||||
"SystemEventQueueThread: " + describe(getEventQueueThread()) +"\n"+ ThreadDumper.dumpThreadsToString()+"\n-----------");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runEdtSafeAction(@NotNull Runnable runnable) {
|
||||
Integer value = ourEdtSafe.get();
|
||||
if (value == null) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
ourEdtSafe.set(value + 1);
|
||||
Status status = getStatus();
|
||||
LOG.assertTrue(getSafeCounter(status) < 1<<26);
|
||||
status.flags++;
|
||||
|
||||
try {
|
||||
runnable.run();
|
||||
}
|
||||
finally {
|
||||
int newValue = ourEdtSafe.get() - 1;
|
||||
ourEdtSafe.set(newValue >= 1 ? newValue : null);
|
||||
status.flags--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,19 +1136,19 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
public void assertIsDispatchThread(@Nullable final JComponent component) {
|
||||
if (component == null) return;
|
||||
|
||||
Thread curThread = Thread.currentThread();
|
||||
if (ourDispatchThread == curThread) {
|
||||
Status status = getStatus();
|
||||
if (isDispatchThread(status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(component.getClientProperty(WAS_EVER_SHOWN))) {
|
||||
assertIsDispatchThread();
|
||||
assertIsDispatchThread(status);
|
||||
}
|
||||
else {
|
||||
final JRootPane root = component.getRootPane();
|
||||
if (root != null) {
|
||||
component.putClientProperty(WAS_EVER_SHOWN, Boolean.TRUE);
|
||||
assertIsDispatchThread();
|
||||
assertIsDispatchThread(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1136,14 +1161,16 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public boolean tryRunReadAction(@NotNull Runnable action) {
|
||||
//if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
|
||||
boolean mustAcquire = !isReadAccessAllowed();
|
||||
Status status = getStatus();
|
||||
//if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
|
||||
boolean mustAcquire = !isReadAccessAllowed(status);
|
||||
|
||||
if (mustAcquire) {
|
||||
LOG.assertTrue(myTestModeFlag || !Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing readAction");
|
||||
assertNoPsiLock();
|
||||
try {
|
||||
// timed version of tryLock() respects fairness unlike the no-args method
|
||||
if (!myLock.readLock().tryLock(0, TimeUnit.MILLISECONDS)) return false;
|
||||
setReadLockAcquired(status, true);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeInterruptedException(e);
|
||||
@@ -1155,6 +1182,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
finally {
|
||||
if (mustAcquire) {
|
||||
setReadLockAcquired(status, false);
|
||||
myLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
@@ -1167,7 +1195,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
if (frame instanceof IdeFrame) {
|
||||
final IdeFrame ideFrame = (IdeFrame)frame;
|
||||
if (isActive() != active) {
|
||||
myActive = Boolean.valueOf(active);
|
||||
myActive = active;
|
||||
System.setProperty("idea.active", myActive.toString());
|
||||
ApplicationActivationListener publisher = getMessageBus().syncPublisher(ApplicationActivationListener.TOPIC);
|
||||
if (active) {
|
||||
@@ -1198,10 +1226,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
@NotNull
|
||||
@Override
|
||||
public AccessToken acquireReadActionLock() {
|
||||
Status status = getStatus();
|
||||
// if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
|
||||
if (isReadAccessAllowed()) return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
if (isReadAccessAllowed(status)) return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
|
||||
return new ReadAccessToken();
|
||||
return new ReadAccessToken(status);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1215,13 +1244,16 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
public WriteAccessToken(Class _clazz) {
|
||||
clazz = _clazz;
|
||||
assertCanRunWriteAction();
|
||||
assertCanRunWriteAction(getStatus());
|
||||
|
||||
ActivityTracker.getInstance().inc();
|
||||
fireBeforeWriteActionStart(_clazz);
|
||||
final AtomicBoolean stopped = new AtomicBoolean(false);
|
||||
|
||||
LOG.assertTrue(isWriteAccessAllowed() || !Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing writeAction");
|
||||
if (!isWriteAccessAllowed()) {
|
||||
assertNoPsiLock();
|
||||
}
|
||||
|
||||
try {
|
||||
if (!myLock.writeLock().tryLock()) {
|
||||
if (ourDumpThreadsOnLongWriteActionWaiting > 0) {
|
||||
@@ -1304,10 +1336,14 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
|
||||
private class ReadAccessToken extends AccessToken {
|
||||
private ReadAccessToken() {
|
||||
assertReadActionAllowed();
|
||||
private final Status myStatus;
|
||||
|
||||
private ReadAccessToken(Status status) {
|
||||
myStatus = status;
|
||||
assertNoPsiLock();
|
||||
try {
|
||||
myLock.readLock().lockInterruptibly();
|
||||
setReadLockAcquired(myStatus, true);
|
||||
acquired();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
@@ -1317,13 +1353,18 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
setReadLockAcquired(myStatus, false);
|
||||
myLock.readLock().unlock();
|
||||
released();
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertReadActionAllowed() {
|
||||
LOG.assertTrue(!Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing readAction");
|
||||
private final boolean myExtraChecks = isUnitTestMode();
|
||||
|
||||
private void assertNoPsiLock() {
|
||||
if (myExtraChecks) {
|
||||
LOG.assertTrue(!Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing readAction");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1334,12 +1375,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
|
||||
@Override
|
||||
public boolean isWriteAccessAllowed() {
|
||||
return myLock.writeLock().isHeldByCurrentThread();
|
||||
return myLock.isWriteLockedByCurrentThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteActionInProgress() {
|
||||
return myLock.writeLock().getHoldCount() != 0;
|
||||
return myLock.getWriteHoldCount() != 0;
|
||||
}
|
||||
|
||||
public void editorPaintStart() {
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author traff
|
||||
*/
|
||||
public interface RemoteSdkAdditionalData<T extends RemoteSdkCredentials>
|
||||
extends SdkAdditionalData, RemoteSdkProducer<T>, RemoteSdkProperties {
|
||||
extends SdkAdditionalData, RemoteSdkCredentialsProducer<T>, RemoteSdkProperties {
|
||||
void completeInitialization();
|
||||
|
||||
boolean isInitialized();
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package com.intellij.remote;
|
||||
|
||||
import com.intellij.remote.MutableRemoteCredentials;
|
||||
import com.intellij.remote.RemoteSdkProperties;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import com.intellij.util.Consumer;
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public interface RemoteSdkProducer<T extends RemoteSdkCredentials> {
|
||||
public interface RemoteSdkCredentialsProducer<T extends RemoteSdkCredentials> {
|
||||
/**
|
||||
* Synchronously returns remote sdk credentials
|
||||
* @return
|
||||
@@ -19,13 +19,10 @@ import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.diagnostic.PerformanceWatcher;
|
||||
import com.intellij.mock.MockApplication;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.command.impl.StartMarkAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -38,14 +35,10 @@ import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSchemes;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.refactoring.rename.PsiElementRenameHandler;
|
||||
import com.intellij.refactoring.rename.RenameHandler;
|
||||
import com.intellij.refactoring.rename.RenameHandlerRegistry;
|
||||
import com.intellij.refactoring.rename.inplace.InplaceRefactoring;
|
||||
import com.intellij.rt.execution.junit.FileComparisonFailure;
|
||||
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
|
||||
@@ -64,6 +57,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Assert;
|
||||
|
||||
import javax.swing.Timer;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -75,6 +69,9 @@ import java.lang.reflect.Modifier;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.DelayQueue;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -178,13 +175,14 @@ public abstract class UsefulTestCase extends TestCase {
|
||||
private static final Set<String> DELETE_ON_EXIT_HOOK_DOT_FILES;
|
||||
private static final Class DELETE_ON_EXIT_HOOK_CLASS;
|
||||
static {
|
||||
Class<?> aClass = null;
|
||||
Set<String> files = null;
|
||||
Class<?> aClass;
|
||||
try {
|
||||
aClass = Class.forName("java.io.DeleteOnExitHook");
|
||||
files = ReflectionUtil.getField(aClass, null, Set.class, "files");
|
||||
}
|
||||
catch (Exception ignored) { }
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Set<String> files = ReflectionUtil.getField(aClass, null, Set.class, "files");
|
||||
DELETE_ON_EXIT_HOOK_CLASS = aClass;
|
||||
DELETE_ON_EXIT_HOOK_DOT_FILES = files;
|
||||
}
|
||||
@@ -777,26 +775,51 @@ public abstract class UsefulTestCase extends TestCase {
|
||||
}
|
||||
|
||||
protected static void checkAllTimersAreDisposed() {
|
||||
Field firstTimerF;
|
||||
Object timerQueue;
|
||||
Object timer;
|
||||
try {
|
||||
Class<?> aClass = Class.forName("javax.swing.TimerQueue");
|
||||
Class<?> TimerQueueC = Class.forName("javax.swing.TimerQueue");
|
||||
Method sharedInstance = TimerQueueC.getDeclaredMethod("sharedInstance");
|
||||
sharedInstance.setAccessible(true);
|
||||
|
||||
Method inst = aClass.getDeclaredMethod("sharedInstance");
|
||||
inst.setAccessible(true);
|
||||
Object queue = inst.invoke(null);
|
||||
Field field = aClass.getDeclaredField("firstTimer");
|
||||
field.setAccessible(true);
|
||||
Object firstTimer = field.get(queue);
|
||||
if (firstTimer != null) {
|
||||
try {
|
||||
fail("Not disposed Timer: " + firstTimer.toString() + "; queue:" + queue);
|
||||
}
|
||||
finally {
|
||||
field.set(queue, null);
|
||||
}
|
||||
firstTimerF = ReflectionUtil.getDeclaredField(TimerQueueC, "firstTimer");
|
||||
timerQueue = sharedInstance.invoke(null);
|
||||
if (firstTimerF == null) {
|
||||
// jdk 8
|
||||
DelayQueue delayQueue = ReflectionUtil.getField(TimerQueueC, timerQueue, DelayQueue.class, "queue");
|
||||
timer = delayQueue.peek();
|
||||
}
|
||||
else {
|
||||
// ancient jdk
|
||||
firstTimerF.setAccessible(true);
|
||||
timer = firstTimerF.get(timerQueue);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
// Ignore
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (timer != null) {
|
||||
if (firstTimerF != null) {
|
||||
ReflectionUtil.resetField(timerQueue, firstTimerF);
|
||||
}
|
||||
String text = "";
|
||||
if (timer instanceof Delayed) {
|
||||
long delay = ((Delayed)timer).getDelay(TimeUnit.MILLISECONDS);
|
||||
text = "(delayed for "+delay+"ms)";
|
||||
Method getTimer = ReflectionUtil.getDeclaredMethod(timer.getClass(), "getTimer");
|
||||
getTimer.setAccessible(true);
|
||||
try {
|
||||
timer = getTimer.invoke(timer);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
Timer t = (Timer)timer;
|
||||
text = "Timer (listeners: "+Arrays.asList(t.getActionListeners()) + ") "+text;
|
||||
|
||||
fail("Not disposed Timer: " + text + "; queue:" + timerQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -886,12 +909,11 @@ public abstract class UsefulTestCase extends TestCase {
|
||||
while (aClass != null && aClass != Object.class) {
|
||||
if (aClass.getAnnotation(annotationClass) != null) return true;
|
||||
if (!methodChecked) {
|
||||
try {
|
||||
Method method = aClass.getDeclaredMethod(methodName);
|
||||
Method method = ReflectionUtil.getDeclaredMethod(aClass, methodName);
|
||||
if (method != null) {
|
||||
if (method.getAnnotation(annotationClass) != null) return true;
|
||||
methodChecked = true;
|
||||
}
|
||||
catch (NoSuchMethodException ignored) { }
|
||||
}
|
||||
aClass = aClass.getSuperclass();
|
||||
}
|
||||
|
||||
@@ -101,12 +101,12 @@ public class StringUtil extends StringUtilRt {
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static String replace(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @Nullable String newS) {
|
||||
public static String replace(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @NotNull String newS) {
|
||||
return replace(text, oldS, newS, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String replaceIgnoreCase(@NotNull String text, @NotNull String oldS, @Nullable String newS) {
|
||||
public static String replaceIgnoreCase(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @NotNull String newS) {
|
||||
return replace(text, oldS, newS, true);
|
||||
}
|
||||
|
||||
@@ -139,23 +139,20 @@ public class StringUtil extends StringUtilRt {
|
||||
return newBuffer == null ? buffer : newBuffer.toString();
|
||||
}
|
||||
|
||||
public static String replace(@NotNull final String text, @NotNull final String oldS, @Nullable final String newS, boolean ignoreCase) {
|
||||
public static String replace(@NonNls @NotNull final String text, @NonNls @NotNull final String oldS, @NonNls @NotNull final String newS, final boolean ignoreCase) {
|
||||
if (text.length() < oldS.length()) return text;
|
||||
|
||||
final String text1 = ignoreCase ? text.toLowerCase() : text;
|
||||
final String oldS1 = ignoreCase ? oldS.toLowerCase() : oldS;
|
||||
StringBuilder newText = null;
|
||||
int i = 0;
|
||||
|
||||
while (i < text1.length()) {
|
||||
int i1 = text1.indexOf(oldS1, i);
|
||||
while (i < text.length()) {
|
||||
final int i1 = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
|
||||
if (i1 < 0) {
|
||||
if (i == 0) return text;
|
||||
newText.append(text, i, text.length());
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (newS == null) return null;
|
||||
if (newText == null) newText = new StringBuilder(text.length() - i);
|
||||
newText.append(text, i, i1);
|
||||
newText.append(newS);
|
||||
|
||||
@@ -272,6 +272,16 @@ public class ReflectionUtil {
|
||||
return findMethod(getClassDeclaredMethods(aClass, false), name, parameters);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Field getDeclaredField(@NotNull Class aClass, @NonNls @NotNull final String name) {
|
||||
return processFields(aClass, new Condition<Field>() {
|
||||
@Override
|
||||
public boolean value(Field field) {
|
||||
return name.equals(field.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static List<Method> getClassPublicMethods(@NotNull Class aClass) {
|
||||
return getClassPublicMethods(aClass, false);
|
||||
}
|
||||
@@ -284,11 +294,17 @@ public class ReflectionUtil {
|
||||
public static List<Method> getClassDeclaredMethods(@NotNull Class aClass) {
|
||||
return getClassDeclaredMethods(aClass, false);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static List<Method> getClassDeclaredMethods(@NotNull Class aClass, boolean includeSynthetic) {
|
||||
Method[] methods = aClass.getDeclaredMethods();
|
||||
return includeSynthetic ? Arrays.asList(methods) : filterRealMethods(methods);
|
||||
}
|
||||
@NotNull
|
||||
public static List<Field> getClassDeclaredFields(@NotNull Class aClass) {
|
||||
Field[] fields = aClass.getDeclaredFields();
|
||||
return Arrays.asList(fields);
|
||||
}
|
||||
|
||||
private static List<Method> filterRealMethods(Method[] methods) {
|
||||
List<Method> result = ContainerUtil.newArrayList();
|
||||
|
||||
+7
-7
@@ -62,7 +62,7 @@ public class ConvertToNestedIfIntention extends Intention {
|
||||
if (returnValue == null || ErrorUtil.containsDeepError(returnValue)) {
|
||||
return;
|
||||
}
|
||||
final String newStatementText = buildIf(returnValue, new StringBuilder()).toString();
|
||||
final String newStatementText = buildIf(returnValue, true, new StringBuilder()).toString();
|
||||
final Project project = returnStatement.getProject();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
final PsiBlockStatement blockStatement = (PsiBlockStatement)elementFactory.createStatementFromText("{" + newStatementText + "}", returnStatement);
|
||||
@@ -73,23 +73,23 @@ public class ConvertToNestedIfIntention extends Intention {
|
||||
PsiReplacementUtil.replaceStatement(returnStatement, "return false;");
|
||||
}
|
||||
|
||||
private static StringBuilder buildIf(@Nullable PsiExpression expression, StringBuilder out) {
|
||||
private static StringBuilder buildIf(@Nullable PsiExpression expression, boolean top, StringBuilder out) {
|
||||
if (expression instanceof PsiPolyadicExpression) {
|
||||
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
|
||||
final PsiExpression[] operands = polyadicExpression.getOperands();
|
||||
final IElementType tokenType = polyadicExpression.getOperationTokenType();
|
||||
if (JavaTokenType.ANDAND.equals(tokenType)) {
|
||||
for (PsiExpression operand : operands) {
|
||||
buildIf(operand, out);
|
||||
buildIf(operand, false, out);
|
||||
}
|
||||
if (!StringUtil.endsWith(out, "return true;")) {
|
||||
if (top && !StringUtil.endsWith(out, "return true;")) {
|
||||
out.append("return true;");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
else if (JavaTokenType.OROR.equals(tokenType)) {
|
||||
else if (top && JavaTokenType.OROR.equals(tokenType)) {
|
||||
for (PsiExpression operand : operands) {
|
||||
buildIf(operand, out);
|
||||
buildIf(operand, false, out);
|
||||
if (!StringUtil.endsWith(out, "return true;")) {
|
||||
out.append("return true;");
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public class ConvertToNestedIfIntention extends Intention {
|
||||
}
|
||||
else if (expression instanceof PsiParenthesizedExpression) {
|
||||
final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression;
|
||||
buildIf(parenthesizedExpression.getExpression(), out);
|
||||
buildIf(parenthesizedExpression.getExpression(), top, out);
|
||||
return out;
|
||||
}
|
||||
if (expression != null) {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.siyeh.ipp.trivialif.convert_to_nested_if;
|
||||
|
||||
public class X {
|
||||
boolean f(boolean a, boolean b, boolean c, boolean d) {
|
||||
return a |<caret>| (b && c) || d;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.siyeh.ipp.trivialif.convert_to_nested_if;
|
||||
|
||||
public class X {
|
||||
boolean f(boolean a, boolean b, boolean c, boolean d) {
|
||||
if (a) return true;
|
||||
if (b) if (c) return true;
|
||||
if (d) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.siyeh.ipp.trivialif.convert_to_nested_if;
|
||||
|
||||
public class X {
|
||||
boolean f(boolean a, boolean b, boolean c, boolean d) {
|
||||
return a &<caret>& (b || c) && d;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.siyeh.ipp.trivialif.convert_to_nested_if;
|
||||
|
||||
public class X {
|
||||
boolean f(boolean a, boolean b, boolean c, boolean d) {
|
||||
if (a) if (b || c) if (d) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.siyeh.ipp.trivialif.convert_to_nested_if;
|
||||
|
||||
public class X {
|
||||
public static boolean foo(double a, double b, double c)
|
||||
{
|
||||
// the following return statement is converted by "Convert to multiple 'ifs'" (on the second &&) to the below, incorrect if-then-else
|
||||
return (a > c && a < b) &<caret>& !bar1(a) && !bar2(a);
|
||||
}
|
||||
|
||||
private static boolean bar1(double a)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean bar2(double a)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.siyeh.ipp.trivialif.convert_to_nested_if;
|
||||
|
||||
public class X {
|
||||
public static boolean foo(double a, double b, double c)
|
||||
{
|
||||
// the following return statement is converted by "Convert to multiple 'ifs'" (on the second &&) to the below, incorrect if-then-else
|
||||
if (a > c) if (a < b) if (!bar1(a)) if (!bar2(a)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean bar1(double a)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean bar2(double a)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+3
@@ -22,6 +22,9 @@ public class ConvertToNestedIfIntentionTest extends IPPTestCase {
|
||||
|
||||
public void testNested() { doTest(); }
|
||||
public void testStaircase() { doTest(); }
|
||||
public void testStaircaseWithParenthesis() { doTest(); }
|
||||
public void testStaircaseWithOrInside() { doTest(); }
|
||||
public void testOrStaircaseInside() { doTest(); }
|
||||
public void testOneLevelStaircase() { assertIntentionNotAvailable(); }
|
||||
|
||||
public void testAndOrMixed() { doTest(); }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,7 +48,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Collects information to push and performs the push.
|
||||
@@ -478,9 +478,7 @@ public final class GitPusher {
|
||||
// and don't show the dialog again if user has chosen not to ask again
|
||||
updateSettings = readUpdateSettings();
|
||||
if (!mySettings.autoUpdateIfPushRejected()) {
|
||||
final GitRejectedPushUpdateDialog dialog = new GitRejectedPushUpdateDialog(myProject, rejectedPushesForCurrentBranch.keySet(), updateSettings);
|
||||
final int exitCode = showDialogAndGetExitCode(dialog);
|
||||
updateSettings = new UpdateSettings(dialog.shouldUpdateAll(), getUpdateMethodFromDialogExitCode(exitCode));
|
||||
updateSettings = showDialogAndGetExitCode(rejectedPushesForCurrentBranch, updateSettings);
|
||||
saveUpdateSettings(updateSettings);
|
||||
}
|
||||
}
|
||||
@@ -519,20 +517,23 @@ public final class GitPusher {
|
||||
return new UpdateSettings(updateAllRoots, updateMethod);
|
||||
}
|
||||
|
||||
private int showDialogAndGetExitCode(@NotNull final GitRejectedPushUpdateDialog dialog) {
|
||||
final AtomicInteger exitCode = new AtomicInteger();
|
||||
private UpdateSettings showDialogAndGetExitCode(final Map<GitRepository, GitBranch> rejectedPushesForCurrentBranch,
|
||||
final UpdateSettings initialSettings) {
|
||||
final AtomicReference<UpdateSettings> updateSettings = new AtomicReference<UpdateSettings>();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final GitRejectedPushUpdateDialog dialog = new GitRejectedPushUpdateDialog(myProject, rejectedPushesForCurrentBranch.keySet(), initialSettings);
|
||||
dialog.show();
|
||||
exitCode.set(dialog.getExitCode());
|
||||
}
|
||||
final int exitCode = dialog.getExitCode();
|
||||
if (exitCode != DialogWrapper.CANCEL_EXIT_CODE) {
|
||||
mySettings.setAutoUpdateIfPushRejected(dialog.shouldAutoUpdateInFuture());
|
||||
}
|
||||
updateSettings.set(new UpdateSettings(dialog.shouldUpdateAll(), getUpdateMethodFromDialogExitCode(exitCode)));
|
||||
|
||||
}
|
||||
});
|
||||
int code = exitCode.get();
|
||||
if (code != DialogWrapper.CANCEL_EXIT_CODE) {
|
||||
mySettings.setAutoUpdateIfPushRejected(dialog.shouldAutoUpdateInFuture());
|
||||
}
|
||||
return code;
|
||||
return updateSettings.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -254,18 +254,29 @@ public class GithubCreateGistAction extends DumbAwareAction {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<FileContent> getContentFromFile(@NotNull VirtualFile file, @NotNull Project project, @Nullable String prefix) {
|
||||
private static List<FileContent> getContentFromFile(@NotNull final VirtualFile file, @NotNull Project project, @Nullable String prefix) {
|
||||
if (file.isDirectory()) {
|
||||
return getContentFromDirectory(file, project, prefix);
|
||||
}
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
String content;
|
||||
if (document != null) {
|
||||
content = document.getText();
|
||||
}
|
||||
else {
|
||||
content = readFile(file);
|
||||
}
|
||||
String content = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String compute() {
|
||||
try {
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document != null) {
|
||||
return document.getText();
|
||||
}
|
||||
else {
|
||||
return new String(file.contentsToByteArray(), file.getCharset());
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info("Couldn't read contents of the file " + file, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (content == null) {
|
||||
GithubNotifications.showWarning(project, FAILED_TO_CREATE_GIST, "Couldn't read the contents of the file " + file);
|
||||
return Collections.emptyList();
|
||||
@@ -289,23 +300,6 @@ public class GithubCreateGistAction extends DumbAwareAction {
|
||||
return contents;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String readFile(@NotNull final VirtualFile file) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public String compute() {
|
||||
try {
|
||||
return new String(file.contentsToByteArray(), file.getCharset());
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info("Couldn't read contents of the file " + file, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String addPrefix(@NotNull String name, @Nullable String prefix, boolean addTrailingSlash) {
|
||||
String pref = prefix == null ? "" : prefix;
|
||||
pref += name;
|
||||
|
||||
+12
-1
@@ -84,6 +84,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
|
||||
private final StructureViewComponent myStructureViewComponent;
|
||||
private final Map<PropertiesFile, Editor> myEditors;
|
||||
private String myOldPropertyName;
|
||||
private final ResourceBundle myResourceBundle;
|
||||
private final Map<PropertiesFile, JPanel> myTitledPanels;
|
||||
private final JComponent myNoPropertySelectedPanel = new NoPropertySelectedPanel().getComponent();
|
||||
@@ -271,7 +272,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
|
||||
private void writeEditorPropertyValue(final Editor editor, final PropertiesFile propertiesFile) {
|
||||
final String currentValue = editor.getDocument().getText();
|
||||
final String selectedProperty = getSelectedPropertyName();
|
||||
final String currentSelectedProperty = getSelectedPropertyName();
|
||||
final String selectedProperty = myOldPropertyName == null ? currentSelectedProperty : myOldPropertyName;
|
||||
|
||||
assert selectedProperty != null;
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -505,10 +508,18 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
}
|
||||
private void selectionChanged() {
|
||||
myBackSlashPressed.clear();
|
||||
final String currentSelectedPropertyName = getSelectedPropertyName();
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myOldPropertyName != null && !myOldPropertyName.equals(currentSelectedPropertyName)) {
|
||||
for (final Map.Entry<PropertiesFile, Editor> entry : myEditors.entrySet()) {
|
||||
writeEditorPropertyValue(entry.getValue(), entry.getKey());
|
||||
}
|
||||
}
|
||||
updateEditorsFromProperties();
|
||||
myOldPropertyName = currentSelectedPropertyName;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public layoutCommunity(String classesPath, Set usedJars) {
|
||||
String tarRoot = isEap() ? "pycharm-community-$buildNumber" : "pycharm-community-${p("component.version.major")}.${p("component.version.minor")}"
|
||||
buildTarGz(tarRoot, "$paths.artifacts/pycharmPC-${buildNumber}.tar", [paths.distAll, paths.distUnix])
|
||||
|
||||
String macAppRoot = isEap() ? "PyCharm CE ${p("component.version.major")}.${p("component.version.minor")} EAP.app" : "PyCharm CE.app"
|
||||
String macAppRoot = isEap() ? "PyCharm CE ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm CE.app/Contents"
|
||||
buildMacZip(macAppRoot, "${paths.artifacts}/pycharmPC-${buildNumber}.sit", [paths.distAll], paths.distMac)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user