Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-06-16 20:22:34 +02:00
38 changed files with 711 additions and 430 deletions
+5 -4
View File
@@ -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) {
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems/>
@@ -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");
@@ -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
@@ -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;
@@ -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);
}
}
}
@@ -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
*/
@@ -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();
@@ -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) {
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
@@ -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;
}
});
}
+1 -1
View File
@@ -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)
}