From 9a77627c092218575aca90ac0f94b2f47a33496c Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 13 Jun 2012 15:15:27 +0200 Subject: [PATCH 001/100] VcsConnectionProblem --- .../openapi/vcs/VcsConnectionProblem.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java new file mode 100644 index 000000000000..e0cbee87416a --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.vcs; + +import java.util.Collection; + +/** + * @author peter + */ +public class VcsConnectionProblem extends VcsException { + public VcsConnectionProblem(String message) { + super(message); + } + + public VcsConnectionProblem(Throwable throwable, boolean isWarning) { + super(throwable, isWarning); + } + + public VcsConnectionProblem(Throwable throwable) { + super(throwable); + } + + public VcsConnectionProblem(String message, Throwable cause) { + super(message, cause); + } + + public VcsConnectionProblem(String message, boolean isWarning) { + super(message, isWarning); + } + + public VcsConnectionProblem(Collection messages) { + super(messages); + } +} From 38ceb42d6810aec7b5ef0e4775379812c30b6ce1 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 13 Jun 2012 17:02:44 +0200 Subject: [PATCH 002/100] show the whole error trace --- .../src/com/intellij/openapi/command/WriteCommandAction.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java b/platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java index 87a47e9cc75a..5f0a4b030a80 100644 --- a/platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java +++ b/platform/lang-api/src/com/intellij/openapi/command/WriteCommandAction.java @@ -85,9 +85,7 @@ public abstract class WriteCommandAction extends BaseActionRunnable { } } catch (Throwable e) { if (e instanceof InvocationTargetException) e = e.getCause(); - if (e instanceof Error) throw (Error)e; - if (e instanceof RuntimeException) throw (RuntimeException)e; - throw new Error(e); + throw new RuntimeException(e); } return result; } From d23b574b2669fde81f973f81e52c0c2f08012ed9 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 13 Jun 2012 18:03:36 +0200 Subject: [PATCH 003/100] com.intellij.openapi.vfs.VfsUtilCore.virtualToIoFiles --- .../src/com/intellij/openapi/vfs/VfsUtilCore.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index ad4d1e5454a0..bf6674308a6a 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -17,7 +17,9 @@ package com.intellij.openapi.vfs; import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.Function; import com.intellij.util.PathUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,6 +27,7 @@ import org.jetbrains.annotations.Nullable; import java.io.*; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; public class VfsUtilCore { @@ -238,4 +241,13 @@ public class VfsUtilCore { public static String pathToUrl(@NonNls @NotNull String path) { return VirtualFileManager.constructUrl(StandardFileSystems.FILE_PROTOCOL, path); } + + public static List virtualToIoFiles(Collection scope) { + return ContainerUtil.map2List(scope, new Function() { + @Override + public File fun(VirtualFile file) { + return virtualToIoFile(file); + } + }); + } } From b88bb2aec2965d6d0504f6c5086c697d67526a2c Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 13 Jun 2012 21:27:09 +0200 Subject: [PATCH 004/100] handle inability to login to p4 (IDEA-48151) --- .../openapi/vcs/impl/GenericNotifierImpl.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java index 1eb2f2347d47..aa1691b5e005 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -94,17 +95,11 @@ public abstract class GenericNotifierImpl { } private void expireNotification(final MyNotification notification) { - final Application application = ApplicationManager.getApplication(); - final Runnable runnable = new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { notification.expire(); } - }; - if (application.isDispatchThread()) { - runnable.run(); - } else { - application.invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed()); - } + }); } public boolean ensureNotify(final T obj) { From 45d9a2b75cbaad0715ba211756d7cd82f18292e9 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 13 Jun 2012 21:52:54 +0200 Subject: [PATCH 005/100] no Notification.toString is needed --- .../openapi/vcs/impl/GenericNotifierImpl.java | 20 +++++++------------ .../idea/svn/SvnAuthenticationNotifier.java | 6 ------ .../svn/SvnProxyAuthenticationNotifier.java | 6 ------ 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java index aa1691b5e005..1988c07b85d0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java @@ -58,9 +58,6 @@ public abstract class GenericNotifierImpl { @NotNull protected abstract String getNotificationContent(final T obj); - @NotNull - protected abstract String getToString(final T obj); - protected Collection getAllCurrentKeys() { synchronized (myLock) { return new ArrayList(myState.keySet()); @@ -109,7 +106,7 @@ public abstract class GenericNotifierImpl { if (myState.containsKey(key)) { return false; } - notification = new MyNotification(myGroupId, myTitle, getNotificationContent(obj), myType, myListener, obj, getToString(obj)); + notification = new MyNotification(myGroupId, myTitle, getNotificationContent(obj), myType, myListener, obj); myState.put(key, notification); } final boolean state = onFirstNotification(obj); @@ -180,24 +177,21 @@ public abstract class GenericNotifierImpl { protected static class MyNotification extends Notification { private final T myObj; - private final String myStringPresentation; - protected MyNotification(@NotNull String groupId, @NotNull String title, @NotNull String content, @NotNull NotificationType type, @Nullable NotificationListener listener, - @NotNull final T obj, - final String stringPresentation) { + protected MyNotification(@NotNull String groupId, + @NotNull String title, + @NotNull String content, + @NotNull NotificationType type, + @Nullable NotificationListener listener, + @NotNull final T obj) { super(groupId, title, content, type, listener); myObj = obj; - myStringPresentation = stringPresentation; } public T getObj() { return myObj; } - @Override - public String toString() { - return myStringPresentation; - } } private static void log(final String s) { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java index 53dcac7c99c1..70fff2d294f6 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java @@ -233,12 +233,6 @@ public class SvnAuthenticationNotifier extends GenericNotifierImplClick to fix. Not logged In to Subversion '" + obj.getRealm() + "' (" + obj.getUrl().toDecodedString() + ")"; } - @NotNull - @Override - protected String getToString(AuthenticationRequest obj) { - return "Click to fix. Not logged In to Subversion '" + obj.getRealm() + "' (" + obj.getUrl().toDecodedString() + ")"; - } - public static class AuthenticationRequest { private final Project myProject; private final String myKind; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxyAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxyAuthenticationNotifier.java index 9c7f77018367..e949b4aae8f7 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxyAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxyAuthenticationNotifier.java @@ -43,10 +43,4 @@ public class SvnProxyAuthenticationNotifier extends GenericNotifierImpl Date: Thu, 14 Jun 2012 12:06:38 +0200 Subject: [PATCH 006/100] VcsConnectionProblem.attemptQuickFix --- .../openapi/vcs/VcsConnectionProblem.java | 22 ++----------------- .../vcs/changes/ChangeListManagerImpl.java | 10 ++++++++- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java index e0cbee87416a..949ef8ea78fc 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConnectionProblem.java @@ -15,8 +15,6 @@ */ package com.intellij.openapi.vcs; -import java.util.Collection; - /** * @author peter */ @@ -25,23 +23,7 @@ public class VcsConnectionProblem extends VcsException { super(message); } - public VcsConnectionProblem(Throwable throwable, boolean isWarning) { - super(throwable, isWarning); - } - - public VcsConnectionProblem(Throwable throwable) { - super(throwable); - } - - public VcsConnectionProblem(String message, Throwable cause) { - super(message, cause); - } - - public VcsConnectionProblem(String message, boolean isWarning) { - super(message, isWarning); - } - - public VcsConnectionProblem(Collection messages) { - super(messages); + public boolean attemptQuickFix(boolean mayDisplayDialogs) { + return false; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 0345b050d32b..edc2b566f351 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -625,8 +625,16 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec builder.setCurrent(scope, foldersCutDownWorker); changeProvider.getChanges(scope, builder, myUpdateChangesProgressIndicator, gate); } - catch (VcsException e) { + catch (final VcsException e) { LOG.info(e); + if (e instanceof VcsConnectionProblem) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + ((VcsConnectionProblem)e).attemptQuickFix(false); + } + }); + } if (myUpdateException == null) { if (ApplicationManager.getApplication().isUnitTestMode()) { e.printStackTrace(); From 1daf8b46e04c12c1ee429c2b7afd65f6fcccc1ec Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 14 Jun 2012 20:23:16 +0400 Subject: [PATCH 007/100] Fixed double click in tree views. Consuming events now really matters --- .../src/com/intellij/ui/AutoScrollToSourceHandler.java | 4 ++-- .../openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java b/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java index dea05dd95ecb..9c66a0d9bb57 100644 --- a/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java +++ b/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java @@ -60,7 +60,7 @@ public abstract class AutoScrollToSourceHandler { TreePath location = tree.getPathForLocation(e.getPoint().x, e.getPoint().y); if (location != null) { onMouseClicked(tree); - return true; + return isAutoScrollMode(); } return false; @@ -91,7 +91,7 @@ public abstract class AutoScrollToSourceHandler { Component location = table.getComponentAt(e.getPoint()); if (location != null) { onMouseClicked(table); - return true; + return isAutoScrollMode(); } return false; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java index 595b5d2dd84b..9b91ea49d7bf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java @@ -31,7 +31,6 @@ public abstract class LinkMouseListenerBase extends ClickListener implements Mou if (e.getButton() == 1) { Object tag = getTagAt(e); handleTagClick(tag, e); - return true; } return false; } From fb2cc0edd72860430a87011fc80991560bfdcc6d Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Thu, 14 Jun 2012 21:08:03 +0400 Subject: [PATCH 008/100] Palette --- .../android-designer/src/META-INF/plugin.xml | 2 - .../componentTree/AndroidTreeDecorator.java | 4 +- .../AndroidDesignerEditorPanel.java | 27 +--- .../palette/ViewsPaletteProvider.java | 46 ------ .../ui-designer-new/src/META-INF/plugin.xml | 6 +- .../designSurface/DesignerEditorPanel.java | 46 ++---- .../intellij/designer/model/MetaManager.java | 19 ++- .../intellij/designer/model/MetaModel.java | 8 +- .../palette/AbstractPaletteProvider.java | 61 -------- .../{Item.java => DefaultPaletteItem.java} | 34 +--- .../com/intellij/designer/palette/Group.java | 73 --------- .../PaletteContainer.java | 2 +- .../{palette2 => palette}/PaletteGroup.java | 2 +- .../PaletteGroupComponent.java | 5 +- .../{palette2 => palette}/PaletteItem.java | 2 +- .../PaletteItemsComponent.java | 77 +++++++++- .../designer/palette/PalettePanel.java | 145 ++++++++++++++++++ .../PaletteToolWindowManager.java | 8 +- .../designer/palette2/PalettePanel.java | 69 --------- 19 files changed, 265 insertions(+), 371 deletions(-) delete mode 100644 plugins/android-designer/src/com/intellij/android/designer/palette/ViewsPaletteProvider.java delete mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/AbstractPaletteProvider.java rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/{Item.java => DefaultPaletteItem.java} (58%) delete mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Group.java rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/{palette2 => palette}/PaletteContainer.java (98%) rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/{palette2 => palette}/PaletteGroup.java (96%) rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/{palette2 => palette}/PaletteGroupComponent.java (97%) rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/{palette2 => palette}/PaletteItem.java (94%) rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/{palette2 => palette}/PaletteItemsComponent.java (70%) create mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java rename plugins/ui-designer/ui-designer-new/src/com/intellij/designer/{palette2 => palette}/PaletteToolWindowManager.java (92%) delete mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PalettePanel.java diff --git a/plugins/android-designer/src/META-INF/plugin.xml b/plugins/android-designer/src/META-INF/plugin.xml index 79c31c21e215..17837831aa63 100644 --- a/plugins/android-designer/src/META-INF/plugin.xml +++ b/plugins/android-designer/src/META-INF/plugin.xml @@ -20,8 +20,6 @@ - - diff --git a/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java b/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java index af6196f8fac0..635579b6909c 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java +++ b/plugins/android-designer/src/com/intellij/android/designer/componentTree/AndroidTreeDecorator.java @@ -21,7 +21,7 @@ import com.intellij.designer.componentTree.TreeComponentDecorator; import com.intellij.designer.model.IComponentDecorator; import com.intellij.designer.model.MetaModel; import com.intellij.designer.model.RadComponent; -import com.intellij.designer.palette.Item; +import com.intellij.designer.palette.DefaultPaletteItem; import com.intellij.designer.propertyTable.Property; import com.intellij.designer.propertyTable.PropertyTable; import com.intellij.openapi.util.text.StringUtil; @@ -46,7 +46,7 @@ public final class AndroidTreeDecorator implements TreeComponentDecorator { } StringBuilder fullTitle = new StringBuilder(); - Item item = metaModel.getPaletteItem(); + DefaultPaletteItem item = metaModel.getPaletteItem(); if (item != null) { fullTitle.append(item.getTitle()); } diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java index 6acfa7bb3cde..20032b5eb9ad 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java @@ -32,11 +32,10 @@ import com.intellij.designer.designSurface.OperationContext; import com.intellij.designer.designSurface.selection.NonResizeSelectionDecorator; import com.intellij.designer.designSurface.tools.ComponentCreationFactory; import com.intellij.designer.designSurface.tools.ComponentPasteFactory; -import com.intellij.designer.model.MetaManager; import com.intellij.designer.model.RadComponent; -import com.intellij.designer.palette.Item; -import com.intellij.designer.palette2.PaletteGroup; -import com.intellij.ide.palette.PaletteItem; +import com.intellij.designer.palette.DefaultPaletteItem; +import com.intellij.designer.palette.PaletteGroup; +import com.intellij.designer.palette.PaletteItem; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.module.Module; @@ -62,7 +61,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; import java.util.List; /** @@ -446,32 +444,19 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { return null; } - private List myPaletteGroups; - @Override public List getPaletteGroups() { - if (myPaletteGroups == null) { - myPaletteGroups = new ArrayList(); - MetaManager metaManager = ViewsMetaManager.getInstance(getProject()); - for (com.intellij.ide.palette.PaletteGroup group : metaManager.getPaletteGroups()) { - PaletteGroup newGroup = new PaletteGroup(group.getName()); - for (PaletteItem item : group.getItems()) { - newGroup.addItem((com.intellij.designer.palette2.PaletteItem)item); - } - myPaletteGroups.add(newGroup); - } - } - return myPaletteGroups; + return ViewsMetaManager.getInstance(getProject()).getPaletteGroups(); } @Override @NotNull - protected ComponentCreationFactory createCreationFactory(final Item paletteItem) { + protected ComponentCreationFactory createCreationFactory(final PaletteItem paletteItem) { return new ComponentCreationFactory() { @NotNull @Override public RadComponent create() throws Exception { - RadViewComponent component = ModelParser.createComponent(null, paletteItem.getMetaModel()); + RadViewComponent component = ModelParser.createComponent(null, ((DefaultPaletteItem)paletteItem).getMetaModel()); if (component instanceof IConfigurableComponent) { ((IConfigurableComponent)component).configure(myRootComponent); } diff --git a/plugins/android-designer/src/com/intellij/android/designer/palette/ViewsPaletteProvider.java b/plugins/android-designer/src/com/intellij/android/designer/palette/ViewsPaletteProvider.java deleted file mode 100644 index a2cee8d4ca5a..000000000000 --- a/plugins/android-designer/src/com/intellij/android/designer/palette/ViewsPaletteProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.android.designer.palette; - -import com.intellij.android.designer.AndroidDesignerEditorProvider; -import com.intellij.android.designer.model.ViewsMetaManager; -import com.intellij.designer.DesignerToolWindowManager; -import com.intellij.designer.model.MetaManager; -import com.intellij.designer.palette.AbstractPaletteProvider; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; - -/** - * @author Alexander Lobas - */ -public class ViewsPaletteProvider extends AbstractPaletteProvider { - private final Project myProject; - - public ViewsPaletteProvider(Project project) { - myProject = project; - } - - @Override - protected boolean accept(VirtualFile virtualFile) { - return AndroidDesignerEditorProvider.acceptLayout(myProject, virtualFile) && - DesignerToolWindowManager.getInstance(myProject).getActiveDesigner() != null; - } - - @Override - protected MetaManager getMetaManager() { - return ViewsMetaManager.getInstance(myProject); - } -} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml index 95581745aef9..4c98e602a95f 100644 --- a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml +++ b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml @@ -12,9 +12,9 @@ com.intellij.designer.DesignerToolWindowManager - + + com.intellij.designer.palette.PaletteToolWindowManager + diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java index 963c35edd47d..7102c3e2ceb6 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java @@ -23,14 +23,13 @@ import com.intellij.designer.componentTree.TreeComponentDecorator; import com.intellij.designer.designSurface.tools.*; import com.intellij.designer.model.FindComponentVisitor; import com.intellij.designer.model.RadComponent; -import com.intellij.designer.palette.Item; -import com.intellij.designer.palette2.PaletteGroup; -import com.intellij.designer.palette2.PaletteItem; +import com.intellij.designer.palette.PaletteGroup; +import com.intellij.designer.palette.PaletteItem; +import com.intellij.designer.palette.PaletteToolWindowManager; import com.intellij.designer.propertyTable.InplaceContext; import com.intellij.designer.propertyTable.Property; import com.intellij.diagnostic.LogMessageEx; import com.intellij.diagnostic.errordialog.Attachment; -import com.intellij.ide.palette.impl.PaletteManager; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.DataProvider; @@ -61,8 +60,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; import java.awt.*; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -107,7 +104,6 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider private FeedbackLayer myFeedbackLayer; private InplaceEditingLayer myInplaceEditingLayer; - private ListSelectionListener myPaletteListener; protected ToolProvider myToolProvider; protected EditableArea mySurfaceArea; @@ -207,21 +203,6 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider } }; - myPaletteListener = new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - if (DesignerToolWindowManager.getInstance(getProject()).getActiveDesigner() == DesignerEditorPanel.this) { - Item paletteItem = (Item)PaletteManager.getInstance(getProject()).getActiveItem(); - if (paletteItem != null) { - myToolProvider.setActiveTool(new CreationTool(true, createCreationFactory(paletteItem))); - } - else if (myToolProvider.getActiveTool() instanceof CreationTool) { - myToolProvider.loadDefaultTool(); - } - } - } - }; - myToolProvider = new ToolProvider() { @Override public void loadDefaultTool() { @@ -231,7 +212,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider @Override public void setActiveTool(InputTool tool) { if (getActiveTool() instanceof CreationTool && !(tool instanceof CreationTool)) { - PaletteManager.getInstance(getProject()).clearActiveItem(); + PaletteToolWindowManager.getInstance(getProject()).clearActiveItem(); } if (!(tool instanceof SelectionTool)) { hideInspections(); @@ -327,8 +308,6 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider myDesignerCard.add(content); add(myDesignerCard, DESIGNER_CARD); - PaletteManager.getInstance(getProject()).addSelectionListener(myPaletteListener); - mySourceSelectionListener = new ComponentSelectionListener() { @Override public void selectionChanged(EditableArea area) { @@ -338,8 +317,13 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider mySurfaceArea.addSelectionListener(mySourceSelectionListener); } - public void activatePaletteItem(@Nullable PaletteItem item) { - // XXX + public final void activatePaletteItem(@Nullable PaletteItem paletteItem) { + if (paletteItem != null) { + myToolProvider.setActiveTool(new CreationTool(true, createCreationFactory(paletteItem))); + } + else if (myToolProvider.getActiveTool() instanceof CreationTool) { + myToolProvider.loadDefaultTool(); + } } protected final void showDesignerCard() { @@ -697,13 +681,10 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider protected abstract void execute(List operations); - public List getPaletteGroups() { - // XXX - return null; - } + public abstract List getPaletteGroups(); @NotNull - protected abstract ComponentCreationFactory createCreationFactory(Item paletteItem); + protected abstract ComponentCreationFactory createCreationFactory(PaletteItem paletteItem); @Nullable public abstract ComponentPasteFactory createPasteFactory(String xmlComponents); @@ -731,7 +712,6 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider } public void dispose() { - PaletteManager.getInstance(getProject()).removeSelectionListener(myPaletteListener); Disposer.dispose(myProgressIcon); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java index 5a7666d275fc..792e5b0bbc83 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java @@ -15,9 +15,8 @@ */ package com.intellij.designer.model; -import com.intellij.designer.palette.Group; -import com.intellij.designer.palette.Item; -import com.intellij.ide.palette.PaletteGroup; +import com.intellij.designer.palette.DefaultPaletteItem; +import com.intellij.designer.palette.PaletteGroup; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; @@ -49,7 +48,7 @@ public abstract class MetaManager { private final Map myTag2Model = new HashMap(); private final Map myTarget2Model = new HashMap(); - private final List myPaletteGroups = new ArrayList(); + private final List myPaletteGroups = new ArrayList(); private PropertyChangeSupport myPaletteChangeSupport; @@ -71,7 +70,7 @@ public abstract class MetaManager { } for (Object element : rootElement.getChild(PALETTE).getChildren(GROUP)) { - loadGroup(name, (Element)element); + loadGroup((Element)element); } for (Map.Entry> entry : modelToMorphing.entrySet()) { @@ -122,7 +121,7 @@ public abstract class MetaManager { Element palette = element.getChild("palette"); if (palette != null) { meta.setPaletteItem( - new Item(palette.getAttributeValue("title"), palette.getAttributeValue("icon"), palette.getAttributeValue("tooltip"))); + new DefaultPaletteItem(palette.getAttributeValue("title"), palette.getAttributeValue("icon"), palette.getAttributeValue("tooltip"))); } Element creation = element.getChild("creation"); @@ -177,8 +176,8 @@ public abstract class MetaManager { } } - private void loadGroup(String tab, Element element) throws Exception { - Group group = new Group(tab, element.getAttributeValue(NAME)); + private void loadGroup(Element element) throws Exception { + PaletteGroup group = new PaletteGroup(element.getAttributeValue(NAME)); for (Object child : element.getChildren(ITEM)) { String tag = ((Element)child).getAttributeValue(TAG); @@ -207,8 +206,8 @@ public abstract class MetaManager { return myTarget2Model.get(target); } - public PaletteGroup[] getPaletteGroups() { - return myPaletteGroups.toArray(new PaletteGroup[myPaletteGroups.size()]); + public List getPaletteGroups() { + return myPaletteGroups; } public void setPaletteChangeSupport(PropertyChangeSupport paletteChangeSupport) { diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java index 81844aad55ef..15769877d2a2 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaModel.java @@ -15,7 +15,7 @@ */ package com.intellij.designer.model; -import com.intellij.designer.palette.Item; +import com.intellij.designer.palette.DefaultPaletteItem; import com.intellij.designer.propertyTable.IPropertyDecorator; import com.intellij.designer.propertyTable.Property; import com.intellij.openapi.util.IconLoader; @@ -33,7 +33,7 @@ public class MetaModel { private Class myLayout; private final String myTarget; private final String myTag; - private Item myPaletteItem; + private DefaultPaletteItem myPaletteItem; private String myTitle; private String myIconPath; private Icon myIcon; @@ -109,11 +109,11 @@ public class MetaModel { myIcon = null; } - public Item getPaletteItem() { + public DefaultPaletteItem getPaletteItem() { return myPaletteItem; } - public void setPaletteItem(@NotNull Item paletteItem) { + public void setPaletteItem(@NotNull DefaultPaletteItem paletteItem) { myPaletteItem = paletteItem; myPaletteItem.setMetaModel(this); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/AbstractPaletteProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/AbstractPaletteProvider.java deleted file mode 100644 index 53b6dccf6c6f..000000000000 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/AbstractPaletteProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.designer.palette; - -import com.intellij.designer.model.MetaManager; -import com.intellij.ide.palette.PaletteGroup; -import com.intellij.ide.palette.PaletteItemProvider; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.vfs.VirtualFile; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; - -/** - * @author Alexander Lobas - */ -public abstract class AbstractPaletteProvider implements PaletteItemProvider { - private static final Logger LOG = Logger.getInstance("#com.intellij.designer.palette.AbstractPaletteProvider"); - - private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this); - - @Override - public PaletteGroup[] getActiveGroups(VirtualFile virtualFile) { - if (accept(virtualFile)) { - MetaManager manager = getMetaManager(); - if (manager != null) { - manager.setPaletteChangeSupport(myPropertyChangeSupport); - return manager.getPaletteGroups(); - } - LOG.error("VirtualFile: " + virtualFile + " accepted but MetaManager is null"); - } - return PaletteGroup.EMPTY_ARRAY; - } - - protected abstract boolean accept(VirtualFile virtualFile); - - protected abstract MetaManager getMetaManager(); - - @Override - public void addListener(PropertyChangeListener listener) { - myPropertyChangeSupport.addPropertyChangeListener(listener); - } - - @Override - public void removeListener(PropertyChangeListener listener) { - myPropertyChangeSupport.removePropertyChangeListener(listener); - } -} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/DefaultPaletteItem.java similarity index 58% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/DefaultPaletteItem.java index f2e65797b783..2c6ee2264ada 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Item.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/DefaultPaletteItem.java @@ -16,20 +16,14 @@ package com.intellij.designer.palette; import com.intellij.designer.model.MetaModel; -import com.intellij.ide.dnd.DnDDragStartBean; -import com.intellij.ide.palette.PaletteItem; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; -import com.intellij.ui.ColoredListCellRenderer; -import com.intellij.ui.SimpleTextAttributes; import javax.swing.*; /** * @author Alexander Lobas */ -public final class Item implements PaletteItem, com.intellij.designer.palette2.PaletteItem { +public final class DefaultPaletteItem implements PaletteItem { private String myTitle; private String myIconPath; private Icon myIcon; @@ -37,16 +31,18 @@ public final class Item implements PaletteItem, com.intellij.designer.palette2.P private MetaModel myMetaModel; - public Item(String title, String iconPath, String tooltip) { + public DefaultPaletteItem(String title, String iconPath, String tooltip) { myTitle = title; myIconPath = iconPath; myTooltip = tooltip; } + @Override public String getTitle() { return myTitle; } + @Override public Icon getIcon() { if (myIcon == null) { myIcon = IconLoader.findIcon(myIconPath, myMetaModel.getModel()); @@ -59,28 +55,6 @@ public final class Item implements PaletteItem, com.intellij.designer.palette2.P return myTooltip; } - @Override - public void customizeCellRenderer(ColoredListCellRenderer cellRenderer, boolean selected, boolean hasFocus) { - cellRenderer.setIcon(getIcon()); - cellRenderer.append(myTitle, SimpleTextAttributes.REGULAR_ATTRIBUTES); - cellRenderer.setToolTipText(myTooltip); - } - - @Override - public DnDDragStartBean startDragging() { - return null; - } - - @Override - public ActionGroup getPopupActionGroup() { - return null; // TODO: Auto-generated method stub - } - - @Override - public Object getData(Project project, String dataId) { - return null; // TODO: Auto-generated method stub - } - public MetaModel getMetaModel() { return myMetaModel; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Group.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Group.java deleted file mode 100644 index d3b2f46332fa..000000000000 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/Group.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.designer.palette; - -import com.intellij.ide.palette.PaletteGroup; -import com.intellij.ide.palette.PaletteItem; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Alexander Lobas - */ -public final class Group implements PaletteGroup { - private final String myTabName; - private final String myName; - private List myItems = new ArrayList(); - - public Group(String tabName, String name) { - myTabName = tabName; - myName = name; - } - - public void addItem(@NotNull Item item) { - myItems.add(item); - } - - @Override - public PaletteItem[] getItems() { - return myItems.toArray(new PaletteItem[myItems.size()]); - } - - @Override - public String getName() { - return myName; - } - - @Override - public String getTabName() { - return myTabName; - } - - @Override - public ActionGroup getPopupActionGroup() { - return null; // TODO: Auto-generated method stub - } - - @Override - public Object getData(Project project, String dataId) { - return null; // TODO: Auto-generated method stub - } - - @Override - public void handleDrop(Project project, PaletteItem item, int index) { - // TODO: Auto-generated method stub - } -} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteContainer.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteContainer.java similarity index 98% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteContainer.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteContainer.java index 27c19709ed79..2468bde9cc51 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteContainer.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteContainer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.designer.palette2; +package com.intellij.designer.palette; import javax.swing.*; import java.awt.*; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteGroup.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteGroup.java similarity index 96% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteGroup.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteGroup.java index 544e841edd6b..cc223095fdc4 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteGroup.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteGroup.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.designer.palette2; +package com.intellij.designer.palette; import java.util.ArrayList; import java.util.List; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteGroupComponent.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteGroupComponent.java similarity index 97% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteGroupComponent.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteGroupComponent.java index 277b982d37d0..634b6006f32b 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteGroupComponent.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteGroupComponent.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.designer.palette2; +package com.intellij.designer.palette; import com.intellij.icons.AllIcons; import com.intellij.util.ui.UIUtil; @@ -28,12 +28,9 @@ import java.awt.event.KeyEvent; * @author Alexander Lobas */ public class PaletteGroupComponent extends JCheckBox { - private final PaletteGroup myGroup; private PaletteItemsComponent myItemsComponent; public PaletteGroupComponent(PaletteGroup group) { - myGroup = group; - setText(group.getName()); setSelected(true); setIcon(AllIcons.Nodes.TreeClosed); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteItem.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItem.java similarity index 94% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteItem.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItem.java index 08c38da4aa81..33f631320074 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteItem.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItem.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.designer.palette2; +package com.intellij.designer.palette; import javax.swing.*; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteItemsComponent.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java similarity index 70% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteItemsComponent.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java index 1c290a2ff5bf..61bcf90e8ec0 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteItemsComponent.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java @@ -13,21 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.designer.palette2; +package com.intellij.designer.palette; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.components.JBList; +import com.intellij.util.ui.UIUtil; import javax.swing.*; +import javax.swing.plaf.basic.BasicListUI; import java.awt.*; import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; /** * @author Alexander Lobas */ public class PaletteItemsComponent extends JBList { private final PaletteGroup myGroup; + private int myBeforeClickSelectedRow = -1; + private boolean myNeedClearSelection; + private Integer myTempWidth; public PaletteItemsComponent(PaletteGroup group) { myGroup = group; @@ -43,7 +51,8 @@ public class PaletteItemsComponent extends JBList { return myGroup.getItems().get(index); } }); - setCellRenderer(new ColoredListCellRenderer() { + + ColoredListCellRenderer renderer = new ColoredListCellRenderer() { @Override protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { clear(); @@ -52,16 +61,76 @@ public class PaletteItemsComponent extends JBList { append(item.getTitle(), SimpleTextAttributes.REGULAR_ATTRIBUTES); setToolTipText(item.getTooltip()); } - }); + }; + renderer.getIpad().left = UIUtil.getTreeLeftChildIndent(); + renderer.getIpad().right = UIUtil.getTreeRightChildIndent(); + setCellRenderer(renderer); setVisibleRowCount(0); setLayoutOrientation(HORIZONTAL_WRAP); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + myNeedClearSelection = SwingUtilities.isLeftMouseButton(e) && + myBeforeClickSelectedRow >= 0 && + locationToIndex(e.getPoint()) == myBeforeClickSelectedRow && + !UIUtil.isControlKeyDown(e) && !e.isShiftDown(); + } + + @Override + public void mouseReleased(MouseEvent e) { + if (SwingUtilities.isLeftMouseButton(e) && + myBeforeClickSelectedRow >= 0 && + locationToIndex(e.getPoint()) == myBeforeClickSelectedRow && + !UIUtil.isControlKeyDown(e) && !e.isShiftDown() && myNeedClearSelection) { + clearSelection(); + } + } + }); + initActions(); } - Integer myTempWidth; + @Override + public void updateUI() { + setUI(new BasicListUI() { + MouseListener myListener; + + @Override + protected void updateLayoutState() { + super.updateLayoutState(); + + Insets insets = list.getInsets(); + int listWidth = list.getWidth() - (insets.left + insets.right); + if (listWidth >= cellWidth) { + int columnCount = listWidth / cellWidth; + cellWidth = (columnCount == 0) ? 1 : listWidth / columnCount; + } + } + + @Override + protected void installListeners() { + addMouseListener(myListener = new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + myBeforeClickSelectedRow = list.getSelectedIndex(); + } + }); + super.installListeners(); + } + + @Override + protected void uninstallListeners() { + if (myListener != null) { + removeMouseListener(myListener); + } + super.uninstallListeners(); + } + }); + invalidate(); + } public int getWidth() { return (myTempWidth == null) ? super.getWidth() : myTempWidth.intValue(); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java new file mode 100644 index 000000000000..7ad81f93cfa8 --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java @@ -0,0 +1,145 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.designer.palette; + +import com.intellij.designer.designSurface.DesignerEditorPanel; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CustomShortcutSet; +import com.intellij.ui.ScrollPaneFactory; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Alexander Lobas + */ +public class PalettePanel extends JPanel { + private final JPanel myPaletteContainer = new PaletteContainer(); + private List myGroupComponents = Collections.emptyList(); + private List myItemsComponents = Collections.emptyList(); + private List myGroups = Collections.emptyList(); + private DesignerEditorPanel myDesigner; + private final ListSelectionListener mySelectionListener = new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent event) { + notifySelection(event); + } + }; + + public PalettePanel() { + super(new GridLayout(1, 1)); + + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myPaletteContainer); + scrollPane.setBorder(null); + add(scrollPane); + + new AnAction() { + @Override + public void actionPerformed(AnActionEvent e) { + clearActiveItem(); + } + }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), scrollPane); + } + + @Nullable + public PaletteItem getActiveItem() { + for (PaletteGroupComponent groupComponent : myGroupComponents) { + if (groupComponent.isSelected()) { + PaletteItem paletteItem = (PaletteItem)groupComponent.getItemsComponent().getSelectedValue(); + if (paletteItem != null) { + return paletteItem; + } + } + } + return null; + } + + public void clearActiveItem() { + if (getActiveItem() != null) { + for (PaletteItemsComponent itemsComponent : myItemsComponents) { + itemsComponent.clearSelection(); + } + notifySelection(null); + } + } + + public boolean isEmpty() { + return myGroups.isEmpty(); + } + + public void loadPalette(@Nullable DesignerEditorPanel designer) { + for (PaletteItemsComponent itemsComponent : myItemsComponents) { + itemsComponent.removeListSelectionListener(mySelectionListener); + } + + myDesigner = designer; + myPaletteContainer.removeAll(); + + if (designer == null) { + myGroups = Collections.emptyList(); + myGroupComponents = Collections.emptyList(); + myItemsComponents = Collections.emptyList(); + } + else { + myGroups = designer.getPaletteGroups(); + myGroupComponents = new ArrayList(); + myItemsComponents = new ArrayList(); + } + + for (PaletteGroup group : myGroups) { + PaletteGroupComponent groupComponent = new PaletteGroupComponent(group); + PaletteItemsComponent itemsComponent = new PaletteItemsComponent(group); + + groupComponent.setItemsComponent(itemsComponent); + myPaletteContainer.add(groupComponent); + myPaletteContainer.add(itemsComponent); + + myGroupComponents.add(groupComponent); + + itemsComponent.addListSelectionListener(mySelectionListener); + myItemsComponents.add(itemsComponent); + } + + myPaletteContainer.revalidate(); + } + + private void notifySelection(@Nullable ListSelectionEvent event) { + if (event != null) { + PaletteItemsComponent sourceItemsComponent = (PaletteItemsComponent)event.getSource(); + for (int i = event.getFirstIndex(); i <= event.getLastIndex(); i++) { + if (sourceItemsComponent.isSelectedIndex(i)) { + for (PaletteItemsComponent itemsComponent : myItemsComponents) { + if (itemsComponent != sourceItemsComponent) { + itemsComponent.clearSelection(); + } + } + break; + } + } + } + if (myDesigner != null) { + myDesigner.activatePaletteItem(getActiveItem()); + } + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteToolWindowManager.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteToolWindowManager.java similarity index 92% rename from plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteToolWindowManager.java rename to plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteToolWindowManager.java index 9cbf68e810cc..965cdf8c7318 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PaletteToolWindowManager.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteToolWindowManager.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.designer.palette2; +package com.intellij.designer.palette; import com.intellij.designer.AbstractToolWindowManager; import com.intellij.designer.designSurface.DesignerEditorPanel; @@ -41,17 +41,13 @@ public class PaletteToolWindowManager extends AbstractToolWindowManager { return project.getComponent(PaletteToolWindowManager.class); } - public PaletteItem getActiveItem() { - return myToolWindowPanel.getActiveItem(); - } - public void clearActiveItem() { myToolWindowPanel.clearActiveItem(); } @Override protected void initToolWindow() { - myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow("Palette2", false, ToolWindowAnchor.RIGHT, myProject, true); + myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow("Palette\t", false, ToolWindowAnchor.RIGHT, myProject, true); myToolWindow.setIcon(AllIcons.Toolwindows.ToolWindowPalette); ContentManager contentManager = myToolWindow.getContentManager(); diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PalettePanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PalettePanel.java deleted file mode 100644 index 9b6e12c64436..000000000000 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette2/PalettePanel.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.designer.palette2; - -import com.intellij.designer.designSurface.DesignerEditorPanel; -import com.intellij.ui.ScrollPaneFactory; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.awt.*; -import java.util.Collections; -import java.util.List; - -/** - * @author Alexander Lobas - */ -public class PalettePanel extends JPanel { - private final JPanel myPaletteContainer = new PaletteContainer(); - private List myGroups = Collections.emptyList(); - - public PalettePanel() { - super(new GridLayout(1, 1)); - JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myPaletteContainer); - scrollPane.setBorder(null); - add(scrollPane); - } - - public PaletteItem getActiveItem() { - // XXX - return null; - } - - public void clearActiveItem() { - // XXX - } - - public boolean isEmpty() { - return myGroups.isEmpty(); - } - - public void loadPalette(@Nullable DesignerEditorPanel designer) { - myGroups = designer.getPaletteGroups(); - myPaletteContainer.removeAll(); - - for (PaletteGroup group : myGroups) { - PaletteGroupComponent groupComponent = new PaletteGroupComponent(group); - PaletteItemsComponent itemsComponent = new PaletteItemsComponent(group); - - groupComponent.setItemsComponent(itemsComponent); - myPaletteContainer.add(groupComponent); - myPaletteContainer.add(itemsComponent); - } - - myPaletteContainer.revalidate(); - } -} \ No newline at end of file From a312c17b8e03e6023a8441579fcd16419dae1ab8 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 14 Jun 2012 21:56:41 +0400 Subject: [PATCH 009/100] IDEA-87310: Make sure backspace works for actions, where Delete is advertised as shortcut. MacBook's don't have Delete key --- .../execution/actions/ChooseRunConfigurationAction.java | 6 ++++++ .../ide/bookmarks/actions/DeleteBookmarkAction.java | 2 +- .../ide/favoritesTreeView/FavoritesTreeViewPanel.java | 2 +- .../src/com/intellij/ui/CommonActionsPanel.java | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java index 935bfcfa2627..6a092226235b 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java @@ -161,6 +161,12 @@ public class ChooseRunConfigurationAction extends AnAction { } }); + popup.registerAction("deleteConfiguration_bksp", KeyStroke.getKeyStroke("BACK_SPACE"), new AbstractAction() { + public void actionPerformed(ActionEvent e) { + popup.removeSelected(); + } + }); + final Action action0 = createNumberAction(0, popup, getDefaultExecutor()); final Action action0_ = createNumberAction(0, popup, getAlternateExecutor()); popup.registerAction("0Action", KeyStroke.getKeyStroke("0"), action0); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java index d8c1c49f2a26..385495b320a0 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java @@ -35,7 +35,7 @@ class DeleteBookmarkAction extends DumbAwareAction { super("Delete", "Delete current bookmark", AllIcons.General.Remove); myProject = project; myList = list; - registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke("DELETE")), list); + registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE", "BACK_SPACE"), list); } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java index d8aadd19df70..14836b7836b8 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java @@ -258,7 +258,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { @Override public ShortcutSet getShortcut() { - return CustomShortcutSet.fromString("DELETE"); + return CustomShortcutSet.fromString("DELETE", "BACK_SPACE"); } }).addExtraAction(new AnActionButton("Edit", AllIcons.Actions.Edit) { @Override diff --git a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java index 8b3a07447eb9..6d4b415b21c3 100644 --- a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java +++ b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java @@ -166,7 +166,7 @@ public class CommonActionsPanel extends JPanel { } removeButton.update(e); } - }.registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE"), removeButton.getContextComponent()); + }.registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE", "BACK_SPACE"), removeButton.getContextComponent()); } public void setEnabled(Buttons button, boolean enabled) { From 69f124786791eba49520e8eef83bba8137b2c2f1 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Tue, 5 Jun 2012 18:03:55 +0400 Subject: [PATCH 010/100] IDEA-86397 Delete line (Ctrl+Y) moves caret to the 1st column position Correct 'duplicate lines' processing in case of the last line --- .../intellij/openapi/editor/actions/DuplicateAction.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateAction.java index 551d8efcc8d9..9bd2213b8559 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DuplicateAction.java @@ -85,8 +85,10 @@ public class DuplicateAction extends EditorAction { final int lineToCheck = nextLineStart.line - 1; int newOffset = end + offset - start; - if(lineToCheck == document.getLineCount () /*empty document*/ || - document.getLineSeparatorLength(lineToCheck) == 0) { + if(lineToCheck == document.getLineCount () /* empty document */ + || nextLineStart.line == document.getLineCount() - 1 /* last line*/ + || document.getLineSeparatorLength(lineToCheck) == 0) + { s = "\n"+s; newOffset++; } From 4c4c41267ad4dd52fc116b26ace1b9fe7a7bb884 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Fri, 15 Jun 2012 11:01:53 +0400 Subject: [PATCH 011/100] typo --- .../src/com/intellij/openapi/keymap/ex/KeymapManagerEx.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/ex/KeymapManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/keymap/ex/KeymapManagerEx.java index c38222825553..0dc7c02223a2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/ex/KeymapManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/ex/KeymapManagerEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ public abstract class KeymapManagerEx extends KeymapManager { } /** - * @return all available keymaps. The method return an aempty array if no + * @return all available keymaps. The method return an empty array if no * keymaps are available. */ public abstract Keymap[] getAllKeymaps(); From f0e495bfe9a9274a929d607c3c5280ac05398c95 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 15 Jun 2012 09:31:03 +0200 Subject: [PATCH 012/100] Undo: correctly taking active editor --- .../openapi/command/impl/UndoManagerImpl.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java index 82741248cd9a..60dc5b2e20e7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -16,8 +16,10 @@ package com.intellij.openapi.command.impl; import com.intellij.CommonBundle; +import com.intellij.ide.DataManager; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.*; @@ -43,6 +45,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; import com.intellij.util.containers.HashSet; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -264,14 +267,13 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap } private void addFocusedDocumentAsAffected() { - VirtualFile[] selected = FileEditorManager.getInstance(myProject).getSelectedFiles(); - if (selected.length == 0) return; + PsiFile psiFile = LangDataKeys.PSI_FILE.getData(DataManager.getInstance().getDataContext()); + if (psiFile == null) return; - final DocumentReference[] refs = new DocumentReference[selected.length]; - for (int i = 0; i < refs.length; i++) { - refs[i] = DocumentReferenceManager.getInstance().create(selected[i]); - } + VirtualFile file = psiFile.getVirtualFile(); + if (file == null) return; + final DocumentReference[] refs = new DocumentReference[]{DocumentReferenceManager.getInstance().create(file)}; myCurrentMerger.addAction(new BasicUndoableAction() { @Override public void undo() throws UnexpectedUndoException { From b166db5d125b556b4b9aace7b13a49aad201a98d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 11:24:56 +0400 Subject: [PATCH 013/100] memory --- .../debugger/ui/JavaDebuggerSupport.java | 4 +- .../intellij/patterns/PsiMethodPattern.java | 13 +++++-- .../src/com/intellij/find/FindModel.java | 5 ++- .../codeInsight/lookup/impl/Advertiser.java | 3 +- .../execution/impl/RunManagerImpl.java | 37 ++++++++++++++++++- .../history/core/changes/ChangeSet.java | 3 +- .../com/intellij/ui/tabs/impl/JBTabsImpl.java | 5 ++- .../com/intellij/notification/EventLog.java | 3 +- .../openapi/wm/impl/AltStateManager.java | 4 +- .../src/com/intellij/ui/ColorPicker.java | 3 +- .../src/com/intellij/ui/SlideComponent.java | 7 ++-- .../openapi/util/registry/RegistryValue.java | 5 ++- .../com/intellij/util/ReflectionCache.java | 14 ++++++- .../breakpoints/XBreakpointPanelProvider.java | 6 +-- .../siyeh/ig/ui/ExternalizableStringSet.java | 3 +- .../spellchecker/engine/BaseSpellChecker.java | 5 ++- 16 files changed, 89 insertions(+), 31 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 2dda3d70feb4..3b4ff49e6eff 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -33,6 +33,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Key; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.AbstractDebuggerSession; import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; @@ -50,7 +51,6 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; /** * @author nik @@ -187,7 +187,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { } private static class JavaBreakpointPanelProvider extends BreakpointPanelProvider { - private List myListeners = new CopyOnWriteArrayList(); + private List myListeners = ContainerUtil.createEmptyCOWList(); @NotNull public Collection> getBreakpointPanels(@NotNull final Project project, @NotNull final DialogWrapper parentDialog) { diff --git a/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java b/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java index 87247577c30f..d4f60967aff4 100644 --- a/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java +++ b/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java @@ -22,6 +22,7 @@ import com.intellij.psi.*; import com.intellij.psi.search.searches.SuperMethodsSearch; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.PairProcessor; import com.intellij.util.ProcessingContext; import com.intellij.util.Processor; @@ -38,6 +39,7 @@ public class PsiMethodPattern extends PsiMemberPattern("withParameterCount") { + @Override public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) { return method.getParameterList().getParametersCount() == paramCount; } @@ -46,12 +48,14 @@ public class PsiMethodPattern extends PsiMemberPattern
  • "?" - means any type
  • ".." - instructs pattern to accept the rest of the arguments
  • * @return */ - public PsiMethodPattern withParameters(@NonNls final String... types) { + public PsiMethodPattern withParameters(@NonNls final String... inputTypes) { + final String[] types = inputTypes.length == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : inputTypes; return with(new PatternCondition("withParameters") { + @Override public boolean accepts(@NotNull final PsiMethod psiMethod, final ProcessingContext context) { final PsiParameterList parameterList = psiMethod.getParameterList(); int dotsIndex = -1; @@ -91,7 +95,7 @@ public class PsiMethodPattern extends PsiMemberPattern result = Ref.create(Boolean.TRUE); SuperMethodsSearch.search(t, null, true, false).forEach(new Processor() { + @Override public boolean process(final MethodSignatureBackedByPsiMethod signature) { if (!processor.process(signature.getMethod().getContainingClass(), context)) { result.set(Boolean.FALSE); @@ -118,6 +123,7 @@ public class PsiMethodPattern extends PsiMemberPattern("constructor") { + @Override public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) { return method.isConstructor() == isConstructor; } @@ -127,6 +133,7 @@ public class PsiMethodPattern extends PsiMemberPattern pattern) { return with(new PatternCondition("withThrowsList") { + @Override public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) { return pattern.accepts(method.getThrowsList()); } diff --git a/platform/lang-api/src/com/intellij/find/FindModel.java b/platform/lang-api/src/com/intellij/find/FindModel.java index 07ad7422fd96..0af15cb80990 100644 --- a/platform/lang-api/src/com/intellij/find/FindModel.java +++ b/platform/lang-api/src/com/intellij/find/FindModel.java @@ -19,11 +19,12 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.search.SearchScope; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -49,7 +50,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable { void findModelChanged(FindModel findModel); } - private final CopyOnWriteArrayList myObservers = new CopyOnWriteArrayList(); + private final List myObservers = ContainerUtil.createEmptyCOWList(); public void addObserver(FindModelObserver observer) { myObservers.add(observer); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java index 43b01646d15a..760f07ac614f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.lookup.impl; import com.google.common.collect.ImmutableMap; import com.intellij.openapi.application.ApplicationManager; import com.intellij.ui.ClickListener; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -34,7 +35,7 @@ import java.util.concurrent.CopyOnWriteArrayList; * @author peter */ public class Advertiser { - private final List myTexts = new CopyOnWriteArrayList(); + private final List myTexts = ContainerUtil.createEmptyCOWList(); private volatile Dimension myCachedPrefSize; private final JPanel myComponent = new JPanel(new GridBagLayout()) { private JLabel mySample = createLabel(); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java index 58ba805b5f96..f3b498d36e61 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.java @@ -87,6 +87,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, // separate method needed for tests public final void initializeConfigurationTypes(@NotNull final ConfigurationType[] factories) { Arrays.sort(factories, new Comparator() { + @Override public int compare(final ConfigurationType o1, final ConfigurationType o2) { return o1.getDisplayName().compareTo(o2.getDisplayName()); } @@ -109,15 +110,19 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, initializeConfigurationTypes(configurationTypes); } + @Override public void disposeComponent() { } + @Override public void initComponent() { } + @Override public void projectOpened() { } + @Override @NotNull public RunnerAndConfigurationSettings createConfiguration(final String name, final ConfigurationFactory factory) { return createConfiguration(doCreateConfiguration(name, factory, true), factory); @@ -134,6 +139,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } } + @Override @NotNull public RunnerAndConfigurationSettings createConfiguration(final RunConfiguration runConfiguration, final ConfigurationFactory factory) { @@ -145,14 +151,17 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return settings; } + @Override public void projectClosed() { myTemplateConfigurationsMap.clear(); } + @Override public RunManagerConfig getConfig() { return myConfig; } + @Override @NotNull public ConfigurationType[] getConfigurationFactories() { return myTypes.clone(); @@ -177,6 +186,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, /** * Template configuration is not included */ + @Override @NotNull public RunConfiguration[] getConfigurations(@NotNull final ConfigurationType type) { @@ -191,6 +201,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return array.toArray(new RunConfiguration[array.size()]); } + @Override @NotNull public RunConfiguration[] getAllConfigurations() { RunConfiguration[] result = new RunConfiguration[myConfigurations.size()]; @@ -215,6 +226,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, /** * Template configuration is not included */ + @Override @NotNull public RunnerAndConfigurationSettings[] getConfigurationSettings(@NotNull final ConfigurationType type) { @@ -240,6 +252,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return template; } + @Override public void addConfiguration(RunnerAndConfigurationSettings settings, boolean shared, List tasks, boolean addEnabledTemplateTasksIfAbsent) { @@ -336,6 +349,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } } + @Override @Nullable public RunnerAndConfigurationSettings getSelectedConfiguration() { if (mySelectedConfigurationId == null && myLoadedSelectedConfigurationUniqueName != null) { @@ -344,6 +358,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return mySelectedConfigurationId == null ? null : myConfigurations.get(mySelectedConfigurationId); } + @Override public void setSelectedConfiguration(@Nullable RunnerAndConfigurationSettings settings) { setSelectedConfigurationId(settings == null ? null : settings.getConfiguration().getUniqueID()); if (settings != null) { @@ -420,6 +435,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return true; } + @Override public void writeExternal(@NotNull final Element parentNode) throws WriteExternalException { writeContext(parentNode); for (final RunnerAndConfigurationSettings runnerAndConfigurationSettings : myTemplateConfigurationsMap.values()) { @@ -529,10 +545,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } + @Override public void readExternal(final Element parentNode) throws InvalidDataException { clear(); final Comparator comparator = new Comparator() { + @Override public int compare(Element a, Element b) { final boolean aDefault = Boolean.valueOf(a.getAttributeValue("default", "false")); final boolean bDefault = Boolean.valueOf(b.getAttributeValue("default", "false")); @@ -716,11 +734,13 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return null; } + @Override @NotNull public String getComponentName() { return "RunManager"; } + @Override public void setTemporaryConfiguration(@Nullable final RunnerAndConfigurationSettings tempConfiguration) { if (tempConfiguration == null) return; @@ -748,18 +768,22 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return result.values(); } + @Override public boolean isTemporary(@NotNull final RunConfiguration configuration) { return Arrays.asList(getTempConfigurations()).contains(configuration); } + @Override public boolean isTemporary(@NotNull RunnerAndConfigurationSettings settings) { return settings.isTemporary(); } + @Override @NotNull public RunConfiguration[] getTempConfigurations() { List configurations = ContainerUtil.mapNotNull(myConfigurations.values(), new NullableFunction() { + @Override public RunConfiguration fun(RunnerAndConfigurationSettings settings) { return settings.isTemporary() ? settings.getConfiguration() : null; } @@ -767,6 +791,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return configurations.toArray(new RunConfiguration[configurations.size()]); } + @Override public void makeStable(@NotNull RunConfiguration configuration) { RunnerAndConfigurationSettings settings = getSettings(configuration); if (settings != null) { @@ -780,11 +805,13 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } } + @Override @NotNull public RunnerAndConfigurationSettings createRunConfiguration(String name, ConfigurationFactory type) { return createConfiguration(name, type); } + @Override public boolean isConfigurationShared(final RunnerAndConfigurationSettings settings) { Boolean shared = mySharedConfigurations.get(settings.getConfiguration().getUniqueID()); if (shared == null) { @@ -794,6 +821,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return shared != null && shared.booleanValue(); } + @Override @NotNull public List getBeforeRunTasks(Key taskProviderID) { final List tasks = new ArrayList(); @@ -822,10 +850,12 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return tasks; } + @Override public void invalidateConfigurationIcon(@NotNull final RunnerAndConfigurationSettings settings) { myIdToIcon.remove(settings.getConfiguration().getUniqueID()); } + @Override public Icon getConfigurationIcon(@NotNull final RunnerAndConfigurationSettings settings) { final int uniqueID = settings.getConfiguration().getUniqueID(); Icon icon = myIdToIcon.get(uniqueID); @@ -881,6 +911,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, return result; } + @Override @NotNull public List getBeforeRunTasks(final RunConfiguration settings) { final List tasks = myConfigurationToBeforeTasksMap.get(settings); @@ -920,7 +951,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, result.add(task.clone()); } } - return result; + return result.isEmpty() ? Collections.emptyList() : result; } public void shareConfiguration(final RunConfiguration runConfiguration, final boolean shareConfiguration) { @@ -933,6 +964,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, if (shouldFire) fireRunConfigurationChanged(settings); } + @Override public final void setBeforeRunTasks(final RunConfiguration runConfiguration, @NotNull List tasks, boolean addEnabledTemplateTasksIfAbsent) { List result = new ArrayList(tasks); if (addEnabledTemplateTasksIfAbsent) { @@ -949,7 +981,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, } } } - myConfigurationToBeforeTasksMap.put(runConfiguration, result); + myConfigurationToBeforeTasksMap.put(runConfiguration, result.isEmpty() ? Collections.emptyList() : result); fireBeforeRunTasksUpdated(); } @@ -958,6 +990,7 @@ public class RunManagerImpl extends RunManagerEx implements JDOMExternalizable, fireBeforeRunTasksUpdated(); } + @Override public void addConfiguration(final RunnerAndConfigurationSettings settings, final boolean isShared) { addConfiguration(settings, isShared, getTemplateBeforeRunTasks(settings.getConfiguration()), false); } diff --git a/platform/lvcs-impl/src/com/intellij/history/core/changes/ChangeSet.java b/platform/lvcs-impl/src/com/intellij/history/core/changes/ChangeSet.java index 527a48760745..210205d50029 100644 --- a/platform/lvcs-impl/src/com/intellij/history/core/changes/ChangeSet.java +++ b/platform/lvcs-impl/src/com/intellij/history/core/changes/ChangeSet.java @@ -31,7 +31,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; public class ChangeSet { private final long myId; @@ -44,7 +43,7 @@ public class ChangeSet { public ChangeSet(long id, long timestamp) { myId = id; myTimestamp = timestamp; - myChanges = new CopyOnWriteArrayList(); + myChanges = ContainerUtil.createEmptyCOWList(); } public ChangeSet(DataInput in) throws IOException { diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index 20c3a1753343..04ac15d65fd4 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -38,6 +38,7 @@ import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout; import com.intellij.ui.tabs.impl.singleRow.SingleRowPassInfo; import com.intellij.ui.tabs.impl.table.TableLayout; import com.intellij.ui.tabs.impl.table.TablePassInfo; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.Animator; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.TimedDeadzone; @@ -80,8 +81,8 @@ public class JBTabsImpl extends JComponent private Insets myInnerInsets = JBInsets.NONE; - private final List myTabMouseListeners = new CopyOnWriteArrayList(); - private final List myTabListeners = new CopyOnWriteArrayList(); + private final List myTabMouseListeners = ContainerUtil.createEmptyCOWList(); + private final List myTabListeners = ContainerUtil.createEmptyCOWList(); private boolean myFocused; private Getter myPopupGroup; diff --git a/platform/platform-impl/src/com/intellij/notification/EventLog.java b/platform/platform-impl/src/com/intellij/notification/EventLog.java index a0233b7afbee..e03f6db7de40 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLog.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLog.java @@ -47,6 +47,7 @@ import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import com.intellij.util.containers.CollectionFactory; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NonNls; @@ -344,7 +345,7 @@ public class EventLog implements Notifications { public static class ProjectTracker extends AbstractProjectComponent { private volatile EventLogConsole myConsole; - private final List myInitial = new CopyOnWriteArrayList(); + private final List myInitial = ContainerUtil.createEmptyCOWList(); private final LogModel myProjectModel; public ProjectTracker(@NotNull final Project project) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/AltStateManager.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/AltStateManager.java index 3f11e60200d5..34a4025c51cf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/AltStateManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/AltStateManager.java @@ -16,12 +16,12 @@ package com.intellij.openapi.wm.impl; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.util.containers.ContainerUtil; import java.awt.*; import java.awt.event.AWTEventListener; import java.awt.event.KeyEvent; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; /** * @author pegov @@ -37,7 +37,7 @@ public class AltStateManager implements AWTEventListener { } } - private final List myListeners = new CopyOnWriteArrayList(); + private final List myListeners = ContainerUtil.createEmptyCOWList(); public interface AltListener { void altPressed(); diff --git a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java index d51711bac17a..5a4a57c1868c 100644 --- a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java +++ b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.openapi.wm.WindowManager; import com.intellij.util.Alarm; import com.intellij.util.Consumer; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -440,7 +441,7 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen private Color myColor; - private CopyOnWriteArrayList myListeners = new CopyOnWriteArrayList(); + private CopyOnWriteArrayList myListeners = ContainerUtil.createEmptyCOWList(); private int myOpacity; private ColorWheel() { diff --git a/platform/platform-impl/src/com/intellij/ui/SlideComponent.java b/platform/platform-impl/src/com/intellij/ui/SlideComponent.java index 3be566722165..b331220ffd54 100644 --- a/platform/platform-impl/src/com/intellij/ui/SlideComponent.java +++ b/platform/platform-impl/src/com/intellij/ui/SlideComponent.java @@ -19,12 +19,13 @@ import com.intellij.codeInsight.hint.HintUtil; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Consumer; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import javax.swing.*; import java.awt.*; import java.awt.event.*; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.List; /** * @author Alexey Pegov @@ -37,9 +38,9 @@ class SlideComponent extends JComponent { private final boolean myVertical; private final String myTitle; - private CopyOnWriteArrayList> myListeners = new CopyOnWriteArrayList>(); + private final List> myListeners = ContainerUtil.createEmptyCOWList(); private LightweightHint myTooltipHint; - private JLabel myLabel = new JLabel(); + private final JLabel myLabel = new JLabel(); SlideComponent(String title, boolean vertical) { myTitle = title; diff --git a/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java b/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java index 076e298aa218..6f93e6e5cf0b 100644 --- a/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java +++ b/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java @@ -17,10 +17,11 @@ package com.intellij.openapi.util.registry; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; +import com.intellij.util.containers.ContainerUtil; import java.awt.*; +import java.util.List; import java.util.MissingResourceException; -import java.util.concurrent.CopyOnWriteArraySet; /** * @author Kirill Kalishev @@ -31,7 +32,7 @@ public class RegistryValue { private final Registry myRegistry; private final String myKey; - private final CopyOnWriteArraySet myListeners = new CopyOnWriteArraySet(); + private final List myListeners = ContainerUtil.createEmptyCOWList(); private boolean myChangedSinceStart; diff --git a/platform/util/src/com/intellij/util/ReflectionCache.java b/platform/util/src/com/intellij/util/ReflectionCache.java index 4c65b45c29ed..9e310236e196 100644 --- a/platform/util/src/com/intellij/util/ReflectionCache.java +++ b/platform/util/src/com/intellij/util/ReflectionCache.java @@ -29,42 +29,52 @@ import java.lang.reflect.TypeVariable; @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) public class ReflectionCache { private static final ConcurrentFactoryMap ourSuperClasses = new ConcurrentFactoryMap() { + @Override protected Class create(final Class key) { return key.getSuperclass(); } }; private static final ConcurrentFactoryMap ourInterfaces = new ConcurrentFactoryMap() { + @Override @NotNull protected Class[] create(final Class key) { - return key.getInterfaces(); + Class[] classes = key.getInterfaces(); + return classes.length == 0 ? ArrayUtil.EMPTY_CLASS_ARRAY : classes; } }; + private static final Method[] EMPTY_METHODS = new Method[0]; private static final ConcurrentFactoryMap ourMethods = new ConcurrentFactoryMap() { + @Override @NotNull protected Method[] create(final Class key) { - return key.getMethods(); + Method[] methods = key.getMethods(); + return methods.length == 0 ? EMPTY_METHODS : methods; } }; private static final ConcurrentFactoryMap ourIsInterfaces = new ConcurrentFactoryMap() { + @Override @NotNull protected Boolean create(final Class key) { return key.isInterface(); } }; private static final ConcurrentFactoryMap ourTypeParameters = new ConcurrentFactoryMap() { + @Override @NotNull protected TypeVariable[] create(final Class key) { return key.getTypeParameters(); } }; private static final ConcurrentFactoryMap ourGenericInterfaces = new ConcurrentFactoryMap() { + @Override @NotNull protected Type[] create(final Class key) { return key.getGenericInterfaces(); } }; private static final ConcurrentFactoryMap ourActualTypeArguments = new ConcurrentFactoryMap() { + @Override @NotNull protected Type[] create(final ParameterizedType key) { return key.getActualTypeArguments(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java index 02ca25d275f0..877871da0451 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java @@ -24,6 +24,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XDebuggerUtil; import com.intellij.xdebugger.breakpoints.*; @@ -40,14 +41,13 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; /** * @author nik */ public class XBreakpointPanelProvider extends BreakpointPanelProvider { - private List myListeners = new CopyOnWriteArrayList(); + private final List myListeners = ContainerUtil.createEmptyCOWList(); @Override public void createBreakpointsGroupingRules(Collection rules) { @@ -173,7 +173,7 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider myType; + private final XBreakpointType myType; public AddXBreakpointAction(XBreakpointType type) { myType = type; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java index 828311aae432..63d69e367aac 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.containers.OrderedSet; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -48,7 +49,7 @@ public class ExternalizableStringSet extends OrderedSet * note: reference to defaultValues is retained by this set! */ public ExternalizableStringSet(@NonNls String... defaultValues) { - this.defaultValues = defaultValues; + this.defaultValues = defaultValues.length == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : defaultValues; for (String defaultValue : defaultValues) { add(defaultValue); } diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java b/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java index ac3b703bb513..091237bb2b9a 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/engine/BaseSpellChecker.java @@ -33,6 +33,7 @@ import com.intellij.spellchecker.dictionary.EditableDictionary; import com.intellij.spellchecker.dictionary.EditableDictionaryLoader; import com.intellij.spellchecker.dictionary.Loader; import com.intellij.util.Consumer; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -49,11 +50,11 @@ public class BaseSpellChecker implements SpellCheckerEngine { private final Transformation transform = new Transformation(); private final Set dictionaries = new THashSet(); - private final List bundledDictionaries = new CopyOnWriteArrayList(); + private final List bundledDictionaries = ContainerUtil.createEmptyCOWList(); private final Metrics metrics = new LevenshteinDistance(); private AtomicBoolean myLoadingDictionaries = new AtomicBoolean(false); - private List>> myDictionariesToLoad = new CopyOnWriteArrayList>>(); + private List>> myDictionariesToLoad = ContainerUtil.createEmptyCOWList(); private Project myProject; public BaseSpellChecker(final Project project) { From 800e69f616cf24f5f18ba2d741c403f5269be447 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 15 Jun 2012 10:34:10 +0200 Subject: [PATCH 014/100] Undo: asking confirmation when undoing 'reload from disk' command (IDEA-87407) --- .../src/com/intellij/ide/actions/ReloadFromDiskAction.java | 3 +-- .../openapi/fileEditor/impl/FileDocumentManagerImpl.java | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java b/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java index 94969d53c9d0..702f3c79d679 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/ReloadFromDiskAction.java @@ -22,8 +22,8 @@ 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.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -53,7 +53,6 @@ public class ReloadFromDiskAction extends AnAction implements DumbAware { new Runnable() { public void run() { PsiManager.getInstance(project).reloadFromDisk(psiFile); - CommandProcessor.getInstance().markCurrentCommandAsGlobal(project); } } ); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index fbfeb4b0b30a..28efc4d225f6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -21,6 +21,7 @@ import com.intellij.codeStyle.CodeStyleFacade; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.UndoConfirmationPolicy; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.DiffManager; @@ -578,7 +579,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl } ); } - }, UIBundle.message("file.cache.conflict.action"), null); + }, UIBundle.message("file.cache.conflict.action"), null, UndoConfirmationPolicy.REQUEST_CONFIRMATION); myUnsavedDocuments.remove(document); From 45565ae31d917c65fe1f531afcaafaa480093cf4 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 15 Jun 2012 12:56:08 +0400 Subject: [PATCH 015/100] IDEA-87425 New category classes in Groovy 2.0 --- .../resources/standardDsls/extensions.gdsl | 11 +++ plugins/groovy/src/META-INF/plugin.xml | 12 +++ .../plugins/groovy/dgm/DGMClassReference.java | 95 +++++++++++++++++++ .../groovy/dgm/DGMCompletionContributor.java | 73 ++++++++++++++ .../groovy/dgm/DGMFileTypeFactory.java | 36 +++++++ .../dgm/DGMImplicitPropertyUsageProvider.java | 34 +++++++ .../groovy/dgm/DGMReferenceContributor.java | 80 ++++++++++++++++ .../jetbrains/plugins/groovy/dgm/DGMUtil.java | 36 +++++++ .../groovy/dgm/GroovyExtensionProvider.java | 80 ++++++++++++++++ .../lang/resolve/ResolveMethodTest.groovy | 17 ++++ plugins/properties/src/META-INF/plugin.xml | 7 +- .../unused/ImplicitPropertyUsageProvider.java | 36 +++++++ .../unused}/UnusedPropertyInspection.java | 9 +- 13 files changed, 523 insertions(+), 3 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMCompletionContributor.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMFileTypeFactory.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMImplicitPropertyUsageProvider.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMUtil.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/GroovyExtensionProvider.java create mode 100644 plugins/properties/src/com/intellij/codeInspection/unused/ImplicitPropertyUsageProvider.java rename plugins/properties/src/com/intellij/{lang/properties => codeInspection/unused}/UnusedPropertyInspection.java (92%) diff --git a/plugins/groovy/resources/standardDsls/extensions.gdsl b/plugins/groovy/resources/standardDsls/extensions.gdsl index 17a71ec16568..534814cd2e97 100644 --- a/plugins/groovy/resources/standardDsls/extensions.gdsl +++ b/plugins/groovy/resources/standardDsls/extensions.gdsl @@ -17,6 +17,9 @@ package standardDsls +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider + /** * @author Maxim.Medvedev */ @@ -35,4 +38,12 @@ contributor([:]) { category "org.codehaus.groovy.runtime.SwingGroovyMethods" category "org.codehaus.groovy.runtime.XmlGroovyMethods" + def pair = GroovyExtensionProvider.getInstance(project).collectExtensions(GlobalSearchScope.allScope(project)) + for (def inst : pair.first) { + category inst, false + } + + for (def stat : pair.second) { + category stat, true + } } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 13f1dd3e41b5..1d302ffb98a1 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -139,6 +139,10 @@
    + + + + @@ -163,6 +167,7 @@ + @@ -290,6 +295,8 @@ + + + + + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java new file mode 100644 index 000000000000..12d81532794a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +/** + * @author Max Medvedev + */ +public class DGMClassReference implements PsiReference { + private final PsiElement myElement; + private TextRange myRange; + + public DGMClassReference(PsiElement element, int start, int end) { + + myElement = element; + myRange = new TextRange(start, end); + } + + + @Override + public PsiElement getElement() { + return myElement; + } + + @Override + public TextRange getRangeInElement() { + return myRange; + } + + @Override + public PsiElement resolve() { + Project project = myElement.getProject(); + return JavaPsiFacade.getInstance(project).findClass(myRange.substring(myElement.getText()), myElement.getResolveScope()); + } + + @NotNull + @Override + public String getCanonicalText() { + return myRange.substring(myElement.getText()); + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + if (element instanceof PsiClass) { + String qname = ((PsiClass)element).getQualifiedName(); + if (qname == null) return myElement; + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myElement.getProject()); + Document document = documentManager.getDocument(myElement.getContainingFile()); + TextRange range = myRange.shiftRight(myElement.getTextRange().getStartOffset()); + document.replaceString(range.getStartOffset(), range.getEndOffset(), qname); + documentManager.commitDocument(document); + } + return myElement; + } + + @Override + public boolean isReferenceTo(PsiElement element) { + return myElement.getManager().areElementsEquivalent(element, resolve()); + } + + @NotNull + @Override + public Object[] getVariants() { + return EMPTY_ARRAY; + } + + @Override + public boolean isSoft() { + return true; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMCompletionContributor.java new file mode 100644 index 000000000000..16f71c77b922 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMCompletionContributor.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.lang.properties.parsing.PropertiesTokenTypes; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.util.Consumer; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil; + +import java.util.Map; + +/** + * @author Max Medvedev + */ +public class DGMCompletionContributor extends CompletionContributor { + public DGMCompletionContributor() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement(PropertiesTokenTypes.KEY_CHARACTERS), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + if (!DGMUtil.isInDGMFile(position)) return; + + Map map = ((PropertiesFile)position.getContainingFile()).getNamesMap(); + for (String key : DGMUtil.KEYS) { + if (!map.containsKey(key)) { + result.addElement(LookupElementBuilder.create(key)); + } + } + } + }); + + extend(CompletionType.BASIC, PlatformPatterns.psiElement(PropertiesTokenTypes.VALUE_CHARACTERS), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull final CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + if (!DGMUtil.isInDGMFile(position)) return; + + AllClassesGetter.processJavaClasses(parameters, result.getPrefixMatcher(), true, new Consumer() { + @Override + public void consume(PsiClass aClass) { + result.addElement(GroovyCompletionUtil.createClassLookupItem(aClass)); + } + }); + } + }); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMFileTypeFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMFileTypeFactory.java new file mode 100644 index 000000000000..e82c560e4571 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMFileTypeFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.lang.properties.PropertiesFileType; +import com.intellij.openapi.fileTypes.ExactFileNameMatcher; +import com.intellij.openapi.fileTypes.FileTypeConsumer; +import com.intellij.openapi.fileTypes.FileTypeFactory; +import com.intellij.openapi.util.SystemInfo; +import org.jetbrains.annotations.NotNull; + +/** + * @author Max Medvedev + */ +public class DGMFileTypeFactory extends FileTypeFactory { + + @Override + public void createFileTypes(@NotNull FileTypeConsumer consumer) { + ExactFileNameMatcher matcher = new ExactFileNameMatcher(GroovyExtensionProvider.ORG_CODEHAUS_GROOVY_RUNTIME_EXTENSION_MODULE, + !SystemInfo.isFileSystemCaseSensitive); + consumer.consume(PropertiesFileType.INSTANCE, matcher); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMImplicitPropertyUsageProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMImplicitPropertyUsageProvider.java new file mode 100644 index 000000000000..9fc2820b840a --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMImplicitPropertyUsageProvider.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.codeInspection.unused.ImplicitPropertyUsageProvider; +import com.intellij.lang.properties.psi.Property; +import com.intellij.util.ArrayUtil; + +/** + * @author Max Medvedev + */ +public class DGMImplicitPropertyUsageProvider extends ImplicitPropertyUsageProvider { + @Override + protected boolean isUsed(Property property) { + if (DGMUtil.isInDGMFile(property)) { + String name = property.getName(); + return ArrayUtil.find(DGMUtil.KEYS, name) >= 0; + } + return false; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java new file mode 100644 index 000000000000..442f3e4caed7 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.lang.properties.IProperty; +import com.intellij.lang.properties.parsing.PropertiesTokenTypes; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.*; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +/** + * @author Max Medvedev + */ +public class DGMReferenceContributor extends PsiReferenceContributor { + + @Override + public void registerReferenceProviders(PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider(PlatformPatterns.psiElement(PropertiesTokenTypes.VALUE_CHARACTERS), new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + if (!DGMUtil.isInDGMFile(element)) return PsiReference.EMPTY_ARRAY; + + IProperty parent = (IProperty)element.getParent(); + if (!"extensionClasses".equals(parent.getName())) { + return PsiReference.EMPTY_ARRAY; + } + + ArrayList result = new ArrayList(); + + String text = element.getText(); + + int i = 0; + while ((i = skipWhiteSpace(i, text)) < text.length()) { + int end = findWhiteSpaceOrComma(i, text); + if (end <= text.length()) { + result.add(new DGMClassReference(element, i, end)); + } + i = end; + i = skipWhiteSpace(i, text); + if (i == text.length()) break; + if (text.charAt(i) == ',') i++; + i = skipWhiteSpace(i, text); + } + + return result.toArray(new PsiReference[result.size()]); + } + }); + } + + private static int skipWhiteSpace(int i, String text) { + while (i < text.length() && Character.isWhitespace(text.charAt(i))) { + i++; + } + return i; + } + + private static int findWhiteSpaceOrComma(int i, String text) { + while (i < text.length() && !Character.isWhitespace(text.charAt(i)) && text.charAt(i) != ',') { + i++; + } + return i; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMUtil.java new file mode 100644 index 000000000000..af695a38be7c --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMUtil.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; + +/** + * @author Max Medvedev + */ +public class DGMUtil { + public static final String[] KEYS = new String[]{"moduleName", "moduleVersion", "extensionClasses", "staticExtensionClasses",}; + + public static boolean isInDGMFile(PsiElement e) { + PsiFile file = e.getContainingFile(); + return file instanceof PropertiesFile && + Comparing.equal(file.getName(), GroovyExtensionProvider.ORG_CODEHAUS_GROOVY_RUNTIME_EXTENSION_MODULE, + SystemInfo.isFileSystemCaseSensitive); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/GroovyExtensionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/GroovyExtensionProvider.java new file mode 100644 index 000000000000..c4ae7fe067af --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/GroovyExtensionProvider.java @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.dgm; + +import com.intellij.lang.properties.IProperty; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NonNls; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Max Medvedev + */ +public class GroovyExtensionProvider { + @NonNls public static final String ORG_CODEHAUS_GROOVY_RUNTIME_EXTENSION_MODULE = "org.codehaus.groovy.runtime.ExtensionModule"; + private final Project myProject; + + public GroovyExtensionProvider(Project project) { + myProject = project; + } + + public static GroovyExtensionProvider getInstance(Project project) { + return ServiceManager.getService(project, GroovyExtensionProvider.class); + } + + public Pair, List> collectExtensions(GlobalSearchScope resolveScope) { + PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage("META-INF.services"); + if (aPackage == null) { + return new Pair, List>(Collections.emptyList(), Collections.emptyList()); + } + + + List instanceClasses = new ArrayList(); + List staticClasses = new ArrayList(); + for (PsiDirectory directory : aPackage.getDirectories(resolveScope)) { + PsiFile file = directory.findFile("org.codehaus.groovy.runtime.ExtensionModule"); + if (file instanceof PropertiesFile) { + IProperty inst = ((PropertiesFile)file).findPropertyByKey("extensionClasses"); + IProperty stat = ((PropertiesFile)file).findPropertyByKey("staticExtensionClasses"); + + if (inst != null) collectClasses(inst, instanceClasses); + if (stat != null) collectClasses(stat, staticClasses); + } + } + + return new Pair, List>(instanceClasses, staticClasses); + } + + private static void collectClasses(IProperty pr, List classes) { + String value = pr.getValue(); + if (value == null) return; + value = value.trim(); + String[] qnames = value.split("\\s*,\\s*"); + ContainerUtil.addAll(classes, qnames); + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy index a576a32b8805..cc9229809b73 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy @@ -1053,4 +1053,21 @@ class Category2 { assertNotNull(ref.resolve()) } + + void testGroovyExtensions() { + def ref = configureByText('pack._a.groovy', '''\ +package pack + +class StringExt { + static sub(String s) {} +} + +"".sub()''') + + myFixture.addFileToProject("META-INF/services/org.codehaus.groovy.runtime.ExtensionModule", """\ +extensionClasses=pack.StringExt +""") + + assertNotNull(ref.resolve()) + } } diff --git a/plugins/properties/src/META-INF/plugin.xml b/plugins/properties/src/META-INF/plugin.xml index b5053ce9440b..8e152052a51b 100644 --- a/plugins/properties/src/META-INF/plugin.xml +++ b/plugins/properties/src/META-INF/plugin.xml @@ -6,6 +6,11 @@ This plugin enables smart editing of properties files. JetBrains + + + + + + implementationClass="com.intellij.codeInspection.unused.UnusedPropertyInspection"/> diff --git a/plugins/properties/src/com/intellij/codeInspection/unused/ImplicitPropertyUsageProvider.java b/plugins/properties/src/com/intellij/codeInspection/unused/ImplicitPropertyUsageProvider.java new file mode 100644 index 000000000000..ee0b9f593638 --- /dev/null +++ b/plugins/properties/src/com/intellij/codeInspection/unused/ImplicitPropertyUsageProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection.unused; + +import com.intellij.lang.properties.psi.Property; +import com.intellij.openapi.extensions.ExtensionPointName; + +/** + * @author Max Medvedev + */ +public abstract class ImplicitPropertyUsageProvider { + private static final ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.properties.implicitPropertyUsageProvider"); + + public static boolean isImplicitlyUsed(Property property) { + for (ImplicitPropertyUsageProvider provider : EP_NAME.getExtensions()) { + if (provider.isUsed(property)) return true; + } + return false; + } + + protected abstract boolean isUsed(Property property); +} diff --git a/plugins/properties/src/com/intellij/lang/properties/UnusedPropertyInspection.java b/plugins/properties/src/com/intellij/codeInspection/unused/UnusedPropertyInspection.java similarity index 92% rename from plugins/properties/src/com/intellij/lang/properties/UnusedPropertyInspection.java rename to plugins/properties/src/com/intellij/codeInspection/unused/UnusedPropertyInspection.java index 0166a7c989f0..86d58988e5fe 100644 --- a/plugins/properties/src/com/intellij/lang/properties/UnusedPropertyInspection.java +++ b/plugins/properties/src/com/intellij/codeInspection/unused/UnusedPropertyInspection.java @@ -13,12 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.lang.properties; +package com.intellij.codeInspection.unused; import com.intellij.codeInspection.LocalInspectionToolSession; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.lang.ASTNode; +import com.intellij.lang.properties.PropertiesBundle; +import com.intellij.lang.properties.PropertySuppressableInspectionBase; +import com.intellij.lang.properties.RemovePropertyLocalFix; import com.intellij.lang.properties.findUsages.PropertySearcher; import com.intellij.lang.properties.psi.Property; import com.intellij.openapi.extensions.Extensions; @@ -75,6 +78,8 @@ public class UnusedPropertyInspection extends PropertySuppressableInspectionBase original.setText(PropertiesBundle.message("searching.for.property.key.progress.text", property.getUnescapedKey())); } + if (ImplicitPropertyUsageProvider.isImplicitlyUsed(property)) return; + String name = property.getName(); if (name == null) return; if (searcher != null) { @@ -97,7 +102,7 @@ public class UnusedPropertyInspection extends PropertySuppressableInspectionBase PsiElement key = nodes.length == 0 ? property : nodes[0].getPsi(); String description = PropertiesBundle.message("unused.property.problem.descriptor.name"); - holder.registerProblem(key, description, ProblemHighlightType.LIKE_UNUSED_SYMBOL,RemovePropertyLocalFix.INSTANCE); + holder.registerProblem(key, description, ProblemHighlightType.LIKE_UNUSED_SYMBOL, RemovePropertyLocalFix.INSTANCE); } }; } From c6e6a726ad88441da662359702353c9508780725 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 14 Jun 2012 20:20:35 +0400 Subject: [PATCH 016/100] disable make class extend itself when assignment is not valid e.g. due to wrong type args --- .../quickfix/ChangeParameterClassFix.java | 1 + .../beforeDifferentTypeArgs.java | 10 +++++++ .../quickFix/ChangeTypeArgumentsFixTest.java | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeParameterClass/beforeDifferentTypeArgs.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeTypeArgumentsFixTest.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeParameterClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeParameterClassFix.java index c4dab56f1f17..9c6d5f19bfbc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeParameterClassFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeParameterClassFix.java @@ -122,6 +122,7 @@ public class ChangeParameterClassFix extends ExtendsListFix { if (rClass instanceof PsiAnonymousClass) return; if (rClass.isInheritor(lClass, true)) return; if (lClass.isInheritor(rClass, true)) return; + if (lClass == rClass) return; QuickFixAction.registerQuickFixAction(info, new ChangeParameterClassFix(rClass, (PsiClassType)lType)); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeParameterClass/beforeDifferentTypeArgs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeParameterClass/beforeDifferentTypeArgs.java new file mode 100644 index 000000000000..599d08760860 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeParameterClass/beforeDifferentTypeArgs.java @@ -0,0 +1,10 @@ +// "Make 'Generic' extend 'Generic'" "false" +class Generic { + Generic(E arg) { } +} + +class Tester { + void method() { + Generic aIntegerGeneric = new Generic(""); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeTypeArgumentsFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeTypeArgumentsFixTest.java new file mode 100644 index 000000000000..7aa289c49cbf --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeTypeArgumentsFixTest.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon.quickFix; + +public class ChangeTypeArgumentsFixTest extends LightQuickFix15TestCase { + + public void test() throws Exception { doAllTests(); } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs"; + } +} From 679e1c6bcf94f7578bff92fa4a75835d70c1db79 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 14 Jun 2012 20:33:26 +0400 Subject: [PATCH 017/100] change type args fix (IDEA-84097) --- .../impl/analysis/HighlightMethodUtil.java | 1 + .../impl/quickfix/ChangeTypeArgumentsFix.java | 165 ++++++++++++++++++ .../quickFix/changeTypeArgs/after1.java | 11 ++ .../changeTypeArgs/afterMultipleParams.java | 11 ++ .../changeTypeArgs/afterSuperType.java | 13 ++ .../quickFix/changeTypeArgs/before1.java | 11 ++ .../beforeCorrectTypeParam.java | 11 ++ .../changeTypeArgs/beforeDisabled.java | 13 ++ .../changeTypeArgs/beforeIncomplete.java | 11 ++ .../changeTypeArgs/beforeIncomplete2.java | 11 ++ .../changeTypeArgs/beforeMultipleParams.java | 11 ++ .../changeTypeArgs/beforeSuperType.java | 11 ++ 12 files changed, 280 insertions(+) create mode 100644 java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/after1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterMultipleParams.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterSuperType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/before1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeCorrectTypeParam.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeDisabled.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete2.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeMultipleParams.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeSuperType.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 555cbfef7581..14e7352028ee 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -1278,6 +1278,7 @@ public class HighlightMethodUtil { if (classReference != null) { ConstructorParametersFixer.registerFixActions(classReference, constructorCall, info, getFixRange(infoElement)); ChangeMethodSignatureFromUsageFix.registerIntentions(results, list, info, null); + ChangeTypeArgumentsFix.registerIntentions(results, list, info, aClass); ConvertDoubleToFloatFix.registerIntentions(results, list, info, null); PermuteArgumentsFix.registerFix(info, constructorCall, toMethodCandidates(results), getFixRange(list)); ChangeParameterClassFix.registerQuickFixActions(constructorCall, list, info); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java new file mode 100644 index 000000000000..3945e632a75a --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeTypeArgumentsFix.java @@ -0,0 +1,165 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Created by IntelliJ IDEA. + * User: cdr + * Date: Nov 13, 2002 + * Time: 3:26:50 PM + * To change this template use Options | File Templates. + */ +package com.intellij.codeInsight.daemon.impl.quickfix; + +import com.intellij.codeInsight.CodeInsightUtilBase; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.intention.HighPriorityAction; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; + +public class ChangeTypeArgumentsFix implements IntentionAction, HighPriorityAction { + private final PsiMethod myTargetMethod; + private final PsiClass myPsiClass; + private final PsiExpression[] myExpressions; + private static final Logger LOG = Logger.getInstance("#" + ChangeTypeArgumentsFix.class.getName()); + private final PsiNewExpression myNewExpression; + + ChangeTypeArgumentsFix(@NotNull PsiMethod targetMethod, + PsiClass psiClass, + @NotNull PsiExpression[] expressions, + @NotNull PsiElement context) { + myTargetMethod = targetMethod; + myPsiClass = psiClass; + myExpressions = expressions; + myNewExpression = PsiTreeUtil.getParentOfType(context, PsiNewExpression.class); + } + + @Override + @NotNull + public String getText() { + final PsiSubstitutor substitutor = inferTypeArguments(); + return "Change type arguments to <" + StringUtil.join(myPsiClass.getTypeParameters(), new Function() { + @Override + public String fun(PsiTypeParameter typeParameter) { + return substitutor.substitute(typeParameter).getPresentableText(); + } + }, ", ") + ">"; + } + + + @Override + @NotNull + public String getFamilyName() { + return "Change type arguments"; + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + final PsiTypeParameter[] typeParameters = myPsiClass.getTypeParameters(); + if (typeParameters.length > 0) { + if (myNewExpression != null && myNewExpression.isValid() && myNewExpression.getArgumentList() != null) { + final PsiJavaCodeReferenceElement reference = myNewExpression.getClassOrAnonymousClassReference(); + if (reference != null) { + final PsiReferenceParameterList parameterList = reference.getParameterList(); + if (parameterList != null) { + final PsiSubstitutor substitutor = inferTypeArguments(); + final PsiParameter[] parameters = myTargetMethod.getParameterList().getParameters(); + if (parameters.length != myExpressions.length) return false; + for (int i = 0, length = parameters.length; i < length; i++) { + PsiParameter parameter = parameters[i]; + final PsiType expectedType = substitutor.substitute(parameter.getType()); + if (!myExpressions[i].isValid()) return false; + final PsiType actualType = myExpressions[i].getType(); + if (expectedType == null || actualType == null || !TypeConversionUtil.isAssignable(expectedType, actualType)) return false; + } + return true; + } + } + } + } + return false; + } + + @Override + public void invoke(@NotNull final Project project, Editor editor, final PsiFile file) { + if (!CodeInsightUtilBase.prepareFileForWrite(file)) return; + + final PsiTypeParameter[] typeParameters = myPsiClass.getTypeParameters(); + final PsiSubstitutor psiSubstitutor = inferTypeArguments(); + final PsiJavaCodeReferenceElement reference = myNewExpression.getClassOrAnonymousClassReference(); + LOG.assertTrue(reference != null, myNewExpression); + final PsiReferenceParameterList parameterList = reference.getParameterList(); + LOG.assertTrue(parameterList != null, myNewExpression); + PsiTypeElement[] elements = parameterList.getTypeParameterElements(); + for (int i = elements.length - 1; i >= 0; i--) { + PsiTypeElement typeElement = elements[i]; + final PsiType typeArg = psiSubstitutor.substitute(typeParameters[i]); + typeElement.replace(JavaPsiFacade.getElementFactory(project).createTypeElement(typeArg)); + } + } + + private PsiSubstitutor inferTypeArguments() { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(myNewExpression.getProject()); + final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + final PsiParameter[] parameters = myTargetMethod.getParameterList().getParameters(); + final PsiExpressionList argumentList = myNewExpression.getArgumentList(); + LOG.assertTrue(argumentList != null); + final PsiExpression[] expressions = argumentList.getExpressions(); + return resolveHelper.inferTypeArguments(myPsiClass.getTypeParameters(), parameters, expressions, + PsiSubstitutor.EMPTY, + myNewExpression.getParent(), + DefaultParameterTypeInferencePolicy.INSTANCE); + } + + + public static void registerIntentions(@NotNull JavaResolveResult[] candidates, + @NotNull PsiExpressionList list, + @NotNull HighlightInfo highlightInfo, + PsiClass psiClass) { + if (candidates.length == 0) return; + PsiExpression[] expressions = list.getExpressions(); + for (JavaResolveResult candidate : candidates) { + registerIntention(expressions, highlightInfo, psiClass, candidate, list); + } + } + + private static void registerIntention(@NotNull PsiExpression[] expressions, + @NotNull HighlightInfo highlightInfo, + PsiClass psiClass, + @NotNull JavaResolveResult candidate, + @NotNull PsiElement context) { + if (!candidate.isStaticsScopeCorrect()) return; + PsiMethod method = (PsiMethod)candidate.getElement(); + PsiSubstitutor substitutor = candidate.getSubstitutor(); + if (method != null && context.getManager().isInProject(method)) { + final ChangeTypeArgumentsFix fix = new ChangeTypeArgumentsFix(method, psiClass, expressions, context); + QuickFixAction.registerQuickFixAction(highlightInfo, null, fix); + } + } + + @Override + public boolean startInWriteAction() { + return true; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/after1.java new file mode 100644 index 000000000000..430b68756e80 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/after1.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg) { + } +} + +class Tester { + void method() { + new Generic("hi"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterMultipleParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterMultipleParams.java new file mode 100644 index 000000000000..55ff7b66dbb4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterMultipleParams.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg, K arg1) { + } +} + +class Tester { + void method() { + new Generic("hi", 1); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterSuperType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterSuperType.java new file mode 100644 index 000000000000..337708e8fb14 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/afterSuperType.java @@ -0,0 +1,13 @@ +import java.io.Serializable; + +// "Change type arguments to " "true" +class Generic { + Generic(E arg, E arg1) { + } +} + +class Tester { + void method() { + new Generic("hi", 1); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/before1.java new file mode 100644 index 000000000000..dd660b853e5c --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/before1.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg) { + } +} + +class Tester { + void method() { + new Generic("hi"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeCorrectTypeParam.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeCorrectTypeParam.java new file mode 100644 index 000000000000..3d3c223e7260 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeCorrectTypeParam.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "false" +class Generic { + Generic(E arg, int i) { + } +} + +class Tester { + void method() { + new Generic("hi", ""); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeDisabled.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeDisabled.java new file mode 100644 index 000000000000..2869486b752e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeDisabled.java @@ -0,0 +1,13 @@ +// "Change type arguments to " "false" +import java.util.List; + +class Generic { + Generic(E arg, List arg1) { + } +} + +class Tester { + void method() { + new Generic("hi", "hi"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete.java new file mode 100644 index 000000000000..b6b5b04cbf2a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "false" +class Generic { + Generic(E arg) { + } +} + +class Tester { + void method() { + new Generic("hi" + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete2.java new file mode 100644 index 000000000000..9b1def3056fc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeIncomplete2.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "false" +class Generic { + Generic(E arg, int i) { + } +} + +class Tester { + void method() { + new Generic("hi"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeMultipleParams.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeMultipleParams.java new file mode 100644 index 000000000000..896686b641fc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeMultipleParams.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg, K arg1) { + } +} + +class Tester { + void method() { + new Generic("hi", 1); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeSuperType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeSuperType.java new file mode 100644 index 000000000000..1b6580752258 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeTypeArgs/beforeSuperType.java @@ -0,0 +1,11 @@ +// "Change type arguments to " "true" +class Generic { + Generic(E arg, E arg1) { + } +} + +class Tester { + void method() { + new Generic("hi", 1); + } +} \ No newline at end of file From 8797cdc948655ac18327be88f5befcbc3a8a392f Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 15 Jun 2012 11:13:17 +0200 Subject: [PATCH 018/100] Undo: skip transparent changes when adding active editor to undo (IDEA-87432) --- .../src/com/intellij/openapi/command/impl/CommandMerger.java | 2 +- .../src/com/intellij/openapi/command/impl/UndoManagerImpl.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java index 20a9f76f8891..7aaaacd6b6c7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java @@ -180,7 +180,7 @@ public class CommandMerger { myForcedGlobal = true; } - private boolean isTransparent() { + public boolean isTransparent() { return myTransparent; } diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java index 60dc5b2e20e7..f753b1fc3996 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -256,7 +256,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap myCommandLevel--; if (myCommandLevel > 0) return; - if (myProject != null && myCurrentMerger.hasActions() && !myCurrentMerger.isGlobal()) { + if (myProject != null && !myCurrentMerger.isGlobal() && myCurrentMerger.hasActions() && !myCurrentMerger.isTransparent()) { addFocusedDocumentAsAffected(); } @@ -270,6 +270,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap PsiFile psiFile = LangDataKeys.PSI_FILE.getData(DataManager.getInstance().getDataContext()); if (psiFile == null) return; + VirtualFile file = psiFile.getVirtualFile(); if (file == null) return; From bfcde9348f36c377dd0c213fff6420730c636f30 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Fri, 15 Jun 2012 13:22:13 +0400 Subject: [PATCH 019/100] Palette --- .../designSurface/DesignerEditorPanel.java | 7 +++++++ .../palette/PaletteItemsComponent.java | 15 ++++++++++++++ .../designer/palette/PalettePanel.java | 20 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java index 7102c3e2ceb6..ac236143dc01 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java @@ -111,6 +111,7 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider protected QuickFixManager myQuickFixManager; + private PaletteItem myActivePaletteItem; private List myExpandedComponents; private Property mySelectionProperty; private int[][] myExpandedState; @@ -317,7 +318,13 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider mySurfaceArea.addSelectionListener(mySourceSelectionListener); } + @Nullable + public final PaletteItem getActivePaletteItem() { + return myActivePaletteItem; + } + public final void activatePaletteItem(@Nullable PaletteItem paletteItem) { + myActivePaletteItem = paletteItem; if (paletteItem != null) { myToolProvider.setActiveTool(new CreationTool(true, createCreationFactory(paletteItem))); } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java index 61bcf90e8ec0..97bca2ef27a2 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PaletteItemsComponent.java @@ -160,6 +160,21 @@ public class PaletteItemsComponent extends JBList { } } + public void restoreSelection(PaletteItem paletteItem) { + if (paletteItem == null) { + clearSelection(); + } + else { + int index = myGroup.getItems().indexOf(paletteItem); + if (index == -1) { + clearSelection(); + } + else { + takeFocusFrom(index); + } + } + } + ////////////////////////////////////////////////////////////////////////////////////////// // // diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java index 7ad81f93cfa8..3a420b558fb5 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java @@ -89,6 +89,15 @@ public class PalettePanel extends JPanel { } public void loadPalette(@Nullable DesignerEditorPanel designer) { + if (myDesigner == null && designer == null) { + return; + } + if (myDesigner != null && designer != null && myGroups.equals(designer.getPaletteGroups())) { + myDesigner = designer; + restoreSelection(); + return; + } + for (PaletteItemsComponent itemsComponent : myItemsComponents) { itemsComponent.removeListSelectionListener(mySelectionListener); } @@ -122,6 +131,17 @@ public class PalettePanel extends JPanel { } myPaletteContainer.revalidate(); + + if (myDesigner != null) { + restoreSelection(); + } + } + + private void restoreSelection() { + PaletteItem paletteItem = myDesigner.getActivePaletteItem(); + for (PaletteItemsComponent itemsComponent : myItemsComponents) { + itemsComponent.restoreSelection(paletteItem); + } } private void notifySelection(@Nullable ListSelectionEvent event) { From c662eb7f4d673f69ea8d3779565d26a2b748be04 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 14 Jun 2012 15:30:33 +0200 Subject: [PATCH 020/100] To JB dictionary; sort --- .../com/intellij/spellchecker/jetbrains.dic | 88 +------------------ 1 file changed, 4 insertions(+), 84 deletions(-) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index b66cb41a1fe0..10afb5b0571f 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -216,8 +216,8 @@ minextents minimizable minvalue miny -mlslabel mixin +mlslabel multi multilinestring multipoint @@ -225,6 +225,7 @@ multipolygon multiset mutex mutexes +mxml mysql namespace namespaces @@ -239,9 +240,9 @@ nocopy nocreate nocycle nodegroup +nohistory noinspection noinspections -nohistory nologging nomapping nomaxvalue @@ -268,9 +269,9 @@ nvarchar oauth objc oidindex -online onchange onclick +online openid openssl outfile @@ -389,84 +390,3 @@ subpartition subpartitions subst substring -subtree -subtrees -subview -subviews -superclass -superclasses -superview -superviews -symlink -symlinks -sysdate -systimestamp -tablespace -taglib -temptable -throwable -timestamp -tinyblob -tinyint -tinytext -todo -toggleable -tokenize -tokenizer -tooltip -tooltips -trebuchet -twitter -typedef -typedefs -unboxing -uncomment -uncommented -underwave -undoable -undofile -unhandled -uninstall -unpivot -unprotect -unwatch -uploader -urowid -username -utf -util -utils -uuid -validator -validators -vararg -varargs -varbinary -varchar -varcharacter -varray -verdana -versa -vertices -watchlist -webservice -whitespace -whitespaces -wifi -wiki -wildcard -wildcards -wordwrap -workflow -wsdl -xcode -xcodeproj -xhtml -xmlschema -xmlschemas -xmltype -xpath -xslt -youtube -zend -zerofill From bcb36ce139a521e06953a340a315e753f0b60671 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 15 Jun 2012 12:16:01 +0200 Subject: [PATCH 021/100] IDEA-79442 (workaround for another useless Metacity clone) --- .../platform-impl/src/com/intellij/idea/IdeaApplication.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java index 679636ad55d1..2c77069a348d 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java @@ -148,6 +148,10 @@ public class IdeaApplication { setWM(xwm, "METACITY_WM"); } } + else if ("Marco".equals(wmName)) { + // Marco is another useless Metacity clone + setWM(xwm, "METACITY_WM"); + } else if ("awesome".equals(wmName)) { try { xwmClass.getDeclaredField("OTHER_NONREPARENTING_WM"); From af31dfe0f7a26be8b4add0eab437136c3d5026f7 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Fri, 15 Jun 2012 15:08:10 +0400 Subject: [PATCH 022/100] IDEA-52112 Make $MODULE_DIR$ default working directory for Maven Run Configurations --- .../execution/MavenRunConfigurationType.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java index 238c88e83a66..4d909653bb41 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfigurationType.java @@ -66,6 +66,29 @@ public class MavenRunConfigurationType implements ConfigurationType { return new MavenRunConfiguration(project, this, ""); } + @Override + public RunConfiguration createConfiguration(String name, RunConfiguration template) { + MavenRunConfiguration cfg = (MavenRunConfiguration)super.createConfiguration(name, template); + + if (!StringUtil.isEmptyOrSpaces(cfg.getRunnerParameters().getWorkingDirPath())) return cfg; + + Project project = cfg.getProject(); + if (project == null) return cfg; + + MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(project); + + List projects = projectsManager.getProjects(); + if (projects.size() != 1) { + return cfg; + } + + VirtualFile directory = projects.get(0).getDirectoryFile(); + + cfg.getRunnerParameters().setWorkingDirPath(directory.getPath()); + + return cfg; + } + @Override public void configureBeforeRunTaskDefaults(Key providerID, BeforeRunTask task) { if (providerID == CompileStepBeforeRun.ID) { From a423481233d27b4943369b459fd3934ab6480891 Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Thu, 14 Jun 2012 18:42:33 +0400 Subject: [PATCH 023/100] IDEA-86405 partial fix --- .../generation/GenerateMembersUtil.java | 283 +++++++++++------- 1 file changed, 178 insertions(+), 105 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 4a9c4df3fb1d..c4ea3d7ab73b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -25,6 +25,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; @@ -32,6 +33,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.psi.impl.light.LightMethodBuilder; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiUtil; @@ -100,7 +102,7 @@ public class GenerateMembersUtil { element = element.getNextSibling(); } if (element instanceof PsiField) { - PsiField field = (PsiField) element; + PsiField field = (PsiField)element; PsiTypeElement typeElement = field.getTypeElement(); if (typeElement != null && !field.equals(typeElement.getParent())) { field.normalizeDeclaration(); @@ -129,7 +131,7 @@ public class GenerateMembersUtil { LOG.assertTrue(firstMember.isValid()); if (toEditMethodBody) { - PsiMethod method = (PsiMethod) firstMember; + PsiMethod method = (PsiMethod)firstMember; PsiCodeBlock body = method.getBody(); if (body != null) { PsiElement l = body.getFirstBodyElement(); @@ -154,7 +156,7 @@ public class GenerateMembersUtil { int offset; if (firstMember instanceof PsiMethod) { - PsiMethod method = (PsiMethod) firstMember; + PsiMethod method = (PsiMethod)firstMember; PsiCodeBlock body = method.getBody(); if (body == null) { offset = method.getTextRange().getStartOffset(); @@ -226,116 +228,187 @@ public class GenerateMembersUtil { return substituteGenericMethod(method, substitutor, null); } - public static PsiMethod substituteGenericMethod(PsiMethod method, - final PsiSubstitutor substitutor, - @Nullable final PsiElement target) { - Project project = method.getProject(); - final JVMElementFactory factory; - if (target != null) { - factory = JVMElementFactories.getFactory(target.getLanguage(), method.getProject()); - } - else { - factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - } + public static PsiMethod substituteGenericMethod(@NotNull PsiMethod sourceMethod, + @NotNull PsiSubstitutor substitutor, + @Nullable PsiElement target) { + final Project project = sourceMethod.getProject(); + final JVMElementFactory factory = getFactory(sourceMethod, target); + final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); + + final Module module = target != null ? ModuleUtil.findModuleForPsiElement(target) : null; + final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null; try { - PsiType returnType = method.getReturnType(); + //final LightMethodBuilder method = new LightMethodBuilder(PsiManager.getInstance(project),""); - PsiMethod newMethod; - if (method.isConstructor()) { - newMethod = factory.createConstructor(); - newMethod.setName(method.getName()); - } - else { - final PsiType substitutedReturnType = substituteType(substitutor, returnType); - newMethod = factory.createMethod(method.getName(), substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType): substitutedReturnType); - } - - VisibilityUtil.setVisibility(newMethod.getModifierList(), VisibilityUtil.getVisibilityModifier(method.getModifierList())); - - PsiElement navigationElement = method.getNavigationElement(); - PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment(); - if (docComment != null) { - newMethod.addAfter(docComment, null); - } - - final Module module = target != null ? ModuleUtil.findModuleForPsiElement(target) : null; - final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null; - - PsiParameter[] parameters = method.getParameterList().getParameters(); - JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); - Map> m = new HashMap>(); - for (int i = 0; i < parameters.length; i++) { - PsiParameter parameter = parameters[i]; - final PsiType parameterType = parameter.getType(); - PsiType substituted = substituteType(substitutor, parameterType); - @NonNls String paramName = parameter.getName(); - boolean isBaseNameGenerated = true; - final boolean isSubstituted = substituted.equals(parameterType); - if (!isSubstituted && isBaseNameGenerated(codeStyleManager, TypeConversionUtil.erasure(parameterType), paramName)) { - isBaseNameGenerated = false; - } - - if (paramName == null || isBaseNameGenerated && !isSubstituted && isBaseNameGenerated(codeStyleManager, parameterType, paramName)) { - Pair pair = m.get(substituted); - if (pair != null) { - paramName = pair.first + pair.second; - m.put(substituted, Pair.create(pair.first, pair.second.intValue() + 1)); - } - else { - String[] names = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, substituted).names; - if (names.length > 0) { - paramName = names[0]; - } else paramName = "p" + i; - - m.put(substituted, new Pair(paramName, 1)); - } - } - - if (paramName == null) paramName = "p" + i; - - PsiParameter newParameter = factory.createParameter(paramName, substituted); - if (parameter.getLanguage() == newParameter.getLanguage()) { - PsiModifierList modifierList = newParameter.getModifierList(); - modifierList = (PsiModifierList)modifierList.replace(parameter.getModifierList()); - if (parameter.getLanguage() == JavaLanguage.INSTANCE) { - processAnnotations(project, modifierList, moduleScope); - } - } - else { - GenerateConstructorHandler.copyModifierList(factory,parameter, newParameter); - } - newMethod.getParameterList().add(newParameter); - } - - for (PsiTypeParameter typeParam : method.getTypeParameters()) { - final PsiElement copy = typeParam.copy(); - final Map replacementMap = new HashMap(); - copy.accept(new JavaRecursiveElementVisitor(){ - @Override - public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { - super.visitReferenceElement(reference); - final PsiElement resolve = reference.resolve(); - if (resolve instanceof PsiTypeParameter) { - replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, factory.createType((PsiTypeParameter)resolve)))); - } - } - }); - newMethod.getTypeParameterList().add(RefactoringUtil.replaceElementsWithMap(copy, replacementMap)); - } - - PsiClassType[] thrownTypes = method.getThrowsList().getReferencedTypes(); - for (PsiClassType thrownType : thrownTypes) { - newMethod.getThrowsList().add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType))); - } - return newMethod; + final PsiMethod resultMethod = createMethod(factory, sourceMethod, substitutor); + copyDocComment(resultMethod, sourceMethod); + copyModifiers(sourceMethod.getModifierList(), resultMethod.getModifierList()); + final PsiSubstitutor collisionResolvedSubstitutor = substituteTypeParameters(factory, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor); + substituteParameters(project, factory, codeStyleManager, moduleScope, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor); + substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor); + return resultMethod; } catch (IncorrectOperationException e) { LOG.error(e); - return method; + return sourceMethod; } } + private static void copyModifiers(@NotNull PsiModifierList sourceModifierList, + @NotNull PsiModifierList targetModifierList) { + VisibilityUtil.setVisibility(targetModifierList, VisibilityUtil.getVisibilityModifier(sourceModifierList)); + } + + @NotNull + private static PsiSubstitutor substituteTypeParameters(@NotNull JVMElementFactory factory, + @Nullable PsiTypeParameterList sourceTypeParameterList, + @Nullable PsiTypeParameterList targetTypeParameterList, + @NotNull PsiSubstitutor substitutor) { + if (sourceTypeParameterList == null || targetTypeParameterList == null) { + return substitutor; + } + + final Map substitutionMap = new HashMap(substitutor.getSubstitutionMap()); + for (PsiTypeParameter typeParam : sourceTypeParameterList.getTypeParameters()) { + final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor); + + final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory,substitutedTypeParam,substitutor); + targetTypeParameterList.add(resolvedTypeParam); + if (substitutedTypeParam != resolvedTypeParam){ + substitutionMap.put(typeParam, factory.createType(resolvedTypeParam)); + } + } + return substitutionMap.isEmpty() ? substitutor : factory.createSubstitutor(substitutionMap); + } + + @NotNull + private static PsiTypeParameter resolveTypeParametersCollision(@NotNull JVMElementFactory factory, + @NotNull PsiTypeParameter typeParam, + @NotNull PsiSubstitutor substitutor) { + for (PsiType type : substitutor.getSubstitutionMap().values()) { + if (Comparing.equal(type.getCanonicalText(), typeParam.getName())) { + final String newName = typeParam.getName() + "1"; + final PsiTypeParameter newTypeParameter = factory.createTypeParameter(newName, typeParam.getSuperTypes()); + substitutor.put(typeParam,factory.createType(newTypeParameter)); + return newTypeParameter; + } + } + return typeParam; + } + + @NotNull + private static PsiTypeParameter substituteTypeParameter(final @NotNull JVMElementFactory factory, + @NotNull PsiTypeParameter typeParameter, + final @NotNull PsiSubstitutor substitutor) { + final PsiElement copy = typeParameter.copy(); + final Map replacementMap = new HashMap(); + copy.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + super.visitReferenceElement(reference); + final PsiElement resolve = reference.resolve(); + if (resolve instanceof PsiTypeParameter) { + final PsiType type = factory.createType((PsiTypeParameter)resolve); + replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type))); + } + } + }); + return (PsiTypeParameter)RefactoringUtil.replaceElementsWithMap(copy, replacementMap); + } + + private static void substituteParameters(@NotNull Project project, + @NotNull JVMElementFactory factory, + @NotNull JavaCodeStyleManager codeStyleManager, + @Nullable GlobalSearchScope moduleScope, + @NotNull PsiParameterList sourceParameterList, + @NotNull PsiParameterList targetParameterList, + @NotNull PsiSubstitutor substitutor) { + PsiParameter[] parameters = sourceParameterList.getParameters(); + Map> m = new HashMap>(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + final PsiType parameterType = parameter.getType(); + final PsiType substituted = substituteType(substitutor, parameterType); + @NonNls String paramName = parameter.getName(); + boolean isBaseNameGenerated = true; + final boolean isSubstituted = substituted.equals(parameterType); + if (!isSubstituted && isBaseNameGenerated(codeStyleManager, TypeConversionUtil.erasure(parameterType), paramName)) { + isBaseNameGenerated = false; + } + + if (paramName == null || isBaseNameGenerated && !isSubstituted && isBaseNameGenerated(codeStyleManager, parameterType, paramName)) { + Pair pair = m.get(substituted); + if (pair != null) { + paramName = pair.first + pair.second; + m.put(substituted, Pair.create(pair.first, pair.second.intValue() + 1)); + } + else { + String[] names = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, substituted).names; + if (names.length > 0) { + paramName = names[0]; + } + else { + paramName = "p" + i; + } + + m.put(substituted, new Pair(paramName, 1)); + } + } + + if (paramName == null) paramName = "p" + i; + final PsiParameter newParameter = factory.createParameter(paramName, substituted); + if (parameter.getLanguage() == newParameter.getLanguage()) { + PsiModifierList modifierList = newParameter.getModifierList(); + modifierList = (PsiModifierList)modifierList.replace(parameter.getModifierList()); + if (parameter.getLanguage() == JavaLanguage.INSTANCE) { + processAnnotations(project, modifierList, moduleScope); + } + } + else { + GenerateConstructorHandler.copyModifierList(factory, parameter, newParameter); + } + targetParameterList.add(newParameter); + } + } + + private static void substituteThrows(@NotNull JVMElementFactory factory, + @NotNull PsiReferenceList sourceThrowsList, + @NotNull PsiReferenceList targetThrowsList, + @NotNull PsiSubstitutor substitutor) { + for (PsiClassType thrownType : sourceThrowsList.getReferencedTypes()) { + targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType))); + } + } + + private static void copyDocComment(PsiMethod source, PsiMethod target) { + final PsiElement navigationElement = source.getNavigationElement(); + final PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment(); + if (docComment != null) { + target.addAfter(docComment, null); + } + } + + @NotNull + private static PsiMethod createMethod(@NotNull JVMElementFactory factory, + @NotNull PsiMethod method, + @NotNull PsiSubstitutor substitutor) { + if (method.isConstructor()) { + return factory.createConstructor(method.getName()); + } + final PsiType substitutedReturnType = substituteType(substitutor, method.getReturnType()); + return factory.createMethod(method.getName(), substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType) : substitutedReturnType); + } + + @NotNull + private static JVMElementFactory getFactory(@NotNull PsiMethod method, @Nullable PsiElement target) { + if (target == null) { + return JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + } + + return JVMElementFactories.getFactory(target.getLanguage(), method.getProject()); + } + private static boolean isBaseNameGenerated(JavaCodeStyleManager codeStyleManager, PsiType parameterType, String paramName) { final String[] baseSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, parameterType).names; boolean isBaseNameGenerated = false; @@ -399,7 +472,7 @@ public class GenerateMembersUtil { public static boolean shouldAddOverrideAnnotation(PsiElement context, boolean interfaceMethod) { CodeStyleSettings style = CodeStyleSettingsManager.getSettings(context.getProject()); if (!style.INSERT_OVERRIDE_ANNOTATION) return false; - + if (interfaceMethod) return PsiUtil.isLanguageLevel6OrHigher(context); return PsiUtil.isLanguageLevel5OrHigher(context); } From 1abe4e08428841d402aaea2f2b13df58ffe8858c Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Thu, 14 Jun 2012 22:12:38 +0400 Subject: [PATCH 024/100] IDEA-86405 fixed --- .../generation/GenerateMembersUtil.java | 65 +++++++++++++++---- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index c4ea3d7ab73b..7f7870030cbe 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -34,8 +34,10 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.impl.light.LightMethodBuilder; +import com.intellij.psi.impl.light.LightTypeElement; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.util.RefactoringUtil; @@ -239,12 +241,12 @@ public class GenerateMembersUtil { final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null; try { - //final LightMethodBuilder method = new LightMethodBuilder(PsiManager.getInstance(project),""); - - final PsiMethod resultMethod = createMethod(factory, sourceMethod, substitutor); + final PsiMethod resultMethod = createMethod(factory, sourceMethod); copyDocComment(resultMethod, sourceMethod); copyModifiers(sourceMethod.getModifierList(), resultMethod.getModifierList()); - final PsiSubstitutor collisionResolvedSubstitutor = substituteTypeParameters(factory, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor); + final PsiSubstitutor collisionResolvedSubstitutor = + substituteTypeParameters(factory, codeStyleManager, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor); + substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor); substituteParameters(project, factory, codeStyleManager, moduleScope, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor); substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor); return resultMethod; @@ -262,6 +264,8 @@ public class GenerateMembersUtil { @NotNull private static PsiSubstitutor substituteTypeParameters(@NotNull JVMElementFactory factory, + @NotNull JavaCodeStyleManager codeStyleManager, + @Nullable PsiElement target, @Nullable PsiTypeParameterList sourceTypeParameterList, @Nullable PsiTypeParameterList targetTypeParameterList, @NotNull PsiSubstitutor substitutor) { @@ -273,9 +277,9 @@ public class GenerateMembersUtil { for (PsiTypeParameter typeParam : sourceTypeParameterList.getTypeParameters()) { final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor); - final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory,substitutedTypeParam,substitutor); + final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory, sourceTypeParameterList, target, substitutedTypeParam, substitutor); targetTypeParameterList.add(resolvedTypeParam); - if (substitutedTypeParam != resolvedTypeParam){ + if (substitutedTypeParam != resolvedTypeParam) { substitutionMap.put(typeParam, factory.createType(resolvedTypeParam)); } } @@ -284,19 +288,45 @@ public class GenerateMembersUtil { @NotNull private static PsiTypeParameter resolveTypeParametersCollision(@NotNull JVMElementFactory factory, + @NotNull PsiTypeParameterList sourceTypeParameterList, + @Nullable PsiElement target, @NotNull PsiTypeParameter typeParam, @NotNull PsiSubstitutor substitutor) { for (PsiType type : substitutor.getSubstitutionMap().values()) { if (Comparing.equal(type.getCanonicalText(), typeParam.getName())) { - final String newName = typeParam.getName() + "1"; + final String newName = suggestUniqueTypeParameterName(typeParam.getName(), sourceTypeParameterList, PsiTreeUtil.getParentOfType(target, PsiClass.class,false)); final PsiTypeParameter newTypeParameter = factory.createTypeParameter(newName, typeParam.getSuperTypes()); - substitutor.put(typeParam,factory.createType(newTypeParameter)); + substitutor.put(typeParam, factory.createType(newTypeParameter)); return newTypeParameter; } } return typeParam; } + @NotNull + private static String suggestUniqueTypeParameterName(@NonNls String baseName, @NotNull PsiTypeParameterList typeParameterList, @Nullable PsiClass targetClass) { + String newName = baseName; + int index = 0; + while ((!checkUniqueTypeParameterName(newName, typeParameterList)) || (targetClass != null && !checkUniqueTypeParameterName(newName, targetClass.getTypeParameterList()))) { + newName = baseName + ++index; + } + + return newName; + } + + + private static boolean checkUniqueTypeParameterName(@NonNls @NotNull String baseName, @Nullable PsiTypeParameterList typeParameterList) { + if (typeParameterList == null) return true; + + for (PsiTypeParameter typeParameter : typeParameterList.getTypeParameters()) { + if (Comparing.equal(typeParameter.getName(), baseName)) { + return false; + } + } + return true; + } + + @NotNull private static PsiTypeParameter substituteTypeParameter(final @NotNull JVMElementFactory factory, @NotNull PsiTypeParameter typeParameter, @@ -391,13 +421,24 @@ public class GenerateMembersUtil { @NotNull private static PsiMethod createMethod(@NotNull JVMElementFactory factory, - @NotNull PsiMethod method, - @NotNull PsiSubstitutor substitutor) { + @NotNull PsiMethod method) { if (method.isConstructor()) { return factory.createConstructor(method.getName()); } - final PsiType substitutedReturnType = substituteType(substitutor, method.getReturnType()); - return factory.createMethod(method.getName(), substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType) : substitutedReturnType); + return factory.createMethod(method.getName(), PsiType.VOID); + } + + private static void substituteReturnType(@NotNull PsiManager manager, + @NotNull PsiMethod method, + @NotNull PsiType returnType, + @NotNull PsiSubstitutor substitutor) { + final PsiTypeElement returnTypeElement = method.getReturnTypeElement(); + if (returnTypeElement == null) { + return; + } + final PsiType substitutedReturnType = substituteType(substitutor, returnType); + + returnTypeElement.replace(new LightTypeElement(manager, substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType) : substitutedReturnType)); } @NotNull From 9da692026b2f3c2176bd9d4faec5f7cd238eec3b Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Fri, 15 Jun 2012 13:40:09 +0400 Subject: [PATCH 025/100] IDEA-86405 "Implement methods" fails to alpha-rename type variables that conflict with class type parameters fixed --- .../codeInsight/generation/GenerateMembersUtil.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 7f7870030cbe..b1cc007de249 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -305,13 +305,13 @@ public class GenerateMembersUtil { @NotNull private static String suggestUniqueTypeParameterName(@NonNls String baseName, @NotNull PsiTypeParameterList typeParameterList, @Nullable PsiClass targetClass) { - String newName = baseName; - int index = 0; - while ((!checkUniqueTypeParameterName(newName, typeParameterList)) || (targetClass != null && !checkUniqueTypeParameterName(newName, targetClass.getTypeParameterList()))) { - newName = baseName + ++index; + int i =0; + while (true) { + final String newName = baseName + ++i; + if (checkUniqueTypeParameterName(newName, typeParameterList) && (targetClass == null || checkUniqueTypeParameterName(newName, targetClass.getTypeParameterList()))){ + return newName; + } } - - return newName; } From 8ab72023cb301bcd0270e56cefaff34376bb8e91 Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Fri, 15 Jun 2012 14:23:37 +0400 Subject: [PATCH 026/100] npe fix --- .../InitializeFinalFieldInConstructorFix.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java index 127aacc4a9a4..f3ab59a2d78a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java @@ -60,14 +60,17 @@ public class InitializeFinalFieldInConstructorFix implements IntentionAction { @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - PsiClass containingClass = myField == null ? null : myField.getContainingClass(); - return myField != null - && myField.getManager().isInProject(myField) - && !myField.hasModifierProperty(PsiModifier.STATIC) - && myField.isValid() - && !myField.hasInitializer() - && containingClass != null - && containingClass.getName() != null; + if (myField == null || myField.hasModifierProperty(PsiModifier.STATIC) || !myField.isValid() || myField.hasInitializer()) { + return false; + } + + final PsiClass containingClass = myField.getContainingClass(); + if (containingClass == null || containingClass.getName() == null){ + return false; + } + + final PsiManager manager = myField.getManager(); + return manager != null && manager.isInProject(myField); } @Override @@ -75,7 +78,9 @@ public class InitializeFinalFieldInConstructorFix implements IntentionAction { if (!CodeInsightUtilBase.prepareFileForWrite(file)) return; final PsiClass myClass = myField.getContainingClass(); - + if (myClass == null) { + return; + } if (myClass.getConstructors().length == 0) { createDefaultConstructor(myClass, project, editor, file); } From c95dcb1535ec49e8381bb4ae0c97306eb1d18890 Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Fri, 15 Jun 2012 15:03:57 +0400 Subject: [PATCH 027/100] family name fixed --- .../intention/impl/BaseRunRefactoringAction.java | 8 +------- .../intention/impl/EncapsulateFieldAction.java | 8 +++++++- ....java => IntroduceVariableIntentionAction.java} | 8 +++++++- .../intention/impl/RunRefactoringAction.java | 8 +++++++- .../src/messages/CodeInsightBundle.properties | 1 - resources/src/META-INF/IdeaPlugin.xml | 14 +++++++------- 6 files changed, 29 insertions(+), 18 deletions(-) rename java/java-impl/src/com/intellij/codeInsight/intention/impl/{IntroduceVariableAction.java => IntroduceVariableIntentionAction.java} (94%) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java index b9fbab23fa76..01678b5fceb5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java @@ -28,15 +28,9 @@ import javax.swing.*; /** * @author Danila Ponomarenko */ -public abstract class BaseRunRefactoringAction implements IntentionAction, Iconable, LowPriorityAction { +public abstract class BaseRunRefactoringAction implements IntentionAction, Iconable, LowPriorityAction { public static final Icon REFACTORING_BULB = AllIcons.Actions.RefactoringBulb; - @NotNull - @Override - public final String getFamilyName() { - return CodeInsightBundle.message("intention.refactoring.family"); - } - @Override public final boolean startInWriteAction() { return false; diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java index 685f37b375b0..cc6f7bee9a25 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable; /** * @author Danila Ponomarenko */ -public class EncapsulateFieldAction extends BaseRunRefactoringAction { +public class EncapsulateFieldAction extends BaseRunRefactoringAction { @NotNull @Override @@ -36,6 +36,12 @@ public class EncapsulateFieldAction extends BaseRunRefactoringAction { +public class IntroduceVariableIntentionAction extends BaseRunRefactoringAction { @NotNull @Override @@ -37,6 +37,12 @@ public class IntroduceVariableAction extends BaseRunRefactoringAction { +public class RunRefactoringAction extends BaseRunRefactoringAction { private final RefactoringActionHandler myHandler; private final String myCommandName; @@ -41,6 +41,12 @@ public class RunRefactoringAction extends BaseRunRefactoringActionDeclaration - com.intellij.codeInsight.intention.impl.IntroduceVariableAction - Declaration - - - com.intellij.codeInsight.intention.impl.EncapsulateFieldAction + com.intellij.codeInsight.daemon.impl.quickfix.DelegateWithDefaultParamValueIntentionAction Declaration - com.intellij.codeInsight.daemon.impl.quickfix.DelegateWithDefaultParamValueIntentionAction - Declaration + com.intellij.codeInsight.intention.impl.IntroduceVariableAction + Refactorings + + + com.intellij.codeInsight.intention.impl.EncapsulateFieldAction + Refactorings From f30cc1ea2eca70a2528372b107233b2a944d59c4 Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Fri, 15 Jun 2012 15:17:53 +0400 Subject: [PATCH 028/100] additional resources renamed --- .../after.java.template | 0 .../before.java.template | 0 .../description.html | 0 resources/src/META-INF/IdeaPlugin.xml | 2 +- 4 files changed, 1 insertion(+), 1 deletion(-) rename resources-en/src/intentionDescriptions/{IntroduceVariableAction => IntroduceVariableIntentionAction}/after.java.template (100%) rename resources-en/src/intentionDescriptions/{IntroduceVariableAction => IntroduceVariableIntentionAction}/before.java.template (100%) rename resources-en/src/intentionDescriptions/{IntroduceVariableAction => IntroduceVariableIntentionAction}/description.html (100%) diff --git a/resources-en/src/intentionDescriptions/IntroduceVariableAction/after.java.template b/resources-en/src/intentionDescriptions/IntroduceVariableIntentionAction/after.java.template similarity index 100% rename from resources-en/src/intentionDescriptions/IntroduceVariableAction/after.java.template rename to resources-en/src/intentionDescriptions/IntroduceVariableIntentionAction/after.java.template diff --git a/resources-en/src/intentionDescriptions/IntroduceVariableAction/before.java.template b/resources-en/src/intentionDescriptions/IntroduceVariableIntentionAction/before.java.template similarity index 100% rename from resources-en/src/intentionDescriptions/IntroduceVariableAction/before.java.template rename to resources-en/src/intentionDescriptions/IntroduceVariableIntentionAction/before.java.template diff --git a/resources-en/src/intentionDescriptions/IntroduceVariableAction/description.html b/resources-en/src/intentionDescriptions/IntroduceVariableIntentionAction/description.html similarity index 100% rename from resources-en/src/intentionDescriptions/IntroduceVariableAction/description.html rename to resources-en/src/intentionDescriptions/IntroduceVariableIntentionAction/description.html diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 442ee82d5606..79a5842fb080 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -645,7 +645,7 @@ - com.intellij.codeInsight.intention.impl.IntroduceVariableAction + com.intellij.codeInsight.intention.impl.IntroduceVariableIntentionAction Refactorings From 30cdbb7791a26c7b1ab438957442cd388cc0a1d0 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 15 Jun 2012 15:15:44 +0400 Subject: [PATCH 029/100] @Nullable --- .../daemon/impl/HighlightInfo.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index 4f0cc0719f27..7255f18995cf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -179,6 +179,7 @@ public class HighlightInfo implements Segment { return EditorColorsManager.getInstance().getGlobalScheme(); } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, @Nullable String description) @@ -192,6 +193,7 @@ public class HighlightInfo implements Segment { return description == null ? null : ""+ XmlStringUtil.escapeString(description)+""; } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, String description, String toolTip) { TextRange range = element.getTextRange(); int start = range.getStartOffset(); @@ -199,10 +201,11 @@ public class HighlightInfo implements Segment { return createHighlightInfo(type, element, start, end, description, toolTip); } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description, String toolTip, boolean isEndOfLine, - TextAttributes forcedAttributes) { + @Nullable TextAttributes forcedAttributes) { LOG.assertTrue(element != null || ArrayUtil.find(HighlightSeverity.DEFAULT_SEVERITIES, type.getSeverity(element)) != -1, "Custom type demands element to detect its text attributes"); HighlightInfo highlightInfo = new HighlightInfo(forcedAttributes, null, type, start, end, description, toolTip, type.getSeverity(element), isEndOfLine, null, false); @@ -214,18 +217,22 @@ public class HighlightInfo implements Segment { } return highlightInfo; } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description, String toolTip) { return createHighlightInfo(type, element, start, end, description, toolTip, false, null); } - @NotNull private static HighlightInfoFilter[] getFilters() { + @NotNull + private static HighlightInfoFilter[] getFilters() { return ApplicationManager.getApplication().getExtensions(HighlightInfoFilter.EXTENSION_POINT_NAME); } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, int start, int end, String description) { return createHighlightInfo(type, null, start, end, description, htmlEscapeToolTip(description)); } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull TextRange textRange, String description) { return createHighlightInfo(type, textRange.getStartOffset(), textRange.getEndOffset(), description); } @@ -346,6 +353,7 @@ public class HighlightInfo implements Segment { return s; } + @Nullable public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull ASTNode childByRole, String localizedMessage) { return createHighlightInfo(type, childByRole.getPsi(), localizedMessage); } @@ -369,8 +377,8 @@ public class HighlightInfo implements Segment { public static HighlightInfo createHighlightInfo(@NotNull final HighlightInfoType type, @NotNull final PsiElement element, - final String message, - final TextAttributes attributes) { + @Nullable final String message, + @Nullable final TextAttributes attributes) { TextRange textRange = element.getTextRange(); // do not use HighlightInfoFilter return new HighlightInfo(attributes, null, type, textRange.getStartOffset(), textRange.getEndOffset(), message, @@ -470,11 +478,11 @@ public class HighlightInfo implements Segment { this(action, null, null, icon); } - public IntentionActionDescriptor(@NotNull IntentionAction action, final List options, final String displayName, Icon icon) { + public IntentionActionDescriptor(@NotNull IntentionAction action, @Nullable final List options, @Nullable final String displayName, @Nullable Icon icon) { this(action, options, displayName, icon, null); } - public IntentionActionDescriptor(@NotNull IntentionAction action, final List options, final String displayName, Icon icon, HighlightDisplayKey key) { + public IntentionActionDescriptor(@NotNull IntentionAction action, final List options, final String displayName, Icon icon, @Nullable HighlightDisplayKey key) { myAction = action; myOptions = options; myDisplayName = displayName; From 8ca4b4a86aeeec8aabdc5bddeeb3e31802ca9f1a Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 15 Jun 2012 15:19:43 +0400 Subject: [PATCH 030/100] Separate keyword highlighting --- plugins/groovy/src/META-INF/plugin.xml | 3 + .../groovy/annotator/GroovyAnnotator.java | 23 ----- .../annotator/KeywordHighlightFactory.java | 44 +++++++++ .../groovy/annotator/KeywordHighlighter.java | 94 +++++++++++++++++++ 4 files changed, 141 insertions(+), 23 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlightFactory.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 1d302ffb98a1..7561c19d5b88 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -1347,6 +1347,9 @@ org.jetbrains.plugins.groovy.codeInspection.local.GroovyUnusedImportsPassFactory + + org.jetbrains.plugins.groovy.annotator.KeywordHighlightFactory + org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManager org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicManagerImpl diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 352f44cf2dd6..2173bb5b9549 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -137,29 +137,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } myHolder = null; } - else { - final IElementType token = element.getNode().getElementType(); - if (TokenSets.KEYWORDS.contains(token)) { - highlightKeyword(element, holder, token); - } - } - } - - private static void highlightKeyword(PsiElement element, AnnotationHolder holder, IElementType token) { - final PsiElement parent = element.getParent(); - if (parent instanceof GrArgumentLabel) return; //don't highlight: print (void:'foo') - - if (PsiTreeUtil.getParentOfType(element, GrCodeReferenceElement.class) != null) { - if (token == GroovyTokenTypes.kDEF || token == GroovyTokenTypes.kIN || token == GroovyTokenTypes.kAS) { - return; //It is allowed to name packages 'as', 'in' or 'def' - } - } - else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) { - return; //don't highlight foo.def - } - - final Annotation annotation = holder.createInfoAnnotation(element, null); - annotation.setTextAttributes(DefaultHighlighter.KEYWORD); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlightFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlightFactory.java new file mode 100644 index 000000000000..64582fe22579 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlightFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.annotator; + +import com.intellij.codeHighlighting.TextEditorHighlightingPass; +import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory; +import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar; +import com.intellij.openapi.components.AbstractProjectComponent; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; + +/** + * @author Max Medvedev + */ +public class KeywordHighlightFactory extends AbstractProjectComponent implements TextEditorHighlightingPassFactory { + protected KeywordHighlightFactory(Project project) { + super(project); + + TextEditorHighlightingPassRegistrar.getInstance(project).registerTextEditorHighlightingPass(this, null, null, false, -1); + } + + + @Override + public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull Editor editor) { + if (!(file instanceof GroovyFile)) return null; + return new KeywordHighlighter((GroovyFile)file, editor.getDocument()); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java new file mode 100644 index 000000000000..600c86638322 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.annotator; + +import com.intellij.codeHighlighting.TextEditorHighlightingPass; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiRecursiveElementVisitor; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.highlighter.DefaultHighlighter; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Max Medvedev + */ +public class KeywordHighlighter extends TextEditorHighlightingPass { + private final GroovyFile myFile; + + private List toHighlight; + + protected KeywordHighlighter(GroovyFile file, Document document) { + super(file.getProject(), document); + myFile = file; + } + + @Override + public void doCollectInformation(@NotNull ProgressIndicator progress) { + final List result = new ArrayList(); + myFile.accept(new PsiRecursiveElementVisitor() { + @Override + public void visitElement(PsiElement element) { + IElementType tokenType = element.getNode().getElementType(); + if (TokenSets.KEYWORDS.contains(tokenType)) { + highlightKeyword(element, result, tokenType); + } + else { + super.visitElement(element); + } + } + }); + toHighlight = result; + } + + private static void highlightKeyword(PsiElement element, List result, IElementType token) { + final PsiElement parent = element.getParent(); + if (parent instanceof GrArgumentLabel) return; //don't highlight: print (void:'foo') + + if (PsiTreeUtil.getParentOfType(element, GrCodeReferenceElement.class) != null) { + if (token == GroovyTokenTypes.kDEF || token == GroovyTokenTypes.kIN || token == GroovyTokenTypes.kAS) { + return; //It is allowed to name packages 'as', 'in' or 'def' + } + } + else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) { + return; //don't highlight foo.def + } + + result.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, element, null, DefaultHighlighter.KEYWORD_ATTRIBUTES)); + } + + + @Override + public void doApplyInformationToEditor() { + if (toHighlight == null) return; + UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, 0, myFile.getTextLength(), toHighlight, getColorsScheme(), + getId()); + } +} From d88e8140b8730a41a8578ce7b5536329e9cc5390 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Thu, 7 Jun 2012 19:47:39 +0400 Subject: [PATCH 031/100] IDEA-83794 File types panel: no speed search in 'Recognized types' list --- .../fileTypes/impl/FileTypeConfigurable.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java index dfde6a833df6..62a90587bbb9 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeConfigurable.java @@ -374,23 +374,27 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable public void run(AnActionButton button) { myController.addFileType(); } - }).setRemoveAction(new AnActionButtonRunnable() { + }) + .setRemoveAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { myController.removeFileType(); } - }).setEditAction(new AnActionButtonRunnable() { + }) + .setEditAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { myController.editFileType(); } - }).setEditActionUpdater(new AnActionButtonUpdater() { + }) + .setEditActionUpdater(new AnActionButtonUpdater() { @Override public boolean isEnabled(AnActionEvent e) { final FileType fileType = getSelectedFileType(); return canBeModified(fileType); } - }).setRemoveActionUpdater(new AnActionButtonUpdater() { + }) + .setRemoveActionUpdater(new AnActionButtonUpdater() { @Override public boolean isEnabled(AnActionEvent e) { final FileType fileType = getSelectedFileType(); @@ -398,7 +402,8 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable final boolean shared = getSchemesManager().isShared(fileType); return shared || modified; } - }).disableUpDownActions(); + }) + .disableUpDownActions(); if (getSchemesManager().isImportAvailable()) { toolbarDecorator.addExtraAction(new AnActionButton("Import Shared...", PlatformIcons.IMPORT_ICON) { @@ -435,6 +440,16 @@ public class FileTypeConfigurable extends BaseConfigurable implements Searchable add(toolbarDecorator.createPanel(), BorderLayout.CENTER); setBorder(IdeBorderFactory.createTitledBorder(FileTypesBundle.message("filetypes.recognized.group"), false)); + + new ListSpeedSearch(myFileTypesList) { + @Override + protected String getElementText(Object element) { + if (element instanceof FileType) { + return ((FileType)element).getDescription(); + } + return super.getElementText(element); + } + }; } private SchemesManager getSchemesManager() { From 59be3cffef81f079c4a7962a99bb3f326d264db5 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Fri, 15 Jun 2012 14:13:01 +0400 Subject: [PATCH 032/100] Icons for bookmarks popup --- .../intellij/ide/bookmarks/actions/DeleteBookmarkAction.java | 2 +- .../ide/bookmarks/actions/EditBookmarkDescriptionAction.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java index 385495b320a0..465e7e617f2f 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/DeleteBookmarkAction.java @@ -32,7 +32,7 @@ class DeleteBookmarkAction extends DumbAwareAction { private final JList myList; DeleteBookmarkAction(Project project, JList list) { - super("Delete", "Delete current bookmark", AllIcons.General.Remove); + super("Delete", "Delete current bookmark", AllIcons.Actions.Delete); myProject = project; myList = list; registerCustomShortcutSet(CustomShortcutSet.fromString("DELETE", "BACK_SPACE"), list); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java index a825d8104602..6860839c8510 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java @@ -35,7 +35,7 @@ class EditBookmarkDescriptionAction extends DumbAwareAction { private JBPopup myPopup; EditBookmarkDescriptionAction(Project project, JList list) { - super("Edit Description", "Assign short description for the bookmark to be shown along the file name", AllIcons.Actions.Properties); + super("Edit Description", "Assign short description for the bookmark to be shown along the file name", AllIcons.Actions.Edit); myProject = project; myList = list; registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(SystemInfo.isMac ? "meta ENTER" : "control ENTER")), list); From 7ae5c857eec076ec8b71b3c7ff8d42029051709c Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Fri, 15 Jun 2012 14:13:49 +0400 Subject: [PATCH 033/100] new icons for HideableTitledPanel --- .../src/com/intellij/ui/HideableTitledPanel.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java b/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java index a3cf0799354d..d6de4db85d25 100644 --- a/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java +++ b/platform/platform-impl/src/com/intellij/ui/HideableTitledPanel.java @@ -11,8 +11,8 @@ import java.awt.event.*; * @author evgeny zakrevsky */ public class HideableTitledPanel extends JPanel { - private final static Icon OFF_ICON = AllIcons.General.ComboArrow; - private final static Icon ON_ICON = AllIcons.General.ComboUpPassive; + private final static Icon OFF_ICON = AllIcons.General.ComboArrowRight; + private final static Icon ON_ICON = AllIcons.General.ComboArrowDown; private TitledSeparatorWithMnemonic myTitledSeparator; private boolean myOn; @@ -25,8 +25,6 @@ public class HideableTitledPanel extends JPanel { add(myContent, BorderLayout.CENTER); myTitledSeparator = new TitledSeparatorWithMnemonic("", null); add(myTitledSeparator, BorderLayout.NORTH); - myTitledSeparator.getLabel().setIcon(OFF_ICON); - myTitledSeparator.getLabel().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); myTitledSeparator.getLabel().addMouseListener(new MouseAdapter() { @Override @@ -65,6 +63,7 @@ public class HideableTitledPanel extends JPanel { protected void on() { myOn = true; myTitledSeparator.getLabel().setIcon(ON_ICON); + myTitledSeparator.getLabel().setIconTextGap(5); myContent.setVisible(true); adjustWindow(); invalidate(); @@ -74,6 +73,7 @@ public class HideableTitledPanel extends JPanel { protected void off() { myOn = false; myTitledSeparator.getLabel().setIcon(OFF_ICON); + myTitledSeparator.getLabel().setIconTextGap(5 + ON_ICON.getIconWidth() - OFF_ICON.getIconWidth()); myContent.setVisible(false); myPreviousContentSize = myContent.getSize(); adjustWindow(); From b598c6d877f659f1b834d4f80505397a08064cd3 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Fri, 15 Jun 2012 15:41:30 +0400 Subject: [PATCH 034/100] removed duplicate borders in bookmarks popup --- .../src/com/intellij/ui/popup/util/DetailViewImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java index 6b0f0fbc6c40..c5f37a7a060d 100644 --- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java @@ -150,7 +150,7 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder validate(); getEditor().getScrollingModel().scrollToCaret(ScrollType.CENTER); - getEditor().setBorder(IdeBorderFactory.createBorder(SideBorder.BOTTOM)); + getEditor().setBorder(IdeBorderFactory.createBorder(SideBorder.NONE)); clearHightlighting(); if (lineAttributes != null) { From 9244fe38f4619ab01acd6d9abbb02335ed36d5fc Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 15 Jun 2012 15:49:55 +0400 Subject: [PATCH 035/100] added ModuleRootModel's implementation delegating to the new project model --- .../model/java/JavaSourceRootProperties.java | 4 +- .../model/library/JpsLibraryReference.java | 3 + .../module/JpsModuleSourceDependency.java | 7 + .../jps/model/module/JpsSdkDependency.java | 6 + .../impl/JpsNamedElementReferenceBase.java | 12 +- .../module/impl/JpsDependenciesListImpl.java | 2 +- .../impl/JpsModuleSourceDependency.java | 25 -- .../impl/JpsModuleSourceDependencyImpl.java | 24 ++ .../module/impl/JpsSdkDependencyImpl.java | 16 +- .../projectModel-impl/projectModel-impl.iml | 2 + .../roots/impl/ModuleOrderEnumerator.java | 6 +- .../openapi/roots/impl/RootModelBase.java | 221 ++++++++++++++++++ .../openapi/roots/impl/RootModelImpl.java | 218 ++--------------- .../project/model/JpsLibraryManager.java | 26 +++ .../project/model/JpsModelManager.java | 40 ++++ .../project/model/JpsModuleManager.java | 26 +++ .../intellij/project/model/JpsSdkManager.java | 31 +++ .../model/impl/JpsModelManagerImpl.java | 77 ++++++ .../impl/library/JpsLibraryManagerImpl.java | 35 +++ .../impl/module/JpsModuleManagerImpl.java | 35 +++ .../impl/module/JpsOrderEntryFactory.java | 46 ++++ .../model/impl/module/JpsRootModel.java | 111 +++++++++ .../impl/module/content/JpsContentEntry.java | 190 +++++++++++++++ .../module/content/JpsContentFolderBase.java | 63 +++++ .../impl/module/content/JpsExcludeFolder.java | 27 +++ .../content/JpsExcludeOutputFolder.java | 32 +++ .../impl/module/content/JpsSourceFolder.java | 61 +++++ .../dependencies/JpsExportableOrderEntry.java | 62 +++++ .../JpsInheritedSdkOrderEntry.java | 36 +++ .../dependencies/JpsLibraryOrderEntry.java | 106 +++++++++ .../dependencies/JpsModuleOrderEntry.java | 71 ++++++ .../dependencies/JpsModuleSdkOrderEntry.java | 36 +++ .../JpsModuleSourceOrderEntry.java | 76 ++++++ .../module/dependencies/JpsOrderEntry.java | 56 +++++ .../dependencies/JpsSdkOrderEntryBase.java | 86 +++++++ .../model/impl/sdk/JpsSdkManagerImpl.java | 35 +++ 36 files changed, 1679 insertions(+), 231 deletions(-) create mode 100644 jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceDependency.java delete mode 100644 jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependency.java create mode 100644 jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependencyImpl.java create mode 100644 platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelBase.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/JpsLibraryManager.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/JpsModelManager.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/JpsModuleManager.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/JpsSdkManager.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/JpsModelManagerImpl.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryManagerImpl.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsModuleManagerImpl.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentFolderBase.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeFolder.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeOutputFolder.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java create mode 100644 platform/projectModel-impl/src/com/intellij/project/model/impl/sdk/JpsSdkManagerImpl.java diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java index 716fc48a91e0..2b1e38ce3d49 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JavaSourceRootProperties.java @@ -1,5 +1,6 @@ package org.jetbrains.jps.model.java; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElementProperties; /** @@ -12,10 +13,11 @@ public class JavaSourceRootProperties extends JpsElementProperties { myPackagePrefix = ""; } - public JavaSourceRootProperties(String packagePrefix) { + public JavaSourceRootProperties(@NotNull String packagePrefix) { myPackagePrefix = packagePrefix; } + @NotNull public String getPackagePrefix() { return myPackagePrefix; } diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java index fb6b173279e7..38200bb70e76 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryReference.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.model.library; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsCompositeElement; import org.jetbrains.jps.model.JpsElementReference; import org.jetbrains.jps.model.JpsModel; @@ -13,4 +14,6 @@ public interface JpsLibraryReference extends JpsElementReference { @Override JpsLibraryReference asExternal(@NotNull JpsModel model); + + JpsElementReference getParentReference(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceDependency.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceDependency.java new file mode 100644 index 000000000000..499a755e7843 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModuleSourceDependency.java @@ -0,0 +1,7 @@ +package org.jetbrains.jps.model.module; + +/** + * @author nik + */ +public interface JpsModuleSourceDependency extends JpsDependencyElement { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java index 934b98c930c7..4bcee42044be 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsSdkDependency.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.model.module; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; import org.jetbrains.jps.model.library.JpsSdkType; /** @@ -14,4 +15,9 @@ public interface JpsSdkDependency extends JpsDependencyElement { @Nullable JpsLibrary resolveSdk(); + + @Nullable + JpsLibraryReference getSdkReference(); + + boolean isInherited(); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java index 94bbe930b864..168652b6ee5e 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java @@ -8,8 +8,10 @@ import java.util.List; /** * @author nik */ -public abstract class JpsNamedElementReferenceBase> extends JpsCompositeElementBase implements JpsElementReference { - private static final JpsElementKind> PARENT_REFERENCE_KIND = new JpsElementKindBase>("parent"); +public abstract class JpsNamedElementReferenceBase> + extends JpsCompositeElementBase implements JpsElementReference { + private static final JpsElementKind> PARENT_REFERENCE_KIND = + new JpsElementKindBase>("parent"); private final JpsElementCollectionKind myCollectionKind; protected final String myElementName; @@ -30,7 +32,7 @@ public abstract class JpsNamedElementReferenceBase elements = parent.getContainer().getChild(myCollectionKind).getElements(); @@ -41,4 +43,8 @@ public abstract class JpsNamedElementReferenceBase getParentReference() { + return myContainer.getChild(PARENT_REFERENCE_KIND); + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java index 6281eb2ed117..a5d0bbb5d11b 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java @@ -63,7 +63,7 @@ public class JpsDependenciesListImpl extends JpsCompositeElementBase { - public JpsModuleSourceDependency() { - super(); - } - - public JpsModuleSourceDependency(JpsModuleSourceDependency original) { - super(original); - } - - @NotNull - @Override - public JpsModuleSourceDependency createCopy() { - return new JpsModuleSourceDependency(this); - } -} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependencyImpl.java new file mode 100644 index 000000000000..611a664aecc0 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceDependencyImpl.java @@ -0,0 +1,24 @@ +package org.jetbrains.jps.model.module.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.JpsModuleSourceDependency; + +/** + * @author nik + */ +public class JpsModuleSourceDependencyImpl extends JpsDependencyElementBase + implements JpsModuleSourceDependency { + public JpsModuleSourceDependencyImpl() { + super(); + } + + public JpsModuleSourceDependencyImpl(JpsModuleSourceDependencyImpl original) { + super(original); + } + + @NotNull + @Override + public JpsModuleSourceDependencyImpl createCopy() { + return new JpsModuleSourceDependencyImpl(this); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java index ebf38444d4c7..5c7954a61e15 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkDependencyImpl.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibraryReference; import org.jetbrains.jps.model.library.JpsSdkType; @@ -11,7 +12,7 @@ import org.jetbrains.jps.model.module.JpsSdkDependency; */ public class JpsSdkDependencyImpl extends JpsDependencyElementBase implements JpsSdkDependency { private final JpsSdkType mySdkType; - + public JpsSdkDependencyImpl(@NotNull JpsSdkType sdkType) { super(); mySdkType = sdkType; @@ -36,10 +37,21 @@ public class JpsSdkDependencyImpl extends JpsDependencyElementBase + + diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java index 4129b5aa54fd..46dc8177942d 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleOrderEnumerator.java @@ -26,10 +26,10 @@ import org.jetbrains.annotations.NotNull; * @author nik */ public class ModuleOrderEnumerator extends OrderEnumeratorBase { - private final RootModelImpl myRootModel; + private final ModuleRootModel myRootModel; - public ModuleOrderEnumerator(RootModelImpl rootModel, final OrderRootsCache cache) { - super(rootModel.getModule(), rootModel.getProject(), cache); + public ModuleOrderEnumerator(ModuleRootModel rootModel, final OrderRootsCache cache) { + super(rootModel.getModule(), rootModel.getModule().getProject(), cache); myRootModel = rootModel; } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelBase.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelBase.java new file mode 100644 index 000000000000..81f6860351de --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelBase.java @@ -0,0 +1,221 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; +import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author nik + */ +public abstract class RootModelBase implements ModuleRootModel { + @Override + @NotNull + public VirtualFile[] getContentRoots() { + final ArrayList result = new ArrayList(); + + for (ContentEntry contentEntry : getContent()) { + final VirtualFile file = contentEntry.getFile(); + if (file != null) { + result.add(file); + } + } + return ContainerUtil.toArray(result, new VirtualFile[result.size()]); + } + + @Override + @NotNull + public String[] getContentRootUrls() { + if (getContent().isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY; + final ArrayList result = new ArrayList(getContent().size()); + + for (ContentEntry contentEntry : getContent()) { + result.add(contentEntry.getUrl()); + } + + return ContainerUtil.toArray(result, new String[result.size()]); + } + + @Override + @NotNull + public String[] getExcludeRootUrls() { + final List result = new SmartList(); + for (ContentEntry contentEntry : getContent()) { + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); + for (ExcludeFolder excludeFolder : excludeFolders) { + result.add(excludeFolder.getUrl()); + } + } + return ContainerUtil.toArray(result, new String[result.size()]); + } + + @Override + @NotNull + public VirtualFile[] getExcludeRoots() { + final List result = new SmartList(); + for (ContentEntry contentEntry : getContent()) { + final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); + for (ExcludeFolder excludeFolder : excludeFolders) { + final VirtualFile file = excludeFolder.getFile(); + if (file != null) { + result.add(file); + } + } + } + return ContainerUtil.toArray(result, new VirtualFile[result.size()]); + } + + @Override + @NotNull + public String[] getSourceRootUrls() { + return getSourceRootUrls(true); + } + + @Override + @NotNull + public String[] getSourceRootUrls(boolean includingTests) { + List result = new SmartList(); + for (ContentEntry contentEntry : getContent()) { + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (SourceFolder sourceFolder : sourceFolders) { + if (includingTests || !sourceFolder.isTestSource()) { + result.add(sourceFolder.getUrl()); + } + } + } + return ContainerUtil.toArray(result, new String[result.size()]); + } + + @Override + @NotNull + public VirtualFile[] getSourceRoots() { + return getSourceRoots(true); + } + + @Override + @NotNull + public VirtualFile[] getSourceRoots(final boolean includingTests) { + List result = new SmartList(); + for (ContentEntry contentEntry : getContent()) { + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (SourceFolder sourceFolder : sourceFolders) { + final VirtualFile file = sourceFolder.getFile(); + if (file != null && (includingTests || !sourceFolder.isTestSource())) { + result.add(file); + } + } + } + return ContainerUtil.toArray(result, new VirtualFile[result.size()]); + } + + @Override + public ContentEntry[] getContentEntries() { + final Collection content = getContent(); + return content.toArray(new ContentEntry[content.size()]); + } + + protected abstract Collection getContent(); + + @Override + public Sdk getSdk() { + for (OrderEntry orderEntry : getOrderEntries()) { + if (orderEntry instanceof JdkOrderEntry) { + return ((JdkOrderEntry)orderEntry).getJdk(); + } + } + return null; + } + + @Override + public boolean isSdkInherited() { + for (OrderEntry orderEntry : getOrderEntries()) { + if (orderEntry instanceof InheritedJdkOrderEntry) { + return true; + } + } + return false; + } + + @NotNull + @Override + public OrderEnumerator orderEntries() { + return new ModuleOrderEnumerator(this, null); + } + + @Override + public R processOrder(RootPolicy policy, R initialValue) { + R result = initialValue; + for (OrderEntry orderEntry : getOrderEntries()) { + result = orderEntry.accept(policy, result); + } + return result; + } + + @Override + @NotNull + public String[] getDependencyModuleNames() { + List result = orderEntries().withoutSdk().withoutLibraries().withoutModuleSourceEntries() + .process(new CollectDependentModules(), new ArrayList()); + return ArrayUtil.toStringArray(result); + } + + @Override + @NotNull + public Module[] getModuleDependencies() { + return getModuleDependencies(true); + } + + @Override + @NotNull + public Module[] getModuleDependencies(boolean includeTests) { + final List result = new ArrayList(); + + for (OrderEntry entry : getOrderEntries()) { + if (entry instanceof ModuleOrderEntry) { + ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)entry; + final DependencyScope scope = moduleOrderEntry.getScope(); + if (!includeTests && !scope.isForProductionCompile() && !scope.isForProductionRuntime()) { + continue; + } + final Module module1 = moduleOrderEntry.getModule(); + if (module1 != null) { + result.add(module1); + } + } + } + + return ContainerUtil.toArray(result, new Module[result.size()]); + } + + private static class CollectDependentModules extends RootPolicy> { + @NotNull + @Override + public List visitModuleOrderEntry(@NotNull ModuleOrderEntry moduleOrderEntry, @NotNull List arrayList) { + arrayList.add(moduleOrderEntry.getModuleName()); + return arrayList; + } + } +} diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java index 14b0ba6ecb79..c50c7949a17c 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -34,7 +34,6 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.util.ArrayUtil; -import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -46,7 +45,7 @@ import java.util.*; /** * @author dsl */ -public class RootModelImpl implements ModifiableRootModel { +public class RootModelImpl extends RootModelBase implements ModifiableRootModel { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootModelImpl"); private final Set myContent = new TreeSet(ContentComparator.INSTANCE); @@ -74,7 +73,8 @@ public class RootModelImpl implements ModifiableRootModel { private final Set myExtensions = new TreeSet(); - private final Map myOrderRootPointerContainers = new HashMap(); + private final Map myOrderRootPointerContainers = + new HashMap(); private final RootConfigurationAccessor myConfigurationAccessor; @@ -83,7 +83,9 @@ public class RootModelImpl implements ModifiableRootModel { // have to register all child disposables using this fake object since all clients just call ModifiableModel.dispose() private final Disposable myDisposable = Disposer.newDisposable(); - RootModelImpl(@NotNull ModuleRootManagerImpl moduleRootManager, ProjectRootManagerImpl projectRootManager, VirtualFilePointerManager filePointerManager) { + RootModelImpl(@NotNull ModuleRootManagerImpl moduleRootManager, + ProjectRootManagerImpl projectRootManager, + VirtualFilePointerManager filePointerManager) { myModuleRootManager = moduleRootManager; myProjectRootManager = projectRootManager; myFilePointerManager = filePointerManager; @@ -145,7 +147,7 @@ public class RootModelImpl implements ModifiableRootModel { myWritable = true; - for(PersistentOrderRootType orderRootType: OrderRootType.getAllPersistentTypes()) { + for (PersistentOrderRootType orderRootType : OrderRootType.getAllPersistentTypes()) { String paths = orderRootType.getModulePathsName(); if (paths != null) { final Element pathsElement = element.getChild(paths); @@ -223,7 +225,7 @@ public class RootModelImpl implements ModifiableRootModel { private void copyContainersFrom(@NotNull RootModelImpl rootModel) { myOrderRootPointerContainers.clear(); - for(PersistentOrderRootType orderRootType: OrderRootType.getAllPersistentTypes()) { + for (PersistentOrderRootType orderRootType : OrderRootType.getAllPersistentTypes()) { final VirtualFilePointerContainer otherContainer = rootModel.getOrderRootContainer(orderRootType); if (otherContainer != null) { myOrderRootPointerContainers.put(orderRootType, otherContainer.clone(myDisposable, null)); @@ -267,110 +269,6 @@ public class RootModelImpl implements ModifiableRootModel { return ContainerUtil.toArray(result, new String[result.size()]); } - @Override - @NotNull - public VirtualFile[] getContentRoots() { - final ArrayList result = new ArrayList(); - - for (ContentEntry contentEntry : myContent) { - final VirtualFile file = contentEntry.getFile(); - if (file != null) { - result.add(file); - } - } - return ContainerUtil.toArray(result, new VirtualFile[result.size()]); - } - - @Override - @NotNull - public String[] getContentRootUrls() { - if (myContent.isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY; - final ArrayList result = new ArrayList(myContent.size()); - - for (ContentEntry contentEntry : myContent) { - result.add(contentEntry.getUrl()); - } - - return ContainerUtil.toArray(result, new String[result.size()]); - } - - @Override - @NotNull - public String[] getExcludeRootUrls() { - final List result = new SmartList(); - for (ContentEntry contentEntry : myContent) { - final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); - for (ExcludeFolder excludeFolder : excludeFolders) { - result.add(excludeFolder.getUrl()); - } - } - return ContainerUtil.toArray(result, new String[result.size()]); - } - - @Override - @NotNull - public VirtualFile[] getExcludeRoots() { - final List result = new SmartList(); - for (ContentEntry contentEntry : myContent) { - final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders(); - for (ExcludeFolder excludeFolder : excludeFolders) { - final VirtualFile file = excludeFolder.getFile(); - if (file != null) { - result.add(file); - } - } - } - return ContainerUtil.toArray(result, new VirtualFile[result.size()]); - } - - @Override - @NotNull - public String[] getSourceRootUrls() { - return getSourceRootUrls(true); - } - - @Override - @NotNull - public String[] getSourceRootUrls(boolean includingTests) { - List result = new SmartList(); - for (ContentEntry contentEntry : myContent) { - final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); - for (SourceFolder sourceFolder : sourceFolders) { - if (includingTests || !sourceFolder.isTestSource()) { - result.add(sourceFolder.getUrl()); - } - } - } - return ContainerUtil.toArray(result, new String[result.size()]); - } - - @Override - @NotNull - public VirtualFile[] getSourceRoots() { - return getSourceRoots(true); - } - - @Override - @NotNull - public VirtualFile[] getSourceRoots(final boolean includingTests) { - List result = new SmartList(); - for (ContentEntry contentEntry : myContent) { - final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); - for (SourceFolder sourceFolder : sourceFolders) { - final VirtualFile file = sourceFolder.getFile(); - if (file != null && (includingTests || !sourceFolder.isTestSource())) { - result.add(file); - } - } - } - return ContainerUtil.toArray(result, new VirtualFile[result.size()]); - } - - @Override - public ContentEntry[] getContentEntries() { - return myContent.toArray(new ContentEntry[myContent.size()]); - } - @Override @NotNull public OrderEntry[] getOrderEntries() { @@ -388,8 +286,8 @@ public class RootModelImpl implements ModifiableRootModel { @Override public void removeContentEntry(@NotNull ContentEntry entry) { assertWritable(); - LOG.assertTrue(myContent.contains(entry)); - myContent.remove(entry); + LOG.assertTrue(getContent().contains(entry)); + getContent().remove(entry); } @Override @@ -473,6 +371,7 @@ public class RootModelImpl implements ModifiableRootModel { String error = checkValidRearrangement(newEntries); LOG.assertTrue(error == null, error); } + @Nullable private String checkValidRearrangement(@NotNull OrderEntry[] newEntries) { if (newEntries.length != myOrderEntries.size()) { @@ -547,21 +446,6 @@ public class RootModelImpl implements ModifiableRootModel { return myModuleLibraryTable; } - @Override - public R processOrder(RootPolicy policy, R initialValue) { - R result = initialValue; - for (OrderEntry orderEntry : getOrderEntries()) { - result = orderEntry.accept(policy, result); - } - return result; - } - - @NotNull - @Override - public OrderEnumerator orderEntries() { - return new ModuleOrderEnumerator(this, null); - } - @Override public Project getProject() { return myProjectRootManager.getProject(); @@ -610,7 +494,7 @@ public class RootModelImpl implements ModifiableRootModel { element.addContent(new Element(EXCLUDE_EXPLODED_TAG)); } - for (ContentEntry contentEntry : myContent) { + for (ContentEntry contentEntry : getContent()) { if (contentEntry instanceof ContentEntryImpl) { final Element subElement = new Element(ContentEntryImpl.ELEMENT_NAME); ((ContentEntryImpl)contentEntry).writeExternal(subElement); @@ -624,7 +508,7 @@ public class RootModelImpl implements ModifiableRootModel { } } - for(PersistentOrderRootType orderRootType: myOrderRootPointerContainers.keySet()) { + for (PersistentOrderRootType orderRootType : myOrderRootPointerContainers.keySet()) { VirtualFilePointerContainer container = myOrderRootPointerContainers.get(orderRootType); if (container != null && container.size() > 0) { final Element javaDocPaths = new Element(orderRootType.getModulePathsName()); @@ -645,7 +529,6 @@ public class RootModelImpl implements ModifiableRootModel { jdkLibraryEntry = null; } replaceEntryOfType(JdkOrderEntry.class, jdkLibraryEntry); - } @Override @@ -680,26 +563,6 @@ public class RootModelImpl implements ModifiableRootModel { } } - @Override - public Sdk getSdk() { - for (OrderEntry orderEntry : getOrderEntries()) { - if (orderEntry instanceof JdkOrderEntry) { - return ((JdkOrderEntry)orderEntry).getJdk(); - } - } - return null; - } - - @Override - public boolean isSdkInherited() { - for (OrderEntry orderEntry : getOrderEntries()) { - if (orderEntry instanceof InheritedJdkOrderEntry) { - return true; - } - } - return false; - } - @Override public String getSdkName() { for (OrderEntry orderEntry : getOrderEntries()) { @@ -733,6 +596,11 @@ public class RootModelImpl implements ModifiableRootModel { return false; } + @Override + protected Set getContent() { + return myContent; + } + private static class ContentComparator implements Comparator { public static final ContentComparator INSTANCE = new ContentComparator(); @@ -800,7 +668,8 @@ public class RootModelImpl implements ModifiableRootModel { final VirtualFilePointerContainer otherContainer = getSourceModel().myOrderRootPointerContainers.get(type); if (container == null || otherContainer == null) { if (container != otherContainer) return true; - } else { + } + else { final String[] urls = container.getUrls(); final String[] otherUrls = otherContainer.getUrls(); if (urls.length != otherUrls.length) return true; @@ -998,6 +867,7 @@ public class RootModelImpl implements ModifiableRootModel { private void clearCachedEntries() { myCachedOrderEntries = null; } + private void setIndicies(int startIndex) { for (int j = startIndex; j < size(); j++) { ((OrderEntryBaseImpl)get(j)).setIndex(j); @@ -1005,13 +875,6 @@ public class RootModelImpl implements ModifiableRootModel { } } - @Override - @NotNull - public String[] getDependencyModuleNames() { - List result = orderEntries().withoutSdk().withoutLibraries().withoutModuleSourceEntries().process(new CollectDependentModules(), new ArrayList()); - return ContainerUtil.toArray(result, new String[result.size()]); - } - @Override @NotNull public VirtualFile[] getRootPaths(final OrderRootType rootType) { @@ -1036,55 +899,18 @@ public class RootModelImpl implements ModifiableRootModel { return ArrayUtil.EMPTY_STRING_ARRAY; } - @Override - @NotNull - public Module[] getModuleDependencies() { - return getModuleDependencies(true); - } - - @Override - @NotNull - public Module[] getModuleDependencies(boolean includeTests) { - final List result = new ArrayList(); - - for (OrderEntry entry : getOrderEntries()) { - if (entry instanceof ModuleOrderEntry) { - ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)entry; - final DependencyScope scope = moduleOrderEntry.getScope(); - if (!includeTests && !scope.isForProductionCompile() && !scope.isForProductionRuntime()) { - continue; - } - final Module module1 = moduleOrderEntry.getModule(); - if (module1 != null) { - result.add(module1); - } - } - } - - return ContainerUtil.toArray(result, new Module[result.size()]); - } - private RootModelImpl getSourceModel() { assertWritable(); return myModuleRootManager.getRootModel(); } - private static class CollectDependentModules extends RootPolicy> { - @NotNull - @Override - public List visitModuleOrderEntry(@NotNull ModuleOrderEntry moduleOrderEntry, @NotNull List arrayList) { - arrayList.add(moduleOrderEntry.getModuleName()); - return arrayList; - } - } - @Override public void setRootUrls(final OrderRootType orderRootType, @NotNull final String[] urls) { assertWritable(); VirtualFilePointerContainer container = myOrderRootPointerContainers.get(orderRootType); if (container == null) { container = myFilePointerManager.createContainer(myDisposable, null); - myOrderRootPointerContainers.put((PersistentOrderRootType) orderRootType, container); + myOrderRootPointerContainers.put((PersistentOrderRootType)orderRootType, container); } container.clear(); for (final String url : urls) { diff --git a/platform/projectModel-impl/src/com/intellij/project/model/JpsLibraryManager.java b/platform/projectModel-impl/src/com/intellij/project/model/JpsLibraryManager.java new file mode 100644 index 000000000000..59bdc722d7a0 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/JpsLibraryManager.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model; + +import com.intellij.openapi.roots.libraries.Library; +import org.jetbrains.jps.model.library.JpsLibrary; + +/** + * @author nik + */ +public interface JpsLibraryManager { + Library getLibrary(JpsLibrary library); +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/JpsModelManager.java b/platform/projectModel-impl/src/com/intellij/project/model/JpsModelManager.java new file mode 100644 index 000000000000..db71750268a4 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/JpsModelManager.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsEventDispatcher; + +/** + * @author nik + */ +public abstract class JpsModelManager { + @NotNull + public abstract JpsModuleManager getModuleManager(); + + public abstract void startModification(JpsEventDispatcher eventDispatcher); + + public abstract void commitChanges(); + + @NotNull + public abstract JpsLibraryManager getLibraryManager(); + + public static JpsModelManager getInstance(@NotNull Project project) { + return ServiceManager.getService(project, JpsModelManager.class); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/JpsModuleManager.java b/platform/projectModel-impl/src/com/intellij/project/model/JpsModuleManager.java new file mode 100644 index 000000000000..05784102b053 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/JpsModuleManager.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model; + +import com.intellij.openapi.module.Module; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public interface JpsModuleManager { + Module getModule(JpsModule jpsModule); +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/JpsSdkManager.java b/platform/projectModel-impl/src/com/intellij/project/model/JpsSdkManager.java new file mode 100644 index 000000000000..5eaf17de9ec4 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/JpsSdkManager.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.projectRoots.Sdk; +import org.jetbrains.jps.model.library.JpsLibrary; + +/** + * @author nik + */ +public abstract class JpsSdkManager { + public static JpsSdkManager getInstance() { + return ServiceManager.getService(JpsSdkManager.class); + } + + public abstract Sdk getSdk(JpsLibrary library); +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/JpsModelManagerImpl.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/JpsModelManagerImpl.java new file mode 100644 index 000000000000..41bf14ab3015 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/JpsModelManagerImpl.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl; + +import com.intellij.project.model.JpsLibraryManager; +import com.intellij.project.model.JpsModelManager; +import com.intellij.project.model.JpsModuleManager; +import com.intellij.project.model.impl.library.JpsLibraryManagerImpl; +import com.intellij.project.model.impl.module.JpsModuleManagerImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsEventDispatcher; +import org.jetbrains.jps.model.JpsModel; +import org.jetbrains.jps.model.JpsNamedElement; +import org.jetbrains.jps.model.impl.JpsEventDispatcherBase; +import org.jetbrains.jps.model.impl.JpsModelImpl; + +/** + * @author nik + */ +public class JpsModelManagerImpl extends JpsModelManager { + private JpsModel myModel; + private JpsModel myModifiableModel; + private final JpsModuleManagerImpl myModuleManager; + private final JpsLibraryManagerImpl myLibraryManager; + + public JpsModelManagerImpl() { + myModel = new JpsModelImpl(new MyJpsEventDispatcher()); + myModuleManager = new JpsModuleManagerImpl(); + myLibraryManager = new JpsLibraryManagerImpl(); + } + + @NotNull + @Override + public JpsModuleManager getModuleManager() { + return myModuleManager; + } + + @Override + @NotNull + public JpsLibraryManager getLibraryManager() { + return myLibraryManager; + } + + @Override + public void startModification(JpsEventDispatcher eventDispatcher) { + myModifiableModel = myModel.createModifiableModel(eventDispatcher); + } + + @Override + public void commitChanges() { + myModifiableModel.commit(); + } + + private static class MyJpsEventDispatcher extends JpsEventDispatcherBase implements JpsEventDispatcher { + @Override + public void fireElementChanged(@NotNull JpsElement element) { + } + + @Override + public void fireElementRenamed(@NotNull JpsNamedElement element, @NotNull String oldName, @NotNull String newName) { + } + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryManagerImpl.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryManagerImpl.java new file mode 100644 index 000000000000..6bbfcf8a4634 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/library/JpsLibraryManagerImpl.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.library; + +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.project.model.JpsLibraryManager; +import org.jetbrains.jps.model.library.JpsLibrary; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author nik + */ +public class JpsLibraryManagerImpl implements JpsLibraryManager { + private Map myLibraries = new HashMap(); + + @Override + public Library getLibrary(JpsLibrary library) { + return myLibraries.get(library); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsModuleManagerImpl.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsModuleManagerImpl.java new file mode 100644 index 000000000000..585f018a6f1d --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsModuleManagerImpl.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module; + +import com.intellij.openapi.module.Module; +import com.intellij.project.model.JpsModuleManager; +import org.jetbrains.jps.model.module.JpsModule; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author nik + */ +public class JpsModuleManagerImpl implements JpsModuleManager { + private Map myModules = new HashMap(); + + @Override + public Module getModule(JpsModule jpsModule) { + return myModules.get(jpsModule); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java new file mode 100644 index 000000000000..2d010ed97ccd --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module; + +import com.intellij.project.model.impl.module.dependencies.*; +import org.jetbrains.jps.model.module.*; + +/** + * @author nik + */ +public class JpsOrderEntryFactory { + public static JpsOrderEntry createOrderEntry(JpsRootModel model, JpsDependencyElement dependencyElement) { + if (dependencyElement instanceof JpsModuleSourceDependency) { + return new JpsModuleSourceOrderEntry(model, (JpsModuleSourceDependency)dependencyElement); + } + else if (dependencyElement instanceof JpsModuleDependency) { + return new JpsModuleOrderEntry(model, (JpsModuleDependency)dependencyElement); + } + else if (dependencyElement instanceof JpsLibraryDependency) { + return new JpsLibraryOrderEntry(model, (JpsLibraryDependency)dependencyElement); + } + else if (dependencyElement instanceof JpsSdkDependency) { + final JpsSdkDependency sdkDependency = (JpsSdkDependency)dependencyElement; + if (sdkDependency.isInherited()) { + return new JpsInheritedSdkOrderEntry(model, sdkDependency); + } + else { + return new JpsModuleSdkOrderEntry(model, sdkDependency); + } + } + throw new UnsupportedOperationException(); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java new file mode 100644 index 000000000000..32e8d44981e5 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.impl.RootModelBase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.project.model.impl.module.content.JpsContentEntry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.JpsDependencyElement; +import org.jetbrains.jps.model.module.JpsModule; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author nik + */ +public class JpsRootModel extends RootModelBase implements ModuleRootModel { + private Module myModule; + private JpsModule myJpsModule; + public VirtualFilePointer myExplodedDirectoryPointer; + private List myContentEntries; + private List myOrderEntries; + + public JpsRootModel(Module module, JpsModule jpsModule) { + myModule = module; + myJpsModule = jpsModule; + myContentEntries = new ArrayList(); + for (String contentRoot : myJpsModule.getContentRootsList().getUrls()) { + myContentEntries.add(new JpsContentEntry(jpsModule, this, contentRoot)); + } + myOrderEntries = new ArrayList(); + for (JpsDependencyElement element : myJpsModule.getDependenciesList().getDependencies()) { + myOrderEntries.add(JpsOrderEntryFactory.createOrderEntry(this, element)); + } + } + + public JpsModule getJpsModule() { + return myJpsModule; + } + + @NotNull + @Override + public Module getModule() { + return myModule; + } + + @Override + protected Collection getContent() { + return myContentEntries; + } + + @NotNull + @Override + public OrderEntry[] getOrderEntries() { + return myOrderEntries.toArray(new OrderEntry[myOrderEntries.size()]); + } + + @Override + public VirtualFile getExplodedDirectory() { + throw new UnsupportedOperationException("'getExplodedDirectory' not implemented in " + getClass().getName()); + } + + @Override + public String getExplodedDirectoryUrl() { + throw new UnsupportedOperationException("'getExplodedDirectoryUrl' not implemented in " + getClass().getName()); + } + + @NotNull + @Override + public VirtualFile[] getRootPaths(OrderRootType rootType) { + throw new UnsupportedOperationException("'getRootPaths' not implemented in " + getClass().getName()); + } + + @NotNull + @Override + public String[] getRootUrls(OrderRootType rootType) { + throw new UnsupportedOperationException("'getRootUrls' not implemented in " + getClass().getName()); + } + + @Override + public T getModuleExtension(Class klass) { + throw new UnsupportedOperationException("'getModuleExtension' not implemented in " + getClass().getName()); + } + + public Project getProject() { + return myModule.getProject(); + } + + public boolean isExcludeExplodedDirectory() { + return false; + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java new file mode 100644 index 000000000000..38343a8bb911 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentEntry.java @@ -0,0 +1,190 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.content; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.roots.ExcludeFolder; +import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.roots.impl.DirectoryIndexExcludePolicy; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleSourceRoot; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class JpsContentEntry implements ContentEntry, Disposable { + private final VirtualFilePointer myRoot; + private final JpsModule myModule; + private final JpsRootModel myRootModel; + private List mySourceFolders; + private List myExcludeFolders; + + public JpsContentEntry(JpsModule module, JpsRootModel rootModel, String rootUrl) { + myModule = module; + myRootModel = rootModel; + myRoot = VirtualFilePointerManager.getInstance().create(rootUrl, this, null); + mySourceFolders = new ArrayList(); + String rootPath = VfsUtilCore.urlToPath(getUrl()); + for (JpsModuleSourceRoot root : myModule.getSourceRoots()) { + if (FileUtil.isAncestor(rootPath, VfsUtilCore.urlToPath(root.getUrl()), false)) { + mySourceFolders.add(new JpsSourceFolder(root, this)); + } + } + myExcludeFolders = new ArrayList(); + for (String excludedUrl : myModule.getExcludeRootsList().getUrls()) { + if (FileUtil.isAncestor(rootPath, VfsUtilCore.urlToPath(excludedUrl), false)) { + myExcludeFolders.add(new JpsExcludeFolder(excludedUrl, this)); + } + } + } + + @Override + public VirtualFile getFile() { + return myRoot.getFile(); + } + + @NotNull + @Override + public String getUrl() { + return myRoot.getUrl(); + } + + @Override + public SourceFolder[] getSourceFolders() { + return mySourceFolders.toArray(new SourceFolder[mySourceFolders.size()]); + } + + @Override + public VirtualFile[] getSourceFolderFiles() { + return getFiles(getSourceFolders()); + } + + private static VirtualFile[] getFiles(ContentFolder[] sourceFolders) { + ArrayList result = new ArrayList(sourceFolders.length); + for (ContentFolder sourceFolder : sourceFolders) { + final VirtualFile file = sourceFolder.getFile(); + if (file != null) { + result.add(file); + } + } + return VfsUtilCore.toVirtualFileArray(result); + } + + @Override + public ExcludeFolder[] getExcludeFolders() { + final ArrayList result = new ArrayList(myExcludeFolders); + for (DirectoryIndexExcludePolicy excludePolicy : Extensions.getExtensions(DirectoryIndexExcludePolicy.EP_NAME, + myRootModel.getProject())) { + final VirtualFilePointer[] files = excludePolicy.getExcludeRootsForModule(myRootModel); + for (VirtualFilePointer file : files) { + addExcludeForOutputPath(file, result); + } + } + if (myRootModel.isExcludeExplodedDirectory()) { + addExcludeForOutputPath(myRootModel.myExplodedDirectoryPointer, result); + } + return result.toArray(new ExcludeFolder[result.size()]); + } + + private void addExcludeForOutputPath(@Nullable final VirtualFilePointer outputPath, @NotNull ArrayList result) { + if (outputPath == null) return; + final VirtualFile outputPathFile = outputPath.getFile(); + final VirtualFile file = myRoot.getFile(); + if (outputPathFile != null && file != null && VfsUtilCore.isAncestor(file, outputPathFile, false)) { + result.add(new JpsExcludeOutputFolder(outputPath.getUrl(), this)); + } + } + + @Override + public VirtualFile[] getExcludeFolderFiles() { + return getFiles(getExcludeFolders()); + } + + @Override + public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource) { + throw new UnsupportedOperationException("'addSourceFolder' not implemented in " + getClass().getName()); + } + + @Override + public SourceFolder addSourceFolder(@NotNull VirtualFile file, boolean isTestSource, @NotNull String packagePrefix) { + throw new UnsupportedOperationException("'addSourceFolder' not implemented in " + getClass().getName()); + } + + @Override + public SourceFolder addSourceFolder(@NotNull String url, boolean isTestSource) { + throw new UnsupportedOperationException("'addSourceFolder' not implemented in " + getClass().getName()); + } + + @Override + public void removeSourceFolder(@NotNull SourceFolder sourceFolder) { + throw new UnsupportedOperationException(); + } + + @Override + public void clearSourceFolders() { + throw new UnsupportedOperationException(); + } + + @Override + public ExcludeFolder addExcludeFolder(@NotNull VirtualFile file) { + throw new UnsupportedOperationException("'addExcludeFolder' not implemented in " + getClass().getName()); + } + + @Override + public ExcludeFolder addExcludeFolder(@NotNull String url) { + throw new UnsupportedOperationException("'addExcludeFolder' not implemented in " + getClass().getName()); + } + + @Override + public void removeExcludeFolder(@NotNull ExcludeFolder excludeFolder) { + throw new UnsupportedOperationException(); + } + + @Override + public void clearExcludeFolders() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isSynthetic() { + return false; + } + + @Override + public void dispose() { + for (JpsSourceFolder folder : mySourceFolders) { + Disposer.dispose(folder); + } + for (JpsExcludeFolder folder : myExcludeFolders) { + Disposer.dispose(folder); + } + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentFolderBase.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentFolderBase.java new file mode 100644 index 000000000000..fa55d06c1dc5 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsContentFolderBase.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.content; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ContentFolder; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; +import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class JpsContentFolderBase implements Disposable, ContentFolder { + protected final JpsContentEntry myContentEntry; + protected VirtualFilePointer myFilePointer; + + public JpsContentFolderBase(String url, JpsContentEntry contentEntry) { + myFilePointer = VirtualFilePointerManager.getInstance().create(url, this, null); + myContentEntry = contentEntry; + } + + @Override + public VirtualFile getFile() { + return myFilePointer.getFile(); + } + + @NotNull + @Override + public ContentEntry getContentEntry() { + return myContentEntry; + } + + @NotNull + @Override + public String getUrl() { + return myFilePointer.getUrl(); + } + + @Override + public boolean isSynthetic() { + return false; + } + + @Override + public void dispose() { + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeFolder.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeFolder.java new file mode 100644 index 000000000000..71bb676f2eed --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeFolder.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.content; + +import com.intellij.openapi.roots.ExcludeFolder; + +/** + * @author nik + */ +public class JpsExcludeFolder extends JpsContentFolderBase implements ExcludeFolder { + public JpsExcludeFolder(String url, JpsContentEntry contentEntry) { + super(url, contentEntry); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeOutputFolder.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeOutputFolder.java new file mode 100644 index 000000000000..262c413fd4cc --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsExcludeOutputFolder.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.content; + +import com.intellij.openapi.roots.ExcludedOutputFolder; + +/** + * @author nik + */ +public class JpsExcludeOutputFolder extends JpsContentFolderBase implements ExcludedOutputFolder { + public JpsExcludeOutputFolder(String url, JpsContentEntry contentEntry) { + super(url, contentEntry); + } + + @Override + public boolean isSynthetic() { + return true; + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java new file mode 100644 index 000000000000..219b0f8bdd12 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/content/JpsSourceFolder.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.content; + +import com.intellij.openapi.roots.SourceFolder; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.java.JavaSourceRootProperties; +import org.jetbrains.jps.model.java.JavaSourceRootType; +import org.jetbrains.jps.model.module.JpsModuleSourceRoot; + +/** + * @author nik + */ +public class JpsSourceFolder extends JpsContentFolderBase implements SourceFolder { + private JpsModuleSourceRoot mySourceRoot; + + public JpsSourceFolder(JpsModuleSourceRoot sourceRoot, JpsContentEntry contentEntry) { + super(sourceRoot.getUrl(), contentEntry); + mySourceRoot = sourceRoot; + } + + @Override + public boolean isTestSource() { + return mySourceRoot.getRootType() == JavaSourceRootType.TEST_SOURCE; + } + + @Override + public String getPackagePrefix() { + final JavaSourceRootProperties properties = getJavaProperties(); + return properties != null ? properties.getPackagePrefix() : ""; + } + + @Nullable + private JavaSourceRootProperties getJavaProperties() { + if (mySourceRoot.getRootType() == JavaSourceRootType.SOURCE) { + return mySourceRoot.getProperties(JavaSourceRootType.SOURCE); + } + else if (mySourceRoot.getRootType() == JavaSourceRootType.TEST_SOURCE) { + return mySourceRoot.getProperties(JavaSourceRootType.TEST_SOURCE); + } + return null; + } + + @Override + public void setPackagePrefix(String packagePrefix) { + mySourceRoot.setProperties((JavaSourceRootType)mySourceRoot.getRootType(), new JavaSourceRootProperties(packagePrefix)); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java new file mode 100644 index 000000000000..693899a33517 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.DependencyScope; +import com.intellij.openapi.roots.ExportableOrderEntry; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.java.JpsJavaDependencyExtension; +import org.jetbrains.jps.model.java.JpsJavaDependencyScope; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.module.JpsDependencyElement; + +/** + * @author nik + */ +public abstract class JpsExportableOrderEntry extends JpsOrderEntry implements ExportableOrderEntry { + public JpsExportableOrderEntry(JpsRootModel rootModel, E dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public boolean isExported() { + final JpsJavaDependencyExtension extension = getExtension(); + return extension != null && extension.isExported(); + } + + @Override + public void setExported(boolean value) { + JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(myDependencyElement).setExported(value); + } + + @NotNull + @Override + public DependencyScope getScope() { + final JpsJavaDependencyExtension extension = getExtension(); + return extension != null ? DependencyScope.valueOf(extension.getScope().name()) : DependencyScope.COMPILE; + } + + private JpsJavaDependencyExtension getExtension() { + return myDependencyElement.getContainer().getChild(JpsJavaExtensionService.getInstance().getDependencyExtensionKind()); + } + + @Override + public void setScope(@NotNull DependencyScope scope) { + JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(myDependencyElement) + .setScope(JpsJavaDependencyScope.valueOf(scope.name())); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java new file mode 100644 index 000000000000..71e3d8423b32 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.InheritedJdkOrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public class JpsInheritedSdkOrderEntry extends JpsSdkOrderEntryBase implements InheritedJdkOrderEntry { + public JpsInheritedSdkOrderEntry(JpsRootModel rootModel, JpsSdkDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + return policy.visitInheritedJdkOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java new file mode 100644 index 000000000000..fe13eb35d967 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.JpsModelManager; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsGlobal; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.module.JpsLibraryDependency; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public class JpsLibraryOrderEntry extends JpsExportableOrderEntry implements LibraryOrderEntry { + public JpsLibraryOrderEntry(JpsRootModel rootModel, JpsLibraryDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public Library getLibrary() { + final JpsLibrary library = myDependencyElement.getLibraryReference().resolve(); + if (library != null) return null; + return JpsModelManager.getInstance(myRootModel.getProject()).getLibraryManager().getLibrary(library); + } + + @Override + public String getLibraryName() { + return myDependencyElement.getLibraryReference().getLibraryName(); + } + + @Override + public String getPresentableName() { + return getLibraryName(); + } + + @NotNull + @Override + public VirtualFile[] getFiles(OrderRootType type) { + return getRootFiles(type); + } + + @NotNull + @Override + public String[] getUrls(OrderRootType rootType) { + return getRootUrls(rootType); + } + + @Override + public VirtualFile[] getRootFiles(OrderRootType type) { + final Library library = getLibrary(); + return library != null ? library.getFiles(type) : VirtualFile.EMPTY_ARRAY; + } + + @Override + public String[] getRootUrls(OrderRootType type) { + final Library library = getLibrary(); + return library != null ? library.getUrls(type) : ArrayUtil.EMPTY_STRING_ARRAY; + } + + @Override + public String getLibraryLevel() { + final JpsElementReference reference = myDependencyElement.getLibraryReference().getParentReference(); + final JpsCompositeElement parent = reference.resolve(); + if (parent instanceof JpsGlobal) return LibraryTablesRegistrar.APPLICATION_LEVEL; + if (parent instanceof JpsProject) return LibraryTablesRegistrar.PROJECT_LEVEL; + if (parent instanceof JpsModule) return LibraryTableImplUtil.MODULE_LEVEL; + return LibraryTablesRegistrar.PROJECT_LEVEL; + } + + @Override + public boolean isModuleLevel() { + return LibraryTableImplUtil.MODULE_LEVEL.equals(getLibraryLevel()); + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + return policy.visitLibraryOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java new file mode 100644 index 000000000000..3617589faf25 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModuleOrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.JpsModelManager; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleDependency; + +/** + * @author nik + */ +public class JpsModuleOrderEntry extends JpsExportableOrderEntry implements ModuleOrderEntry { + public JpsModuleOrderEntry(JpsRootModel rootModel, JpsModuleDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public Module getModule() { + final JpsModule module = myDependencyElement.getModuleReference().resolve(); + if (module != null) return null; + return JpsModelManager.getInstance(myRootModel.getProject()).getModuleManager().getModule(module); + } + + @Override + public String getModuleName() { + return myDependencyElement.getModuleReference().getModuleName(); + } + + @Override + public String getPresentableName() { + return getModuleName(); + } + + @NotNull + @Override + public VirtualFile[] getFiles(OrderRootType type) { + throw new UnsupportedOperationException("'getFiles' not implemented in " + getClass().getName()); + } + + @NotNull + @Override + public String[] getUrls(OrderRootType rootType) { + throw new UnsupportedOperationException("'getUrls' not implemented in " + getClass().getName()); + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + return policy.visitModuleOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java new file mode 100644 index 000000000000..6f263935564a --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.ModuleJdkOrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public class JpsModuleSdkOrderEntry extends JpsSdkOrderEntryBase implements ModuleJdkOrderEntry { + public JpsModuleSdkOrderEntry(JpsRootModel rootModel, JpsSdkDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + return policy.visitModuleJdkOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java new file mode 100644 index 000000000000..27c28c86baee --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsModuleSourceDependency; + +import java.util.ArrayList; + +/** + * @author nik + */ +public class JpsModuleSourceOrderEntry extends JpsOrderEntry implements ModuleSourceOrderEntry { + public JpsModuleSourceOrderEntry(JpsRootModel rootModel, JpsModuleSourceDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + return policy.visitModuleSourceOrderEntry(this, initialValue); + } + + @Override + public String getPresentableName() { + return ProjectBundle.message("project.root.module.source"); + } + + @NotNull + public VirtualFile[] getFiles(OrderRootType type) { + if (OrderRootType.SOURCES.equals(type)) { + return getRootModel().getSourceRoots(); + } + return getRootModel().getRootPaths(type); + } + + @NotNull + public String[] getUrls(OrderRootType type) { + final ArrayList result = new ArrayList(); + if (OrderRootType.SOURCES.equals(type)) { + final ContentEntry[] content = getRootModel().getContentEntries(); + for (ContentEntry contentEntry : content) { + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (SourceFolder sourceFolder : sourceFolders) { + final String url = sourceFolder.getUrl(); + result.add(url); + } + } + return ArrayUtil.toStringArray(result); + } + return getRootModel().getRootUrls(type); + } + + @Override + public ModuleRootModel getRootModel() { + return myRootModel; + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java new file mode 100644 index 000000000000..256354e19807 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.JpsDependencyElement; + +/** + * @author nik + */ +public abstract class JpsOrderEntry implements OrderEntry { + protected final JpsRootModel myRootModel; + protected final E myDependencyElement; + + protected JpsOrderEntry(JpsRootModel rootModel, E dependencyElement) { + myRootModel = rootModel; + myDependencyElement = dependencyElement; + } + + @NotNull + @Override + public Module getOwnerModule() { + return myRootModel.getModule(); + } + + @Override + public boolean isSynthetic() { + return false; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public int compareTo(OrderEntry o) { + throw new UnsupportedOperationException("'compareTo' not implemented in " + getClass().getName()); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java new file mode 100644 index 000000000000..b081c6ba71ef --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.JdkOrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.JpsSdkManager; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public abstract class JpsSdkOrderEntryBase extends JpsOrderEntry implements JdkOrderEntry { + public JpsSdkOrderEntryBase(JpsRootModel rootModel, JpsSdkDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public String getJdkName() { + final JpsLibraryReference reference = myDependencyElement.getSdkReference(); + return reference != null ? reference.getLibraryName() : null; + } + + @NotNull + @Override + public VirtualFile[] getFiles(OrderRootType type) { + return getRootFiles(type); + } + + @NotNull + @Override + public String[] getUrls(OrderRootType rootType) { + return getRootUrls(rootType); + } + + @Override + public Sdk getJdk() { + final JpsLibrary library = myDependencyElement.resolveSdk(); + if (library == null) return null; + return JpsSdkManager.getInstance().getSdk(library); + } + + @Override + public String getPresentableName() { + return "< " + getJdkName() + " >"; + } + + @Override + public VirtualFile[] getRootFiles(OrderRootType type) { + final Sdk sdk = getJdk(); + if (sdk == null) return VirtualFile.EMPTY_ARRAY; + return sdk.getRootProvider().getFiles(type); + } + + @Override + public String[] getRootUrls(OrderRootType type) { + final Sdk jdk = getJdk(); + if (jdk == null) return ArrayUtil.EMPTY_STRING_ARRAY; + return jdk.getRootProvider().getUrls(type); + } + + @Override + public boolean isSynthetic() { + return true; + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/sdk/JpsSdkManagerImpl.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/sdk/JpsSdkManagerImpl.java new file mode 100644 index 000000000000..79690cd6d7c2 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/sdk/JpsSdkManagerImpl.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.sdk; + +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.project.model.JpsSdkManager; +import org.jetbrains.jps.model.library.JpsLibrary; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author nik + */ +public class JpsSdkManagerImpl extends JpsSdkManager { + private Map mySdks = new HashMap(); + + @Override + public Sdk getSdk(JpsLibrary library) { + return mySdks.get(library); + } +} From 3f2bb226b27d3a102c4f3f1d4e49bef3f354e5eb Mon Sep 17 00:00:00 2001 From: irengrig Date: Fri, 15 Jun 2012 16:19:44 +0400 Subject: [PATCH 036/100] short diff: merge neighbour highlighters with same text attributes - save memory --- .../FragmentedEditorHighlighter.java | 47 +++++++++++++++++-- .../changes/PreparedFragmentedContent.java | 4 +- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java index ee88d769d6ae..489ab120d88c 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java @@ -16,6 +16,8 @@ package com.intellij.openapi.editor.highlighter; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.markup.TextAttributes; @@ -36,12 +38,18 @@ public class FragmentedEditorHighlighter implements EditorHighlighter { private final TreeMap myPieces; private final Document myDocument; private final int myAdditionalOffset; + private TextAttributes myUsualAttributes; + private final boolean myMergeByTextAttributes; public FragmentedEditorHighlighter(HighlighterIterator sourceIterator, List ranges) { - this(sourceIterator, ranges, 0); + this(sourceIterator, ranges, 0, false); } - public FragmentedEditorHighlighter(HighlighterIterator sourceIterator, List ranges, final int additionalOffset) { + public FragmentedEditorHighlighter(HighlighterIterator sourceIterator, + List ranges, + final int additionalOffset, + boolean mergeByTextAttributes) { + myMergeByTextAttributes = mergeByTextAttributes; myDocument = sourceIterator.getDocument(); myPieces = new TreeMap(); myAdditionalOffset = additionalOffset; @@ -58,8 +66,23 @@ public class FragmentedEditorHighlighter implements EditorHighlighter { } while (range.getEndOffset() >= iterator.getEnd()) { int relativeStart = iterator.getStart() - range.getStartOffset(); - myPieces.put(offset + relativeStart, new Element(offset + relativeStart, - offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(), iterator.getTextAttributes())); + boolean merged = false; + if (myMergeByTextAttributes && ! myPieces.isEmpty()) { + final Integer first = myPieces.descendingKeySet().first(); + final Element element = myPieces.get(first); + if (element.getEnd() >= offset + relativeStart && myPieces.get(first).getAttributes().equals(iterator.getTextAttributes())) { + // merge + merged = true; + myPieces.put(element.getStart(), new Element(element.getStart(), + offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(), + iterator.getTextAttributes())); + } + } + if (! merged) { + myPieces.put(offset + relativeStart, new Element(offset + relativeStart, + offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(), + iterator.getTextAttributes())); + } iterator.advance(); if (iterator.atEnd()) return; } @@ -152,6 +175,22 @@ public class FragmentedEditorHighlighter implements EditorHighlighter { return myDocument; } } + + private boolean isUsualAttributes(final TextAttributes ta) { + if (myUsualAttributes == null) { + final EditorColorsManager manager = EditorColorsManager.getInstance(); + final EditorColorsScheme[] schemes = manager.getAllSchemes(); + EditorColorsScheme defaultScheme = schemes[0]; + for (EditorColorsScheme scheme : schemes) { + if (manager.isDefaultScheme(scheme)) { + defaultScheme = scheme; + break; + } + } + myUsualAttributes = defaultScheme.getAttributes(HighlighterColors.TEXT); + } + return myUsualAttributes.equals(ta); + } private static class Element { private final int myStart; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java index dc56cb400b9e..7582b10d7c7a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java @@ -316,7 +316,7 @@ public class PreparedFragmentedContent { highlighter.setText(oldDocument.getText()); HighlighterIterator iterator = highlighter.createIterator(ranges.get(0).getBefore().getStartOffset()); FragmentedEditorHighlighter beforeHighlighter = - new FragmentedEditorHighlighter(iterator, getBeforeFragments(), 1); + new FragmentedEditorHighlighter(iterator, getBeforeFragments(), 1, true); setBeforeHighlighter(beforeHighlighter); final EditorHighlighter highlighter1 = @@ -325,7 +325,7 @@ public class PreparedFragmentedContent { highlighter1.setText(document.getText()); HighlighterIterator iterator1 = highlighter1.createIterator(ranges.get(0).getAfter().getStartOffset()); FragmentedEditorHighlighter afterHighlighter = - new FragmentedEditorHighlighter(iterator1, getAfterFragments(), 1); + new FragmentedEditorHighlighter(iterator1, getAfterFragments(), 1, true); setAfterHighlighter(afterHighlighter); } From 9d023ff669b96c31e4e114a5728a585c6969e5ff Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 15 Jun 2012 14:25:34 +0200 Subject: [PATCH 037/100] take sdk minir version into account when choosing sdk to run the build process. From several sdks of the same major version prefer the one with higher minor version --- .../compiler/server/BuildManager.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 5b88d0b428ea..da89f9948413 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -597,6 +597,7 @@ public class BuildManager implements ApplicationComponent{ Sdk projectJdk = internalJdk; final String versionString = projectJdk.getVersionString(); JavaSdkVersion sdkVersion = versionString != null? ((JavaSdk)projectJdk.getSdkType()).getVersion(versionString) : null; + int sdkMinorVersion = getMinorVersion(versionString); if (sdkVersion != null) { final Set candidates = new HashSet(); for (Module module : ModuleManager.getInstance(project).getModules()) { @@ -611,8 +612,11 @@ public class BuildManager implements ApplicationComponent{ if (vs != null) { final JavaSdkVersion candidateVersion = ((JavaSdk)candidate.getSdkType()).getVersion(vs); if (candidateVersion != null) { - if (candidateVersion.compareTo(sdkVersion) > 0) { + final int candidateMinorVersion = getMinorVersion(vs); + final int result = candidateVersion.compareTo(sdkVersion); + if (result > 0 || (result == 0 && candidateMinorVersion > sdkMinorVersion)) { sdkVersion = candidateVersion; + sdkMinorVersion = candidateMinorVersion; projectJdk = candidate; } } @@ -727,6 +731,30 @@ public class BuildManager implements ApplicationComponent{ return cmdLine.createProcess(); } + private static int getMinorVersion(String vs) { + final int dashIndex = vs.lastIndexOf('_'); + if (dashIndex >= 0) { + StringBuilder builder = new StringBuilder(); + for (int idx = dashIndex + 1; idx < vs.length(); idx++) { + final char ch = vs.charAt(idx); + if (Character.isDigit(ch)) { + builder.append(ch); + } + else { + break; + } + } + if (builder.length() > 0) { + try { + return Integer.parseInt(builder.toString()); + } + catch (NumberFormatException ignored) { + } + } + } + return 0; + } + private static void ensureLogConfigExists(File workDirectory) { final File logConfig = new File(workDirectory, LOGGER_CONFIG); if (!logConfig.exists()) { From 18acea604b17e4a308a0688269944cc9d7e47e69 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Fri, 15 Jun 2012 17:10:07 +0400 Subject: [PATCH 038/100] Palette --- .../designer/palette/PalettePanel.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java index 3a420b558fb5..d4a57f06718c 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/palette/PalettePanel.java @@ -26,6 +26,9 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Collections; @@ -40,6 +43,15 @@ public class PalettePanel extends JPanel { private List myItemsComponents = Collections.emptyList(); private List myGroups = Collections.emptyList(); private DesignerEditorPanel myDesigner; + + private final FocusListener myFocusListener = new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + for (PaletteItemsComponent itemsComponent : myItemsComponents) { + itemsComponent.clearSelection(); + } + } + }; private final ListSelectionListener mySelectionListener = new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent event) { @@ -121,13 +133,14 @@ public class PalettePanel extends JPanel { PaletteItemsComponent itemsComponent = new PaletteItemsComponent(group); groupComponent.setItemsComponent(itemsComponent); - myPaletteContainer.add(groupComponent); - myPaletteContainer.add(itemsComponent); - + groupComponent.addFocusListener(myFocusListener); myGroupComponents.add(groupComponent); itemsComponent.addListSelectionListener(mySelectionListener); myItemsComponents.add(itemsComponent); + + myPaletteContainer.add(groupComponent); + myPaletteContainer.add(itemsComponent); } myPaletteContainer.revalidate(); From 34e001cc6e724b0a4354e5f06764a86d489fd980 Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Fri, 15 Jun 2012 17:10:56 +0400 Subject: [PATCH 039/100] tests fixed --- .../codeInsight/generation/GenerateMembersUtil.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index b1cc007de249..2699efc024f3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -293,8 +293,8 @@ public class GenerateMembersUtil { @NotNull PsiTypeParameter typeParam, @NotNull PsiSubstitutor substitutor) { for (PsiType type : substitutor.getSubstitutionMap().values()) { - if (Comparing.equal(type.getCanonicalText(), typeParam.getName())) { - final String newName = suggestUniqueTypeParameterName(typeParam.getName(), sourceTypeParameterList, PsiTreeUtil.getParentOfType(target, PsiClass.class,false)); + if (type != null && Comparing.equal(type.getCanonicalText(), typeParam.getName())) { + final String newName = suggestUniqueTypeParameterName(typeParam.getName(), sourceTypeParameterList, PsiTreeUtil.getParentOfType(target, PsiClass.class, false)); final PsiTypeParameter newTypeParameter = factory.createTypeParameter(newName, typeParam.getSuperTypes()); substitutor.put(typeParam, factory.createType(newTypeParameter)); return newTypeParameter; @@ -305,10 +305,10 @@ public class GenerateMembersUtil { @NotNull private static String suggestUniqueTypeParameterName(@NonNls String baseName, @NotNull PsiTypeParameterList typeParameterList, @Nullable PsiClass targetClass) { - int i =0; + int i = 0; while (true) { final String newName = baseName + ++i; - if (checkUniqueTypeParameterName(newName, typeParameterList) && (targetClass == null || checkUniqueTypeParameterName(newName, targetClass.getTypeParameterList()))){ + if (checkUniqueTypeParameterName(newName, typeParameterList) && (targetClass == null || checkUniqueTypeParameterName(newName, targetClass.getTypeParameterList()))) { return newName; } } @@ -430,10 +430,10 @@ public class GenerateMembersUtil { private static void substituteReturnType(@NotNull PsiManager manager, @NotNull PsiMethod method, - @NotNull PsiType returnType, + @Nullable PsiType returnType, @NotNull PsiSubstitutor substitutor) { final PsiTypeElement returnTypeElement = method.getReturnTypeElement(); - if (returnTypeElement == null) { + if (returnTypeElement == null || returnType == null) { return; } final PsiType substitutedReturnType = substituteType(substitutor, returnType); From ae78fbe1cb82271bd93341469a23d82eba2ddb67 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 15 Jun 2012 17:40:00 +0400 Subject: [PATCH 040/100] +ColorUIResource --- .../intellij/codeInsight/daemon/impl/JavaColorProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java index 7342d334dd0a..6d9370a71315 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaColorProvider.java @@ -37,7 +37,8 @@ public class JavaColorProvider implements ElementColorProvider { if (type != null) { final PsiClass aClass = PsiTypesUtil.getPsiClass(type); if (aClass != null) { - if ("java.awt.Color".equals(aClass.getQualifiedName())) { + final String fqn = aClass.getQualifiedName(); + if ("java.awt.Color".equals(fqn) || "javax.swing.plaf.ColorUIResource".equals(fqn)) { return getColor(expr.getArgumentList()); } } @@ -106,8 +107,7 @@ public class JavaColorProvider implements ElementColorProvider { PsiExpression[] expr = argumentList.getExpressions(); ColorConstructors type = getConstructorType(argumentList.getExpressionTypes()); - PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject()); - + assert type != null; switch (type) { From 1f4c408ac2953593a7d619a8bd69baec0a162bd5 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 15 Jun 2012 16:47:38 +0400 Subject: [PATCH 041/100] JavaClassReference in groovy extension descriptor --- .../plugins/groovy/dgm/DGMClassReference.java | 95 ------------------- .../groovy/dgm/DGMReferenceContributor.java | 8 +- 2 files changed, 7 insertions(+), 96 deletions(-) delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java deleted file mode 100644 index 12d81532794a..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMClassReference.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.dgm; - -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; - -/** - * @author Max Medvedev - */ -public class DGMClassReference implements PsiReference { - private final PsiElement myElement; - private TextRange myRange; - - public DGMClassReference(PsiElement element, int start, int end) { - - myElement = element; - myRange = new TextRange(start, end); - } - - - @Override - public PsiElement getElement() { - return myElement; - } - - @Override - public TextRange getRangeInElement() { - return myRange; - } - - @Override - public PsiElement resolve() { - Project project = myElement.getProject(); - return JavaPsiFacade.getInstance(project).findClass(myRange.substring(myElement.getText()), myElement.getResolveScope()); - } - - @NotNull - @Override - public String getCanonicalText() { - return myRange.substring(myElement.getText()); - } - - @Override - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - @Override - public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { - if (element instanceof PsiClass) { - String qname = ((PsiClass)element).getQualifiedName(); - if (qname == null) return myElement; - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myElement.getProject()); - Document document = documentManager.getDocument(myElement.getContainingFile()); - TextRange range = myRange.shiftRight(myElement.getTextRange().getStartOffset()); - document.replaceString(range.getStartOffset(), range.getEndOffset(), qname); - documentManager.commitDocument(document); - } - return myElement; - } - - @Override - public boolean isReferenceTo(PsiElement element) { - return myElement.getManager().areElementsEquivalent(element, resolve()); - } - - @NotNull - @Override - public Object[] getVariants() { - return EMPTY_ARRAY; - } - - @Override - public boolean isSoft() { - return true; - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java index 442f3e4caed7..2dd7f99dd95c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dgm/DGMReferenceContributor.java @@ -19,7 +19,10 @@ import com.intellij.lang.properties.IProperty; import com.intellij.lang.properties.parsing.PropertiesTokenTypes; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.*; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceSet; import com.intellij.util.ProcessingContext; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -29,6 +32,8 @@ import java.util.ArrayList; */ public class DGMReferenceContributor extends PsiReferenceContributor { + private final JavaClassReferenceProvider myProvider = new JavaClassReferenceProvider(); + @Override public void registerReferenceProviders(PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider(PlatformPatterns.psiElement(PropertiesTokenTypes.VALUE_CHARACTERS), new PsiReferenceProvider() { @@ -50,7 +55,8 @@ public class DGMReferenceContributor extends PsiReferenceContributor { while ((i = skipWhiteSpace(i, text)) < text.length()) { int end = findWhiteSpaceOrComma(i, text); if (end <= text.length()) { - result.add(new DGMClassReference(element, i, end)); + JavaClassReferenceSet set = new JavaClassReferenceSet(text.substring(i, end), element, i, true, myProvider); + ContainerUtil.addAll(result, set.getAllReferences()); } i = end; i = skipWhiteSpace(i, text); From 460d64b5e22bb0a319045571653a652cf64c92b1 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Fri, 15 Jun 2012 17:41:48 +0400 Subject: [PATCH 042/100] fix gdsl --- plugins/groovy/resources/standardDsls/extensions.gdsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/groovy/resources/standardDsls/extensions.gdsl b/plugins/groovy/resources/standardDsls/extensions.gdsl index 534814cd2e97..eeb7f4f4b3ad 100644 --- a/plugins/groovy/resources/standardDsls/extensions.gdsl +++ b/plugins/groovy/resources/standardDsls/extensions.gdsl @@ -17,8 +17,8 @@ package standardDsls -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider +//import com.intellij.psi.search.GlobalSearchScope +//import org.jetbrains.plugins.groovy.dgm.GroovyExtensionProvider /** * @author Maxim.Medvedev @@ -38,12 +38,12 @@ contributor([:]) { category "org.codehaus.groovy.runtime.SwingGroovyMethods" category "org.codehaus.groovy.runtime.XmlGroovyMethods" - def pair = GroovyExtensionProvider.getInstance(project).collectExtensions(GlobalSearchScope.allScope(project)) +/* def pair = GroovyExtensionProvider.getInstance(project).collectExtensions(GlobalSearchScope.allScope(project)) for (def inst : pair.first) { category inst, false } for (def stat : pair.second) { category stat, true - } + }*/ } From b19d88c79b97db43986713471797838ec507590d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 15 Jun 2012 15:01:38 +0400 Subject: [PATCH 043/100] EA-36638 - IAE: DialogWrapperPeerImpl. --- .../src/com/intellij/ide/plugins/PluginManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java index b93eb4736d10..6d0f1127c28a 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java @@ -35,6 +35,8 @@ import com.intellij.openapi.extensions.LogProvider; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.BuildNumber; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; @@ -582,7 +584,7 @@ public class PluginManager { final String description = event.getDescription(); if (EDIT.equals(description)) { final PluginManagerConfigurable configurable = new PluginManagerConfigurable(PluginManagerUISettings.getInstance()); - final Component focusOwner = IdeFocusManager.findInstance().getFocusOwner(); + final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); ShowSettingsUtil.getInstance().editConfigurable(focusOwner, configurable); return; } From 1b873a71610a70f77556101b95925b1da7e2e4b6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 15 Jun 2012 16:53:39 +0400 Subject: [PATCH 044/100] fix inspection display name --- resources/src/META-INF/IdeaPlugin.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 79a5842fb080..f4bbd5083e5a 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -459,8 +459,8 @@ - Date: Fri, 15 Jun 2012 16:57:21 +0400 Subject: [PATCH 045/100] cleanup --- .../refactoring/makeStatic/MakeClassStaticProcessor.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeClassStaticProcessor.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeClassStaticProcessor.java index e3f325f68811..03af8f885246 100644 --- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeClassStaticProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeClassStaticProcessor.java @@ -220,10 +220,7 @@ public class MakeClassStaticProcessor extends MakeMethodOrClassStaticProcessor

    Date: Fri, 15 Jun 2012 17:35:23 +0400 Subject: [PATCH 046/100] do not introduce from q.selection (IDEA-87461) --- .../introduceVariable/IntroduceVariableBase.java | 3 +++ .../IncorrectExpressionSelected.java | 5 +++++ .../intellij/refactoring/IntroduceVariableTest.java | 13 +++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/IncorrectExpressionSelected.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 619ee12db84c..7ec43b9a534d 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -365,6 +365,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { final PsiReferenceExpression refExpr = PsiTreeUtil.getParentOfType(toBeExpression.findElementAt(refIdx[0]), PsiReferenceExpression.class); assert refExpr != null; + if (toBeExpression == refExpr && refIdx[0] > 0) { + return null; + } if (ReplaceExpressionUtil.isNeedParenthesis(refExpr.getNode(), tempExpr.getNode())) { tempExpr.putCopyableUserData(NEED_PARENTHESIS, Boolean.TRUE); return tempExpr; diff --git a/java/java-tests/testData/refactoring/introduceVariable/IncorrectExpressionSelected.java b/java/java-tests/testData/refactoring/introduceVariable/IncorrectExpressionSelected.java new file mode 100644 index 000000000000..a61d032add80 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/IncorrectExpressionSelected.java @@ -0,0 +1,5 @@ +class Foo { + void bar() { + this.toString() + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 2b39a6fea5cb..dda7a76bf962 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -306,6 +306,19 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { }); } + + public void testIncorrectExpressionSelected() throws Exception { + try { + doTest(new MockIntroduceVariableHandler("toString", false, false, false, "java.lang.String")); + } + catch (Exception e) { + assertEquals(e.getMessage(), "Error message:Cannot perform refactoring.\n" + + "Selected block should represent an expression."); + return; + } + fail("Should not be able to perform refactoring"); + } + public void testMultiCatchSimple() throws Exception { doTest(new MockIntroduceVariableHandler("e", true, true, false, "java.lang.Exception", true)); } From 0205891edb6b67ee8fbf6281581626d968e4ba8d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 15 Jun 2012 17:46:10 +0400 Subject: [PATCH 047/100] mnemonic (IDEA-87429) --- .../src/messages/RefactoringBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index e5385b9079b8..b3c3bb13714c 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -378,7 +378,7 @@ make.static.command=Making {0} static introduce.parameter.elements.header=Adding parameter to a method annotate.field.as.nonnls.checkbox=Annotate &field as @NonNls replace.all.occurences.checkbox=Replace &all occurrences -introduce.constant.introduce.to.class=Extract to class (fully qualified name): +introduce.constant.introduce.to.class=Extract to &class (fully qualified name)\: introduce.field.static.field.of.type=Static field of &type: introduce.field.field.of.type=Field of &type: replace.all.occurrences.of.expression.0.occurrences=Replace &all occurrences ({0}) From 71f8951f915265e9f139ac93a99f9feacfab279a Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Fri, 15 Jun 2012 19:02:07 +0400 Subject: [PATCH 048/100] WI-9587 A file load/parse error in JsTestDriver tests --- .../intellij/execution/testframework/sm/FileUrlProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java index 746baebfa6e5..1d3153203314 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/FileUrlProvider.java @@ -93,8 +93,8 @@ public class FileUrlProvider implements TestLocationProvider, DumbAware { } @Nullable - protected static Location createLocationFor(final Project project, - @NotNull final VirtualFile virtualFile, final int lineNum) { + public static Location createLocationFor(final Project project, + @NotNull final VirtualFile virtualFile, final int lineNum) { assert lineNum > 0; final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); From ab0bb9f8f24831c0c56ba2465a58f6e0394f5056 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 15 Jun 2012 12:13:38 +0200 Subject: [PATCH 049/100] don't show @TupleConstructor-generated members in structure view => don't fail on navigation to next/prev member --- .../impl/java/JavaClassTreeElement.java | 6 ++++- .../lang/GroovyStructureViewTest.groovy | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java b/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java index 42ff00545a81..cbae41312814 100644 --- a/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java +++ b/java/java-impl/src/com/intellij/ide/structureView/impl/java/JavaClassTreeElement.java @@ -18,6 +18,7 @@ package com.intellij.ide.structureView.impl.java; import com.intellij.ide.structureView.StructureViewTreeElement; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; +import com.intellij.psi.impl.light.LightElement; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -77,7 +78,10 @@ public class JavaClassTreeElement extends JavaClassTreeElementBase { private static void addPhysicalElements(PsiElement[] elements, LinkedHashSet to) { for (PsiElement element : elements) { - to.add(PsiImplUtil.handleMirror(element)); + PsiElement mirror = PsiImplUtil.handleMirror(element); + if (!(mirror instanceof LightElement)) { + to.add(mirror); + } } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStructureViewTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStructureViewTest.groovy index b2df51554016..7205dd0cd9e1 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStructureViewTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyStructureViewTest.groovy @@ -101,4 +101,27 @@ class Bar extends Foo { } + public void testTupleConstructor() { + myFixture.addClass 'package groovy.transform; public @interface TupleConstructor{}' + myFixture.configureByText 'a.groovy', ''' +@groovy.transform.TupleConstructor +class Foo { + int prop + void foo() {} +} +''' + myFixture.testStructureView(new Consumer() { + @Override + public void consume(StructureViewComponent component) { + component.setActionActive(JavaInheritedMembersNodeProvider.ID, false); + assertTreeEqual(component.getTree(), """-a.groovy + -Foo + foo():void + prop:int +"""); + } + }); + + } + } From bf10735c724e7cd17ab87a4d676e66bec8834bc0 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 15 Jun 2012 12:36:32 +0200 Subject: [PATCH 050/100] when there was a problem during changelist update, still turn off the progress icon when it's finished --- .../com/intellij/openapi/vcs/changes/ChangesViewManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java index 682bc24383f5..67035d680734 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java @@ -501,9 +501,9 @@ public class ChangesViewManager implements ChangesViewI, JDOMExternalizable, Pro scheduleRefresh(); ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(myProject); VcsException updateException = changeListManager.getUpdateException(); + setBusy(false); if (updateException == null) { updateProgressText("", false); - setBusy(false); final Factory additionalUpdateInfo = changeListManager.getAdditionalUpdateInfo(); if (additionalUpdateInfo != null) { updateProgressComponent(additionalUpdateInfo); From 46927c04d0a524b49187531410ffd70d1aef8597 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 15 Jun 2012 13:39:26 +0200 Subject: [PATCH 051/100] a notification suggesting to turn on p4 login option --- .../openapi/vcs/impl/GenericNotifierImpl.java | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java index 1988c07b85d0..78c9e2cac3a0 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/GenericNotifierImpl.java @@ -38,7 +38,7 @@ public abstract class GenericNotifierImpl { @NotNull private final NotificationType myType; @NotNull - private final Map> myState; + private final Map myState; private final MyListener myListener; private final Object myLock; @@ -47,7 +47,7 @@ public abstract class GenericNotifierImpl { myTitle = title; myType = type; myProject = project; - myState = new HashMap>(); + myState = new HashMap(); myListener = new MyListener(); myLock = new Object(); } @@ -71,15 +71,15 @@ public abstract class GenericNotifierImpl { } public void clear() { - final List> notifications; + final List notifications; synchronized (myLock) { - notifications = new ArrayList>(myState.values()); + notifications = new ArrayList(myState.values()); myState.clear(); } final Application application = ApplicationManager.getApplication(); final Runnable runnable = new Runnable() { public void run() { - for (MyNotification notification : notifications) { + for (MyNotification notification : notifications) { notification.expire(); } } @@ -91,7 +91,7 @@ public abstract class GenericNotifierImpl { } } - private void expireNotification(final MyNotification notification) { + private void expireNotification(final MyNotification notification) { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { notification.expire(); @@ -100,13 +100,13 @@ public abstract class GenericNotifierImpl { } public boolean ensureNotify(final T obj) { - final MyNotification notification; + final MyNotification notification; synchronized (myLock) { final Key key = getKey(obj); if (myState.containsKey(key)) { return false; } - notification = new MyNotification(myGroupId, myTitle, getNotificationContent(obj), myType, myListener, obj); + notification = new MyNotification(myGroupId, myTitle, getNotificationContent(obj), myType, myListener, obj); myState.put(key, notification); } final boolean state = onFirstNotification(obj); @@ -123,7 +123,7 @@ public abstract class GenericNotifierImpl { } public void removeLazyNotificationByKey(final Key key) { - final MyNotification notification; + final MyNotification notification; synchronized (myLock) { notification = myState.get(key); if (notification != null) { @@ -136,7 +136,7 @@ public abstract class GenericNotifierImpl { } public void removeLazyNotification(final T obj) { - final MyNotification notification; + final MyNotification notification; synchronized (myLock) { final Key key = getKey(obj); notification = myState.get(key); @@ -151,18 +151,15 @@ public abstract class GenericNotifierImpl { private class MyListener implements NotificationListener { public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { - final String description = event.getDescription(); - if (notification instanceof MyNotification) { - final MyNotification concreteNotification = (MyNotification) notification; - final T obj = concreteNotification.getObj(); - final boolean state = ask(obj, description); - if (state) { - synchronized (myLock) { - final Key key = getKey(obj); - myState.remove(key); - } - expireNotification(concreteNotification); + final MyNotification concreteNotification = (MyNotification) notification; + final T obj = concreteNotification.getObj(); + final boolean state = ask(obj, event.getDescription()); + if (state) { + synchronized (myLock) { + final Key key = getKey(obj); + myState.remove(key); } + expireNotification(concreteNotification); } } } @@ -170,12 +167,12 @@ public abstract class GenericNotifierImpl { @Nullable protected T getObj(final Key key) { synchronized (myLock) { - final MyNotification notification = myState.get(key); + final MyNotification notification = myState.get(key); return notification == null ? null : notification.getObj(); } } - protected static class MyNotification extends Notification { + protected class MyNotification extends Notification { private final T myObj; protected MyNotification(@NotNull String groupId, @@ -192,6 +189,13 @@ public abstract class GenericNotifierImpl { return myObj; } + @Override + public void expire() { + super.expire(); + synchronized (myLock) { + myState.remove(getKey(myObj)); + } + } } private static void log(final String s) { From b4ee10efbbea330e782e9fce642fc2f81882d1d7 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 15 Jun 2012 16:50:43 +0200 Subject: [PATCH 052/100] scroll to the end of Event Log when new notifications appear --- .../src/com/intellij/notification/EventLogConsole.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java index 89490155d5db..25dbb98ea411 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java @@ -134,7 +134,7 @@ class EventLogConsole { } Document document = editor.getDocument(); - boolean scroll = document.getTextLength() == editor.getCaretModel().getOffset(); + boolean scroll = document.getTextLength() == editor.getCaretModel().getOffset() || !editor.getContentComponent().hasFocus(); Long notificationTime = myProjectModel.getNotificationTime(notification); if (notificationTime == null) { From 1d935ce5a64b84abf329b684c4463d9c34d2cc28 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 15 Jun 2012 17:47:36 +0200 Subject: [PATCH 053/100] @NotNull --- .../vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java | 2 +- .../com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java | 2 +- plugins/git4idea/tests/git4idea/test/MockVcsHelper.java | 2 +- .../hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java index 12834d4124ed..dcb230a7bb62 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/AbstractVcsHelper.java @@ -85,7 +85,7 @@ public abstract class AbstractVcsHelper { public abstract void showWhatDiffersBrowser(@Nullable Component parent, Collection changes, @Nls String title); @Nullable - public abstract T chooseCommittedChangeList(CommittedChangesProvider provider, + public abstract T chooseCommittedChangeList(@NotNull CommittedChangesProvider provider, RepositoryLocation location); public abstract void openCommittedChangesTab(AbstractVcs vcs, diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java index ac91eac9666a..f6747b33d9cf 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/AbstractVcsHelperImpl.java @@ -532,7 +532,7 @@ public class AbstractVcsHelperImpl extends AbstractVcsHelper { } @Nullable - public T chooseCommittedChangeList(CommittedChangesProvider provider, + public T chooseCommittedChangeList(@NotNull CommittedChangesProvider provider, RepositoryLocation location) { final List changes; try { diff --git a/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java index 3fa663253131..888cf0aedc69 100644 --- a/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java +++ b/plugins/git4idea/tests/git4idea/test/MockVcsHelper.java @@ -101,7 +101,7 @@ public class MockVcsHelper extends AbstractVcsHelper { } @Override - public T chooseCommittedChangeList(CommittedChangesProvider provider, + public T chooseCommittedChangeList(@NotNull CommittedChangesProvider provider, RepositoryLocation location) { throw new UnsupportedOperationException(); } diff --git a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java index ee4f0b92b2e3..4c75d27c207c 100644 --- a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java +++ b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgMockVcsHelper.java @@ -95,7 +95,7 @@ public class HgMockVcsHelper extends AbstractVcsHelper { } @Override - public T chooseCommittedChangeList(CommittedChangesProvider provider, + public T chooseCommittedChangeList(@NotNull CommittedChangesProvider provider, RepositoryLocation location) { return null; } From ed788f420be27d254b7056841779346bcfc0749e Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 15 Jun 2012 18:20:25 +0200 Subject: [PATCH 054/100] new "Merge sequential method calls into call chain" intention --- .../IntentionPowerPak/src/META-INF/plugin.xml | 4 + .../siyeh/IntentionPowerPackBundle.properties | 2 + .../concatenation/CallSequencePredicate.java | 92 +++++++++++++++++++ .../MergeCallSequenceToChainIntention.java | 78 ++++++++++++++++ .../after.java.template | 6 ++ .../before.java.template | 7 ++ .../description.html | 5 + .../concatenation/merge_sequence/Append.java | 9 ++ .../merge_sequence/Append_after.java | 8 ++ ...MergeCallSequenceToChainIntentionTest.java | 23 +++++ 10 files changed, 234 insertions(+) create mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CallSequencePredicate.java create mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntention.java create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/after.java.template create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/before.java.template create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/description.html create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/META-INF/plugin.xml b/plugins/IntentionPowerPak/src/META-INF/plugin.xml index b022104c9475..878e3435132a 100644 --- a/plugins/IntentionPowerPak/src/META-INF/plugin.xml +++ b/plugins/IntentionPowerPak/src/META-INF/plugin.xml @@ -370,6 +370,10 @@ com.siyeh.ipp.concatenation.MakeCallChainIntoCallSequenceIntention intention.category.other + + com.siyeh.ipp.concatenation.MergeCallSequenceToChainIntention + intention.category.other + com.siyeh.ipp.exceptions.DetailExceptionsIntention intention.category.other diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 86fe12496982..636391392211 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -83,6 +83,8 @@ replace.equality.with.equals.intention.name=Replace '==' with '.equals()' replace.equality.with.equals.intention.family.name=Replace Equality with Equals make.call.chain.into.call.sequence.intention.name=Make method call chain into method call sequence make.call.chain.into.call.sequence.intention.family.name=Make Call Chain Into Call Sequence +merge.call.sequence.to.chain.intention.name=Merge sequential method calls into call chain +merge.call.sequence.to.chain.intention.family.name=Merge Sequential Method Calls into Call Chain detail.exceptions.intention.name=Detail exceptions detail.exceptions.intention.family.name=Detail Exceptions flip.conditional.intention.name=Flip '?:' diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CallSequencePredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CallSequencePredicate.java new file mode 100644 index 000000000000..b5a17409ae32 --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CallSequencePredicate.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.concatenation; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.siyeh.ipp.base.PsiElementPredicate; +import org.jetbrains.annotations.Nullable; + +/** + * @author Bas Leijdekkers + */ +public class CallSequencePredicate implements PsiElementPredicate { + + @Override + public boolean satisfiedBy(PsiElement element) { + if (!(element instanceof PsiExpressionStatement)) { + return false; + } + final PsiStatement statement = (PsiStatement)element; + final PsiStatement nextSibling = PsiTreeUtil.getNextSiblingOfType(statement, PsiStatement.class); + if (nextSibling == null) { + return false; + } + final PsiVariable variable1 = getVariable(statement); + if (variable1 == null) { + return false; + } + final PsiVariable variable2 = getVariable(nextSibling); + return variable1.equals(variable2); + } + + @Nullable + private static PsiVariable getVariable(PsiStatement statement) { + if (!(statement instanceof PsiExpressionStatement)) { + return null; + } + final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)statement; + final PsiExpression expression = expressionStatement.getExpression(); + if (!(expression instanceof PsiMethodCallExpression)) { + return null; + } + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + return getVariable(methodCallExpression); +} + @Nullable + private static PsiVariable getVariable(PsiMethodCallExpression methodCallExpression) { + final PsiType type = methodCallExpression.getType(); + if (!(type instanceof PsiClassType)) { + return null; + } + final PsiClassType classType = (PsiClassType)type; + final PsiClass aClass = classType.resolve(); + if (aClass == null) { + return null; + } + final PsiMethod method = methodCallExpression.resolveMethod(); + if (method == null) { + return null; + } + final PsiClass containingClass = method.getContainingClass(); + if (!aClass.equals(containingClass)) { + return null; + } + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + if (qualifierExpression instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression expression = (PsiMethodCallExpression)qualifierExpression; + return getVariable(expression); + } else if (!(qualifierExpression instanceof PsiReferenceExpression)) { + return null; + }final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifierExpression; + final PsiElement target = referenceExpression.resolve(); + if (!(target instanceof PsiVariable)) { + return null; + } + return (PsiVariable)target; + } +} diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntention.java new file mode 100644 index 000000000000..6f314dce5a6b --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntention.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.concatenation; + +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import com.siyeh.ipp.base.Intention; +import com.siyeh.ipp.base.PsiElementPredicate; +import org.jetbrains.annotations.NotNull; + +/** + * @author Bas Leijdekkers + */ +public class MergeCallSequenceToChainIntention extends Intention { + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new CallSequencePredicate(); + } + + @Override + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + if (!(element instanceof PsiExpressionStatement)) { + return; + } + final PsiExpressionStatement statement = (PsiExpressionStatement)element; + final PsiExpressionStatement nextSibling = PsiTreeUtil.getNextSiblingOfType(statement, PsiExpressionStatement.class); + if (nextSibling == null) { + return; + } + final PsiExpression expression = statement.getExpression(); + final StringBuilder newMethodCallExpression = new StringBuilder(expression.getText()); + final PsiExpression expression1 = nextSibling.getExpression(); + if (!(expression1 instanceof PsiMethodCallExpression)) { + return; + } + PsiMethodCallExpression methodCallExpression = getRootMethodCallExpression((PsiMethodCallExpression)expression1); + while (true) { + final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + final String methodName = methodExpression.getReferenceName(); + newMethodCallExpression.append('.').append(methodName).append(argumentList.getText()); + final PsiElement parent = methodCallExpression.getParent(); + final PsiElement grandParent = parent.getParent(); + if (!(grandParent instanceof PsiMethodCallExpression)) { + break; + } + methodCallExpression = (PsiMethodCallExpression)grandParent; + } + replaceExpression(newMethodCallExpression.toString(), expression); + nextSibling.delete(); + } + + public static PsiMethodCallExpression getRootMethodCallExpression(PsiMethodCallExpression expression) { + final PsiReferenceExpression methodExpression = expression.getMethodExpression(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + if (qualifierExpression instanceof PsiMethodCallExpression) { + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)qualifierExpression; + return getRootMethodCallExpression(methodCallExpression); + } + return expression; + } +} diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/after.java.template new file mode 100644 index 000000000000..8473270fe4ae --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/after.java.template @@ -0,0 +1,6 @@ +public class X { + void f(String a, String b) { + StringBuffer buffer = new StringBuffer(); + buffer.append(a).append(b); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/before.java.template new file mode 100644 index 000000000000..434470b03b25 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/before.java.template @@ -0,0 +1,7 @@ +public class X { + void f(String a, String b) { + StringBuffer buffer = new StringBuffer(); + buffer.append(a); + buffer.append(b); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/description.html new file mode 100644 index 000000000000..4b4963b357ea --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeCallSequenceToChainIntention/description.html @@ -0,0 +1,5 @@ + + +This intention replaces a sequence of two method call statements with the equivalent chain of method calls (may alter semantics). + + diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append.java new file mode 100644 index 000000000000..5cf927048b3f --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append.java @@ -0,0 +1,9 @@ +package com.siyeh.ipp.concatenation.merge_sequence; + +class Append { + + void foo(StringBuilder s) { + s.append(1).append(2); + s.append(3).append(4); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append_after.java new file mode 100644 index 000000000000..ba7b83a3f4af --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/merge_sequence/Append_after.java @@ -0,0 +1,8 @@ +package com.siyeh.ipp.concatenation.merge_sequence; + +class Append { + + void foo(StringBuilder s) { + s.append(1).append(2).append(3).append(4); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntentionTest.java new file mode 100644 index 000000000000..5bd7f85847f7 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/MergeCallSequenceToChainIntentionTest.java @@ -0,0 +1,23 @@ + +package com.siyeh.ipp.concatenation; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @author Bas Leijdekkers + */ +public class MergeCallSequenceToChainIntentionTest extends IPPTestCase { + + public void testAppend() { doTest(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("merge.call.sequence.to.chain.intention.name"); + } + + @Override + protected String getRelativePath() { + return "concatenation/merge_sequence"; + } +} From fb2d9924f8a7fce0b45cdb30031c58215221182d Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Fri, 15 Jun 2012 20:53:46 +0400 Subject: [PATCH 055/100] Palette --- .../designer/model/views-meta-model.xml | 86 +++++++++++-------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml index 3ed8a4dda653..7e004335d2e4 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml +++ b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml @@ -34,7 +34,7 @@ - @@ -46,7 +46,7 @@ - @@ -87,7 +87,7 @@ @@ -257,6 +257,8 @@ + + - + + + + + - @@ -474,6 +480,8 @@ + + + + - - - @@ -1444,57 +1452,61 @@ + + - - - - - - - - - - - - - - - + - - - - - - - - - + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + From 304e4cca1234da31084df81a433384dcdd214141 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 16 Jun 2012 12:17:58 +0400 Subject: [PATCH 056/100] Move to GitHub API v3, refactor. IDEA-85769 * Introduce getRequest() and postRequest() methods as entry points to do a query to the API instead of doREST, which requires releasing an HttpMethod and so on. * Return parsed JsonElement from these methods, since Github API returns the response in JSON format. * Post request in JSON format as well. Get-methods are not called with parameters yet, so don't bother for them. * Use these methods from GithubCreateGistAction which already uses API v3. * Introduce getApiUrl to return the correct API url for github as well as for enterprise installations. * Introduce GithubUser to encapsulate information about a user. Currently it works only for the current user, and stores only its plan to know if private repositories are allowed for the person. * Rewrite RepositoryInfo to be a structured holder of the information about a repository, without working with DOM elements and so on. Rename some methods to make their return value more obvious. * Add @Nullable, @NotNull, javadocs, code style fixes. * In the GithubShareAction move initial pushing to the background to avoid the modality lock with the dialog asking for the passphrase. This fixes IDEA-86645. --- .../github/GithubCheckoutProvider.java | 4 +- .../github/GithubCreateGistAction.java | 75 ++-- .../plugins/github/GithubRebaseAction.java | 2 +- .../plugins/github/GithubSettings.java | 10 +- .../plugins/github/GithubShareAction.java | 100 ++++-- .../jetbrains/plugins/github/GithubUser.java | 66 ++++ .../jetbrains/plugins/github/GithubUtil.java | 320 ++++++++++++------ .../plugins/github/RepositoryInfo.java | 72 ++-- 8 files changed, 439 insertions(+), 210 deletions(-) create mode 100644 plugins/github/src/org/jetbrains/plugins/github/GithubUser.java diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java index 792bca17e313..766f268acfc0 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCheckoutProvider.java @@ -50,7 +50,7 @@ public class GithubCheckoutProvider implements CheckoutProvider { Collections.sort(availableRepos, new Comparator() { @Override public int compare(final RepositoryInfo r1, final RepositoryInfo r2) { - final int comparedOwners = r1.getOwner().compareTo(r2.getOwner()); + final int comparedOwners = r1.getOwnerName().compareTo(r2.getOwnerName()); return comparedOwners != 0 ? comparedOwners : r1.getName().compareTo(r2.getName()); } }); @@ -58,7 +58,7 @@ public class GithubCheckoutProvider implements CheckoutProvider { final GitCloneDialog dialog = new GitCloneDialog(project); // Add predefined repositories to history for (int i = availableRepos.size() - 1; i>=0; i--){ - dialog.prependToHistory(availableRepos.get(i).getUrl()); + dialog.prependToHistory(availableRepos.get(i).getCloneUrl()); } dialog.show(); if (!dialog.isOK()) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java index 83412ba7f292..8531a4571217 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java @@ -17,8 +17,6 @@ package org.jetbrains.plugins.github; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; import com.intellij.ide.BrowserUtil; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; @@ -34,9 +32,6 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitVcs; import git4idea.Notificator; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.ui.GitHubCreateGistDialog; @@ -130,41 +125,7 @@ public class GithubCreateGistAction extends DumbAwareAction { ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { - // Using GitHub Gist API v3: http://developer.github.com/v3/gists/ - final HttpClient client = anonymous ? GithubUtil.getHttpClient(null, null) : GithubUtil.getHttpClient(settings.getLogin(), password); - final PostMethod method = new PostMethod("https://api.github.com/gists"); - - String request = prepareJsonRequest(description, isPrivate, text, file); - - String response; - try { - method.setRequestEntity(new StringRequestEntity(request, "application/json", "UTF-8")); - client.executeMethod(method); - response = method.getResponseBodyAsString(); - } - catch (IOException e1) { - showError(project, "Failed to create gist", "", null, e1); - return; - } - finally { - method.releaseConnection(); - } - - JsonObject jsonResponse; - try { - jsonResponse = new JsonParser().parse(response).getAsJsonObject(); - } - catch (JsonSyntaxException jse) { - showError(project, "Couldn't parse GitHub response", "", response, jse); - return; - } - - JsonElement htmlUrl = jsonResponse.get("html_url"); - if (htmlUrl == null) { - showError(project, "Invalid GitHub response", "No html_url property", response, null); - return; - } - url.set(htmlUrl.getAsString()); + url.set(createGist(project, settings.getLogin(), password, anonymous, text, isPrivate, file, description)); } }, "Communicating With GitHub", false, project); @@ -188,6 +149,40 @@ public class GithubCreateGistAction extends DumbAwareAction { } } + @Nullable + private static String createGist(@NotNull Project project, @Nullable String login, @Nullable String password, boolean anonymous, + @NotNull String text, boolean isPrivate, @NotNull VirtualFile file, @NotNull String description) { + if (anonymous) { + login = null; + password = null; + } + String requestBody = prepareJsonRequest(description, isPrivate, text, file); + try { + JsonElement jsonElement = GithubUtil.postRequest("https://api.github.com", login, password, "/gists", requestBody); + if (jsonElement == null) { + LOG.info("Null JSON response returned by GitHub"); + showError(project, "Failed to create gist", "Empty JSON response returned by GitHub", null, null); + return null; + } + if (!jsonElement.isJsonObject()) { + LOG.error(String.format("Unexpected JSON result format: %s", jsonElement)); + return null; + } + JsonElement htmlUrl = jsonElement.getAsJsonObject().get("html_url"); + if (htmlUrl == null) { + LOG.info("Invalid JSON response: " + jsonElement); + showError(project, "Invalid GitHub response", "No html_url property", jsonElement.toString(), null); + return null; + } + return htmlUrl.getAsString(); + } + catch (IOException e) { + LOG.info("Exception when creating a Gist", e); + showError(project, "Failed to create gist", "", null, e); + return null; + } + } + private static void showError(@NotNull Project project, @NotNull String title, @NotNull String content, @Nullable String details, @Nullable Exception e) { Notificator.getInstance(project).notifyError(title, content); diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index 5967e49727e3..bff7f575b574 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -139,7 +139,7 @@ public class GithubRebaseAction extends DumbAwareAction { return; } - final String parent = repositoryInfo.getParent(); + final String parent = repositoryInfo.getParentName(); LOG.assertTrue(parent != null, "Parent repository not found!"); final String parentRepoSuffix = parent + ".git"; final String parentRepoUrl = "git://github.com/" + parentRepoSuffix; diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java b/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java index 0208f7fdfdfb..ef3857b14f44 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java @@ -29,7 +29,6 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.Messages; import org.jdom.Element; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author oleg @@ -43,13 +42,14 @@ import org.jetbrains.annotations.Nullable; ) public class GithubSettings implements PersistentStateComponent { + public static final String DEFAULT_GITHUB_HOST = "github.com"; + private static final String GITHUB_SETTINGS_TAG = "GithubSettings"; private static final String LOGIN = "Login"; private static final String HOST = "Host"; private static final String ANONIMOUS_GIST = "Anonymous"; private static final String OPEN_IN_BROWSER_GIST = "OpenInBrowser"; private static final String PRIVATE_GIST = "Private"; - private static final String GITHUB = "github.com"; private static final String GITHUB_SETTINGS_PASSWORD_KEY = "GITHUB_SETTINGS_PASSWORD_KEY"; private String myLogin; @@ -117,7 +117,7 @@ public class GithubSettings implements PersistentStateComponent { return myLogin != null ? myLogin : ""; } - @Nullable + @NotNull public String getPassword() { LOG.assertTrue(!ProgressManager.getInstance().hasProgressIndicator(), "Password should not be accessed under modal progress"); String password; @@ -154,7 +154,7 @@ public class GithubSettings implements PersistentStateComponent { } public String getHost() { - return myHost != null ? myHost : GITHUB; + return myHost != null ? myHost : DEFAULT_GITHUB_HOST; } public boolean isAnonymous() { @@ -187,7 +187,7 @@ public class GithubSettings implements PersistentStateComponent { } public void setHost(final String host) { - myHost = host != null ? host : GITHUB; + myHost = host != null ? host : DEFAULT_GITHUB_HOST; } public void setAnonymousGist(final boolean anonymousGist) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java index 68ddeee657bf..263e038ead8c 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java @@ -15,6 +15,8 @@ */ package org.jetbrains.plugins.github; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; @@ -26,11 +28,11 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.ChangeListManager; @@ -53,6 +55,7 @@ import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import git4idea.util.GitFileUtils; import git4idea.util.GitUIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.github.ui.GithubShareDialog; import java.io.IOException; @@ -83,7 +86,7 @@ public class GithubShareAction extends DumbAwareAction { @Override public void actionPerformed(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - if (!GithubUtil.testGitExecutable(project)){ + if (project == null || !GithubUtil.testGitExecutable(project)){ return; } final VirtualFile root = project.getBaseDir(); @@ -136,22 +139,49 @@ public class GithubShareAction extends DumbAwareAction { final String description = shareDialog.getDescription(); try { LOG.info("Creating GitHub repository"); - final String escapedDescription = JDOMUtil.escapeText(description, true, true).replace("&#", "%"); - GithubUtil.doREST(settings.getHost(), settings.getLogin(), settings.getPassword(), - "/repos/create?name=" + name + "&public=" + (isPrivate ? "0" : "1") + "&description=" + escapedDescription, true).releaseConnection(); - LOG.info("Successfully created GitHub repository"); + boolean repositoryCreated = + createGithubRepository(settings.getHost(), settings.getLogin(), settings.getPassword(), name, description, isPrivate); + if (repositoryCreated) { + LOG.info("Successfully created GitHub repository"); + } + else { + Messages.showErrorDialog(project, "Failed to create new GitHub repository", "Create GitHub Repository"); + return; + } } catch (final Exception e1) { Messages.showErrorDialog(e1.getMessage(), "Failed to create new GitHub repository"); return; } - if (bindToGithub(project, root, gitDetected, settings.getLogin(), name)) { - Notifications.Bus.notify(new Notification("github", "Success", "Successfully created project ''" + name + "'' on github", - NotificationType.INFORMATION)); - } + + bindToGithub(project, root, gitDetected, settings.getLogin(), name); } - private boolean bindToGithub(final Project project, final VirtualFile root, final boolean gitDetected, final String login, String name) { + private static boolean createGithubRepository(@NotNull String host, @NotNull String login, @NotNull String password, @NotNull String name, + @NotNull String description, boolean aPrivate) throws IOException { + String path = "/user/repos"; + String requestBody = prepareRequest(name, description, aPrivate); + JsonElement result = GithubUtil.postRequest(host, login, password, path, requestBody); + if (result == null) { + return false; + } + if (!result.isJsonObject()) { + LOG.error(String.format("Unexpected JSON result format: %s", result)); + return false; + } + return result.getAsJsonObject().has("url"); + } + + private static String prepareRequest(String name, String description, boolean isPrivate) { + JsonObject json = new JsonObject(); + json.addProperty("name", name); + json.addProperty("description", description); + json.addProperty("public", Boolean.toString(!isPrivate)); + return json.toString(); + + } + + private void bindToGithub(final Project project, final VirtualFile root, boolean gitDetected, final String login, final String name) { LOG.info("Binding local project with GitHub"); // creating empty git repo if git isnot initialized if (!gitDetected) { @@ -162,7 +192,7 @@ public class GithubShareAction extends DumbAwareAction { if (!h.errors().isEmpty()) { GitUIUtil.showOperationErrors(project, h.errors(), "git init"); LOG.info("Failed to create empty git repo: " + h.errors()); - return false; + return; } final ProgressManager manager = ProgressManager.getInstance(); manager.runProcessWithProgressSynchronously(new Runnable() { @@ -175,7 +205,7 @@ public class GithubShareAction extends DumbAwareAction { // In this case we should create sample commit for binding project if (!performFirstCommitIfRequired(project, root)) { - return false; + return; } //git remote add origin git@github.com:login/name.git @@ -188,36 +218,40 @@ public class GithubShareAction extends DumbAwareAction { addRemoteHandler.run(); if (addRemoteHandler.getExitCode() != 0) { Messages.showErrorDialog("Failed to add GitHub repository as remote", "Failed to add GitHub repository as remote"); - return false; + return; } } catch (VcsException e) { Messages.showErrorDialog(e.getMessage(), "Failed to add GitHub repository as remote"); LOG.info("Failed to add GitHub as remote: " + e.getMessage()); - return false; + return; } //git push origin master - final ProgressManager manager = ProgressManager.getInstance(); + final ArrayList errors = new ArrayList(); - manager.runProcessWithProgressSynchronously(new Runnable() { - public void run() { - final ProgressIndicator progressIndicator = manager.getProgressIndicator(); - if (progressIndicator != null){ - progressIndicator.setText("Pushing to GitHub"); - } - final GitLineHandler gitPushHandler = new GitLineHandler(project, root, GitCommand.PUSH); - gitPushHandler.addParameters("-u", "origin", "master"); - GitPushUtils.trackPushRejectedAsError(gitPushHandler, "Rejected push (" + root.getPresentableUrl() + "): "); - errors.addAll(GitHandlerUtil.doSynchronouslyWithExceptions(gitPushHandler)); + new Task.Backgroundable(project, "Pushing to GitHub", false) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + final GitLineHandler gitPushHandler = new GitLineHandler(project, root, GitCommand.PUSH); + gitPushHandler.addParameters("-u", "origin", "master"); + GitPushUtils.trackPushRejectedAsError(gitPushHandler, "Rejected push (" + root.getPresentableUrl() + "): "); + errors.addAll(GitHandlerUtil.doSynchronouslyWithExceptions(gitPushHandler)); + if (!errors.isEmpty()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + GitUIUtil.showOperationErrors(project, errors, GitBundle.getString("push.active.pushing")); + } + }); } - }, GitBundle.getString("push.active.pushing"), false, project); - if (!errors.isEmpty()) { - GitUIUtil.showOperationErrors(project, errors, GitBundle.getString("push.active.pushing")); - } - // refresh vcs manually - RefreshAction.doRefresh(project); - return true; + else { + RefreshAction.doRefresh(project); + Notifications.Bus.notify(new Notification("github", "Success", "Successfully created project ''" + name + "'' on github", + NotificationType.INFORMATION)); + } + } + }.queue(); } private boolean performFirstCommitIfRequired(final Project project, final VirtualFile root) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUser.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUser.java new file mode 100644 index 000000000000..dbac8d7e6055 --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUser.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.github; + +import org.jetbrains.annotations.NotNull; + +/** + * Information about a user on GitHub. + * + * @author Kirill Likhodedov + */ +class GithubUser { + + enum Plan { + FREE, + MICRO, + SMALL, + MEDIUM, + BRONZE, + SILVER, + GOLD, + PLATINUM; + + public boolean isPrivateRepoAllowed() { + return this != FREE; + } + + public static Plan fromString(String name) { + for (Plan plan : values()) { + if (plan.name().equalsIgnoreCase(name)) { + return plan; + } + } + return defaultPlan(); + } + + private static Plan defaultPlan() { + return FREE; + } + } + + @NotNull private final Plan myPlan; + + GithubUser(@NotNull Plan plan) { + myPlan = plan; + } + + @NotNull + Plan getPlan() { + return myPlan; + } + +} diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 3be5b107733e..6520e1ad2219 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -15,6 +15,10 @@ */ package org.jetbrains.plugins.github; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -37,35 +41,41 @@ import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; -import org.jdom.Element; -import org.jdom.input.SAXBuilder; +import org.apache.commons.httpclient.methods.StringRequestEntity; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.ui.GithubLoginDialog; import javax.swing.*; -import java.io.InputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** + * Various utility methods for the GutHub plugin. + * * @author oleg + * @author Kirill Likhodedov */ public class GithubUtil { - private static final String API_URL = "/api/v2/xml"; - private static final Logger LOG = Logger.getInstance(GithubUtil.class.getName()); + public static final Icon GITHUB_ICON = IconLoader.getIcon("/org/jetbrains/plugins/github/github_icon.png"); + private static final Logger LOG = Logger.getInstance(GithubUtil.class.getName()); + /** + * @deprecated The host may be defined in different formats. Use {@link #getApiUrl(String)} instead. + */ + @Deprecated public static String getHttpsUrl() { return "https://" + GithubSettings.getInstance().getHost(); } - public static String getHostByUrl(final String url) { - return url.startsWith("https://") ? url.substring(8) : url.startsWith("http://") ? url.substring(7) : url.startsWith("git@") ? url.substring(4) : url; - } - + /** + * @deprecated TODO Use background progress + */ + @Deprecated public static T accessToGithubWithModalProgress(final Project project, final Computable computable) { final Ref result = new Ref(); ProgressManager.getInstance().run(new Task.Modal(project, "Access to GitHub", true) { @@ -76,6 +86,10 @@ public class GithubUtil { return result.get(); } + /** + * @deprecated TODO Use background progress + */ + @Deprecated public static void accessToGithubWithModalProgress(final Project project, final Runnable runnable) { ProgressManager.getInstance().run(new Task.Modal(project, "Access to GitHub", true) { public void run(@NotNull ProgressIndicator indicator) { @@ -84,38 +98,113 @@ public class GithubUtil { }); } - public static boolean testConnection(final String url, final String login, final String password) { + @Nullable + public static JsonElement getRequest(@NotNull String host, @NotNull String login, @NotNull String password, + @NotNull String path) throws IOException { + return request(host, login, password, path, null, false); + } + + @Nullable + public static JsonElement postRequest(@NotNull String host, @Nullable String login, @Nullable String password, + @NotNull String path, @Nullable String requestBody) throws IOException { + return request(host, login, password, path, requestBody, true); + } + + @Nullable + private static JsonElement request(@NotNull String host, @Nullable String login, @Nullable String password, + @NotNull String path, @Nullable String requestBody, boolean post) throws IOException { HttpMethod method = null; try { - method = doREST(url, login, password, "/user/show/" + login, false); - final InputStream stream = method.getResponseBodyAsStream(); - final Element element = new SAXBuilder(false).build(stream).getRootElement(); - if ("error".equals(element.getName())){ - return false; + method = doREST(host, login, password, path, requestBody, post); + String resp = method.getResponseBodyAsString(); + if (resp == null) { + LOG.info(String.format("Unexpectedly empty response: %s", resp)); + return null; } - // In case if authentification was successful we should see some extra fields - return element.getChild("total-private-repo-count") != null; - } - catch (Exception e) { - // Ignore + return parseResponse(resp); } finally { - if (method!=null) { + if (method != null) { method.releaseConnection(); } } - return false; } - public static HttpMethod doREST(final String url, final String login, final String password, final String request, final boolean post) throws Exception { + @NotNull + private static HttpMethod doREST(@NotNull String host, @Nullable String login, @Nullable String password, @NotNull String path, + @Nullable String requestBody, final boolean post) throws IOException { final HttpClient client = getHttpClient(login, password); - final String uri = "https://" + getHostByUrl(url) + API_URL + request; - final HttpMethod method = post ? new PostMethod(uri) : new GetMethod(uri); + final String uri = getApiUrl(host) + path; + final HttpMethod method; + if (post) { + method = new PostMethod(uri); + if (requestBody != null) { + ((PostMethod)method).setRequestEntity(new StringRequestEntity(requestBody, "application/json", "UTF-8")); + } + } + else { + method = new GetMethod(uri); + } + client.executeMethod(method); return method; } - public static HttpClient getHttpClient(@Nullable final String login, @Nullable final String password) { + @NotNull + private static String removeProtocolPrefix(final String url) { + if (url.startsWith("https://")) { + return url.substring(8); + } + else if (url.startsWith("http://")) { + return url.substring(7); + } + else if (url.startsWith("git@")) { + return url.substring(4); + } + else { + return url; + } + } + + @NotNull + private static String getApiUrl(@NotNull String urlFromSettings) { + return "https://" + getApiUrlWithoutProtocol(urlFromSettings); + } + + /* + All API access is over HTTPS, and accessed from the api.github.com domain + (or through yourdomain.com/api/v3/ for enterprise). + http://developer.github.com/v3/ + */ + @NotNull + private static String getApiUrlWithoutProtocol(String urlFromSettings) { + String url = removeTrailingSlash(removeProtocolPrefix(urlFromSettings)); + final String API_PREFIX = "api."; + final String ENTERPRISE_API_SUFFIX = "/api/v3"; + + if (url.equals(GithubSettings.DEFAULT_GITHUB_HOST)) { + return API_PREFIX + url; + } + else if (url.equals(API_PREFIX + GithubSettings.DEFAULT_GITHUB_HOST)) { + return url; + } + else if (url.endsWith(ENTERPRISE_API_SUFFIX)) { + return url; + } + else { + return url + ENTERPRISE_API_SUFFIX; + } + } + + private static String removeTrailingSlash(String s) { + if (s.endsWith("/")) { + return s.substring(0, s.length() - 1); + } + return s; + } + + @NotNull + private static HttpClient getHttpClient(@Nullable final String login, @Nullable final String password) { final HttpClient client = new HttpClient(); client.getParams().setContentCharset("UTF-8"); // Configure proxySettings if it is required @@ -135,87 +224,127 @@ public class GithubUtil { return client; } - public static List getAvailableRepos(final String url, final String login, final String password, final boolean ownOnly) { - HttpMethod method = null; - try { - final String request = (ownOnly ? "/repos/show/" : "/repos/watched/") + login; - method = doREST(url, login, password, request, false); - final InputStream stream = method.getResponseBodyAsStream(); - final Element element = new SAXBuilder(false).build(stream).getRootElement(); - if ("error".equals(element.getName())){ - LOG.warn("Got error element by request: " + request); - return Collections.emptyList(); - } - final List repositories = element.getChildren(); - final List result = new ArrayList(); - for (int i = 0; i < repositories.size(); i++) { - final Element repo = (Element)repositories.get(i); - result.add(new RepositoryInfo(repo)); - } - return result; - } - catch (Exception e) { - // ignore - } - finally { - if (method != null){ - method.releaseConnection(); - } - } - return Collections.emptyList(); + private static boolean testConnection(final String url, final String login, final String password) { + GithubUser user = retrieveCurrentUserInfo(url, login, password); + return user != null; } + @Nullable + private static GithubUser retrieveCurrentUserInfo(@NotNull String url, @NotNull String login, @NotNull String password) { + try { + JsonElement result = getRequest(url, login, password, "/user"); + return parseUserInfo(result); + } + catch (IOException e) { + LOG.info(e); + return null; + } + } @Nullable - public static RepositoryInfo getDetailedRepoInfo(final String url, final String login, final String password, final String owner, final String name) { - HttpMethod method = null; + private static GithubUser parseUserInfo(@Nullable JsonElement result) { + if (result == null) { + return null; + } + if (!result.isJsonObject()) { + LOG.error(String.format("Unexpected JSON result format: %s", result)); + return null; + } + + JsonObject obj = (JsonObject)result; + if (!obj.has("plan")) { + return null; + } + GithubUser.Plan plan = parsePlan(obj.get("plan")); + return new GithubUser(plan); + } + + @NotNull + private static GithubUser.Plan parsePlan(JsonElement plan) { + if (!plan.isJsonObject()) { + return GithubUser.Plan.FREE; + } + return GithubUser.Plan.fromString(plan.getAsJsonObject().get("name").getAsString()); + } + + @NotNull + private static JsonElement parseResponse(@NotNull String githubResponse) throws IOException { try { - final String request = "/repos/show/" + owner + "/" + name; - method = doREST(url, login, password, request, false); - final InputStream stream = method.getResponseBodyAsStream(); - final Element element = new SAXBuilder(false).build(stream).getRootElement(); - if ("error".equals(element.getName())){ - LOG.warn("Got error element by request: " + request); + return new JsonParser().parse(githubResponse); + } + catch (JsonSyntaxException jse) { + throw new IOException(String.format("Couldn't parse GitHub response:%n%s", githubResponse), jse); + } + } + + @NotNull + private static List getAvailableRepos(@NotNull String url, @NotNull String login, @NotNull String password, + boolean ownOnly) { + final String request = (ownOnly ? "/user/repos" : "/user/watched"); + try { + JsonElement result = getRequest(url, login, password, request); + if (result == null) { + return Collections.emptyList(); + } + return parseRepositoryInfos(result); + } + catch (IOException e) { + LOG.error(e); + return Collections.emptyList(); + } + } + + @NotNull + private static List parseRepositoryInfos(@NotNull JsonElement result) { + if (!result.isJsonArray()) { + LOG.assertTrue(result.isJsonObject(), String.format("Unexpected JSON result format: %s", result)); + return Collections.singletonList(parseSingleRepositoryInfo(result.getAsJsonObject())); + } + + List repositories = new ArrayList(); + for (JsonElement element : result.getAsJsonArray()) { + LOG.assertTrue(element.isJsonObject(), + String.format("This element should be a JsonObject: %s%nTotal JSON response: %n%s", element, result)); + repositories.add(parseSingleRepositoryInfo(element.getAsJsonObject())); + } + return repositories; + } + + @NotNull + private static RepositoryInfo parseSingleRepositoryInfo(@NotNull JsonObject result) { + String name = result.get("name").getAsString(); + String cloneUrl = result.get("clone_url").getAsString(); + String ownerName = result.get("owner").getAsJsonObject().get("login").getAsString(); + String parentName = result.has("parent") ? result.get("parent").getAsJsonObject().get("full_name").getAsString(): null; + boolean fork = result.get("fork").getAsBoolean(); + return new RepositoryInfo(name, cloneUrl, ownerName, parentName, fork); + } + + @Nullable + private static RepositoryInfo getDetailedRepoInfo(@NotNull String url, @NotNull String login, @NotNull String password, + @NotNull String owner, @NotNull String name) { + try { + final String request = "/repos/" + owner + "/" + name; + JsonElement jsonObject = getRequest(url, login, password, request); + if (jsonObject == null) { + LOG.info(String.format("Information about repository is unavailable. Owner: %s, Name: %s", owner, name)); return null; } - return (new RepositoryInfo(element)); + return parseSingleRepositoryInfo(jsonObject.getAsJsonObject()); } - catch (Exception e) { - // ignore + catch (IOException e) { + LOG.info(String.format("Exception was thrown when trying to retrieve information about repository. Owner: %s, Name: %s", + owner, name)); + return null; } - finally { - if (method != null){ - method.releaseConnection(); - } - } - return null; } public static boolean isPrivateRepoAllowed(final String url, final String login, final String password) { - HttpMethod method = null; - try { - final String request = "/user/show/" + login; - method = doREST(url, login, password, request, false); - final InputStream stream = method.getResponseBodyAsStream(); - final Element element = new SAXBuilder(false).build(stream).getRootElement(); - if ("error".equals(element.getName())){ - LOG.warn("Got error element by request: " + request); - return false; - } - final Element plan = element.getChild("plan"); - assert plan != null : "Authentification failed"; - final String privateRepos = plan.getChildText("private-repos"); - return privateRepos != null && Integer.valueOf(privateRepos) > 0; + GithubUser user = retrieveCurrentUserInfo(url, login, password); + if (user == null) { + return false; } - catch (Exception e) { - // ignore - } - finally { - if (method != null){ - method.releaseConnection(); - } - } - return false; + return user.getPlan().isPrivateRepoAllowed(); } public static boolean checkCredentials(final Project project) { @@ -291,6 +420,7 @@ public class GithubUtil { // Otherwise our credentials are valid and they are successfully stored in settings final String validPassword = settings.getPassword(); return accessToGithubWithModalProgress(project, new Computable() { + @Nullable @Override public RepositoryInfo compute() { ProgressManager.getInstance().getProgressIndicator().setText("Extracting detailed info about repository ''" + name + "''"); @@ -327,7 +457,7 @@ public class GithubUtil { } return null; } - + public static boolean testGitExecutable(final Project project) { final GitVcsApplicationSettings settings = GitVcsApplicationSettings.getInstance(); final String executable = settings.getPathToGit(); diff --git a/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java b/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java index f9c6632466f4..b59b0addfea0 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java +++ b/plugins/github/src/org/jetbrains/plugins/github/RepositoryInfo.java @@ -1,55 +1,59 @@ package org.jetbrains.plugins.github; -import com.intellij.openapi.util.Comparing; -import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** -* @author oleg -* @date 10/21/10 -*/ + * Information about Github repository. + * + * @author oleg + * @author Kirill Likhodedov + */ public class RepositoryInfo { - private final Element myRepository; - public RepositoryInfo(final Element repository) { - myRepository = repository; + @NotNull private final String myName; + @NotNull private final String myCloneUrl; + @NotNull private final String myOwnerName; + @Nullable private final String myParentName; + private final boolean myFork; + + public RepositoryInfo(@NotNull String name, @NotNull String cloneUrl, @NotNull String ownerName, @Nullable String parentName, + boolean fork) { + myName = name; + myParentName = parentName; + myCloneUrl = cloneUrl; + myOwnerName = ownerName; + myFork = fork; } + @NotNull public String getName() { - return myRepository.getChildText("name"); + return myName; } - public String getOwner() { - return myRepository.getChildText("owner"); + @NotNull + public String getOwnerName() { + return myOwnerName; } public boolean isFork() { - return Boolean.valueOf(myRepository.getChildText("fork")); + return myFork; } - public String getParent() { - return myRepository.getChildText("parent"); + /** + * @return The name of the parent of this repository, or null. + * Null is returned if this repository doesn't have a parent, i. e. is not a fork, + * or if the parent information was not retrieved by the time of constructing of this RepositoryInfo object. + * To be sure use {@link #isFork()}. + */ + @Nullable + public String getParentName() { + return myParentName; } - public String getId() { - return getOwner() + "/" + getName(); + @NotNull + public String getCloneUrl() { + return myCloneUrl; } - public String getUrl() { - return myRepository.getChildText("url") + ".git"; - } - - @Override - public int hashCode() { - return myRepository != null ? myRepository.hashCode() : 0; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof RepositoryInfo)){ - return false; - } - final RepositoryInfo repositoryInfo = (RepositoryInfo)obj; - return Comparing.equal(getName(), repositoryInfo.getName()) && - Comparing.equal(getOwner(), repositoryInfo.getOwner()); - } } From 412129f5f90a293502d64d75e1c3392836d2a71e Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 16 Jun 2012 12:38:10 +0400 Subject: [PATCH 057/100] [github] Handle GithubShareAction result in EDT: show error or refresh need to be called from there. --- .../plugins/github/GithubShareAction.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java index 263e038ead8c..09c71311c194 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubShareAction.java @@ -237,19 +237,19 @@ public class GithubShareAction extends DumbAwareAction { gitPushHandler.addParameters("-u", "origin", "master"); GitPushUtils.trackPushRejectedAsError(gitPushHandler, "Rejected push (" + root.getPresentableUrl() + "): "); errors.addAll(GitHandlerUtil.doSynchronouslyWithExceptions(gitPushHandler)); - if (!errors.isEmpty()) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - GitUIUtil.showOperationErrors(project, errors, GitBundle.getString("push.active.pushing")); + if (!errors.isEmpty()) { + GitUIUtil.showOperationErrors(project, errors, GitBundle.getString("push.active.pushing")); + } + else { + RefreshAction.doRefresh(project); + Notifications.Bus.notify(new Notification("github", "Success", "Successfully created project ''" + name + "'' on github", + NotificationType.INFORMATION)); + } } }); - } - else { - RefreshAction.doRefresh(project); - Notifications.Bus.notify(new Notification("github", "Success", "Successfully created project ''" + name + "'' on github", - NotificationType.INFORMATION)); - } } }.queue(); } From 5a152908bb3d3063f64acd6817132b05502b3c45 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 16 Jun 2012 12:39:12 +0400 Subject: [PATCH 058/100] [github] No need in 'git remote update', because it is equal to fetch, which is executed later. But do update the GitRepository to catch up with newly added remote. --- .../plugins/github/GithubRebaseAction.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index bff7f575b574..9cb1e3ac0912 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -177,25 +177,14 @@ public class GithubRebaseAction extends DumbAwareAction { addRemoteHandler.run(); if (addRemoteHandler.getExitCode() != 0) { showErrorMessageInEDT(project, "Failed to add GitHub remote: '" + parentRepoUrl + "'"); - return; } - LOG.info("Updating remotes"); - ProgressManager.getInstance().getProgressIndicator().setText("Updating remotes"); - final GitSimpleHandler updateRemotesHandler = new GitSimpleHandler(project, root, GitCommand.REMOTE); - updateRemotesHandler.setNoSSH(true); - updateRemotesHandler.setSilent(true); - updateRemotesHandler.addParameters("update"); - updateRemotesHandler.run(); - if (updateRemotesHandler.getExitCode() != 0) { - showErrorMessageInEDT(project, "Failed to update remotes"); - return; - } + // catch newly added remote + gitRepository.update(GitRepository.TrackedTopic.CONFIG); } catch (VcsException e1) { final String message = "Error happened during git operation: " + e1.getMessage(); showErrorMessageInEDT(project, message); - return; } } }); From 9c325ac7a6f3f6087f7c90908937043aca2cbcae Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 16 Jun 2012 13:11:15 +0400 Subject: [PATCH 059/100] @NotNull --- .../github/src/org/jetbrains/plugins/github/GithubUtil.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 6520e1ad2219..04285624791a 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -430,10 +430,9 @@ public class GithubUtil { } @Nullable - public static GitRemote findGitHubRemoteBranch(final GitRepository repository) { + public static GitRemote findGitHubRemoteBranch(@NotNull GitRepository repository) { // i.e. find origin which points on my github repo // Check that given repository is properly configured git repository - for (GitRemote gitRemote : repository.getRemotes()) { if (getGithubUrl(gitRemote) != null){ return gitRemote; From 4b5a6b982b468262d0478825ebca34236c21caf9 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 16 Jun 2012 13:11:27 +0400 Subject: [PATCH 060/100] logging --- .../src/org/jetbrains/plugins/github/GithubRebaseAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index 9cb1e3ac0912..25fd38f4a482 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -108,6 +108,7 @@ public class GithubRebaseAction extends DumbAwareAction { final VirtualFile root = project.getBaseDir(); GitRepositoryManager manager = GitUtil.getRepositoryManager(project); if (manager == null) { + LOG.info("No GitRepositoryManager instance available. Action cancelled."); return; } final GitRepository gitRepository = manager.getRepositoryForFile(project.getBaseDir()); From 3d3d2b6b3af7558f65513f8d110354f32047b0a0 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sat, 16 Jun 2012 13:48:52 +0400 Subject: [PATCH 061/100] [git] refresh after rebase. --- plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java b/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java index 452dd6c157bb..b4f6b0b9ec05 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java +++ b/plugins/git4idea/src/git4idea/actions/GitRebaseActionBase.java @@ -70,6 +70,7 @@ public abstract class GitRebaseActionBase extends GitRepositoryAction { if (manager != null) { manager.updateRepository(root, GitRepository.TrackedTopic.ALL_CURRENT); } + root.refresh(false, true); notifyAboutErrorResult(taskResult, resultListener, exceptions, project); } }); From a1d5adbd5dec1d0e4709d2e44788b5cb8990369d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 14:17:02 +0200 Subject: [PATCH 062/100] improve descriptions --- .../MergeIfAndIntention/description.html | 4 ++-- .../MergeParallelForLoopsIntention/description.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeIfAndIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeIfAndIntention/description.html index 6435669410bc..ae9fec178370 100644 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeIfAndIntention/description.html +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeIfAndIntention/description.html @@ -1,6 +1,6 @@ -This intention merges an if-else statement inside -the then-branch of another if-else into one. +This intention merges two if statements into one, if the second is located inside +the then-branch of the first. diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeParallelForLoopsIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeParallelForLoopsIntention/description.html index 010131110e19..6d992039a72e 100644 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeParallelForLoopsIntention/description.html +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeParallelForLoopsIntention/description.html @@ -1,6 +1,6 @@ -This intention merges the sequential for statements, possible.
    +This intention merges sequential for statements, if possible.
    Note that this intention will change order of execution. From f6b8653affe5d8f40b200a92e8c8c30b64fe88d8 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 14:17:37 +0200 Subject: [PATCH 063/100] new "Merge nested try statements" intention --- .../IntentionPowerPak/src/META-INF/plugin.xml | 4 + .../siyeh/IntentionPowerPackBundle.properties | 2 + .../MergeNestedTryStatementsIntention.java | 80 +++++++++++++++++++ .../NestedTryStatementsPredicate.java | 70 ++++++++++++++++ .../after.java.template | 10 +++ .../before.java.template | 11 +++ .../description.html | 6 ++ .../siyeh/ipp/exceptions/mergeTry/Simple.java | 16 ++++ .../ipp/exceptions/mergeTry/Simple_after.java | 12 +++ ...MergeNestedTryStatementsIntentionTest.java | 42 ++++++++++ 10 files changed, 253 insertions(+) create mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntention.java create mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/before.java.template create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/description.html create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/META-INF/plugin.xml b/plugins/IntentionPowerPak/src/META-INF/plugin.xml index 878e3435132a..fe23d3c568a2 100644 --- a/plugins/IntentionPowerPak/src/META-INF/plugin.xml +++ b/plugins/IntentionPowerPak/src/META-INF/plugin.xml @@ -390,6 +390,10 @@ com.siyeh.ipp.exceptions.ReplaceArmWithTryFinallyIntention intention.category.other
    + + com.siyeh.ipp.exceptions.MergeNestedTryStatementsIntention + intention.category.other + com.siyeh.ipp.exceptions.ObscureThrownExceptionsIntention intention.category.other diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 636391392211..82381bfe9db5 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -151,6 +151,8 @@ split.multicatch.intention.name=Split multi-catch into separate 'catch' blocks split.multicatch.intention.family.name=Split Multi-Catch into Separate Catch Blocks replace.arm.with.try.finally.intention.name=Replace Automatic Resource Management with 'try finally' replace.arm.with.try.finally.intention.family.name=Replace Automatic Resource Management with Try-Finally +merge.nested.try.statements.intention.name=Merge nested try statements +merge.nested.try.statements.intention.family.name=Merge Nest Try Statements obscure.thrown.exceptions.intention.family.name=Replace Exceptions in Throws Clause with Single More General Exception add.array.creation.expression.intention.family.name=Add Array Creation Expression replace.diamond.with.explicit.type.arguments.intention.name=Replace '<>' with explicit type arguments diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntention.java new file mode 100644 index 000000000000..18f85334023d --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntention.java @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.exceptions; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.siyeh.ipp.base.Intention; +import com.siyeh.ipp.base.PsiElementPredicate; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author Bas Leijdekkers + */ +public class MergeNestedTryStatementsIntention extends Intention { + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new NestedTryStatementsPredicate(); + } + + @Override + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + final PsiTryStatement tryStatement1 = (PsiTryStatement)element.getParent(); + final StringBuilder newTryStatement = new StringBuilder("try ("); + final PsiResourceList list1 = tryStatement1.getResourceList(); + if (list1 == null) { + return; + } + final List variables1 = list1.getResourceVariables(); + boolean semicolon = false; + for (PsiResourceVariable variable : variables1) { + if (semicolon) { + newTryStatement.append(';'); + } else { + semicolon = true; + } + newTryStatement.append(variable.getText()); + } + final PsiCodeBlock tryBlock1 = tryStatement1.getTryBlock(); + if (tryBlock1 == null) { + return; + } + final PsiStatement[] statements = tryBlock1.getStatements(); + final PsiTryStatement tryStatement2 = (PsiTryStatement)statements[0]; + final PsiResourceList list2 = tryStatement2.getResourceList(); + if (list2 == null) { + return; + } + final List variables2 = list2.getResourceVariables(); + for (PsiResourceVariable variable : variables2) { + newTryStatement.append(';'); + newTryStatement.append(variable.getText()); + } + newTryStatement.append(")"); + final PsiCodeBlock tryBlock2 = tryStatement2.getTryBlock(); + if (tryBlock2 == null) { + return; + } + newTryStatement.append(tryBlock2.getText()); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject()); + final PsiStatement newStatement = factory.createStatementFromText(newTryStatement.toString(), element); + tryStatement1.replace(newStatement); + } +} diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java new file mode 100644 index 000000000000..17f0e9b153b6 --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java @@ -0,0 +1,70 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.exceptions; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.siyeh.ipp.base.PsiElementPredicate; + +/** + * @author Bas Leijdekkers + */ +public class NestedTryStatementsPredicate implements PsiElementPredicate { + + @Override + public boolean satisfiedBy(PsiElement element) { + if (!(element instanceof PsiJavaToken)) { + return false; + } + final PsiJavaToken javaToken = (PsiJavaToken)element; + final IElementType tokenType = javaToken.getTokenType(); + if (!JavaTokenType.TRY_KEYWORD.equals(tokenType)) { + return false; + } + final PsiElement parent = element.getParent(); + if (!isSimpleTryWithResources(parent)) { + return false; + } + final PsiTryStatement tryStatement = (PsiTryStatement)parent; + final PsiCodeBlock block = tryStatement.getTryBlock(); + if (block == null) { + return false; + } + final PsiStatement[] statements = block.getStatements(); + if (statements.length != 1) { + return false; + } + final PsiStatement statement = statements[0]; + return isSimpleTryWithResources(statement); + } + + private static boolean isSimpleTryWithResources(PsiElement element) { + if (!(element instanceof PsiTryStatement)) { + return false; + } + final PsiTryStatement tryStatement = (PsiTryStatement)element; + final PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList == null) { + return false; + } + final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); + if (finallyBlock != null) { + return false; + } + final PsiCodeBlock block = tryStatement.getTryBlock(); + return block != null; + } +} diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template new file mode 100644 index 000000000000..a8613e304c27 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template @@ -0,0 +1,10 @@ +import java.io.*; + +public class X { + void f(File file1, File file2) throws FileNotFoundException { + try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { + // do something + } + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/before.java.template new file mode 100644 index 000000000000..bc283f663329 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/before.java.template @@ -0,0 +1,11 @@ +import java.io.*; + +public class X { + void f(File file1, File file2) throws FileNotFoundException { + try (FileInputStream in = new FileInputStream(file1)) { + try (FileOutputStream out = new FileOutputStream(file2)) { + // do something + } + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/description.html new file mode 100644 index 000000000000..d4f830222325 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/description.html @@ -0,0 +1,6 @@ + + +This intention merges two try-with-resources statements into one, if the first is located inside +the second. + + diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple.java new file mode 100644 index 000000000000..a51451b43edd --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple.java @@ -0,0 +1,16 @@ +package com.siyeh.ipp.exceptions.mergeTry; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class Simple { + void foo(File file1, File file2) throws IOException { + try (FileInputStream in = new FileInputStream(file1)) { + try (FileOutputStream out = new FileOutputStream(file2)) { + // do something + } + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java new file mode 100644 index 000000000000..6555dd3d546e --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java @@ -0,0 +1,12 @@ +package com.siyeh.ipp.exceptions.mergeTry; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +public class Simple { + void foo(File file1, File file2) throws IOException { + try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { + // do something + } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntentionTest.java new file mode 100644 index 000000000000..599d1d74b783 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/MergeNestedTryStatementsIntentionTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * (c) 2012 Desert Island BV + * created: 16 06 2012 + */ +package com.siyeh.ipp.exceptions; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @author Bas Leijdekkers + */ +public class MergeNestedTryStatementsIntentionTest extends IPPTestCase { + + public void testSimple() { doTest(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("merge.nested.try.statements.intention.name"); + } + + @Override + protected String getRelativePath() { + return "exceptions/mergeTry"; + } +} From ba393eed89f17650e76cae59e8b12dcbf9592b3c Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 16:43:57 +0200 Subject: [PATCH 064/100] fix test? --- .../test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java index 6555dd3d546e..9589542e4a52 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/mergeTry/Simple_after.java @@ -9,4 +9,6 @@ public class Simple { void foo(File file1, File file2) throws IOException { try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { // do something - } \ No newline at end of file + } + } +} \ No newline at end of file From ecc9c6b38b09a38dbb27334670fa9488c48160b2 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 20:38:00 +0200 Subject: [PATCH 065/100] fix after template --- .../MergeNestedTryStatementsIntention/after.java.template | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template index a8613e304c27..8eed0df07c5a 100644 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/MergeNestedTryStatementsIntention/after.java.template @@ -4,7 +4,6 @@ public class X { void f(File file1, File file2) throws FileNotFoundException { try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { // do something - } } } } \ No newline at end of file From 7fe2f513d031f2f0c40d1bc1cae65533cdc13cc9 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 20:38:45 +0200 Subject: [PATCH 066/100] improve intentions names --- .../src/com/siyeh/IntentionPowerPackBundle.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 82381bfe9db5..6dc33bfda8ac 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -149,10 +149,10 @@ annotate.overridden.methods.intention.method.name=Annotate overriding methods as annotate.overridden.methods.intention.parameters.name=Annotate same parameter of overriding methods as ''@{0}'' split.multicatch.intention.name=Split multi-catch into separate 'catch' blocks split.multicatch.intention.family.name=Split Multi-Catch into Separate Catch Blocks -replace.arm.with.try.finally.intention.name=Replace Automatic Resource Management with 'try finally' -replace.arm.with.try.finally.intention.family.name=Replace Automatic Resource Management with Try-Finally -merge.nested.try.statements.intention.name=Merge nested try statements -merge.nested.try.statements.intention.family.name=Merge Nest Try Statements +replace.arm.with.try.finally.intention.name=Replace 'try-with-resources' with 'try finally' +replace.arm.with.try.finally.intention.family.name=Replace Try-With-Resources with Try-Finally +merge.nested.try.statements.intention.name=Merge nested 'try' statements +merge.nested.try.statements.intention.family.name=Merge Nested Try Statements obscure.thrown.exceptions.intention.family.name=Replace Exceptions in Throws Clause with Single More General Exception add.array.creation.expression.intention.family.name=Add Array Creation Expression replace.diamond.with.explicit.type.arguments.intention.name=Replace '<>' with explicit type arguments From 86d30a708e2e7279ba4ef9e0fabc54dcc98aec7a Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 20:46:53 +0200 Subject: [PATCH 067/100] make predicate package local --- .../com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java index 17f0e9b153b6..103bbf1cb81b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/NestedTryStatementsPredicate.java @@ -22,7 +22,7 @@ import com.siyeh.ipp.base.PsiElementPredicate; /** * @author Bas Leijdekkers */ -public class NestedTryStatementsPredicate implements PsiElementPredicate { +class NestedTryStatementsPredicate implements PsiElementPredicate { @Override public boolean satisfiedBy(PsiElement element) { From a7cb17d3d48a2248efaa6c9eeb9805c67fa201cc Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sat, 16 Jun 2012 21:00:35 +0200 Subject: [PATCH 068/100] new "Split 'try' statement with multiple resources" intention --- .../IntentionPowerPak/src/META-INF/plugin.xml | 4 ++ .../siyeh/IntentionPowerPackBundle.properties | 2 + ...plitTryWithMultipleResourcesIntention.java | 65 +++++++++++++++++++ .../TryWithMultipleResourcesPredicate.java | 63 ++++++++++++++++++ .../after.java.template | 11 ++++ .../before.java.template | 9 +++ .../description.html | 5 ++ .../siyeh/ipp/exceptions/splitTry/Simple.java | 11 ++++ .../ipp/exceptions/splitTry/Simple_after.java | 13 ++++ ...TryWithMultipleResourcesIntentionTest.java | 22 +++++++ 10 files changed, 205 insertions(+) create mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java create mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/after.java.template create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/before.java.template create mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/description.html create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/META-INF/plugin.xml b/plugins/IntentionPowerPak/src/META-INF/plugin.xml index fe23d3c568a2..ba2dfad06f36 100644 --- a/plugins/IntentionPowerPak/src/META-INF/plugin.xml +++ b/plugins/IntentionPowerPak/src/META-INF/plugin.xml @@ -394,6 +394,10 @@ com.siyeh.ipp.exceptions.MergeNestedTryStatementsIntention intention.category.other + + com.siyeh.ipp.exceptions.SplitTryWithMultipleResourcesIntention + intention.category.other + com.siyeh.ipp.exceptions.ObscureThrownExceptionsIntention intention.category.other diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 6dc33bfda8ac..08b08fd25ea5 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -153,6 +153,8 @@ replace.arm.with.try.finally.intention.name=Replace 'try-with-resources' with 't replace.arm.with.try.finally.intention.family.name=Replace Try-With-Resources with Try-Finally merge.nested.try.statements.intention.name=Merge nested 'try' statements merge.nested.try.statements.intention.family.name=Merge Nested Try Statements +split.try.with.multiple.resources.intention.name=Split 'try' statement with multiple resources +split.try.with.multiple.resources.intention.family.name=Split Try Statement with Multiple Resources obscure.thrown.exceptions.intention.family.name=Replace Exceptions in Throws Clause with Single More General Exception add.array.creation.expression.intention.family.name=Add Array Creation Expression replace.diamond.with.explicit.type.arguments.intention.name=Replace '<>' with explicit type arguments diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java new file mode 100644 index 000000000000..c836078fdd87 --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntention.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.exceptions; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.siyeh.ipp.base.Intention; +import com.siyeh.ipp.base.PsiElementPredicate; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author Bas Leijdekkers + */ +public class SplitTryWithMultipleResourcesIntention extends Intention { + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new TryWithMultipleResourcesPredicate(); + } + + @Override + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + final PsiTryStatement tryStatement = (PsiTryStatement)element.getParent(); + final PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList == null) { + return; + } + final StringBuilder newTryStatementText = new StringBuilder(); + final List variables = resourceList.getResourceVariables(); + boolean braces = false; + for (PsiResourceVariable variable : variables) { + if (braces) { + newTryStatementText.append("{\n"); + } else { + braces = true; + } + newTryStatementText.append("try (").append(variable.getText()).append(")"); + } + final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (tryBlock == null) { + return; + } + newTryStatementText.append(tryBlock.getText()); + for (int i = 1; i < variables.size(); i++) { + newTryStatementText.append("\n}"); + } + replaceStatement(newTryStatementText.toString(), tryStatement); + } +} diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java new file mode 100644 index 000000000000..1dfdf84476da --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/TryWithMultipleResourcesPredicate.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ipp.exceptions; + +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.siyeh.ipp.base.PsiElementPredicate; + +import java.util.List; + +/** + * @author Bas Leijdekkers + */ +class TryWithMultipleResourcesPredicate implements PsiElementPredicate { + + @Override + public boolean satisfiedBy(PsiElement element) { + if (!(element instanceof PsiJavaToken)) { + return false; + } + final PsiJavaToken javaToken = (PsiJavaToken)element; + final IElementType tokenType = javaToken.getTokenType(); + if (!JavaTokenType.TRY_KEYWORD.equals(tokenType)) { + return false; + } + final PsiElement parent = element.getParent(); + if (!(parent instanceof PsiTryStatement)) { + return false; + } + final PsiTryStatement tryStatement = (PsiTryStatement)parent; + final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); + if (catchBlocks.length > 0) { + return false; + } + final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); + if (finallyBlock != null) { + return false; + } + final PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList == null) { + return false; + } + final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (tryBlock == null) { + return false; + } + final List variables = resourceList.getResourceVariables(); + return variables.size() > 1; + } +} diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/after.java.template new file mode 100644 index 000000000000..8b181b89ddb8 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/after.java.template @@ -0,0 +1,11 @@ +import java.io.*; + +public class X { + void f(File file1, File file2) throws FileNotFoundException { + try (FileInputStream in = new FileInputStream(file1)) { + try (FileOutputStream out = new FileOutputStream(file2)) { + // do something + } + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/before.java.template new file mode 100644 index 000000000000..2736a4bb3c03 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/before.java.template @@ -0,0 +1,9 @@ +import java.io.*; + +public class X { + void f(File file1, File file2) throws FileNotFoundException { + try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { + // do something + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/description.html new file mode 100644 index 000000000000..4a618540be5a --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/SplitTryWithMultipleResourcesIntention/description.html @@ -0,0 +1,5 @@ + + +This intention splits a try statement with multiple resources into two nested try-with-resources statements. + + diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple.java new file mode 100644 index 000000000000..25d0048ba039 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple.java @@ -0,0 +1,11 @@ +package com.siyeh.ipp.exceptions.splitTry; + +import java.io.*; + +public class Simple { + void foo(File file1, File file2) throws IOException { + try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { + + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple_after.java new file mode 100644 index 000000000000..51b243a7748b --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/splitTry/Simple_after.java @@ -0,0 +1,13 @@ +package com.siyeh.ipp.exceptions.splitTry; + +import java.io.*; + +public class Simple { + void foo(File file1, File file2) throws IOException { + try (FileInputStream in = new FileInputStream(file1)) { + try (FileOutputStream out = new FileOutputStream(file2)) { + + } + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java new file mode 100644 index 000000000000..cce64b4edcd8 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/SplitTryWithMultipleResourcesIntentionTest.java @@ -0,0 +1,22 @@ +package com.siyeh.ipp.exceptions; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @author Bas Leijdekkers + */ +public class SplitTryWithMultipleResourcesIntentionTest extends IPPTestCase { + + public void testSimple() { doTest(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("split.try.with.multiple.resources.intention.name"); + } + + @Override + protected String getRelativePath() { + return "exceptions/splitTry"; + } +} From 23af1bf293f701b632d3d1aeccd5290c1e4f7195 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sat, 16 Jun 2012 21:37:42 +0200 Subject: [PATCH 069/100] support old format of annotation processors configuration --- .../compiler/CompilerConfigurationImpl.java | 241 +++++++++--------- .../compiler/ProcessorConfigProfile.java | 123 ++++++++- 2 files changed, 237 insertions(+), 127 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java index 0eb6af979ed6..1de1eebfcf70 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java @@ -79,6 +79,10 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements return o1.compareToIgnoreCase(o2); } }; + private static final String ENTRY = "entry"; + private static final String NAME = "name"; + private static final String ENABLED = "enabled"; + private static final String MODULE = "module"; @SuppressWarnings({"WeakerAccess"}) public String DEFAULT_COMPILER; @NotNull private BackendCompiler myDefaultJavaCompiler; @@ -91,7 +95,6 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements private final List myNegatedCompiledPatterns = new ArrayList(); private boolean myWildcardPatternsInitialized = false; private final Project myProject; - private final ModuleManager myModuleManager; private final ExcludedEntriesConfiguration myExcludedEntriesConfiguration; private final Collection myRegisteredCompilers = new ArrayList(); @@ -113,9 +116,8 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements private String myBytecodeTargetLevel = null; // null means compiler default private final Map myModuleBytecodeTarget = new java.util.HashMap(); - public CompilerConfigurationImpl(Project project, ModuleManager moduleManager) { + public CompilerConfigurationImpl(Project project) { myProject = project; - myModuleManager = moduleManager; myExcludedEntriesConfiguration = new ExcludedEntriesConfiguration(); Disposer.register(project, myExcludedEntriesConfiguration); project.getMessageBus().connect(project).subscribe(ProjectTopics.MODULES, new ModuleAdapter() { @@ -591,12 +593,6 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements private static final String BYTECODE_TARGET_LEVEL = "bytecodeTargetLevel"; private static final String WILDCARD_RESOURCE_PATTERNS = "wildcardResourcePatterns"; private static final String ADD_NOTNULL_ASSERTIONS = "addNotNullAssertions"; - private static final String ENTRY = "entry"; - private static final String NAME = "name"; - private static final String VALUE = "value"; - private static final String ENABLED = "enabled"; - private static final String OPTION = "option"; - private static final String MODULE = "module"; public void readExternal(Element parentNode) throws InvalidDataException { @@ -648,18 +644,25 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements final Element annotationProcessingSettings = parentNode.getChild(ANNOTATION_PROCESSING); if (annotationProcessingSettings != null) { - for (Object elem : annotationProcessingSettings.getChildren("profile")) { - final Element profileElement = (Element)elem; - final boolean isDefault = "true".equals(profileElement.getAttributeValue("default")); - if (isDefault) { - readProfile(profileElement, myDefaultProcessorsProfile); - } - else { - final ProcessorConfigProfile profile = new ProcessorConfigProfile(""); - readProfile(profileElement, profile); - myModuleProcessorProfiles.add(profile); + final List profiles = annotationProcessingSettings.getChildren("profile"); + if (!profiles.isEmpty()) { + for (Object elem : profiles) { + final Element profileElement = (Element)elem; + final boolean isDefault = "true".equals(profileElement.getAttributeValue("default")); + if (isDefault) { + myDefaultProcessorsProfile.readExternal(profileElement); + } + else { + final ProcessorConfigProfile profile = new ProcessorConfigProfile(""); + profile.readExternal(profileElement); + myModuleProcessorProfiles.add(profile); + } } } + else { + // assuming older format + loadProfilesFromOldFormat(annotationProcessingSettings); + } } myBytecodeTargetLevel = null; @@ -681,6 +684,91 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements } } + private void loadProfilesFromOldFormat(Element processing) { + // collect data + final boolean isEnabled = Boolean.parseBoolean(processing.getAttributeValue(ENABLED, "false")); + final boolean isUseClasspath = Boolean.parseBoolean(processing.getAttributeValue("useClasspath", "true")); + final StringBuilder processorPath = new StringBuilder(); + final Set optionPairs = new HashSet(); + final Set processors = new HashSet(); + final List> modulesToProcess = new ArrayList>(); + + for (Object child : processing.getChildren("processorPath")) { + final Element pathElement = (Element)child; + final String path = pathElement.getAttributeValue("value", (String)null); + if (path != null) { + if (processorPath.length() > 0) { + processorPath.append(File.pathSeparator); + } + processorPath.append(path); + } + } + + for (Object child : processing.getChildren("processor")) { + final Element processorElement = (Element)child; + final String proc = processorElement.getAttributeValue(NAME, (String)null); + if (proc != null) { + processors.add(proc); + } + final StringTokenizer tokenizer = new StringTokenizer(processorElement.getAttributeValue("options", ""), " ", false); + while (tokenizer.hasMoreTokens()) { + final String pair = tokenizer.nextToken(); + optionPairs.add(pair); + } + } + + for (Object child : processing.getChildren("processModule")) { + final Element moduleElement = (Element)child; + final String name = moduleElement.getAttributeValue(NAME, (String)null); + if (name == null) { + continue; + } + final String dir = moduleElement.getAttributeValue("generatedDirName", (String)null); + modulesToProcess.add(Pair.create(name, dir)); + } + + myDefaultProcessorsProfile.setEnabled(false); + myDefaultProcessorsProfile.setObtainProcessorsFromClasspath(isUseClasspath); + if (processorPath.length() > 0) { + myDefaultProcessorsProfile.setProcessorPath(processorPath.toString()); + } + if (!optionPairs.isEmpty()) { + for (String pair : optionPairs) { + final int index = pair.indexOf("="); + if (index > 0) { + myDefaultProcessorsProfile.setOption(pair.substring(0, index), pair.substring(index + 1)); + } + } + } + for (String processor : processors) { + myDefaultProcessorsProfile.addProcessor(processor); + } + + final Map> dirNameToModulesMap = new HashMap>(); + for (Pair moduleDirPair : modulesToProcess) { + final String dir = moduleDirPair.getSecond(); + Set set = dirNameToModulesMap.get(dir); + if (set == null) { + set = new HashSet(); + dirNameToModulesMap.put(dir, set); + } + set.add(moduleDirPair.getFirst()); + } + + int profileIndex = 0; + for (Map.Entry> entry : dirNameToModulesMap.entrySet()) { + final String dirName = entry.getKey(); + final ProcessorConfigProfile profile = new ProcessorConfigProfile(myDefaultProcessorsProfile); + profile.setName("Profile" + (++profileIndex)); + profile.setEnabled(isEnabled); + profile.setGeneratedSourcesDirectoryName(dirName); + for (String moduleName : entry.getValue()) { + profile.addModuleName(moduleName); + } + myModuleProcessorProfiles.add(profile); + } + } + public void writeExternal(Element parentNode) throws WriteExternalException { DefaultJDOMExternalizer.writeExternal(this, parentNode); @@ -705,9 +793,9 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements } final Element annotationProcessingSettings = addChild(parentNode, ANNOTATION_PROCESSING); - writeProfile(addChild(annotationProcessingSettings, "profile").setAttribute("default", "true"), myDefaultProcessorsProfile); + myDefaultProcessorsProfile.writeExternal(addChild(annotationProcessingSettings, "profile").setAttribute("default", "true")); for (ProcessorConfigProfile profile : myModuleProcessorProfiles) { - writeProfile(addChild(annotationProcessingSettings, "profile").setAttribute("default", "false"), profile); + profile.writeExternal(addChild(annotationProcessingSettings, "profile").setAttribute("default", "false")); } if (!StringUtil.isEmpty(myBytecodeTargetLevel) || !myModuleBytecodeTarget.isEmpty()) { @@ -728,109 +816,6 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements } } - private static void readProfile(Element element, ProcessorConfigProfile profile) { - profile.setName(element.getAttributeValue(NAME, "")); - profile.setEnabled(Boolean.valueOf(element.getAttributeValue(ENABLED, "false"))); - - final Element srcOutput = element.getChild("sourceOutputDir"); - profile.setGeneratedSourcesDirectoryName(srcOutput != null? srcOutput.getAttributeValue(NAME) : null); - - profile.clearProcessorOptions(); - for (Object optionElement : element.getChildren(OPTION)) { - final Element elem = (Element)optionElement; - final String key = elem.getAttributeValue(NAME); - final String value = elem.getAttributeValue(VALUE); - if (!StringUtil.isEmptyOrSpaces(key) && value != null) { - profile.setOption(key, value); - } - } - - profile.clearProcessors(); - for (Object procElement : element.getChildren("processor")) { - final String name = ((Element)procElement).getAttributeValue(NAME); - if (StringUtil.isEmptyOrSpaces(name)) { - profile.addProcessor(name); - } - } - - final Element pathElement = element.getChild("processorPath"); - if (pathElement != null) { - profile.setObtainProcessorsFromClasspath(Boolean.parseBoolean(pathElement.getAttributeValue("useClasspath", "true"))); - final StringBuilder pathBuilder = new StringBuilder(); - for (Object entry : pathElement.getChildren(ENTRY)) { - final String path = ((Element)entry).getAttributeValue(NAME); - if (!StringUtil.isEmptyOrSpaces(path)) { - if (pathBuilder.length() > 0) { - pathBuilder.append(File.pathSeparator); - } - pathBuilder.append(FileUtil.toSystemDependentName(path)); - } - } - profile.setProcessorPath(pathBuilder.toString()); - } - - profile.clearModuleNames(); - for (Object moduleElement : element.getChildren(MODULE)) { - final String name = ((Element)moduleElement).getAttributeValue(NAME); - if (!StringUtil.isEmptyOrSpaces(name)) { - profile.addModuleName(name); - } - } - } - - private static void writeProfile(final Element element, ProcessorConfigProfile profile) { - element.setAttribute(NAME, profile.getName()); - element.setAttribute(ENABLED, Boolean.toString(profile.isEnabled())); - - final String srcDirName = profile.getGeneratedSourcesDirectoryName(); - if (srcDirName != null) { - addChild(element, "sourceOutputDir").setAttribute(NAME, srcDirName); - } - - final Map options = profile.getProcessorOptions(); - if (!options.isEmpty()) { - final List keys = new ArrayList(options.keySet()); - Collections.sort(keys, ALPHA_COMPARATOR); - for (String key : keys) { - addChild(element, OPTION).setAttribute(NAME, key).setAttribute(VALUE, options.get(key)); - } - } - - final Set processors = profile.getProcessors(); - if (!processors.isEmpty()) { - final List processorList = new ArrayList(processors); - Collections.sort(processorList, ALPHA_COMPARATOR); - for (String proc : processorList) { - addChild(element, "processor").setAttribute(NAME, proc); - } - } - - final Element pathElement = addChild(element, "processorPath").setAttribute("useClasspath", Boolean.toString(profile.isObtainProcessorsFromClasspath())); - final String path = profile.getProcessorPath(); - if (!StringUtil.isEmpty(path)) { - final StringTokenizer tokenizer = new StringTokenizer(path, File.pathSeparator, false); - while (tokenizer.hasMoreTokens()) { - final String token = tokenizer.nextToken(); - addChild(pathElement, ENTRY).setAttribute(NAME, FileUtil.toSystemIndependentName(token)); - } - } - - final Set moduleNames = profile.getModuleNames(); - if (!moduleNames.isEmpty()) { - final List names = new ArrayList(moduleNames); - Collections.sort(names, ALPHA_COMPARATOR); - for (String name : names) { - addChild(element, MODULE).setAttribute(NAME, name); - } - } - } - - private static Element addChild(Element parent, final String childName) { - final Element child = new Element(childName); - parent.addContent(child); - return child; - } - @NotNull @NonNls public String getComponentName() { return "CompilerConfiguration"; @@ -971,5 +956,11 @@ public class CompilerConfigurationImpl extends CompilerConfiguration implements this.srcRoot = srcRoot; } } - + + private static Element addChild(Element parent, final String childName) { + final Element child = new Element(childName); + parent.addContent(child); + return child; + } + } \ No newline at end of file diff --git a/java/compiler/impl/src/com/intellij/compiler/ProcessorConfigProfile.java b/java/compiler/impl/src/com/intellij/compiler/ProcessorConfigProfile.java index 7922743712b8..ce6f7e5127b1 100644 --- a/java/compiler/impl/src/com/intellij/compiler/ProcessorConfigProfile.java +++ b/java/compiler/impl/src/com/intellij/compiler/ProcessorConfigProfile.java @@ -15,18 +15,34 @@ */ package com.intellij.compiler; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; import java.util.*; /** * @author Eugene Zhuravlev * Date: 5/25/12 */ -public class ProcessorConfigProfile implements AnnotationProcessingConfiguration { - private String myName = ""; +public final class ProcessorConfigProfile implements AnnotationProcessingConfiguration { + private static final Comparator ALPHA_COMPARATOR = new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareToIgnoreCase(o2); + } + }; + private static final String ENTRY = "entry"; + private static final String NAME = "name"; + private static final String VALUE = "value"; + private static final String ENABLED = "enabled"; + private static final String OPTION = "option"; + private static final String MODULE = "module"; + private String myName = ""; private boolean myEnabled = false; private boolean myObtainProcessorsFromClasspath = true; private String myProcessorPath = ""; @@ -44,6 +60,103 @@ public class ProcessorConfigProfile implements AnnotationProcessingConfiguration initFrom(profile); } + public void readExternal(Element element) { + setName(element.getAttributeValue(NAME, "")); + setEnabled(Boolean.valueOf(element.getAttributeValue(ENABLED, "false"))); + + final Element srcOutput = element.getChild("sourceOutputDir"); + setGeneratedSourcesDirectoryName(srcOutput != null ? srcOutput.getAttributeValue(NAME) : null); + + clearProcessorOptions(); + for (Object optionElement : element.getChildren(OPTION)) { + final Element elem = (Element)optionElement; + final String key = elem.getAttributeValue(NAME); + final String value = elem.getAttributeValue(VALUE); + if (!StringUtil.isEmptyOrSpaces(key) && value != null) { + setOption(key, value); + } + } + + clearProcessors(); + for (Object procElement : element.getChildren("processor")) { + final String name = ((Element)procElement).getAttributeValue(NAME); + if (StringUtil.isEmptyOrSpaces(name)) { + addProcessor(name); + } + } + + final Element pathElement = element.getChild("processorPath"); + if (pathElement != null) { + setObtainProcessorsFromClasspath(Boolean.parseBoolean(pathElement.getAttributeValue("useClasspath", "true"))); + final StringBuilder pathBuilder = new StringBuilder(); + for (Object entry : pathElement.getChildren(ENTRY)) { + final String path = ((Element)entry).getAttributeValue(NAME); + if (!StringUtil.isEmptyOrSpaces(path)) { + if (pathBuilder.length() > 0) { + pathBuilder.append(File.pathSeparator); + } + pathBuilder.append(FileUtil.toSystemDependentName(path)); + } + } + setProcessorPath(pathBuilder.toString()); + } + + clearModuleNames(); + for (Object moduleElement : element.getChildren(MODULE)) { + final String name = ((Element)moduleElement).getAttributeValue(NAME); + if (!StringUtil.isEmptyOrSpaces(name)) { + addModuleName(name); + } + } + } + + public void writeExternal(final Element element) { + element.setAttribute(NAME, getName()); + element.setAttribute(ENABLED, Boolean.toString(isEnabled())); + + final String srcDirName = getGeneratedSourcesDirectoryName(); + if (srcDirName != null) { + addChild(element, "sourceOutputDir").setAttribute(NAME, srcDirName); + } + + final Map options = getProcessorOptions(); + if (!options.isEmpty()) { + final List keys = new ArrayList(options.keySet()); + Collections.sort(keys, ALPHA_COMPARATOR); + for (String key : keys) { + addChild(element, OPTION).setAttribute(NAME, key).setAttribute(VALUE, options.get(key)); + } + } + + final Set processors = getProcessors(); + if (!processors.isEmpty()) { + final List processorList = new ArrayList(processors); + Collections.sort(processorList, ALPHA_COMPARATOR); + for (String proc : processorList) { + addChild(element, "processor").setAttribute(NAME, proc); + } + } + + final Element pathElement = addChild(element, "processorPath").setAttribute("useClasspath", Boolean.toString(isObtainProcessorsFromClasspath())); + final String path = getProcessorPath(); + if (!StringUtil.isEmpty(path)) { + final StringTokenizer tokenizer = new StringTokenizer(path, File.pathSeparator, false); + while (tokenizer.hasMoreTokens()) { + final String token = tokenizer.nextToken(); + addChild(pathElement, ENTRY).setAttribute(NAME, FileUtil.toSystemIndependentName(token)); + } + } + + final Set moduleNames = getModuleNames(); + if (!moduleNames.isEmpty()) { + final List names = new ArrayList(moduleNames); + Collections.sort(names, ALPHA_COMPARATOR); + for (String name : names) { + addChild(element, MODULE).setAttribute(NAME, name); + } + } + } + public final void initFrom(ProcessorConfigProfile other) { myName = other.myName; myEnabled = other.myEnabled; @@ -206,5 +319,11 @@ public class ProcessorConfigProfile implements AnnotationProcessingConfiguration public String toString() { return myName; } + + private static Element addChild(Element parent, final String childName) { + final Element child = new Element(childName); + parent.addContent(child); + return child; + } } From ad80249d118674bc646706992a8a821f20b02203 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 17 Jun 2012 15:10:55 +0200 Subject: [PATCH 070/100] shorter intention name --- .../src/com/siyeh/IntentionPowerPackBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 08b08fd25ea5..6c8da6aeb7f1 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -81,7 +81,7 @@ replace.if.with.conditional.intention.name=Replace 'if else' with '?:' replace.if.with.conditional.intention.family.name=Replace If Else with Conditional replace.equality.with.equals.intention.name=Replace '==' with '.equals()' replace.equality.with.equals.intention.family.name=Replace Equality with Equals -make.call.chain.into.call.sequence.intention.name=Make method call chain into method call sequence +make.call.chain.into.call.sequence.intention.name=Make method call chain into call sequence make.call.chain.into.call.sequence.intention.family.name=Make Call Chain Into Call Sequence merge.call.sequence.to.chain.intention.name=Merge sequential method calls into call chain merge.call.sequence.to.chain.intention.family.name=Merge Sequential Method Calls into Call Chain From 5ea707f15fd87f3c1823ffeae9af95c0c3e4eb4f Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 17 Jun 2012 15:12:14 +0200 Subject: [PATCH 071/100] cleanup --- ...oncatenationWithFormatStringIntention.java | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java index 66177cd977d2..a81f8e47aae3 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Bas Leijdekkers + * Copyright 2008-2012 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,8 +26,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -public class ReplaceConcatenationWithFormatStringIntention - extends Intention { +public class ReplaceConcatenationWithFormatStringIntention extends Intention { @Override @NotNull @@ -36,24 +35,17 @@ public class ReplaceConcatenationWithFormatStringIntention } @Override - protected void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - PsiPolyadicExpression expression = - (PsiPolyadicExpression)element; + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + PsiPolyadicExpression expression = (PsiPolyadicExpression)element; PsiElement parent = expression.getParent(); while (ConcatenationUtils.isConcatenation(parent)) { expression = (PsiPolyadicExpression)parent; - if (expression == null) { - return; - } parent = expression.getParent(); } - final StringBuilder formatString = new StringBuilder(); final List formatParameters = new ArrayList(); PsiConcatenationUtil.buildFormatString(expression, formatString, formatParameters, true); - if (replaceWithPrintfExpression(expression, formatString, - formatParameters)) { + if (replaceWithPrintfExpression(expression, formatString, formatParameters)) { return; } final StringBuilder newExpression = new StringBuilder(); @@ -68,11 +60,8 @@ public class ReplaceConcatenationWithFormatStringIntention replaceExpression(newExpression.toString(), expression); } - private static boolean replaceWithPrintfExpression( - PsiExpression expression, - CharSequence formatString, - List formatParameters) - throws IncorrectOperationException { + private static boolean replaceWithPrintfExpression(PsiExpression expression, CharSequence formatString, + List formatParameters) throws IncorrectOperationException { final PsiElement expressionParent = expression.getParent(); if (!(expressionParent instanceof PsiExpressionList)) { return false; @@ -81,10 +70,8 @@ public class ReplaceConcatenationWithFormatStringIntention if (!(grandParent instanceof PsiMethodCallExpression)) { return false; } - final PsiMethodCallExpression methodCallExpression = - (PsiMethodCallExpression)grandParent; - final PsiReferenceExpression methodExpression = - methodCallExpression.getMethodExpression(); + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent; + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); final String name = methodExpression.getReferenceName(); final boolean insertNewline; if ("println".equals(name)) { @@ -110,8 +97,7 @@ public class ReplaceConcatenationWithFormatStringIntention return false; } final StringBuilder newExpression = new StringBuilder(); - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier != null) { newExpression.append(qualifier.getText()); newExpression.append('.'); From 98a778b232f5c44a2177813f6eaacb2346f6b05d Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Sun, 17 Jun 2012 15:14:01 +0200 Subject: [PATCH 072/100] fix "Replace '+' with 'StringBuilder.append()'" intention on concatenation starting with non-string addition expression (e.g. 1 + 2 + "a") --- ...oncatenationWithStringBufferIntention.java | 78 +++++++++++-------- .../SimpleStringConcatenationPredicate.java | 1 + .../ConcatenationInsideAppend.java | 8 ++ .../ConcatenationInsideAppend_after.java | 8 ++ .../NonStringConcatenationStart.java | 8 ++ .../NonStringConcatenationStart_after.java | 8 ++ ...tenationWithStringBufferIntentionTest.java | 23 ++++++ 7 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend_after.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java index f9f9059bc03b..0c2b1e06f720 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,30 +47,19 @@ public class ReplaceConcatenationWithStringBufferIntention extends MutablyNamedI } @Override - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - PsiPolyadicExpression expression = - (PsiPolyadicExpression)element; + public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + PsiPolyadicExpression expression = (PsiPolyadicExpression)element; PsiElement parent = expression.getParent(); - if (parent == null) { - return; - } while (ConcatenationUtils.isConcatenation(parent)) { expression = (PsiPolyadicExpression)parent; parent = expression.getParent(); - if (parent == null) { - return; - } } @NonNls final StringBuilder newExpression = new StringBuilder(); if (isPartOfStringBufferAppend(expression)) { - final PsiMethodCallExpression methodCallExpression = - (PsiMethodCallExpression)parent.getParent(); + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)parent.getParent(); assert methodCallExpression != null; - final PsiReferenceExpression methodExpression = - methodCallExpression.getMethodExpression(); - final PsiExpression qualifierExpression = - methodExpression.getQualifierExpression(); + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (qualifierExpression != null) { final String qualifierText = qualifierExpression.getText(); newExpression.append(qualifierText); @@ -91,8 +80,7 @@ public class ReplaceConcatenationWithStringBufferIntention extends MutablyNamedI } } - private static boolean isPartOfStringBufferAppend( - PsiExpression expression) { + private static boolean isPartOfStringBufferAppend(PsiExpression expression) { PsiElement parent = expression.getParent(); if (!(parent instanceof PsiExpressionList)) { return false; @@ -101,35 +89,57 @@ public class ReplaceConcatenationWithStringBufferIntention extends MutablyNamedI if (!(parent instanceof PsiMethodCallExpression)) { return false; } - final PsiMethodCallExpression methodCall = - (PsiMethodCallExpression)parent; - final PsiReferenceExpression methodExpression = - methodCall.getMethodExpression(); + final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)parent; + final PsiReferenceExpression methodExpression = methodCall.getMethodExpression(); final PsiType type = methodExpression.getType(); if (type == null) { return false; } final String className = type.getCanonicalText(); - if (!CommonClassNames.JAVA_LANG_STRING_BUFFER.equals(className) && - !CommonClassNames.JAVA_LANG_STRING_BUILDER.equals(className)) { + if (!CommonClassNames.JAVA_LANG_STRING_BUFFER.equals(className) && !CommonClassNames.JAVA_LANG_STRING_BUILDER.equals(className)) { return false; } @NonNls final String methodName = methodExpression.getReferenceName(); return "append".equals(methodName); } - private static void turnExpressionIntoChainedAppends( - PsiExpression expression, @NonNls StringBuilder result) { - if (ConcatenationUtils.isConcatenation(expression)) { - final PsiPolyadicExpression concatenation = - (PsiPolyadicExpression)expression; - for (PsiExpression op : concatenation.getOperands()) { - turnExpressionIntoChainedAppends(op, result); + private static void turnExpressionIntoChainedAppends(PsiExpression expression, @NonNls StringBuilder result) { + if (expression instanceof PsiPolyadicExpression) { + final PsiPolyadicExpression concatenation = (PsiPolyadicExpression)expression; + final PsiType type = concatenation.getType(); + if (type != null && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + result.append(".append(").append(concatenation.getText()).append(')'); + return; + } + final PsiExpression[] operands = concatenation.getOperands(); + final PsiType startType = operands[0].getType(); + if (startType == null || startType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + for (PsiExpression operand : operands) { + turnExpressionIntoChainedAppends(operand, result); + } + return; + } + final StringBuilder newExpressionText = new StringBuilder(operands[0].getText()); + boolean string = false; + for (int i = 1; i < operands.length; i++) { + final PsiExpression operand = operands[i]; + if (!string) { + final PsiType operandType = operand.getType(); + if (operandType == null || operandType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(expression.getProject()); + final PsiExpression newExpression = factory.createExpressionFromText(newExpressionText.toString(), expression); + turnExpressionIntoChainedAppends(newExpression, result); + turnExpressionIntoChainedAppends(operand, result); + string = true; + } + newExpressionText.append('+').append(operand.getText()); + } else { + turnExpressionIntoChainedAppends(operand, result); + } } } else { - final PsiExpression strippedExpression = - ParenthesesUtils.stripParentheses(expression); + final PsiExpression strippedExpression = ParenthesesUtils.stripParentheses(expression); result.append(".append("); if (strippedExpression != null) { result.append(strippedExpression.getText()); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java index ff7bacc7c77b..1f932f5f2db7 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java @@ -31,6 +31,7 @@ class SimpleStringConcatenationPredicate implements PsiElementPredicate { this.excludeConcatenationsInsideAnnotations = excludeConcatenationsInsideAnnotations; } + @Override public boolean satisfiedBy(PsiElement element) { if (!ConcatenationUtils.isConcatenation(element)) { return false; diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend.java new file mode 100644 index 000000000000..f48eb251936f --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend.java @@ -0,0 +1,8 @@ +package com.siyeh.ipp.concatenation.string_builder; + +public class ConcatenationInsideAppend { + + StringBuilder foo() { + return new StringBuilder().append("asdf" + 1); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend_after.java new file mode 100644 index 000000000000..e28f84c1c12c --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/ConcatenationInsideAppend_after.java @@ -0,0 +1,8 @@ +package com.siyeh.ipp.concatenation.string_builder; + +public class ConcatenationInsideAppend { + + StringBuilder foo() { + return new StringBuilder().append("asdf").append(1); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart.java new file mode 100644 index 000000000000..6593ab677e3a --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart.java @@ -0,0 +1,8 @@ +package com.siyeh.ipp.concatenation.string_builder; + +public class NonStringConcatenationStart { + + String foo() { + return 1 + 2 + "asdf"; + } +} diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart_after.java new file mode 100644 index 000000000000..114c010548cc --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/concatenation/string_builder/NonStringConcatenationStart_after.java @@ -0,0 +1,8 @@ +package com.siyeh.ipp.concatenation.string_builder; + +public class NonStringConcatenationStart { + + String foo() { + return new StringBuilder().append(1 + 2).append("asdf").toString(); + } +} diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntentionTest.java new file mode 100644 index 000000000000..82ee9ca4b93e --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntentionTest.java @@ -0,0 +1,23 @@ +package com.siyeh.ipp.concatenation; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @author Bas Leijdekkers + */ +public class ReplaceConcatenationWithStringBufferIntentionTest extends IPPTestCase { + + public void testNonStringConcatenationStart() { doTest(); } + public void testConcatenationInsideAppend() { doTest(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("replace.concatenation.with.string.builder.intention.name"); + } + + @Override + protected String getRelativePath() { + return "concatenation/string_builder"; + } +} From 2e1d8fc1148977b2bd34c44331ada5dc6b32ac1d Mon Sep 17 00:00:00 2001 From: Alexey Gopachenko Date: Fri, 15 Jun 2012 23:41:48 +0200 Subject: [PATCH 073/100] Spellchecker avoid IOOBE --- .../src/com/intellij/spellchecker/compress/Alphabet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/compress/Alphabet.java b/plugins/spellchecker/src/com/intellij/spellchecker/compress/Alphabet.java index b7dbcabb024c..eca82090fd3b 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/compress/Alphabet.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/compress/Alphabet.java @@ -18,8 +18,7 @@ public final class Alphabet { */ public int getIndex(char letter, boolean forceAdd) { - final int r = getNextIndex(0, letter, forceAdd); - return r; + return getNextIndex(0, letter, forceAdd); } /* @@ -28,6 +27,7 @@ public final class Alphabet { */ public int getNextIndex(int startFrom, char letter, boolean forceAdd) { for (int i = startFrom; i <= lastIndexUsed; i++) { + if (i == letters.length) return -1; if (letters[i] != 0 && letters[i] == letter) { return i; } From 5fc7e5988548bb7a85befbb0d2f9f90b2aab76f5 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sun, 17 Jun 2012 19:07:09 +0200 Subject: [PATCH 074/100] allow '\r' in debugger text viewer --- .../intellij/debugger/actions/ViewTextAction.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java index dafaacb3aba1..d71e13b4af46 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java @@ -20,8 +20,10 @@ import com.intellij.debugger.engine.evaluation.TextWithImports; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeExpression; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; @@ -89,7 +91,15 @@ public class ViewTextAction extends BaseValueAction { private static class TextViewer extends EditorTextField { private TextViewer(Project project) { - super(EditorFactory.getInstance().createDocument(""), project, FileTypes.PLAIN_TEXT, true, false); + super(createDocument(), project, FileTypes.PLAIN_TEXT, true, false); + } + + private static Document createDocument() { + final Document document = EditorFactory.getInstance().createDocument(""); + if (document instanceof DocumentImpl) { + ((DocumentImpl)document).setAcceptSlashR(true); + } + return document; } protected EditorEx createEditor() { From 5223b04a7860f692b93a2f9817d8effa658eaeef Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sun, 17 Jun 2012 19:34:38 +0200 Subject: [PATCH 075/100] recovering from some errors when saving templates --- .../ide/fileTemplates/impl/FTManager.java | 115 ++++++++++-------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java index 75c3719dc527..8cf851726d2c 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java @@ -186,61 +186,66 @@ class FTManager { } void saveTemplates() { - try { - final File configRoot = getConfigRoot(true); - - final File[] files = configRoot.listFiles(); + final File configRoot = getConfigRoot(true); - final Set allNames = new HashSet(); - final Map templatesOnDisk = files != null && files.length > 0? new HashMap() : Collections.emptyMap(); - if (files != null) { - for (File file : files) { - if (!file.isDirectory()) { - final String name = file.getName(); - templatesOnDisk.put(name, file); - allNames.add(name); - } - } - } + final File[] files = configRoot.listFiles(); - final Map templatesToSave = new HashMap(); - - for (FileTemplateBase template : getAllTemplates(true)) { - if (template instanceof BundledFileTemplate && !((BundledFileTemplate)template).isTextModified()) { - continue; - } - final String name = template.getQualifiedName(); - templatesToSave.put(name, template); - allNames.add(name); - } - - if (!allNames.isEmpty()) { - final String lineSeparator = CodeStyleSettingsManager.getSettings(ProjectManagerEx.getInstanceEx().getDefaultProject()).getLineSeparator(); - for (String name : allNames) { - final File customizedTemplateFile = templatesOnDisk.get(name); - final FileTemplateBase templateToSave = templatesToSave.get(name); - if (customizedTemplateFile == null) { - // template was not saved before - saveTemplate(configRoot, templateToSave, lineSeparator); - } - else if (templateToSave == null) { - // template was removed - FileUtil.delete(customizedTemplateFile); - } - else { - // both customized content on disk and corresponding template are present - final String diskText = StringUtil.convertLineSeparators(FileUtil.loadFile(customizedTemplateFile, CONTENT_ENCODING)); - final String templateText = templateToSave.getText(); - if (!diskText.equals(templateText)) { - // save only if texts differ to avoid unnecessary file touching - saveTemplate(configRoot, templateToSave, lineSeparator); - } - } + final Set allNames = new HashSet(); + final Map templatesOnDisk = files != null && files.length > 0? new HashMap() : Collections.emptyMap(); + if (files != null) { + for (File file : files) { + if (!file.isDirectory()) { + final String name = file.getName(); + templatesOnDisk.put(name, file); + allNames.add(name); } } } - catch (IOException e) { - LOG.error("Unable to save templates", e); + + final Map templatesToSave = new HashMap(); + + for (FileTemplateBase template : getAllTemplates(true)) { + if (template instanceof BundledFileTemplate && !((BundledFileTemplate)template).isTextModified()) { + continue; + } + final String name = template.getQualifiedName(); + templatesToSave.put(name, template); + allNames.add(name); + } + + if (!allNames.isEmpty()) { + final String lineSeparator = CodeStyleSettingsManager.getSettings(ProjectManagerEx.getInstanceEx().getDefaultProject()).getLineSeparator(); + for (String name : allNames) { + final File customizedTemplateFile = templatesOnDisk.get(name); + final FileTemplateBase templateToSave = templatesToSave.get(name); + if (customizedTemplateFile == null) { + // template was not saved before + try { + saveTemplate(configRoot, templateToSave, lineSeparator); + } + catch (IOException e) { + LOG.error("Unable to save template " + name, e); + } + } + else if (templateToSave == null) { + // template was removed + FileUtil.delete(customizedTemplateFile); + } + else { + // both customized content on disk and corresponding template are present + try { + final String diskText = StringUtil.convertLineSeparators(FileUtil.loadFile(customizedTemplateFile, CONTENT_ENCODING)); + final String templateText = templateToSave.getText(); + if (!diskText.equals(templateText)) { + // save only if texts differ to avoid unnecessary file touching + saveTemplate(configRoot, templateToSave, lineSeparator); + } + } + catch (IOException e) { + LOG.error("Unable to save template " + name, e); + } + } + } } } @@ -251,7 +256,15 @@ class FTManager { private static void saveTemplate(File parentDir, FileTemplateBase template, final String lineSeparator) throws IOException { final File templateFile = new File(parentDir, template.getName() + "." + template.getExtension()); - FileOutputStream fileOutputStream = new FileOutputStream(templateFile); + FileOutputStream fileOutputStream; + try { + fileOutputStream = new FileOutputStream(templateFile); + } + catch (FileNotFoundException e) { + // try to recover from the situation 'file exists, but is a directory' + FileUtil.delete(templateFile); + fileOutputStream = new FileOutputStream(templateFile); + } OutputStreamWriter outputStreamWriter; try{ outputStreamWriter = new OutputStreamWriter(fileOutputStream, CONTENT_ENCODING); From 8f5a542c44c062804c10c61512b6aaf3ac21c0f2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Sat, 16 Jun 2012 16:34:02 +0400 Subject: [PATCH 076/100] suggestion to restart or postpone app --- .../plugins/PluginManagerConfigurable.java | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java index 4963e3930086..1774ffec7b9c 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurable.java @@ -161,18 +161,38 @@ public class PluginManagerConfigurable extends BaseConfigurable implements Searc return myPluginManagerMain; } - private static int showShutDownIDEADialog() { + public static int showShutDownIDEADialog() { + return showShutDownIDEADialog(IdeBundle.message("title.plugins.changed")); + } + + public static int showShutDownIDEADialog(final String title) { String message = IdeBundle.message("message.idea.shutdown.required", ApplicationNamesInfo.getInstance().getProductName()); - String title = IdeBundle.message("title.plugins.changed"); - return Messages.showYesNoDialog(message, title, "Shut Down", POSTPONE,Messages.getQuestionIcon()); + return Messages.showYesNoDialog(message, title, "Shut Down", POSTPONE, Messages.getQuestionIcon()); } public static int showRestartIDEADialog() { + return showRestartIDEADialog(IdeBundle.message("title.plugins.changed")); + } + + public static int showRestartIDEADialog(final String title) { String message = IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getProductName()); - String title = IdeBundle.message("title.plugins.changed"); return Messages.showYesNoDialog(message, title, "Restart", POSTPONE, Messages.getQuestionIcon()); } + public static void shutdownOrRestartApp(String title) { + final ApplicationEx app = ApplicationManagerEx.getApplicationEx(); + if (app.isRestartCapable()) { + if (showRestartIDEADialog(title) == 0) { + app.restart(); + } + } + else { + if (showShutDownIDEADialog(title) == 0) { + app.exit(true); + } + } + } + public boolean isModified() { return myPluginManagerMain != null && myPluginManagerMain.isModified(); } From cce603cbbbd2ab9a00f7c79225286f47cab19975 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 18 Jun 2012 08:53:10 +0400 Subject: [PATCH 077/100] new jps modules included into installers layout --- build/scripts/utils.gant | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 903559db0c69..caa584c6452c 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -226,6 +226,7 @@ binding.setVariable("platformApiModules", [ "core-api", "indexing-api", "projectModel-api", + "jps-model-api", "platform-api", "lvcs-api", "lang-api", @@ -239,6 +240,8 @@ binding.setVariable("platformApiModules", [ binding.setVariable("platformImplementationModules", [ "core-impl", "indexing-impl", + "jps-model-impl", + "jps-model-serialization", "projectModel-impl", "platform-impl", "vcs-impl", From 5f277b64723ab09f2e768dc70fda566ddaa1895a Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 18 Jun 2012 09:53:54 +0400 Subject: [PATCH 078/100] get rid of unnecessary creations of ModifiableRootModel --- .../roots/impl/storage/ClasspathStorage.java | 20 ++++---- .../storage/ClasspathStorageProvider.java | 4 +- .../EclipseClasspathStorageProvider.java | 29 ++++++++---- .../export/ExportEclipseProjectsAction.java | 47 +++++++++---------- .../idea/eclipse/EclipseClasspathTest.java | 7 +-- .../idea/eclipse/EclipseEmlTest.java | 16 +++---- .../idea/eclipse/EclipseImlTest.java | 15 +++--- 7 files changed, 70 insertions(+), 68 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java index e4c70d8f3651..b3497c61fcf3 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorage.java @@ -80,7 +80,8 @@ public class ClasspathStorage implements StateStorage { public ClasspathStorage(Module module) { myConverter = getProvider(getStorageType(module)).createConverter(module); final MessageBus messageBus = module.getMessageBus(); - final VirtualFileTracker virtualFileTracker = (VirtualFileTracker)module.getPicoContainer().getComponentInstanceOfType(VirtualFileTracker.class); + final VirtualFileTracker virtualFileTracker = + (VirtualFileTracker)module.getPicoContainer().getComponentInstanceOfType(VirtualFileTracker.class); if (virtualFileTracker != null && messageBus != null) { final ArrayList files = new ArrayList(); try { @@ -125,7 +126,7 @@ public class ClasspathStorage implements StateStorage { model.dispose(); } } - + final boolean macrosOk = ProjectMacrosUtil.checkNonIgnoredMacros(module.getProject(), macros); PathMacroManager.getInstance(module).expandPaths(element); ModuleRootManagerImpl.ModuleRootManagerState moduleRootManagerState = new ModuleRootManagerImpl.ModuleRootManagerState(); @@ -195,7 +196,7 @@ public class ClasspathStorage implements StateStorage { } @Nullable - public Set analyzeExternalChanges(final Set> changedFiles) { + public Set analyzeExternalChanges(final Set> changedFiles) { return null; } @@ -235,7 +236,8 @@ public class ClasspathStorage implements StateStorage { public void finishSave(final SaveSession saveSession) { try { LOG.assertTrue(mySession == saveSession); - } finally { + } + finally { mySession = null; } } @@ -305,7 +307,7 @@ public class ClasspathStorage implements StateStorage { } } - public static void setStorageType(final ModifiableRootModel model, final String storageID) { + public static void setStorageType(final ModuleRootModel model, final String storageID) { final Module module = model.getModule(); final String oldStorageType = getStorageType(module); if (oldStorageType.equals(storageID)) { @@ -343,7 +345,7 @@ public class ClasspathStorage implements StateStorage { return DEFAULT_STORAGE_DESCR; } - public void assertCompatible(final ModifiableRootModel model) throws ConfigurationException { + public void assertCompatible(final ModuleRootModel model) throws ConfigurationException { } public void detach(Module module) { @@ -357,7 +359,7 @@ public class ClasspathStorage implements StateStorage { throw new UnsupportedOperationException(getDescription()); } - public String getContentRoot(ModifiableRootModel model) { + public String getContentRoot(ModuleRootModel model) { return null; } @@ -383,7 +385,7 @@ public class ClasspathStorage implements StateStorage { return "Unsupported classpath format " + myType; } - public void assertCompatible(final ModifiableRootModel model) throws ConfigurationException { + public void assertCompatible(final ModuleRootModel model) throws ConfigurationException { throw new UnsupportedOperationException(getDescription()); } @@ -411,7 +413,7 @@ public class ClasspathStorage implements StateStorage { }; } - public String getContentRoot(ModifiableRootModel model) { + public String getContentRoot(ModuleRootModel model) { return null; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorageProvider.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorageProvider.java index 20935866199b..b00df210303d 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorageProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/storage/ClasspathStorageProvider.java @@ -43,7 +43,7 @@ public interface ClasspathStorageProvider { @Nls String getDescription(); - void assertCompatible(final ModifiableRootModel model) throws ConfigurationException; + void assertCompatible(final ModuleRootModel model) throws ConfigurationException; void detach(Module module); @@ -51,7 +51,7 @@ public interface ClasspathStorageProvider { ClasspathConverter createConverter(Module module); - String getContentRoot(ModifiableRootModel model); + String getContentRoot(ModuleRootModel model); void modulePathChanged(Module module, String path); diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseClasspathStorageProvider.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseClasspathStorageProvider.java index 86867b40a344..eff535917510 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseClasspathStorageProvider.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/config/EclipseClasspathStorageProvider.java @@ -63,7 +63,7 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider return DESCR; } - public void assertCompatible(final ModifiableRootModel model) throws ConfigurationException { + public void assertCompatible(final ModuleRootModel model) throws ConfigurationException { final String moduleName = model.getModule().getName(); for (OrderEntry entry : model.getOrderEntries()) { if (entry instanceof LibraryOrderEntry) { @@ -74,7 +74,11 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider libraryEntry.getRootUrls(OrderRootType.CLASSES).length != 1 || library.isJarDirectory(library.getUrls(OrderRootType.CLASSES)[0])) { throw new ConfigurationException( - "Library \'" + entry.getPresentableName() + "\' from module \'" + moduleName + "\' dependencies is incompatible with eclipse format which supports only one library content root"); + "Library \'" + + entry.getPresentableName() + + "\' from module \'" + + moduleName + + "\' dependencies is incompatible with eclipse format which supports only one library content root"); } } } @@ -84,8 +88,12 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider } final String output = model.getModuleExtension(CompilerModuleExtension.class).getCompilerOutputUrl(); final String contentRoot = getContentRoot(model); - if (output == null || !StringUtil.startsWith(VfsUtil.urlToPath(output), contentRoot) && PathMacroManager.getInstance(model.getModule()).collapsePath(output).equals(output)) { - throw new ConfigurationException("Module \'" + moduleName + "\' output path is incompatible with eclipse format which supports output under content root only.\nPlease make sure that \"Inherit project compile output path\" is not selected"); + if (output == null || + !StringUtil.startsWith(VfsUtil.urlToPath(output), contentRoot) && + PathMacroManager.getInstance(model.getModule()).collapsePath(output).equals(output)) { + throw new ConfigurationException("Module \'" + + moduleName + + "\' output path is incompatible with eclipse format which supports output under content root only.\nPlease make sure that \"Inherit project compile output path\" is not selected"); } } @@ -97,7 +105,7 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider return new EclipseClasspathConverter(module); } - public String getContentRoot(ModifiableRootModel model) { + public String getContentRoot(ModuleRootModel model) { final VirtualFile contentRoot = EPathUtil.getContentRoot(model); if (contentRoot != null) return contentRoot.getPath(); return model.getContentRoots()[0].getPath(); @@ -111,7 +119,10 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider } } - public static void registerFiles(final CachedXmlDocumentSet fileCache, final Module module, final String moduleRoot, final String storageRoot) { + public static void registerFiles(final CachedXmlDocumentSet fileCache, + final Module module, + final String moduleRoot, + final String storageRoot) { fileCache.register(EclipseXml.CLASSPATH_FILE, storageRoot); fileCache.register(EclipseXml.PROJECT_FILE, storageRoot); fileCache.register(EclipseXml.PLUGIN_XML_FILE, storageRoot); @@ -185,13 +196,15 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider if (documentSet.exists(EclipseXml.CLASSPATH_FILE)) { classpathReader.readClasspath(model, new ArrayList(), new ArrayList(), usedVariables, new HashSet(), null, documentSet.read(EclipseXml.CLASSPATH_FILE).getRootElement()); - } else { + } + else { EclipseClasspathReader.setupOutput(model, path + "/bin"); } final String eml = model.getModule().getName() + EclipseXml.IDEA_SETTINGS_POSTFIX; if (documentSet.exists(eml)) { IdeaSpecificSettings.readIDEASpecific(documentSet.read(eml).getRootElement(), model); - } else { + } + else { model.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false); } diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java index 39d6f9f1d06e..58b879143bba 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/export/ExportEclipseProjectsAction.java @@ -24,8 +24,8 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModel; import com.intellij.openapi.roots.impl.storage.ClasspathStorage; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; @@ -53,61 +53,62 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware { public void update(final AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - e.getPresentation().setEnabled( project != null ); + e.getPresentation().setEnabled(project != null); } public void actionPerformed(AnActionEvent e) { final Project project = e.getData(PlatformDataKeys.PROJECT); - if ( project == null ) return; + if (project == null) return; project.save(); // to flush iml files final List modules = new ArrayList(); final List incompatibleModules = new ArrayList(); for (Module module : ModuleManager.getInstance(project).getModules()) { if (!EclipseClasspathStorageProvider.ID.equals(ClasspathStorage.getStorageType(module))) { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); try { - ClasspathStorage.getProvider(EclipseClasspathStorageProvider.ID).assertCompatible(model); + ClasspathStorage.getProvider(EclipseClasspathStorageProvider.ID).assertCompatible(ModuleRootManager.getInstance(module)); modules.add(module); } catch (ConfigurationException e1) { incompatibleModules.add(module); - } finally { - model.dispose(); } } } //todo suggest smth with hierarchy modules if (!incompatibleModules.isEmpty()) { - if (Messages.showOkCancelDialog(project, "Eclipse incompatible modules found:


    • " + StringUtil.join(incompatibleModules, new Function() { - public String fun(Module module) { - return module.getName(); - } - }, "
    • ") + "

    Would you like to proceed and possibly lose your configurations?", "Eclipse Incompatible Modules Found", Messages.getWarningIcon()) != DialogWrapper.OK_EXIT_CODE) { + if (Messages.showOkCancelDialog(project, "Eclipse incompatible modules found:

    • " + + StringUtil.join(incompatibleModules, new Function() { + public String fun(Module module) { + return module.getName(); + } + }, "
    • ") + + "

    Would you like to proceed and possibly lose your configurations?", + "Eclipse Incompatible Modules Found", Messages.getWarningIcon()) != DialogWrapper.OK_EXIT_CODE) { return; } - } else if (modules.isEmpty()){ - Messages.showInfoMessage(project, EclipseBundle.message("eclipse.export.nothing.to.do"), EclipseBundle.message("eclipse.export.dialog.title")); + } + else if (modules.isEmpty()) { + Messages.showInfoMessage(project, EclipseBundle.message("eclipse.export.nothing.to.do"), + EclipseBundle.message("eclipse.export.dialog.title")); return; } modules.addAll(incompatibleModules); final ExportEclipseProjectsDialog dialog = new ExportEclipseProjectsDialog(project, modules); - dialog.show (); - if(dialog.isOK()){ + dialog.show(); + if (dialog.isOK()) { if (dialog.isLink()) { for (Module module : dialog.getSelectedModules()) { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - ClasspathStorage.setStorageType(model, EclipseClasspathStorageProvider.ID); - model.dispose(); + ClasspathStorage.setStorageType(ModuleRootManager.getInstance(module), EclipseClasspathStorageProvider.ID); } } else { for (Module module : dialog.getSelectedModules()) { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + final ModuleRootModel model = ModuleRootManager.getInstance(module); final VirtualFile[] contentRoots = model.getContentRoots(); //todo - final String storageRoot = contentRoots.length == 1 ? contentRoots[0].getPath() : ClasspathStorage.getStorageRootFromOptions(module); + final String storageRoot = + contentRoots.length == 1 ? contentRoots[0].getPath() : ClasspathStorage.getStorageRootFromOptions(module); try { final Element classpathEleemnt = new Element(EclipseXml.CLASSPATH_TAG); @@ -135,9 +136,6 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware { catch (WriteExternalException e1) { LOG.error(e1); } - finally { - model.dispose(); - } } } try { @@ -149,5 +147,4 @@ public class ExportEclipseProjectsAction extends AnAction implements DumbAware { project.save(); } } - } diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java index e2e67229c90f..ec5305cf7786 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseClasspathTest.java @@ -29,6 +29,7 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModel; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.SystemInfo; @@ -62,8 +63,6 @@ public class EclipseClasspathTest extends IdeaTestCase { assertTrue(currentTestRoot.getAbsolutePath(), currentTestRoot.isDirectory()); FileUtil.copyDir(currentTestRoot, new File(getProject().getBaseDir().getPath())); - - } private void doTest() throws Exception { @@ -113,10 +112,9 @@ public class EclipseClasspathTest extends IdeaTestCase { fileText1 = fileText1.replaceAll(EclipseXml.FILE_PROTOCOL + "/", EclipseXml.FILE_PROTOCOL); } final Element classpathElement1 = JDOMUtil.loadDocument(fileText1).getRootElement(); - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + final ModuleRootModel model = ModuleRootManager.getInstance(module); final Element resultClasspathElement = new Element(EclipseXml.CLASSPATH_TAG); new EclipseClasspathWriter(model).writeClasspath(resultClasspathElement, classpathElement1); - model.dispose(); String resulted = new String(JDOMUtil.printDocument(new Document(resultClasspathElement), "\n")); Assert.assertTrue(resulted.replaceAll(StringUtil.escapeToRegexp(module.getProject().getBaseDir().getPath()), "\\$ROOT\\$"), @@ -124,7 +122,6 @@ public class EclipseClasspathTest extends IdeaTestCase { } - public void testAbsolutePaths() throws Exception { doTest("/parent/parent/test", getProject()); } diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseEmlTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseEmlTest.java index 17f6d9514c82..d8cd4841bfd8 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseEmlTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseEmlTest.java @@ -28,6 +28,8 @@ import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModel; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -54,12 +56,9 @@ public class EclipseEmlTest extends IdeaTestCase { assertTrue(currentTestRoot.getAbsolutePath(), currentTestRoot.isDirectory()); FileUtil.copyDir(currentTestRoot, new File(getProject().getBaseDir().getPath())); - - } - protected static void doTest(String relativePath, final Project project) throws Exception { final String path = project.getBaseDir().getPath() + relativePath; final Module module = doLoadModule(path, project); @@ -84,7 +83,8 @@ public class EclipseEmlTest extends IdeaTestCase { new EclipseClasspathStorageProvider.EclipseClasspathConverter(module); final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel(); - final Element classpathElement = JDOMUtil.loadDocument(FileUtil.loadFile(new File(path, EclipseXml.DOT_CLASSPATH_EXT))).getRootElement(); + final Element classpathElement = + JDOMUtil.loadDocument(FileUtil.loadFile(new File(path, EclipseXml.DOT_CLASSPATH_EXT))).getRootElement(); converter.getClasspath(rootModel, classpathElement); ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { @@ -95,11 +95,9 @@ public class EclipseEmlTest extends IdeaTestCase { } protected static void checkModule(String path, Module module) throws WriteExternalException, IOException, JDOMException { - ModifiableRootModel rootModel; - rootModel = ModuleRootManager.getInstance(module).getModifiableModel(); + ModuleRootModel rootModel = ModuleRootManager.getInstance(module); final Element root = new Element("component"); IdeaSpecificSettings.writeIDEASpecificClasspath(root, rootModel); - rootModel.dispose(); final String resulted = new String(JDOMUtil.printDocument(new Document(root), "\n")); @@ -128,9 +126,7 @@ public class EclipseEmlTest extends IdeaTestCase { final Module module = doLoadModule(path, project); - final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel(); - modifiableModel.inheritSdk(); - modifiableModel.commit(); + ModuleRootModificationUtil.setSdkInherited(module); checkModule(projectBasePath + "/test/expected", module); } diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java index b47da4e11558..6d19e5988921 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseImlTest.java @@ -31,7 +31,7 @@ import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.impl.RootModelImpl; +import com.intellij.openapi.roots.impl.ModuleRootManagerImpl; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.SystemInfo; @@ -61,8 +61,6 @@ public class EclipseImlTest extends IdeaTestCase { assertTrue(currentTestRoot.getAbsolutePath(), currentTestRoot.isDirectory()); FileUtil.copyDir(currentTestRoot, new File(getProject().getBaseDir().getPath())); - - } private void doTest() throws Exception { @@ -95,24 +93,24 @@ public class EclipseImlTest extends IdeaTestCase { final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, null); classpathReader.init(rootModel); classpathReader - .readClasspath(rootModel, new ArrayList(), new ArrayList(), new HashSet(), new HashSet(), null, classpathElement); + .readClasspath(rootModel, new ArrayList(), new ArrayList(), new HashSet(), new HashSet(), null, + classpathElement); ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { rootModel.commit(); } }); - final RootModelImpl model = (RootModelImpl)ModuleRootManager.getInstance(module).getModifiableModel(); final Element actualImlElement = new Element("root"); - model.writeExternal(actualImlElement); - model.dispose(); + ((ModuleRootManagerImpl)ModuleRootManager.getInstance(module)).getState().writeExternal(actualImlElement); PathMacros.getInstance().setMacro(JUNIT, communityAppDir); PathMacroManager.getInstance(module).collapsePaths(actualImlElement); PathMacroManager.getInstance(project).collapsePaths(actualImlElement); PathMacros.getInstance().removeMacro(JUNIT); - final Element expectedIml = JDOMUtil.loadDocument(new File(project.getBaseDir().getPath() + "/expected", "expected.iml")).getRootElement(); + final Element expectedIml = + JDOMUtil.loadDocument(new File(project.getBaseDir().getPath() + "/expected", "expected.iml")).getRootElement(); Assert.assertTrue(new String(JDOMUtil.printDocument(new Document(actualImlElement), "\n")), JDOMUtil.areElementsEqual(expectedIml, actualImlElement)); } @@ -138,5 +136,4 @@ public class EclipseImlTest extends IdeaTestCase { public void testRoot() throws Exception { doTest(); } - } From f4e5a9dd15642c1d29f7dfd6bb0f166bfbfe24b5 Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 18 Jun 2012 10:33:53 +0400 Subject: [PATCH 079/100] added utility for common ModuleRootModel modifications --- .../impl/SetupSDKNotificationProvider.java | 9 +- .../actions/CreateLibraryFromFilesDialog.java | 11 +- .../daemon/impl/quickfix/OrderEntryFix.java | 18 +-- .../daemon/impl/quickfix/SetupJDKFix.java | 13 +- .../InferNullityAnnotationsAction.java | 46 +++--- .../HeavySmartTypeCompletion15Test.groovy | 10 +- .../daemon/AdvHighlightingTest.java | 153 ++++++++++++------ .../daemon/quickFix/OrderEntryTest.java | 31 ++-- .../JavaAPIUsagesInspectionTest.java | 41 ++--- .../configurations/JavaParametersTest.java | 20 +-- .../roots/impl/ProjectLibrariesTest.java | 19 +-- .../intellij/psi/ClsRepositoryUseTest.java | 67 ++++---- .../psi/impl/cache/impl/SCR14423Test.java | 8 +- .../psi/resolve/ResolveClassTest.java | 35 ++-- .../roots/DirectoryIndexImplTest.java | 21 +-- .../intellij/roots/ExportingModulesTest.java | 13 +- .../com/intellij/roots/InheritedJdkTest.java | 48 ++---- .../roots/ModuleRootManagerTestCase.java | 17 -- .../com/intellij/roots/ModuleScopesTest.java | 5 +- .../com/intellij/roots/OrderEntriesTest.java | 22 ++- .../intellij/roots/OrderEnumeratorTest.java | 32 ++-- .../roots/ProjectClasspathTraversingTest.java | 16 +- .../roots/ProjectRootsTraversingTest.java | 8 +- .../testFramework/InspectionTestCase.java | 33 ++-- .../impl/SdkConfigurationUtil.java | 36 ++--- .../roots/ModuleRootModificationUtil.java | 73 +++++++++ .../platform/ModuleAttachProcessor.java | 23 +-- .../testFramework/PlatformTestCase.java | 26 ++- .../intellij/testFramework/PsiTestUtil.java | 47 +++--- .../com/siyeh/ig/IGInspectionTestCase.java | 2 +- .../AddModuleDependencyTask.java | 16 +- .../android/sdk/AndroidSdkUtils.java | 25 +-- .../jetbrains/android/AndroidTestCase.java | 15 +- .../dom/AndroidLibraryProjectTest.java | 9 +- .../idea/eclipse/Eclipse2ModulesTest.java | 19 +-- .../groovy/mvc/MvcModuleStructureUtil.java | 29 ++-- .../groovy/compiler/GroovyCompilerTest.groovy | 35 ++-- .../compiler/GroovyCompilerTestCase.java | 27 ++-- .../idea/maven/MavenImportingTestCase.java | 12 +- .../importing/DependenciesImportingTest.java | 11 +- .../InsertComponentProcessor.java | 59 ++++--- 41 files changed, 571 insertions(+), 589 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java index ea25eec3f4c1..714a0efe77fd 100644 --- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java +++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java @@ -16,14 +16,9 @@ package com.intellij.codeInsight.daemon.impl; import com.intellij.ProjectTopics; -import com.intellij.icons.AllIcons; import com.intellij.ide.highlighter.JavaClassFileType; -import com.intellij.lang.Language; -import com.intellij.lang.StdLanguages; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.fileTypes.FileTypes; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; @@ -95,9 +90,7 @@ public class SetupSDKNotificationProvider implements EditorNotifications.Provide public void run() { final Module module = ModuleUtil.findModuleForPsiElement(file); if (module != null) { - ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel(); - modifiableModel.inheritSdk(); - modifiableModel.commit(); + ModuleRootModificationUtil.setSdkInherited(module); } } }); diff --git a/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java b/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java index 5737389099ce..a75eb5d5ce5a 100644 --- a/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java +++ b/java/idea-ui/src/com/intellij/ide/projectView/actions/CreateLibraryFromFilesDialog.java @@ -22,6 +22,7 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.impl.libraries.LibraryTypeServiceImpl; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.ui.OrderRoot; @@ -61,8 +62,10 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper { myProject = project; myRoots = roots; final FormBuilder builder = LibraryNameAndLevelPanel.createFormBuilder(); - myDefaultName = LibrariesContainerFactory.createContainer(project).suggestUniqueLibraryName(LibraryTypeServiceImpl.suggestLibraryName(roots)); - myNameAndLevelPanel = new LibraryNameAndLevelPanel(builder, myDefaultName, Arrays.asList(LibrariesContainer.LibraryLevel.values()), LibrariesContainer.LibraryLevel.PROJECT); + myDefaultName = + LibrariesContainerFactory.createContainer(project).suggestUniqueLibraryName(LibraryTypeServiceImpl.suggestLibraryName(roots)); + myNameAndLevelPanel = new LibraryNameAndLevelPanel(builder, myDefaultName, Arrays.asList(LibrariesContainer.LibraryLevel.values()), + LibrariesContainer.LibraryLevel.PROJECT); myNameAndLevelPanel.setDefaultName(myDefaultName); myModulesCombobox = new ModulesCombobox(); myModulesCombobox.fillModules(myProject); @@ -141,9 +144,7 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper { else { final Library library = LibrariesContainerFactory.createContainer(myProject).createLibrary(libraryName, level, myRoots); if (module != null) { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - model.addLibraryEntry(library); - model.commit(); + ModuleRootModificationUtil.addDependency(module, library); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java index f24750334d90..e38e2e3c37b9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java @@ -158,7 +158,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { @Override public void run() { final LocateLibraryDialog dialog = new LocateLibraryDialog(currentModule, PathManager.getLibPath(), "annotations.jar", - QuickFixBundle.message("add.library.annotations.description")); + QuickFixBundle.message("add.library.annotations.description")); dialog.show(); if (dialog.isOK()) { new WriteCommandAction(project) { @@ -212,12 +212,9 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { final Runnable doit = new Runnable() { @Override public void run() { - ModifiableRootModel model = ModuleRootManager.getInstance(currentModule).getModifiableModel(); - final ModuleOrderEntry entry = model.addModuleOrderEntry(classModule); - if (ModuleRootManager.getInstance(currentModule).getFileIndex().isInTestSourceContent(classVFile)) { - entry.setScope(DependencyScope.TEST); - } - model.commit(); + final boolean test = ModuleRootManager.getInstance(currentModule).getFileIndex().isInTestSourceContent(classVFile); + ModuleRootModificationUtil.addDependency(currentModule, classModule, + test ? DependencyScope.TEST : DependencyScope.COMPILE, false); if (editor != null) { final List targetClasses = new ArrayList(); for (PsiClass psiClass : classes) { @@ -257,7 +254,8 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { if (entryForFile instanceof ExportableOrderEntry && ((ExportableOrderEntry)entryForFile).getScope() == DependencyScope.TEST && !ModuleRootManager.getInstance(currentModule).getFileIndex().isInTestSourceContent(classVFile)) { - } else { + } + else { continue; } } @@ -361,9 +359,9 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { final Module classModule, final Runnable doit) { final String message = QuickFixBundle.message("orderEntry.fix.circular.dependency.warning", classModule.getName(), - circularModules.getFirst().getName(), circularModules.getSecond().getName()); + circularModules.getFirst().getName(), circularModules.getSecond().getName()); if (ApplicationManager.getApplication().isUnitTestMode()) throw new RuntimeException(message); - ApplicationManager.getApplication().invokeLater(new Runnable(){ + ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { if (!project.isOpen()) return; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SetupJDKFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SetupJDKFix.java index bbe494cdc1dc..ad033fcb0e26 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SetupJDKFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SetupJDKFix.java @@ -24,8 +24,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.psi.CommonClassNames; import com.intellij.psi.JavaPsiFacade; @@ -34,15 +33,17 @@ import org.jetbrains.annotations.NotNull; /** * @author mike - * Date: Aug 20, 2002 + * Date: Aug 20, 2002 */ public class SetupJDKFix implements IntentionAction, HighPriorityAction { private static final SetupJDKFix ourInstance = new SetupJDKFix(); + public static SetupJDKFix getInstance() { return ourInstance; } - private SetupJDKFix() { } + private SetupJDKFix() { + } @Override @NotNull @@ -70,9 +71,7 @@ public class SetupJDKFix implements IntentionAction, HighPriorityAction { public void run() { Module module = ModuleUtil.findModuleForPsiElement(file); if (module != null) { - ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel(); - modifiableModel.inheritSdk(); - modifiableModel.commit(); + ModuleRootModificationUtil.setSdkInherited(module); } } }); diff --git a/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java b/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java index b3f54b8061d2..c56c86ee2f0c 100644 --- a/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java +++ b/java/java-impl/src/com/intellij/codeInspection/inferNullity/InferNullityAnnotationsAction.java @@ -34,8 +34,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectUtil; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryUtil; import com.intellij.openapi.ui.DialogWrapper; @@ -79,6 +78,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { scope.accept(new PsiElementVisitor() { private int myFileCount = 0; final private Set processed = new HashSet(); + @Override public void visitFile(PsiFile file) { myFileCount++; @@ -94,7 +94,8 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { if (module != null && !processed.contains(module)) { processed.add(module); if (JavaPsiFacade.getInstance(project) - .findClass(NullableNotNullManager.getInstance(project).getDefaultNullable(), GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)) == null) { + .findClass(NullableNotNullManager.getInstance(project).getDefaultNullable(), + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)) == null) { modulesWithoutAnnotations.add(module); } if (PsiUtil.getLanguageLevel(file).compareTo(LanguageLevel.JDK_1_5) < 0) { @@ -104,13 +105,17 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { } }); } - }, "Check applicability...", true, project)) return; + }, "Check applicability...", true, project)) { + return; + } if (!modulesWithLL.isEmpty()) { - Messages.showErrorDialog(project, "Infer Nullity Annotations requires the project language level be set to 1.5 or greater.", INFER_NULLITY_ANNOTATIONS); + Messages.showErrorDialog(project, "Infer Nullity Annotations requires the project language level be set to 1.5 or greater.", + INFER_NULLITY_ANNOTATIONS); return; } if (!modulesWithoutAnnotations.isEmpty()) { - final Library annotationsLib = LibraryUtil.findLibraryByClass(NullableNotNullManager.getInstance(project).getDefaultNullable(), project); + final Library annotationsLib = + LibraryUtil.findLibraryByClass(NullableNotNullManager.getInstance(project).getDefaultNullable(), project); if (annotationsLib != null) { String message = "Module" + (modulesWithoutAnnotations.size() == 1 ? " " : "s "); message += StringUtil.join(modulesWithoutAnnotations, new Function() { @@ -120,25 +125,27 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { } }, ", "); message += (modulesWithoutAnnotations.size() == 1 ? " doesn't" : " don't"); - message += " refer to the existing '" + annotationsLib.getName() + "' library with IDEA nullity annotations. Would you like to add the dependenc"; - message += (modulesWithoutAnnotations.size() == 1 ? "y" : "ies")+ " now?"; - if (Messages.showOkCancelDialog(project, message, INFER_NULLITY_ANNOTATIONS, Messages.getErrorIcon()) == DialogWrapper.OK_EXIT_CODE) { + message += " refer to the existing '" + + annotationsLib.getName() + + "' library with IDEA nullity annotations. Would you like to add the dependenc"; + message += (modulesWithoutAnnotations.size() == 1 ? "y" : "ies") + " now?"; + if (Messages.showOkCancelDialog(project, message, INFER_NULLITY_ANNOTATIONS, Messages.getErrorIcon()) == + DialogWrapper.OK_EXIT_CODE) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { for (Module module : modulesWithoutAnnotations) { - final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel(); - modifiableModel.addLibraryEntry(annotationsLib); - modifiableModel.commit(); + ModuleRootModificationUtil.addDependency(module, annotationsLib); } } }); } - } else if (Messages.showOkCancelDialog(project, "Infer Nullity Annotations requires that the nullity annotations" + - " be available in all your project sources.\n\nYou will need to add annotations.jar as a library. " + - "It is possible to configure custom jar in e.g. Constant Conditions & Exceptions inspection or use JetBrains annotations available in installation. " + - " The IDEA nullity annotations are freely usable and redistributable under the Apache 2.0 license. Would you like to do it now?", - INFER_NULLITY_ANNOTATIONS, Messages.getErrorIcon()) == DialogWrapper.OK_EXIT_CODE) { + } + else if (Messages.showOkCancelDialog(project, "Infer Nullity Annotations requires that the nullity annotations" + + " be available in all your project sources.\n\nYou will need to add annotations.jar as a library. " + + "It is possible to configure custom jar in e.g. Constant Conditions & Exceptions inspection or use JetBrains annotations available in installation. " + + " The IDEA nullity annotations are freely usable and redistributable under the Apache 2.0 license. Would you like to do it now?", + INFER_NULLITY_ANNOTATIONS, Messages.getErrorIcon()) == DialogWrapper.OK_EXIT_CODE) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { final LocateLibraryDialog dialog = @@ -169,6 +176,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { public void run() { scope.accept(new PsiElementVisitor() { int myFileCount = 0; + @Override public void visitFile(final PsiFile file) { myFileCount++; @@ -189,7 +197,9 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction { } }); } - }, INFER_NULLITY_ANNOTATIONS, true, project)) return; + }, INFER_NULLITY_ANNOTATIONS, true, project)) { + return; + } final Runnable applyRunnable = new Runnable() { @Override diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.groovy index c137c3e0ab11..259f7291e3b5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.groovy @@ -4,7 +4,8 @@ import com.intellij.JavaTestUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.StdModuleTypes; import com.intellij.testFramework.PsiTestUtil; -import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase +import com.intellij.openapi.roots.ModuleRootModificationUtil; @SuppressWarnings(["ALL"]) public class HeavySmartTypeCompletion15Test extends JavaCodeInsightFixtureTestCase { @@ -17,7 +18,7 @@ public class HeavySmartTypeCompletion15Test extends JavaCodeInsightFixtureTestCa public void testGetInstance() throws Throwable { myFixture.configureFromExistingVirtualFile( - myFixture.copyFileToProject(BASE_PATH + "/foo/" + getTestName(false) + ".java", "foo/" + getTestName(false) + ".java")); + myFixture.copyFileToProject(BASE_PATH + "/foo/" + getTestName(false) + ".java", "foo/" + getTestName(false) + ".java")); myFixture.complete(CompletionType.SMART); myFixture.type('\n'); myFixture.checkResultByFile(BASE_PATH + "/foo/" + getTestName(false) + "-out.java"); @@ -83,8 +84,8 @@ public class HeavySmartTypeCompletion15Test extends JavaCodeInsightFixtureTestCa Module moduleA = PsiTestUtil.addModule(project, StdModuleTypes.JAVA, 'A', myFixture.tempDirFixture.findOrCreateDir("a")) Module moduleB = PsiTestUtil.addModule(project, StdModuleTypes.JAVA, 'B', myFixture.tempDirFixture.findOrCreateDir("b")) - PsiTestUtil.addDependency(myModule, moduleB) - PsiTestUtil.addDependency(moduleB, moduleA) + ModuleRootModificationUtil.addDependency(myModule, moduleB) + ModuleRootModificationUtil.addDependency(moduleB, moduleA) myFixture.addFileToProject('a/foo/Foo.java', 'package foo; public interface Foo {}') myFixture.addFileToProject('b/bar/Bar.java', 'package bar; public class Bar { public static void accept(foo.Foo i) {} }') @@ -93,5 +94,4 @@ public class HeavySmartTypeCompletion15Test extends JavaCodeInsightFixtureTestCa myFixture.type('\n') checkResult() } - } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java index 205bc25da987..cd2914873945 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java @@ -3,7 +3,6 @@ package com.intellij.codeInsight.daemon; import com.intellij.analysis.PackagesScopesProvider; import com.intellij.application.options.colors.ColorAndFontOptions; import com.intellij.codeInsight.daemon.impl.HighlightInfo; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; @@ -15,8 +14,7 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.packageDependencies.DependencyValidationManager; @@ -48,38 +46,113 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { return JavaSdkImpl.getMockJdk14(); } - public void testPackageLocals() throws Exception { doTest(BASE_PATH+"/packageLocals/x/sub/UsingMain.java", BASE_PATH+"/packageLocals", false, false); } - public void testPackageLocalClassInTheMiddle() throws Exception { doTest(BASE_PATH+"/packageLocals/x/A.java", BASE_PATH+"/packageLocals", false, false); } + public void testPackageLocals() throws Exception { + doTest(BASE_PATH + "/packageLocals/x/sub/UsingMain.java", BASE_PATH + "/packageLocals", false, false); + } - public void testEffectiveAccessLevel() throws Exception { doTest(BASE_PATH+"/accessLevel/effectiveAccess/p2/p3.java", BASE_PATH+"/accessLevel", false, false); } - public void testSingleImportConflict() throws Exception { doTest(BASE_PATH+"/singleImport/d.java", BASE_PATH+"/singleImport", false, false); } + public void testPackageLocalClassInTheMiddle() throws Exception { + doTest(BASE_PATH + "/packageLocals/x/A.java", BASE_PATH + "/packageLocals", false, false); + } - public void testDuplicateTopLevelClass() throws Exception { doTest(BASE_PATH+"/duplicateClass/A.java", BASE_PATH+"/duplicateClass", false, false); } - public void testDuplicateTopLevelClass2() throws Exception { doTest(BASE_PATH+"/duplicateClass/java/lang/Runnable.java", BASE_PATH+"/duplicateClass", false, false); } + public void testEffectiveAccessLevel() throws Exception { + doTest(BASE_PATH + "/accessLevel/effectiveAccess/p2/p3.java", BASE_PATH + "/accessLevel", false, false); + } - public void testProtectedConstructorCall() throws Exception { doTest(BASE_PATH+"/protectedConstructor/p2/C2.java", BASE_PATH+"/protectedConstructor", false, false); } - public void testProtectedConstructorCallInSamePackage() throws Exception { doTest(BASE_PATH+"/protectedConstructor/samePackage/C2.java", BASE_PATH+"/protectedConstructor", false, false); } - public void testProtectedConstructorCallInInner() throws Exception { doTest(BASE_PATH+"/protectedConstructorInInner/p2/C2.java", BASE_PATH+"/protectedConstructorInInner", false, false); } - public void testArrayLengthAccessFromSubClass() throws Exception { doTest(BASE_PATH+"/arrayLength/p2/SubTest.java", BASE_PATH+"/arrayLength", false, false); } - public void testAccessibleMember() throws Exception { doTest(BASE_PATH+"/accessibleMember/com/red/C.java", BASE_PATH+"/accessibleMember", false, false); } - public void testOnDemandImportConflict() throws Exception { doTest(BASE_PATH+"/onDemandImportConflict/Outer.java", BASE_PATH+"/onDemandImportConflict", false, false); } - public void testPackageLocalOverride() throws Exception { doTest(BASE_PATH+"/packageLocalOverride/y/C.java", BASE_PATH+"/packageLocalOverride", false, false); } - public void testPackageLocalOverrideJustCheckThatPackageLocalMethodDoesNotGetOverridden() throws Exception { doTest(BASE_PATH+"/packageLocalOverride/y/B.java", BASE_PATH+"/packageLocalOverride", false, false); } - public void testProtectedAccessFromOtherPackage() throws Exception { doTest(BASE_PATH+"/protectedAccessFromOtherPackage/a/Main.java", BASE_PATH+"/protectedAccessFromOtherPackage", false, false); } - public void testProtectedFieldAccessFromOtherPackage() throws Exception { doTest(BASE_PATH+"/protectedAccessFromOtherPackage/a/A.java", BASE_PATH+"/protectedAccessFromOtherPackage", false, false); } - public void testPackageLocalClassInTheMiddle1() throws Exception { doTest(BASE_PATH+"/foreignPackageInBetween/a/A1.java", BASE_PATH+"/foreignPackageInBetween", false, false); } + public void testSingleImportConflict() throws Exception { + doTest(BASE_PATH + "/singleImport/d.java", BASE_PATH + "/singleImport", false, false); + } - public void testImportOnDemand() throws Exception { doTest(BASE_PATH+"/importOnDemand/y/Y.java", BASE_PATH+"/importOnDemand", false, false); } - public void testImportOnDemandVsSingle() throws Exception { doTest(BASE_PATH+"/importOnDemandVsSingle/y/Y.java", BASE_PATH+"/importOnDemandVsSingle", false, false); } - public void testImportSingleVsSamePackage() throws Exception { doTest(BASE_PATH+"/importSingleVsSamePackage/y/Y.java", BASE_PATH+"/importSingleVsSamePackage", false, false); } - public void testImportSingleVsInherited() throws Exception { doTest(BASE_PATH + "/importSingleVsInherited/Test.java", BASE_PATH + "/importSingleVsInherited", false, false); } - public void testImportOnDemandVsInherited() throws Exception { doTest(BASE_PATH + "/importOnDemandVsInherited/Test.java", BASE_PATH + "/importOnDemandVsInherited", false, false); } + public void testDuplicateTopLevelClass() throws Exception { + doTest(BASE_PATH + "/duplicateClass/A.java", BASE_PATH + "/duplicateClass", false, false); + } - public void testOverridePackageLocal() throws Exception { doTest(BASE_PATH+"/overridePackageLocal/x/y/Derived.java", BASE_PATH+"/overridePackageLocal", false, false); } - public void testAlreadyImportedClass() throws Exception { doTest(BASE_PATH+"/alreadyImportedClass/pack/AlreadyImportedClass.java", BASE_PATH+"/alreadyImportedClass", false, false); } - public void testImportDefaultPackage() throws Exception { doTest(BASE_PATH+"/importDefaultPackage/x/Usage.java", BASE_PATH+"/importDefaultPackage", false, false); } - public void testImportDefaultPackage2() throws Exception { doTest(BASE_PATH+"/importDefaultPackage/x/ImportOnDemandUsage.java", BASE_PATH+"/importDefaultPackage", false, false); } - public void testImportDefaultPackageInvalid() throws Exception { doTest(BASE_PATH+"/importDefaultPackage/x/InvalidUse.java", BASE_PATH+"/importDefaultPackage", false, false); } + public void testDuplicateTopLevelClass2() throws Exception { + doTest(BASE_PATH + "/duplicateClass/java/lang/Runnable.java", BASE_PATH + "/duplicateClass", false, false); + } + + public void testProtectedConstructorCall() throws Exception { + doTest(BASE_PATH + "/protectedConstructor/p2/C2.java", BASE_PATH + "/protectedConstructor", false, false); + } + + public void testProtectedConstructorCallInSamePackage() throws Exception { + doTest(BASE_PATH + "/protectedConstructor/samePackage/C2.java", BASE_PATH + "/protectedConstructor", false, false); + } + + public void testProtectedConstructorCallInInner() throws Exception { + doTest(BASE_PATH + "/protectedConstructorInInner/p2/C2.java", BASE_PATH + "/protectedConstructorInInner", false, false); + } + + public void testArrayLengthAccessFromSubClass() throws Exception { + doTest(BASE_PATH + "/arrayLength/p2/SubTest.java", BASE_PATH + "/arrayLength", false, false); + } + + public void testAccessibleMember() throws Exception { + doTest(BASE_PATH + "/accessibleMember/com/red/C.java", BASE_PATH + "/accessibleMember", false, false); + } + + public void testOnDemandImportConflict() throws Exception { + doTest(BASE_PATH + "/onDemandImportConflict/Outer.java", BASE_PATH + "/onDemandImportConflict", false, false); + } + + public void testPackageLocalOverride() throws Exception { + doTest(BASE_PATH + "/packageLocalOverride/y/C.java", BASE_PATH + "/packageLocalOverride", false, false); + } + + public void testPackageLocalOverrideJustCheckThatPackageLocalMethodDoesNotGetOverridden() throws Exception { + doTest(BASE_PATH + "/packageLocalOverride/y/B.java", BASE_PATH + "/packageLocalOverride", false, false); + } + + public void testProtectedAccessFromOtherPackage() throws Exception { + doTest(BASE_PATH + "/protectedAccessFromOtherPackage/a/Main.java", BASE_PATH + "/protectedAccessFromOtherPackage", false, false); + } + + public void testProtectedFieldAccessFromOtherPackage() throws Exception { + doTest(BASE_PATH + "/protectedAccessFromOtherPackage/a/A.java", BASE_PATH + "/protectedAccessFromOtherPackage", false, false); + } + + public void testPackageLocalClassInTheMiddle1() throws Exception { + doTest(BASE_PATH + "/foreignPackageInBetween/a/A1.java", BASE_PATH + "/foreignPackageInBetween", false, false); + } + + public void testImportOnDemand() throws Exception { + doTest(BASE_PATH + "/importOnDemand/y/Y.java", BASE_PATH + "/importOnDemand", false, false); + } + + public void testImportOnDemandVsSingle() throws Exception { + doTest(BASE_PATH + "/importOnDemandVsSingle/y/Y.java", BASE_PATH + "/importOnDemandVsSingle", false, false); + } + + public void testImportSingleVsSamePackage() throws Exception { + doTest(BASE_PATH + "/importSingleVsSamePackage/y/Y.java", BASE_PATH + "/importSingleVsSamePackage", false, false); + } + + public void testImportSingleVsInherited() throws Exception { + doTest(BASE_PATH + "/importSingleVsInherited/Test.java", BASE_PATH + "/importSingleVsInherited", false, false); + } + + public void testImportOnDemandVsInherited() throws Exception { + doTest(BASE_PATH + "/importOnDemandVsInherited/Test.java", BASE_PATH + "/importOnDemandVsInherited", false, false); + } + + public void testOverridePackageLocal() throws Exception { + doTest(BASE_PATH + "/overridePackageLocal/x/y/Derived.java", BASE_PATH + "/overridePackageLocal", false, false); + } + + public void testAlreadyImportedClass() throws Exception { + doTest(BASE_PATH + "/alreadyImportedClass/pack/AlreadyImportedClass.java", BASE_PATH + "/alreadyImportedClass", false, false); + } + + public void testImportDefaultPackage() throws Exception { + doTest(BASE_PATH + "/importDefaultPackage/x/Usage.java", BASE_PATH + "/importDefaultPackage", false, false); + } + + public void testImportDefaultPackage2() throws Exception { + doTest(BASE_PATH + "/importDefaultPackage/x/ImportOnDemandUsage.java", BASE_PATH + "/importDefaultPackage", false, false); + } + + public void testImportDefaultPackageInvalid() throws Exception { + doTest(BASE_PATH + "/importDefaultPackage/x/InvalidUse.java", BASE_PATH + "/importDefaultPackage", false, false); + } public void testScopeBased() throws Exception { NamedScope xScope = new NamedScope("xxx", new PatternPackageSet("x..*", PatternPackageSet.SCOPE_SOURCE, null)); @@ -107,6 +180,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { scopeManager.removeAllSets(); } } + public void testSharedScopeBased() throws Exception { NamedScope xScope = new NamedScope("xxx", new PatternPackageSet("x..*", PatternPackageSet.SCOPE_ANY, null)); NamedScope utilScope = new NamedScope("util", new PatternPackageSet("java.util.*", PatternPackageSet.SCOPE_LIBRARY, null)); @@ -132,7 +206,7 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { scheme.setAttributes(projectKey, projectAttributes); try { - testFile(BASE_PATH+"/scopeBased/x/Shared.java").projectRoot(BASE_PATH+"/scopeBased").checkSymbolNames().test(); + testFile(BASE_PATH + "/scopeBased/x/Shared.java").projectRoot(BASE_PATH + "/scopeBased").checkSymbolNames().test(); } finally { scopeManager.removeAllSets(); @@ -146,20 +220,9 @@ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { ModuleManager moduleManager = ModuleManager.getInstance(getProject()); final Module java4 = moduleManager.findModuleByName("java4"); Module java5 = moduleManager.findModuleByName("java5"); - final ModuleRootManager rootManager4 = ModuleRootManager.getInstance(java4); - final ModuleRootManager rootManager5 = ModuleRootManager.getInstance(java5); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ModifiableRootModel rootModel4 = rootManager4.getModifiableModel(); - rootModel4.setSdk(JavaSdkImpl.getMockJdk17("java 1.4")); - rootModel4.commit(); - final ModifiableRootModel rootModel5 = rootManager5.getModifiableModel(); - rootModel5.setSdk(JavaSdkImpl.getMockJdk17("java 1.5")); - rootModel5.addModuleOrderEntry(java4); - rootModel5.commit(); - } - }); + ModuleRootModificationUtil.setModuleSdk(java4, JavaSdkImpl.getMockJdk17("java 1.4")); + ModuleRootModificationUtil.setModuleSdk(java5, JavaSdkImpl.getMockJdk17("java 1.5")); + ModuleRootModificationUtil.addDependency(java5, java4); assert root != null; configureByExistingFile(root.findFileByRelativePath("moduleJava5/com/Java5.java")); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/OrderEntryTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/OrderEntryTest.java index 3a6ca8cc358a..6bd671b9f162 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/OrderEntryTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/OrderEntryTest.java @@ -12,6 +12,7 @@ import com.intellij.openapi.module.impl.ModuleManagerImpl; import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; @@ -32,7 +33,8 @@ public class OrderEntryTest extends DaemonAnalyzerTestCase { protected void setUpProject() throws Exception { final String root = PathManagerEx.getTestDataPath() + BASE_PATH; - VirtualFile tempProjectRootDir = PsiTestUtil.createTestProjectStructure(getTestName(true), null, FileUtil.toSystemIndependentName(root), myFilesToDelete, false); + VirtualFile tempProjectRootDir = + PsiTestUtil.createTestProjectStructure(getTestName(true), null, FileUtil.toSystemIndependentName(root), myFilesToDelete, false); VirtualFile projectFile = tempProjectRootDir.findChild("orderEntry.ipr"); @@ -57,7 +59,7 @@ public class OrderEntryTest extends DaemonAnalyzerTestCase { VirtualFile root = ModuleRootManager.getInstance(myModule).getContentRoots()[0].getParent(); VirtualFile virtualFile = root.findFileByRelativePath(fileName); configureByExistingFile(virtualFile); - Pair pair = LightQuickFixTestCase.parseActionHint(getFile(), getFile().getText()); + Pair pair = LightQuickFixTestCase.parseActionHint(getFile(), getFile().getText()); final String text = pair.getFirst(); final boolean actionShouldBeAvailable = pair.getSecond().booleanValue(); Collection infosBefore = highlightErrors(); @@ -65,9 +67,9 @@ public class OrderEntryTest extends DaemonAnalyzerTestCase { if (action == null) { if (actionShouldBeAvailable) { - fail("Action with text '" + text + "' is not available in test " + testFullPath+"." + - "\nAvailable actions are: "+LightQuickFixTestCase.getAvailableActions(getEditor(), getFile()) - +"\nInfos are: "+infosBefore + fail("Action with text '" + text + "' is not available in test " + testFullPath + "." + + "\nAvailable actions are: " + LightQuickFixTestCase.getAvailableActions(getEditor(), getFile()) + + "\nInfos are: " + infosBefore ); } } @@ -87,7 +89,7 @@ public class OrderEntryTest extends DaemonAnalyzerTestCase { if (afterAction != null) { fail("Action '" + text + "' is still available after its invocation in test " + testFullPath); } - assertEquals(infosBefore.size()-1, infosAfter.size()); + assertEquals(infosBefore.size() - 1, infosAfter.size()); } } @@ -96,12 +98,18 @@ public class OrderEntryTest extends DaemonAnalyzerTestCase { return LightQuickFixTestCase.findActionWithText(actions, actionText); } - public void testAddDependency() throws Exception { doTest("B/src/y/AddDependency.java"); } - public void testAddLibrary() throws Exception { doTest("B/src/y/AddLibrary.java"); } + public void testAddDependency() throws Exception { + doTest("B/src/y/AddDependency.java"); + } + + public void testAddLibrary() throws Exception { + doTest("B/src/y/AddLibrary.java"); + } + public void testAddCircularDependency() throws Exception { final Module a = ModuleManager.getInstance(getProject()).findModuleByName("A"); final Module b = ModuleManager.getInstance(getProject()).findModuleByName("B"); - PsiTestUtil.addDependency(a, b); + ModuleRootModificationUtil.addDependency(a, b); try { doTest("B/src/y/AddDependency.java"); @@ -109,12 +117,13 @@ public class OrderEntryTest extends DaemonAnalyzerTestCase { } catch (RuntimeException e) { final String expected = "Adding dependency on module '" + a.getName() + "'" + - " will introduce circular dependency between modules '" + a.getName() + "' and '" + - b.getName() + "'.\n" + "Add dependency anyway?"; + " will introduce circular dependency between modules '" + a.getName() + "' and '" + + b.getName() + "'.\n" + "Add dependency anyway?"; String message = e.getMessage(); assertEquals(expected, message); } } + public void testAddJunit() throws Exception { doTest("A/src/x/DoTest.java"); } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java index 61fb39b75972..cebf9a0d346b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/JavaAPIUsagesInspectionTest.java @@ -7,11 +7,7 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; import com.intellij.codeInspection.java15api.Java15APIUsageInspection; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.roots.ContentIterator; -import com.intellij.openapi.roots.LanguageLevelModuleExtension; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.impl.FileIndexImplUtil; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.JarFileSystem; @@ -22,6 +18,7 @@ import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.javadoc.PsiDocTagValue; +import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.InspectionTestCase; public class JavaAPIUsagesInspectionTest extends InspectionTestCase { @@ -30,38 +27,18 @@ public class JavaAPIUsagesInspectionTest extends InspectionTestCase { return JavaTestUtil.getJavaTestDataPath() + "/inspection"; } - private void doTest() throws Exception { + private void doTest() { final Java15APIUsageInspection usageInspection = new Java15APIUsageInspection(); doTest("usage1.5/" + getTestName(true), new LocalInspectionToolWrapper(usageInspection), "java 1.5"); } public void testConstructor() throws Exception { - final LanguageLevel[] languageLevel = {null}; - try { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - ModifiableRootModel model = ModuleRootManager.getInstance(getModule()).getModifiableModel(); - LanguageLevelModuleExtension extension = model.getModuleExtension(LanguageLevelModuleExtension.class); - languageLevel[0] = extension.getLanguageLevel(); - extension.setLanguageLevel(LanguageLevel.JDK_1_4); - model.commit(); - } - }); - - doTest(); - } - finally { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - ModifiableRootModel model = ModuleRootManager.getInstance(getModule()).getModifiableModel(); - LanguageLevelModuleExtension extension = model.getModuleExtension(LanguageLevelModuleExtension.class); - extension.setLanguageLevel(languageLevel[0]); - model.commit(); - } - }); - } + IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_1_4, new Runnable() { + @Override + public void run() { + doTest(); + } + }); } public void testIgnored() throws Exception { @@ -75,7 +52,7 @@ public class JavaAPIUsagesInspectionTest extends InspectionTestCase { public boolean processFile(VirtualFile fileOrDir) { final PsiFile file = PsiManager.getInstance(getProject()).findFile(fileOrDir); if (file instanceof PsiJavaFile) { - file.accept(new JavaRecursiveElementVisitor(){ + file.accept(new JavaRecursiveElementVisitor() { @Override public void visitElement(PsiElement element) { super.visitElement(element); diff --git a/java/java-tests/testSrc/com/intellij/execution/configurations/JavaParametersTest.java b/java/java-tests/testSrc/com/intellij/execution/configurations/JavaParametersTest.java index 610073ad3b2d..291cb45d7573 100644 --- a/java/java-tests/testSrc/com/intellij/execution/configurations/JavaParametersTest.java +++ b/java/java-tests/testSrc/com/intellij/execution/configurations/JavaParametersTest.java @@ -19,16 +19,16 @@ import com.intellij.execution.CantRunException; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.DependencyScope; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.roots.ModuleRootManagerTestCase; -import com.intellij.testFramework.PsiTestUtil; /** * @author nik */ public class JavaParametersTest extends ModuleRootManagerTestCase { public void testLibrary() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); assertClasspath(myModule, JavaParameters.JDK_AND_CLASSES_AND_TESTS, getRtJar(), getJDomJar()); assertClasspath(myModule, JavaParameters.CLASSES_ONLY, @@ -54,8 +54,8 @@ public class JavaParametersTest extends ModuleRootManagerTestCase { } public void testLibraryScope() throws Exception { - addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.RUNTIME, false); - addLibraryDependency(myModule, createAsmLibrary(), DependencyScope.TEST, false); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.RUNTIME, false); + ModuleRootModificationUtil.addDependency(myModule, createAsmLibrary(), DependencyScope.TEST, false); assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS, getJDomJar(), getAsmJar()); @@ -64,7 +64,7 @@ public class JavaParametersTest extends ModuleRootManagerTestCase { } public void testProvidedScope() throws Exception { - addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.PROVIDED, false); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.PROVIDED, false); assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS, getJDomJar()); assertClasspath(myModule, JavaParameters.CLASSES_ONLY); @@ -74,19 +74,19 @@ public class JavaParametersTest extends ModuleRootManagerTestCase { final Module dep = createModule("dep"); final VirtualFile depOutput = setModuleOutput(dep, false); final VirtualFile depTestOutput = setModuleOutput(dep, true); - addLibraryDependency(dep, createJDomLibrary()); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); assertClasspath(myModule, JavaParameters.CLASSES_ONLY, depOutput, getJDomJar()); assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS, depTestOutput, depOutput, getJDomJar()); } - + public void testModuleDependencyScope() throws Exception { final Module dep = createModule("dep"); - addLibraryDependency(dep, createJDomLibrary()); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.TEST, true); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.TEST, true); assertClasspath(myModule, JavaParameters.CLASSES_ONLY); assertClasspath(myModule, JavaParameters.CLASSES_AND_TESTS, diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/ProjectLibrariesTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/ProjectLibrariesTest.java index 702d0c3a2206..469c5be62660 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/ProjectLibrariesTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/ProjectLibrariesTest.java @@ -4,6 +4,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; import com.intellij.openapi.roots.libraries.Library; @@ -31,14 +32,7 @@ public class ProjectLibrariesTest extends IdeaTestCase { return libraryTable.createLibrary("LIB"); } }); - final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - rootModel.addLibraryEntry(lib); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - rootModel.commit(); - } - }); + ModuleRootModificationUtil.addDependency(myModule, lib); final JavaPsiFacade manager = getJavaFacade(); assertNull(manager.findClass("pack.MyClass", GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule))); final File file = new File(PathManagerEx.getTestDataPath() + "/psi/repositoryUse/cls"); @@ -69,14 +63,7 @@ public class ProjectLibrariesTest extends IdeaTestCase { return libraryTable.createLibrary("LIB"); } }); - final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - rootModel.addLibraryEntry(lib); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - rootModel.commit(); - } - }); + ModuleRootModificationUtil.addDependency(myModule, lib); final JavaPsiFacade manager = getJavaFacade(); assertNull(manager.findClass("pack.MyClass", GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(myModule))); diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java index 88781d154921..cd5014899fc1 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java @@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; @@ -36,7 +37,7 @@ import com.intellij.testFramework.PsiTestUtil; import java.io.File; @PlatformTestCase.WrapInCommand -public class ClsRepositoryUseTest extends PsiTestCase{ +public class ClsRepositoryUseTest extends PsiTestCase { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.ClsRepositoryUseTest"); private static final String TEST_ROOT = PathManagerEx.getTestDataPath() + "/psi/repositoryUse/cls"; @@ -90,12 +91,12 @@ public class ClsRepositoryUseTest extends PsiTestCase{ new Runnable() { @Override public void run() { - try{ + try { VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(classes); assertNotNull(vDir); addLibraryToRoots(vDir, OrderRootType.CLASSES); } - catch(Exception e){ + catch (Exception e) { LOG.error(e); } } @@ -131,10 +132,10 @@ public class ClsRepositoryUseTest extends PsiTestCase{ new Runnable() { @Override public void run() { - try{ + try { vFile.refresh(false, false); } - catch(Exception e){ + catch (Exception e) { LOG.error(e); } } @@ -167,7 +168,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ return vDir; } - public void testGetClasses(){ + public void testGetClasses() { final VirtualFile rootFile = getRootFile(); final VirtualFile pack = rootFile.findChild("pack"); assert pack != null; @@ -183,7 +184,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals(file, aClass.getParent()); } - public void testGetClassName(){ + public void testGetClassName() { final VirtualFile rootFile = getRootFile(); final VirtualFile pack = rootFile.findChild("pack"); assert pack != null; @@ -199,7 +200,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals("MyClass", aClass.getName()); } - public void testGetClassQName(){ + public void testGetClassQName() { final VirtualFile rootFile = getRootFile(); final VirtualFile pack = rootFile.findChild("pack"); assert pack != null; @@ -215,7 +216,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals("pack.MyClass", aClass.getQualifiedName()); } - public void testGetContainingFile(){ + public void testGetContainingFile() { final VirtualFile rootFile = getRootFile(); final VirtualFile pack = rootFile.findChild("pack"); assert pack != null; @@ -231,7 +232,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals(file, aClass.getContainingFile()); } - public void testFindClass(){ + public void testFindClass() { getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.ALL); PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); @@ -241,7 +242,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE); } - public void testIsInterface(){ + public void testIsInterface() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -252,7 +253,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertTrue(elt.isValid()); } - public void testPackageName(){ + public void testPackageName() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -260,7 +261,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals("pack", packageName); } - public void testGetFields(){ + public void testGetFields() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -269,7 +270,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals(aClass, fields[0].getParent()); } - public void testGetMethods(){ + public void testGetMethods() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -278,7 +279,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals(aClass, methods[0].getParent()); } - public void testGetInnerClasses(){ + public void testGetInnerClasses() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -310,21 +311,21 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals(modifierList.getParent(), method); } - public void testGetFieldName(){ + public void testGetFieldName() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); assertEquals("field1", aClass.getFields()[0].getName()); } - public void testGetMethodName(){ + public void testGetMethodName() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); assertEquals("method1", aClass.getMethods()[0].getName()); } - public void testFindFieldByName(){ + public void testFindFieldByName() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -332,7 +333,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertNotNull(field); } - public void testIsDeprecated(){ + public void testIsDeprecated() { PsiClass aClass = myJavaFacade.findClass("pack.MyClass", GlobalSearchScope.allScope(myProject)); assert aClass != null; checkValid(aClass); @@ -403,7 +404,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ PsiField field = aClass.getFields()[1]; PsiType type = field.getType(); LOG.assertTrue(type instanceof PsiArrayType); - PsiType componentType = ((PsiArrayType) type).getComponentType(); + PsiType componentType = ((PsiArrayType)type).getComponentType(); assertTrue(componentType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)); assertEquals("Object", componentType.getPresentableText()); @@ -421,7 +422,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertNull(PsiUtil.resolveClassInType(type1)); PsiField field2 = aClass.getFields()[1]; - PsiType type2 = ((PsiArrayType) field2.getType()).getComponentType(); + PsiType type2 = ((PsiArrayType)field2.getType()).getComponentType(); assertTrue(type2 instanceof PsiClassType); assertTrue(type2.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)); @@ -535,7 +536,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ PsiClass map = myJavaFacade.findClass("java.util.HashMap", RESOLVE_SCOPE); assert map != null; PsiMethod entrySet = map.findMethodsByName("entrySet", false)[0]; - PsiClassType ret = (PsiClassType) entrySet.getReturnType(); + PsiClassType ret = (PsiClassType)entrySet.getReturnType(); assert ret != null : entrySet; final PsiClassType.ClassResolveResult setResolveResult = ret.resolveGenerics(); final PsiClass setResolveResultElement = setResolveResult.getElement(); @@ -560,20 +561,13 @@ public class ClsRepositoryUseTest extends PsiTestCase{ }; assertEquals(2, mapParams.length); assertEquals("K", mapParams[0].getCanonicalText()); - assertTrue(((PsiClassType) mapParams[0]).resolve() instanceof PsiTypeParameter); + assertTrue(((PsiClassType)mapParams[0]).resolve() instanceof PsiTypeParameter); assertEquals("V", mapParams[1].getCanonicalText()); - assertTrue(((PsiClassType) mapParams[1]).resolve() instanceof PsiTypeParameter); + assertTrue(((PsiClassType)mapParams[1]).resolve() instanceof PsiTypeParameter); } private void disableJdk() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - rootModel.setSdk(null); - rootModel.commit(); - } - }); + ModuleRootModificationUtil.setModuleSdk(myModule, null); } public void testGenericReturnType() throws Exception { @@ -583,7 +577,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assert map != null; final PsiElementFactory factory = myJavaFacade.getElementFactory(); final PsiClassType typeMapStringToInteger = - (PsiClassType) factory.createTypeFromText("java.util.Map ", null); + (PsiClassType)factory.createTypeFromText("java.util.Map ", null); final PsiClassType.ClassResolveResult mapResolveResult = typeMapStringToInteger.resolveGenerics(); final PsiClass mapResolveResultElement = mapResolveResult.getElement(); assert mapResolveResultElement != null : typeMapStringToInteger; @@ -595,7 +589,8 @@ public class ClsRepositoryUseTest extends PsiTestCase{ assertEquals("java.util.Set>", entrySetReturnType.getCanonicalText()); final PsiSubstitutor substitutor = ((PsiClassType)entrySetReturnType).resolveGenerics().getSubstitutor(); assertEquals("E of java.util.Set -> ? extends java.util.Map.Entry\n", substitutor.toString()); - final PsiType typeSetOfEntriesOfStringAndInteger = factory.createTypeFromText("java.util.Set>", null); + final PsiType typeSetOfEntriesOfStringAndInteger = + factory.createTypeFromText("java.util.Set>", null); final PsiType substitutedEntrySetReturnType = mapResolveResult.getSubstitutor().substitute(entrySetReturnType); assertTrue(typeSetOfEntriesOfStringAndInteger.equals(substitutedEntrySetReturnType)); assertTrue(typeSetOfEntriesOfStringAndInteger.isAssignableFrom(substitutedEntrySetReturnType)); @@ -608,8 +603,8 @@ public class ClsRepositoryUseTest extends PsiTestCase{ "}"; PsiJavaFile file = (PsiJavaFile)PsiFileFactory.getInstance(getProject()).createFileFromText("Dummy.java", text); - PsiDeclarationStatement decl = (PsiDeclarationStatement) file.getClasses()[0].getInitializers()[0].getBody().getStatements()[0]; - PsiVariable list = (PsiVariable) decl.getDeclaredElements()[0]; + PsiDeclarationStatement decl = (PsiDeclarationStatement)file.getClasses()[0].getInitializers()[0].getBody().getStatements()[0]; + PsiVariable list = (PsiVariable)decl.getDeclaredElements()[0]; final PsiExpression initializer = list.getInitializer(); assert initializer != null : list; final PsiType type = initializer.getType(); diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java index 63d301abecd7..6d6ebf92d4e3 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/cache/impl/SCR14423Test.java @@ -5,6 +5,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; @@ -36,7 +37,8 @@ public class SCR14423Test extends PsiTestCase { @Override public void run() { try { - VirtualFile rootVFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(root.getAbsolutePath().replace(File.separatorChar, '/')); + VirtualFile rootVFile = + LocalFileSystem.getInstance().refreshAndFindFileByPath(root.getAbsolutePath().replace(File.separatorChar, '/')); myPrjDir1 = rootVFile.createChildDirectory(null, "prj1"); mySrcDir1 = myPrjDir1.createChildDirectory(null, "src1"); @@ -121,9 +123,7 @@ public class SCR14423Test extends PsiTestCase { LocalFileSystem.getInstance().refresh(false); - ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - rootModel.setSdk(null); - rootModel.commit(); + ModuleRootModificationUtil.setModuleSdk(myModule, null); psiClass = myJavaFacade.findClass("p.A"); assertNotNull(psiClass); diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveClassTest.java b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveClassTest.java index b3c851d11fb1..1c30fed2065a 100644 --- a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveClassTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveClassTest.java @@ -20,6 +20,7 @@ import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -29,25 +30,25 @@ import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.ResolveTestCase; public class ResolveClassTest extends ResolveTestCase { - public void testFQName() throws Exception{ + public void testFQName() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); } - public void testVarInNew() throws Exception{ + public void testVarInNew() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); } - public void testVarInNew1() throws Exception{ + public void testVarInNew1() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); } - public void testPrivateInExtends() throws Exception{ + public void testPrivateInExtends() throws Exception { PsiReference ref = configure(); final JavaResolveResult result = ((PsiJavaReference)ref).advancedResolve(true); PsiElement target = result.getElement(); @@ -55,13 +56,13 @@ public class ResolveClassTest extends ResolveTestCase { assertFalse(result.isAccessible()); } - public void testQNew1() throws Exception{ + public void testQNew1() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); } - public void testInnerPrivateMember1() throws Exception{ + public void testInnerPrivateMember1() throws Exception { PsiReference ref = configure(); final JavaResolveResult result = ((PsiJavaReference)ref).advancedResolve(true); PsiElement target = result.getElement(); @@ -70,7 +71,7 @@ public class ResolveClassTest extends ResolveTestCase { } - public void testQNew2() throws Exception{ + public void testQNew2() throws Exception { PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)configure(); PsiElement target = ref.advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); @@ -82,7 +83,7 @@ public class ResolveClassTest extends ResolveTestCase { assertEquals(target, ((PsiAnonymousClass)parent).getBaseClassType().resolve()); } - public void testClassExtendsItsInner1() throws Exception{ + public void testClassExtendsItsInner1() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); @@ -96,7 +97,7 @@ public class ResolveClassTest extends ResolveTestCase { assertEquals("B.Foo", ((PsiClass)target1).getQualifiedName()); } - public void testClassExtendsItsInner2() throws Exception{ + public void testClassExtendsItsInner2() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertNull(target); //[ven] this should not be resolved @@ -104,26 +105,26 @@ public class ResolveClassTest extends ResolveTestCase { assertEquals("TTT.Bar", ((PsiClass)target).getQualifiedName());*/ } - public void testSCR40332() throws Exception{ + public void testSCR40332() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertNull(target); } - public void testImportConflict1() throws Exception{ + public void testImportConflict1() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target == null); } - public void testImportConflict2() throws Exception{ + public void testImportConflict2() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); assertEquals("java.util.Date", ((PsiClass)target).getQualifiedName()); } - public void testLocals1() throws Exception{ + public void testLocals1() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); @@ -131,7 +132,7 @@ public class ResolveClassTest extends ResolveTestCase { assertNull(((PsiClass)target).getQualifiedName()); } - public void testLocals2() throws Exception{ + public void testLocals2() throws Exception { PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); @@ -155,14 +156,14 @@ public class ResolveClassTest extends ResolveTestCase { assertTrue("Outer.Double".equals(((PsiClass)element).getQualifiedName())); } - public void testTwoModules() throws Exception{ + public void testTwoModules() throws Exception { configureDependency(); PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); assertTrue(target instanceof PsiClass); } - public void testTwoModules2() throws Exception{ + public void testTwoModules2() throws Exception { configureDependency(); PsiReference ref = configure(); PsiElement target = ((PsiJavaReference)ref).advancedResolve(true).getElement(); @@ -220,7 +221,7 @@ public class ResolveClassTest extends ResolveTestCase { PsiTestUtil.addSourceRoot(module, root.findChild("src")); PsiTestUtil.addSourceRoot(module, root.findChild("test"), true); - PsiTestUtil.addDependency(getModule(), module); + ModuleRootModificationUtil.addDependency(getModule(), module); } }); } diff --git a/java/java-tests/testSrc/com/intellij/roots/DirectoryIndexImplTest.java b/java/java-tests/testSrc/com/intellij/roots/DirectoryIndexImplTest.java index ddec4a1b9d57..ff7afbd486c2 100644 --- a/java/java-tests/testSrc/com/intellij/roots/DirectoryIndexImplTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/DirectoryIndexImplTest.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; import com.intellij.testFramework.IdeaTestCase; import com.intellij.testFramework.PlatformTestCase; +import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.containers.ContainerUtil; import java.io.File; @@ -120,15 +121,10 @@ public class DirectoryIndexImplTest extends IdeaTestCase { // fill roots of module1 { - ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - - rootModel.setSdk(null); - - ContentEntry contentEntry1 = rootModel.addContentEntry(myModule1Dir); - contentEntry1.addSourceFolder(myTestSrc1, true); - contentEntry1.addSourceFolder(mySrcDir1, false); - - rootModel.commit(); + ModuleRootModificationUtil.setModuleSdk(myModule, null); + PsiTestUtil.addContentRoot(myModule, myModule1Dir); + PsiTestUtil.addSourceRoot(myModule, mySrcDir1); + PsiTestUtil.addSourceRoot(myModule, myTestSrc1, true); } ModuleManager moduleManager = ModuleManager.getInstance(myProject); @@ -156,11 +152,8 @@ public class DirectoryIndexImplTest extends IdeaTestCase { VirtualFile moduleFile = myModule3Dir.createChildData(null, "module3.iml"); myModule3 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId()); - ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule3).getModifiableModel(); - rootModel.addContentEntry(myModule3Dir); - rootModel.addModuleOrderEntry(myModule2); // module3 depends on module2 - - rootModel.commit(); + PsiTestUtil.addContentRoot(myModule3, myModule3Dir); + ModuleRootModificationUtil.addDependency(myModule3, myModule2); } } catch (IOException e) { diff --git a/java/java-tests/testSrc/com/intellij/roots/ExportingModulesTest.java b/java/java-tests/testSrc/com/intellij/roots/ExportingModulesTest.java index 8a2673e97c48..f7c416fb037c 100644 --- a/java/java-tests/testSrc/com/intellij/roots/ExportingModulesTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/ExportingModulesTest.java @@ -21,17 +21,13 @@ import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.StdModuleTypes; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleOrderEntry; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.IdeaTestCase; -import com.intellij.testFramework.PsiTestUtil; import java.io.File; @@ -57,12 +53,9 @@ public class ExportingModulesTest extends IdeaTestCase { configureModule(moduleB, testRoot, "B"); configureModule(moduleC, testRoot, "C"); - final ModifiableRootModel rootModelB = ModuleRootManager.getInstance(moduleB).getModifiableModel(); - final ModuleOrderEntry moduleBAentry = rootModelB.addModuleOrderEntry(moduleA); - moduleBAentry.setExported(true); - rootModelB.commit(); + ModuleRootModificationUtil.addDependency(moduleB, moduleA, DependencyScope.COMPILE, true); - PsiTestUtil.addDependency(moduleC, moduleB); + ModuleRootModificationUtil.addDependency(moduleC, moduleB); final PsiClass pCClass = JavaPsiFacade.getInstance(myProject).findClass("p.C", GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(moduleC)); diff --git a/java/java-tests/testSrc/com/intellij/roots/InheritedJdkTest.java b/java/java-tests/testSrc/com/intellij/roots/InheritedJdkTest.java index 06b4794a65ac..6e0c60c0b06f 100644 --- a/java/java-tests/testSrc/com/intellij/roots/InheritedJdkTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/InheritedJdkTest.java @@ -4,10 +4,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; -import com.intellij.openapi.roots.InheritedJdkOrderEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.testFramework.ModuleTestCase; import junit.framework.Assert; @@ -35,23 +32,14 @@ public class InheritedJdkTest extends ModuleTestCase { public void run() { final ProjectRootManagerEx rootManagerEx = ProjectRootManagerEx.getInstanceEx(myProject); rootManagerEx.setProjectSdkName(jdk.getName()); - final ModifiableRootModel rootModel = rootManager.getModifiableModel(); - rootModel.inheritSdk(); - rootModel.commit(); + ModuleRootModificationUtil.setSdkInherited(myModule); } }); assertTrue("JDK is inherited after explicit inheritSdk()", rootManager.isSdkInherited()); assertEquals("Correct jdk inherited", jdk, rootManager.getSdk()); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ModifiableRootModel rootModel = rootManager.getModifiableModel(); - rootModel.setSdk(null); - rootModel.commit(); - } - }); + ModuleRootModificationUtil.setModuleSdk(myModule, null); assertFalse("JDK is not inherited after setJdk(null)", rootManager.isSdkInherited()); assertNull("No JDK assigned", rootManager.getSdk()); @@ -63,14 +51,7 @@ public class InheritedJdkTest extends ModuleTestCase { ProjectJdkTable.getInstance().addJdk(jdk1); } }); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ModifiableRootModel rootModel = rootManager.getModifiableModel(); - rootModel.setSdk(jdk1); - rootModel.commit(); - } - }); + ModuleRootModificationUtil.setModuleSdk(myModule, jdk1); assertFalse("JDK is not inherited after setJdk(jdk1)", rootManager.isSdkInherited()); assertEquals("jdk1 is assigned", jdk1, rootManager.getSdk()); @@ -78,14 +59,7 @@ public class InheritedJdkTest extends ModuleTestCase { public void test2() throws Exception { final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule); - final ModifiableRootModel rootModel = rootManager.getModifiableModel(); - rootModel.inheritSdk(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - rootModel.commit(); - } - }); + ModuleRootModificationUtil.setSdkInherited(myModule); assertTrue("JDK is inherited after inheritSdk()", rootManager.isSdkInherited()); assertNull("No JDK assigned", rootManager.getSdk()); @@ -118,12 +92,12 @@ public class InheritedJdkTest extends ModuleTestCase { assertTrue(rootManager.isSdkInherited()); Assert.assertEquals("Correct non-existing JDK inherited", "jdk1", - rootManager.orderEntries().process(new RootPolicy() { - @Override - public String visitInheritedJdkOrderEntry(InheritedJdkOrderEntry inheritedJdkOrderEntry, String s) { - return inheritedJdkOrderEntry.getJdkName(); - } - }, null)); + rootManager.orderEntries().process(new RootPolicy() { + @Override + public String visitInheritedJdkOrderEntry(InheritedJdkOrderEntry inheritedJdkOrderEntry, String s) { + return inheritedJdkOrderEntry.getJdkName(); + } + }, null)); assertNull("Non-existing JDK", rootManager.getSdk()); final Sdk jdk1 = JavaSdkImpl.getMockJdk17("jdk1"); diff --git a/java/java-tests/testSrc/com/intellij/roots/ModuleRootManagerTestCase.java b/java/java-tests/testSrc/com/intellij/roots/ModuleRootManagerTestCase.java index 0cb757265abe..501f06739c0d 100644 --- a/java/java-tests/testSrc/com/intellij/roots/ModuleRootManagerTestCase.java +++ b/java/java-tests/testSrc/com/intellij/roots/ModuleRootManagerTestCase.java @@ -91,23 +91,6 @@ public abstract class ModuleRootManagerTestCase extends ModuleTestCase { return output; } - protected void addLibraryDependency(Module module, Library dependency) { - addLibraryDependency(module, dependency, DependencyScope.COMPILE, false); - } - - protected void addLibraryDependency(final Module module, final Library dependency, final DependencyScope scope, final boolean exported) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - final LibraryOrderEntry entry = model.addLibraryEntry(dependency); - entry.setScope(scope); - entry.setExported(exported); - model.commit(); - } - }); - } - protected Library createLibrary(final String name, final VirtualFile classesRoot) { return createLibrary(name, classesRoot, null); } diff --git a/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java b/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java index d64c6fb4dcca..4e8d2f743972 100644 --- a/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/ModuleScopesTest.java @@ -84,7 +84,7 @@ public class ModuleScopesTest extends ModuleTestCase { VirtualFile rootB = myFixture.findOrCreateDir("b"); VirtualFile outB = myFixture.findOrCreateDir("out"); - PsiTestUtil.addDependency(moduleA, moduleB, scope, false); + ModuleRootModificationUtil.addDependency(moduleA, moduleB, scope, false); final ModifiableRootModel modelB = ModuleRootManager.getInstance(moduleB).getModifiableModel(); final ContentEntry contentEntry = modelB.addContentEntry(rootB); @@ -176,7 +176,8 @@ public class ModuleScopesTest extends ModuleTestCase { } private static VirtualFile[] getProductionCompileClasspath(Module moduleA) { - return ModuleRootManager.getInstance(moduleA).orderEntries().productionOnly().compileOnly().recursively().exportedOnly().getClassesRoots(); + return ModuleRootManager.getInstance(moduleA).orderEntries().productionOnly().compileOnly().recursively().exportedOnly() + .getClassesRoots(); } private static VirtualFile[] getCompilationClasspath(Module m) { diff --git a/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java b/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java index 033ebcf4eb32..c2bffba57dda 100644 --- a/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/OrderEntriesTest.java @@ -1,12 +1,8 @@ package com.intellij.roots; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEnumerator; -import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.PathsList; /** @@ -15,7 +11,7 @@ import com.intellij.util.PathsList; @SuppressWarnings({"deprecation"}) public class OrderEntriesTest extends ModuleRootManagerTestCase { public void testLibrary() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar()); assertOrderFiles(OrderRootType.SOURCES, getJDomSources()); assertOrderFiles(OrderRootType.CLASSES_AND_OUTPUT, getRtJar(), getJDomJar()); @@ -37,7 +33,7 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase { } public void testLibraryScope() throws Exception { - addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.TEST, false); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.TEST, false); assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar()); assertOrderFiles(OrderRootType.SOURCES, getJDomSources()); @@ -52,8 +48,8 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase { final VirtualFile testRoot = addSourceRoot(dep, true); final VirtualFile output = setModuleOutput(dep, false); final VirtualFile testOutput = setModuleOutput(dep, true); - addLibraryDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar()); assertOrderFiles(OrderRootType.SOURCES, srcRoot, testRoot, getJDomSources()); @@ -64,8 +60,8 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase { public void testModuleDependencyScope() throws Exception { final Module dep = createModule("dep"); - addLibraryDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.TEST, true); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.TEST, true); assertOrderFiles(OrderRootType.CLASSES, getRtJar(), getJDomJar()); assertOrderFiles(OrderRootType.SOURCES, getJDomSources()); @@ -76,8 +72,8 @@ public class OrderEntriesTest extends ModuleRootManagerTestCase { public void testNotExportedLibraryDependency() throws Exception { final Module dep = createModule("dep"); - addLibraryDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, false); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); assertOrderFiles(OrderRootType.CLASSES, getRtJar()); assertOrderFiles(OrderRootType.SOURCES); diff --git a/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java b/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java index af0816067612..c1abd7d6bccd 100644 --- a/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/OrderEnumeratorTest.java @@ -1,12 +1,8 @@ package com.intellij.roots; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.roots.OrderEnumerator; -import com.intellij.openapi.roots.OrderRootsEnumerator; -import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.ArrayUtil; import java.util.ArrayList; @@ -22,7 +18,7 @@ import static com.intellij.openapi.roots.OrderEnumerator.orderEntries; public class OrderEnumeratorTest extends ModuleRootManagerTestCase { public void testLibrary() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); assertClassRoots(orderEntries(myModule), getRtJar(), getJDomJar()); assertClassRoots(orderEntries(myModule).withoutSdk(), getJDomJar()); @@ -47,7 +43,7 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { } public void testLibraryScope() throws Exception { - addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.RUNTIME, false); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.RUNTIME, false); assertClassRoots(orderEntries(myModule).withoutSdk(), getJDomJar()); assertClassRoots(orderEntries(myModule).withoutSdk().exportedOnly()); @@ -60,8 +56,8 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { final VirtualFile depTestRoot = addSourceRoot(dep, true); final VirtualFile depOutput = setModuleOutput(dep, false); final VirtualFile depTestOutput = setModuleOutput(dep, true); - addLibraryDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, true); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, true); final VirtualFile srcRoot = addSourceRoot(myModule, false); final VirtualFile testRoot = addSourceRoot(myModule, true); @@ -93,8 +89,8 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { public void testModuleDependencyScope() throws Exception { final Module dep = createModule("dep"); - addLibraryDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.TEST, true); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, true); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.TEST, true); assertClassRoots(orderEntries(myModule).withoutSdk()); assertClassRoots(orderEntries(myModule).withoutSdk().recursively(), getJDomJar()); @@ -107,9 +103,9 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { public void testNotExportedLibrary() throws Exception { final Module dep = createModule("dep"); - addLibraryDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, false); - addLibraryDependency(myModule, createAsmLibrary(), DependencyScope.COMPILE, false); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary(), DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(myModule, createAsmLibrary(), DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); assertClassRoots(orderEntries(myModule).withoutSdk(), getAsmJar()); assertClassRoots(orderEntries(myModule).withoutSdk().recursively(), getAsmJar(), getJDomJar()); @@ -130,7 +126,7 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { assertSame(roots, orderEntries(myModule).classes().usingCache().getRoots()); assertSame(rootsWithoutSdk, orderEntries(myModule).withoutSdk().classes().usingCache().getRoots()); - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); assertRoots(orderEntries(myModule).classes().usingCache().getPathsList(), getRtJar(), getJDomJar()); assertRoots(orderEntries(myModule).withoutSdk().classes().usingCache().getPathsList(), getJDomJar()); @@ -146,13 +142,13 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { assertSame(urls, orderEntries(myModule).classes().usingCache().getUrls()); assertSame(sourceUrls, orderEntries(myModule).sources().usingCache().getUrls()); - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); assertOrderedEquals(orderEntries(myModule).classes().usingCache().getUrls(), getRtJar().getUrl(), getJDomJar().getUrl()); assertOrderedEquals(orderEntries(myModule).sources().usingCache().getUrls(), getJDomSources().getUrl()); } public void testProject() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); final VirtualFile srcRoot = addSourceRoot(myModule, false); final VirtualFile testRoot = addSourceRoot(myModule, true); @@ -164,7 +160,7 @@ public class OrderEnumeratorTest extends ModuleRootManagerTestCase { } public void testModules() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); final VirtualFile srcRoot = addSourceRoot(myModule, false); final VirtualFile testRoot = addSourceRoot(myModule, true); diff --git a/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java b/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java index 96e648a5cbf5..f606a7f541ce 100644 --- a/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/ProjectClasspathTraversingTest.java @@ -16,12 +16,8 @@ package com.intellij.roots; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.roots.OrderEnumerator; -import com.intellij.openapi.roots.ProjectClasspathTraversing; -import com.intellij.openapi.roots.ProjectRootsTraversing; +import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.PathsList; /** @@ -30,7 +26,7 @@ import com.intellij.util.PathsList; @SuppressWarnings({"deprecation"}) public class ProjectClasspathTraversingTest extends ModuleRootManagerTestCase { public void testLibrary() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar(), getJDomJar()); doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, getJDomJar()); @@ -38,7 +34,7 @@ public class ProjectClasspathTraversingTest extends ModuleRootManagerTestCase { doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_JDK_AND_TESTS, getJDomJar()); doTest(ProjectClasspathTraversing.FULL_CLASSPATH_WITHOUT_TESTS, getRtJar(), getJDomJar()); } - + public void testModuleOutput() throws Exception { addSourceRoot(myModule, false); final VirtualFile output = setModuleOutput(myModule, false); @@ -52,7 +48,7 @@ public class ProjectClasspathTraversingTest extends ModuleRootManagerTestCase { } public void testLibraryScope() throws Exception { - addLibraryDependency(myModule, createJDomLibrary(), DependencyScope.TEST, true); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary(), DependencyScope.TEST, true); doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar(), getJDomJar()); doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, getJDomJar()); @@ -65,8 +61,8 @@ public class ProjectClasspathTraversingTest extends ModuleRootManagerTestCase { final Module dep = createModule("dep"); final VirtualFile output = setModuleOutput(dep, false); final VirtualFile testOutput = setModuleOutput(dep, true); - addLibraryDependency(dep, createJDomLibrary()); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); doTest(ProjectClasspathTraversing.FULL_CLASSPATH, getRtJar()); doTest(ProjectClasspathTraversing.FULL_CLASS_RECURSIVE_WO_JDK, testOutput, output, getJDomJar()); diff --git a/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java b/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java index d8d315bcac4e..c25e1b2cc031 100644 --- a/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/ProjectRootsTraversingTest.java @@ -2,10 +2,10 @@ package com.intellij.roots; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.DependencyScope; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.OrderEnumerator; import com.intellij.openapi.roots.ProjectRootsTraversing; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.PathsList; /** @@ -15,7 +15,7 @@ import com.intellij.util.PathsList; public class ProjectRootsTraversingTest extends ModuleRootManagerTestCase { public void testLibrary() throws Exception { - addLibraryDependency(myModule, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, createJDomLibrary()); doTest(ProjectRootsTraversing.LIBRARIES_AND_JDK, getRtJar(), getJDomJar()); doTest(ProjectRootsTraversing.PROJECT_LIBRARIES, getJDomJar()); doTest(ProjectRootsTraversing.PROJECT_SOURCES); @@ -43,8 +43,8 @@ public class ProjectRootsTraversingTest extends ModuleRootManagerTestCase { setModuleOutput(dep, true); addSourceRoot(dep, false); addSourceRoot(dep, true); - addLibraryDependency(dep, createJDomLibrary()); - PsiTestUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); + ModuleRootModificationUtil.addDependency(dep, createJDomLibrary()); + ModuleRootModificationUtil.addDependency(myModule, dep, DependencyScope.COMPILE, false); doTest(ProjectRootsTraversing.PROJECT_LIBRARIES, getJDomJar()); doTest(ProjectRootsTraversing.PROJECT_SOURCES); diff --git a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java index 185f69538dbb..998a8217f463 100644 --- a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java @@ -62,36 +62,38 @@ public abstract class InspectionTestCase extends PsiTestCase { private VirtualFile ext_src; public InspectionManagerEx getManager() { - return (InspectionManagerEx) InspectionManager.getInstance(myProject); + return (InspectionManagerEx)InspectionManager.getInstance(myProject); } - public void doTest(@NonNls String folderName, LocalInspectionTool tool) throws Exception { + public void doTest(@NonNls String folderName, LocalInspectionTool tool) { doTest(folderName, new LocalInspectionToolWrapper(tool)); } - public void doTest(@NonNls String folderName, GlobalInspectionTool tool) throws Exception { + + public void doTest(@NonNls String folderName, GlobalInspectionTool tool) { doTest(folderName, new GlobalInspectionToolWrapper(tool)); } - public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange) throws Exception { + + public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange) { doTest(folderName, new GlobalInspectionToolWrapper(tool), checkRange); } - public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange, boolean runDeadCodeFirst) throws Exception { + public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange, boolean runDeadCodeFirst) { doTest(folderName, new GlobalInspectionToolWrapper(tool), "java 1.4", checkRange, runDeadCodeFirst); } - public void doTest(@NonNls String folderName, InspectionTool tool) throws Exception { + public void doTest(@NonNls String folderName, InspectionTool tool) { doTest(folderName, tool, "java 1.4"); } - public void doTest(@NonNls String folderName, InspectionTool tool, final boolean checkRange) throws Exception { + public void doTest(@NonNls String folderName, InspectionTool tool, final boolean checkRange) { doTest(folderName, tool, "java 1.4", checkRange); } - public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName) throws Exception { + public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName) { doTest(folderName, tool, jdkName, false); } - public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName, boolean checkRange) throws Exception { + public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName, boolean checkRange) { doTest(folderName, tool, jdkName, checkRange, false); } @@ -100,7 +102,7 @@ public abstract class InspectionTestCase extends PsiTestCase { @NonNls final String jdkName, boolean checkRange, boolean runDeadCodeFirst, - InspectionTool... additional) throws Exception { + InspectionTool... additional) { final String testDir = getTestDataPath() + "/" + folderName; runTool(testDir, jdkName, runDeadCodeFirst, tool, additional); @@ -122,17 +124,19 @@ public abstract class InspectionTestCase extends PsiTestCase { public void run() { try { setupRootModel(testDir, sourceDir, jdkName); - } catch (Exception e) { + } + catch (Exception e) { LOG.error(e); } } }); AnalysisScope scope = createAnalysisScope(sourceDir[0].getParent()); - InspectionManagerEx inspectionManager = (InspectionManagerEx) InspectionManager.getInstance(getProject()); + InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject()); InspectionTool[] tools = runDeadCodeFirst ? new InspectionTool[]{new UnusedDeclarationInspection(), tool} : new InspectionTool[]{tool}; tools = ArrayUtil.mergeArrays(tools, additional); - final GlobalInspectionContextImpl globalContext = CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, tools); + final GlobalInspectionContextImpl globalContext = + CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, tools); InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager); } @@ -236,7 +240,6 @@ public abstract class InspectionTestCase extends PsiTestCase { @Override @NonNls protected String getTestDataPath() { - return PathManagerEx.getTestDataPath()+"/inspection/"; + return PathManagerEx.getTestDataPath() + "/inspection/"; } - } diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java index 91bca1ccdaa4..d359db328e00 100644 --- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java @@ -30,8 +30,7 @@ import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.projectRoots.SdkType; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopupFactory; @@ -71,10 +70,10 @@ public class SdkConfigurationUtil { if (SystemInfo.isMac) { descriptor.putUserData(PathChooserDialog.NATIVE_MAC_CHOOSER_SHOW_HIDDEN_FILES, Boolean.TRUE); } - String suggestedPath = sdkTypes [0].suggestHomePath(); + String suggestedPath = sdkTypes[0].suggestHomePath(); VirtualFile suggestedDir = suggestedPath == null ? null - : LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(suggestedPath)); + : LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(suggestedPath)); FileChooser.chooseFiles(descriptor, project, suggestedDir, new Consumer>() { @Override public void consume(List selectedFiles) { @@ -90,7 +89,7 @@ public class SdkConfigurationUtil { } private static FileChooserDescriptor createCompositeDescriptor(final SdkType... sdkTypes) { - FileChooserDescriptor descriptor0 = sdkTypes [0].getHomeChooserDescriptor(); + FileChooserDescriptor descriptor0 = sdkTypes[0].getHomeChooserDescriptor(); FileChooserDescriptor descriptor = new FileChooserDescriptor(descriptor0.isChooseFiles(), descriptor0.isChooseFolders(), descriptor0.isChooseJars(), descriptor0.isChooseJarsAsFiles(), descriptor0.isChooseJarContents(), descriptor0.isChooseMultiple()) { @@ -105,8 +104,8 @@ public class SdkConfigurationUtil { } } String message = files.length > 0 && files[0].isDirectory() - ? ProjectBundle.message("sdk.configure.home.invalid.error", sdkTypes [0].getPresentableName()) - : ProjectBundle.message("sdk.configure.home.file.invalid.error", sdkTypes [0].getPresentableName()); + ? ProjectBundle.message("sdk.configure.home.invalid.error", sdkTypes[0].getPresentableName()) + : ProjectBundle.message("sdk.configure.home.file.invalid.error", sdkTypes[0].getPresentableName()); throw new Exception(message); } }; @@ -174,15 +173,15 @@ public class SdkConfigurationUtil { ProjectRootManager.getInstance(project).setProjectSdk(sdk); final Module[] modules = ModuleManager.getInstance(project).getModules(); if (modules.length > 0) { - final ModifiableRootModel model = ModuleRootManager.getInstance(modules[0]).getModifiableModel(); - model.inheritSdk(); - model.commit(); + ModuleRootModificationUtil.setSdkInherited(modules[0]); } } }); } - public static void configureDirectoryProjectSdk(final Project project, @Nullable Comparator preferredSdkComparator, final SdkType... sdkTypes) { + public static void configureDirectoryProjectSdk(final Project project, + @Nullable Comparator preferredSdkComparator, + final SdkType... sdkTypes) { Sdk existingSdk = ProjectRootManager.getInstance(project).getProjectSdk(); if (existingSdk != null && ArrayUtil.contains(existingSdk.getSdkType(), sdkTypes)) { return; @@ -226,7 +225,8 @@ public class SdkConfigurationUtil { /** * Tries to create an SDK identified by path; if successful, add the SDK to the global SDK table. - * @param path identifies the SDK + * + * @param path identifies the SDK * @param sdkType * @return newly created SDK, or null. */ @@ -264,7 +264,7 @@ public class SdkConfigurationUtil { return newSdkName; } - public static void selectSdkHome(final SdkType sdkType, @NotNull final Consumer consumer){ + public static void selectSdkHome(final SdkType sdkType, @NotNull final Consumer consumer) { final FileChooserDescriptor descriptor = sdkType.getHomeChooserDescriptor(); FileChooser.chooseFiles(descriptor, null, getSuggestedSdkRoot(sdkType), new Consumer>() { @Override @@ -291,10 +291,10 @@ public class SdkConfigurationUtil { } public static void suggestAndAddSdk(@Nullable final Project project, - final Sdk[] existingSdks, - JComponent popupOwner, - final Consumer callback, - final SdkType... sdkTypes) { + final Sdk[] existingSdks, + JComponent popupOwner, + final Consumer callback, + final SdkType... sdkTypes) { assert sdkTypes.length > 0; final Map suggestedSdkHomes = new LinkedHashMap(); for (SdkType sdkType : sdkTypes) { @@ -339,7 +339,7 @@ public class SdkConfigurationUtil { } else { Sdk sdk = setupSdk(existingSdks, LocalFileSystem.getInstance().findFileByPath(selectedValue), - sdkType, false, null, null); + sdkType, false, null, null); callback.consume(sdk); } return FINAL_CHOICE; diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java b/platform/lang-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java new file mode 100644 index 000000000000..12272d8a6f12 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ModuleRootModificationUtil.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots; + +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.libraries.Library; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class ModuleRootModificationUtil { + public static void addDependency(Module module, Library library) { + addDependency(module, library, DependencyScope.COMPILE, false); + } + + public static void addDependency(Module module, Library library, final DependencyScope scope, final boolean exported) { + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + final LibraryOrderEntry entry = model.addLibraryEntry(library); + entry.setExported(exported); + entry.setScope(scope); + doCommit(model); + } + + public static void setModuleSdk(Module module, @Nullable Sdk sdk) { + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + model.setSdk(sdk); + doCommit(model); + } + + public static void setSdkInherited(Module module) { + final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); + model.inheritSdk(); + doCommit(model); + } + + public static void addDependency(final Module from, final Module to) { + addDependency(from, to, DependencyScope.COMPILE, false); + } + + public static void addDependency(final Module from, final Module to, final DependencyScope scope, final boolean exported) { + final ModifiableRootModel model = ModuleRootManager.getInstance(from).getModifiableModel(); + final ModuleOrderEntry entry = model.addModuleOrderEntry(to); + entry.setScope(scope); + entry.setExported(exported); + doCommit(model); + } + + private static void doCommit(final ModifiableRootModel model) { + new WriteAction() { + @Override + protected void run(Result result) throws Throwable { + model.commit(); + } + }.execute(); + } +} diff --git a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java index e1768278e035..188c848c7d8e 100644 --- a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java +++ b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java @@ -26,8 +26,8 @@ import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectManagerEx; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; @@ -51,11 +51,12 @@ import java.util.List; */ public class ModuleAttachProcessor extends ProjectAttachProcessor { private static final Logger LOG = Logger.getInstance(ModuleAttachProcessor.class); - + @Override public boolean attachToProject(Project project, File projectDir, @Nullable ProjectOpenedCallback callback) { if (!projectDir.exists()) { - Project newProject = ((ProjectManagerEx) ProjectManager.getInstance()).newProject(projectDir.getParentFile().getName(), projectDir.getParent(), true, false); + Project newProject = ((ProjectManagerEx)ProjectManager.getInstance()) + .newProject(projectDir.getParentFile().getName(), projectDir.getParent(), true, false); if (newProject == null) { return false; } @@ -72,7 +73,7 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor { } final String[] files = projectDir.list(); if (files != null) { - for(String file: files) { + for (String file : files) { if (FileUtil.getExtension(file).equals("iml")) { VirtualFile imlFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(projectDir, file)); if (imlFile != null) { @@ -82,7 +83,8 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor { } } } - int rc = Messages.showYesNoDialog(project, "The project at " + FileUtil.toSystemDependentName(projectDir.getPath()) + + int rc = Messages.showYesNoDialog(project, "The project at " + + FileUtil.toSystemDependentName(projectDir.getPath()) + " uses a non-standard layout and cannot be attached to this project. Would you like to open it in a new window?", "Open Project", Messages.getQuestionIcon()); @@ -147,15 +149,7 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor { private static Module addPrimaryModuleDependency(Project project, @NotNull Module newModule) { final Module module = getPrimaryModule(project); if (module != null && module != newModule) { - final ModifiableRootModel modifiableRootModel = ModuleRootManager.getInstance(module).getModifiableModel(); - modifiableRootModel.addModuleOrderEntry(newModule); - AccessToken token = WriteAction.start(); - try { - modifiableRootModel.commit(); - } - finally { - token.finish(); - } + ModuleRootModificationUtil.addDependency(module, newModule); return module; } return null; @@ -188,5 +182,4 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor { } return result; } - } diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index e298fd27cb8e..adc8d6777a56 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -47,8 +47,7 @@ import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.project.impl.ProjectManagerImpl; import com.intellij.openapi.project.impl.TooManyProjectLeakedException; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.EmptyRunnable; @@ -270,7 +269,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } protected File getIprFile() throws IOException { - File tempFile = FileUtil.createTempFile(getName()+"_", ProjectFileType.DOT_DEFAULT_EXTENSION); + File tempFile = FileUtil.createTempFile(getName() + "_", ProjectFileType.DOT_DEFAULT_EXTENSION); myFilesToDelete.add(tempFile); return tempFile; } @@ -499,7 +498,9 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro if (myProject != null) { try { PsiDocumentManager documentManager = myProject.getComponent(PsiDocumentManager.class, null); - if (documentManager != null) EditorFactory.getInstance().getEventMulticaster().removeDocumentListener((DocumentListener)documentManager); + if (documentManager != null) { + EditorFactory.getInstance().getEventMulticaster().removeDocumentListener((DocumentListener)documentManager); + } } catch (Exception ignored) { @@ -560,15 +561,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro // ProjectJdkImpl jdk = ProjectJdkTable.getInstance().addJdk(defaultJdk); Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (Module module : modules) { - final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - final ModifiableRootModel rootModel = rootManager.getModifiableModel(); - rootModel.setSdk(jdk); - rootModel.commit(); - } - }); + ModuleRootModificationUtil.setModuleSdk(module, jdk); } } @@ -665,6 +658,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } */ } + private static int LEAK_WALKS; private static void waitForAllLaters() throws InterruptedException, InvocationTargetException { @@ -775,7 +769,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) - public @interface WrapInCommand {} + public @interface WrapInCommand { + } protected static VirtualFile createChildData(@NotNull final VirtualFile dir, @NotNull @NonNls final String name) { return new WriteAction() { @@ -785,6 +780,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } }.execute().throwException().getResultObject(); } + protected static VirtualFile createChildDirectory(@NotNull final VirtualFile dir, @NotNull @NonNls final String name) { return new WriteAction() { @Override @@ -793,6 +789,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } }.execute().throwException().getResultObject(); } + protected static void delete(@NotNull final VirtualFile file) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override @@ -806,6 +803,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } }); } + protected static void rename(@NotNull final VirtualFile vFile1, @NotNull final String newName) { new WriteCommandAction.Simple(null) { @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java index 82bf1b6c818b..d9b091c6a060 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java @@ -51,7 +51,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -@NonNls public class PsiTestUtil { +@NonNls +public class PsiTestUtil { public static VirtualFile createTestProjectStructure(Project project, Module module, String rootPath, @@ -80,18 +81,20 @@ import java.util.List; final String rootPath, final Collection filesToDelete, final boolean addProjectRoots) throws Exception { - return createTestProjectStructure("unitTest",module, rootPath, filesToDelete, addProjectRoots); + return createTestProjectStructure("unitTest", module, rootPath, filesToDelete, addProjectRoots); } + public static VirtualFile createTestProjectStructure(String tempName, final Module module, final String rootPath, final Collection filesToDelete, final boolean addProjectRoots) throws Exception { - File dir = FileUtil.createTempDirectory(tempName, null,false); + File dir = FileUtil.createTempDirectory(tempName, null, false); filesToDelete.add(dir); - final VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/')); - assert vDir.isDirectory(): vDir; + final VirtualFile vDir = + LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/')); + assert vDir.isDirectory() : vDir; final Exception[] exception = {null}; ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -256,7 +259,10 @@ import java.util.List; commitModel(modifiableModel); } - private static void addProjectLibrary(final Module module, final ModifiableRootModel model, final String libName, final VirtualFile... classesRoots) { + private static void addProjectLibrary(final Module module, + final ModifiableRootModel model, + final String libName, + final VirtualFile... classesRoots) { new WriteCommandAction.Simple(module.getProject()) { @Override protected void run() throws Throwable { @@ -277,7 +283,11 @@ import java.util.List; }.execute().throwException(); } - public static void addLibrary(final Module module, final ModifiableRootModel model, final String libName, final String libPath, final String... jarArr) { + public static void addLibrary(final Module module, + final ModifiableRootModel model, + final String libName, + final String libPath, + final String... jarArr) { List classesRoots = new ArrayList(); for (String jar : jarArr) { if (!libPath.endsWith("/") && !jar.startsWith("/")) { @@ -287,7 +297,8 @@ import java.util.List; VirtualFile root; if (path.endsWith(".jar")) { root = JarFileSystem.getInstance().refreshAndFindFileByPath(path + "!/"); - } else { + } + else { root = LocalFileSystem.getInstance().refreshAndFindFileByPath(path); } assert root != null : "Library root folder not found: " + path + "!/"; @@ -303,7 +314,8 @@ import java.util.List; ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - final String parentUrl = VirtualFileManager.constructUrl(classRoots[0].endsWith(".jar!/") ? JarFileSystem.PROTOCOL : LocalFileSystem.PROTOCOL, libDir); + final String parentUrl = + VirtualFileManager.constructUrl(classRoots[0].endsWith(".jar!/") ? JarFileSystem.PROTOCOL : LocalFileSystem.PROTOCOL, libDir); final Library library = model.getModuleLibraryTable().createLibrary(libName); final Library.ModifiableModel libModifiableModel = library.getModifiableModel(); for (String classRoot : classRoots) { @@ -336,21 +348,4 @@ import java.util.List; } }.execute().getResultObject(); } - - public static void addDependency(final Module from, final Module to) { - addDependency(from, to, DependencyScope.COMPILE, false); - } - - public static void addDependency(final Module from, final Module to, final DependencyScope scope, final boolean exported) { - new WriteCommandAction(from.getProject()) { - @Override - protected void run(Result result) throws Throwable { - final ModifiableRootModel model = ModuleRootManager.getInstance(from).getModifiableModel(); - final ModuleOrderEntry entry = model.addModuleOrderEntry(to); - entry.setScope(scope); - entry.setExported(exported); - model.commit(); - } - }.execute(); - } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGInspectionTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGInspectionTestCase.java index 4c4c1e17f2b0..82f315a392b2 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGInspectionTestCase.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGInspectionTestCase.java @@ -31,7 +31,7 @@ public abstract class IGInspectionTestCase extends InspectionTestCase { } @Override - public void doTest(@NonNls final String folderName, final LocalInspectionTool tool) throws Exception { + public void doTest(@NonNls final String folderName, final LocalInspectionTool tool) { super.doTest(folderName, new LocalInspectionToolWrapper(tool), "java 1.5"); } } diff --git a/plugins/android/src/org/jetbrains/android/importDependencies/AddModuleDependencyTask.java b/plugins/android/src/org/jetbrains/android/importDependencies/AddModuleDependencyTask.java index c48610c3d362..057c348c5642 100644 --- a/plugins/android/src/org/jetbrains/android/importDependencies/AddModuleDependencyTask.java +++ b/plugins/android/src/org/jetbrains/android/importDependencies/AddModuleDependencyTask.java @@ -1,16 +1,15 @@ package org.jetbrains.android.importDependencies; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** -* @author Eugene.Kudelevsky -*/ + * @author Eugene.Kudelevsky + */ class AddModuleDependencyTask extends ImportDependenciesTask { private final ModuleProvider myModuleProvider; private final ModuleProvider myDepModuleProvider; @@ -31,14 +30,7 @@ class AddModuleDependencyTask extends ImportDependenciesTask { final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); if (!rootManager.isDependsOn(depModule)) { - final ModifiableRootModel model = rootManager.getModifiableModel(); - model.addModuleOrderEntry(depModule); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - model.commit(); - } - }); + ModuleRootModificationUtil.addDependency(module, depModule); } return null; } diff --git a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java index 061977ecd604..9d13b4fa546e 100644 --- a/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java +++ b/plugins/android/src/org/jetbrains/android/sdk/AndroidSdkUtils.java @@ -35,10 +35,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; -import com.intellij.openapi.roots.JavadocOrderRootType; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.ui.OrderRoot; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.ui.Messages; @@ -133,7 +130,8 @@ public class AndroidSdkUtils { if (sdkPath != null) { // todo: check if we should do it for new android platforms (api_level >= 15) final VirtualFile annotationsJar = JarFileSystem.getInstance() - .findFileByPath(FileUtil.toSystemIndependentName(sdkPath) + AndroidCommonUtils.ANNOTATIONS_JAR_RELATIVE_PATH + JarFileSystem.JAR_SEPARATOR); + .findFileByPath( + FileUtil.toSystemIndependentName(sdkPath) + AndroidCommonUtils.ANNOTATIONS_JAR_RELATIVE_PATH + JarFileSystem.JAR_SEPARATOR); if (annotationsJar != null) { result.add(new OrderRoot(annotationsJar, OrderRootType.CLASSES)); } @@ -289,23 +287,12 @@ public class AndroidSdkUtils { private static boolean tryToSetAndroidPlatform(Module module, Sdk sdk) { AndroidPlatform platform = AndroidPlatform.parse(sdk); if (platform != null) { - setSdk(module, sdk); + ModuleRootModificationUtil.setModuleSdk(module, sdk); return true; } return false; } - private static void setSdk(Module module, Sdk sdk) { - final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel(); - model.setSdk(sdk); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - model.commit(); - } - }); - } - private static void setupPlatform(@NotNull Module module) { if (tryToImportSdkFromPropertyFiles(module)) { return; @@ -359,7 +346,7 @@ public class AndroidSdkUtils { final Sdk sdk = findSuitableAndroidSdk(targetHashString, sdkDir); if (sdk != null) { - setSdk(module, sdk); + ModuleRootModificationUtil.setModuleSdk(module, sdk); return true; } @@ -388,7 +375,7 @@ public class AndroidSdkUtils { if (target != null) { final Sdk androidSdk = createNewAndroidPlatform(target, sdkData.getLocation(), true); if (androidSdk != null) { - setSdk(module, androidSdk); + ModuleRootModificationUtil.setModuleSdk(module, androidSdk); return true; } } diff --git a/plugins/android/testSrc/org/jetbrains/android/AndroidTestCase.java b/plugins/android/testSrc/org/jetbrains/android/AndroidTestCase.java index 644b260dd43d..656852c8036a 100644 --- a/plugins/android/testSrc/org/jetbrains/android/AndroidTestCase.java +++ b/plugins/android/testSrc/org/jetbrains/android/AndroidTestCase.java @@ -26,8 +26,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; @@ -80,7 +79,8 @@ public abstract class AndroidTestCase extends UsefulTestCase { public void setUp() throws Exception { super.setUp(); - final TestFixtureBuilder projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); + final TestFixtureBuilder projectBuilder = + IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture()); final JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); tuneModule(moduleFixtureBuilder, myFixture.getTempDirPath()); @@ -144,14 +144,7 @@ public abstract class AndroidTestCase extends UsefulTestCase { private static void addAndroidSdk(Module module, String sdkPath) { Sdk androidSdk = createAndroidSdk(sdkPath); - final ModifiableRootModel moduleModel = ModuleRootManager.getInstance(module).getModifiableModel(); - moduleModel.setSdk(androidSdk); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - moduleModel.commit(); - } - }); + ModuleRootModificationUtil.setModuleSdk(module, androidSdk); } private static Sdk createAndroidSdk(String sdkPath) { diff --git a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java index ce72c2f2ead3..6207725f35da 100644 --- a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java @@ -5,11 +5,11 @@ import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.testFramework.IdeaTestCase; -import com.intellij.testFramework.PsiTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.*; @@ -48,7 +48,8 @@ public class AndroidLibraryProjectTest extends UsefulTestCase { @Override public void setUp() throws Exception { super.setUp(); - final TestFixtureBuilder projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); + final TestFixtureBuilder projectBuilder = + IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture()); myFixture.enableInspections(AndroidDomInspection.class); @@ -81,8 +82,8 @@ public class AndroidLibraryProjectTest extends UsefulTestCase { myLibFacet = AndroidTestCase.addAndroidFacet(myLibModule, getTestSdkPath()); myLibFacet.getConfiguration().LIBRARY_PROJECT = true; - PsiTestUtil.addDependency(myAppModule, myLibModule); - PsiTestUtil.addDependency(myLibModule, myLibGenModule); + ModuleRootModificationUtil.addDependency(myAppModule, myLibModule); + ModuleRootModificationUtil.addDependency(myLibModule, myLibGenModule); } private void createInitialStructure() { diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/Eclipse2ModulesTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/Eclipse2ModulesTest.java index 46333beab9ab..7d566178418c 100644 --- a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/Eclipse2ModulesTest.java +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/Eclipse2ModulesTest.java @@ -23,13 +23,12 @@ package org.jetbrains.idea.eclipse; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PluginPathManager; import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.IdeaTestCase; +import com.intellij.testFramework.PsiTestUtil; import junit.framework.Assert; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -69,7 +68,6 @@ public abstract class Eclipse2ModulesTest extends IdeaTestCase { } protected void doTest(final String workspaceRoot, final String projectRoot) throws Exception { - final ModifiableRootModel model = ModuleRootManager.getInstance(getModule()).getModifiableModel(); final VirtualFile file = ApplicationManager.getApplication().runWriteAction( new Computable() { @@ -78,22 +76,17 @@ public abstract class Eclipse2ModulesTest extends IdeaTestCase { public VirtualFile compute() { final VirtualFile baseDir = getProject().getBaseDir(); assert baseDir != null; - return LocalFileSystem.getInstance().refreshAndFindFileByPath(baseDir.getPath() + "/" + workspaceRoot + "/" + myDependantModulePath); + return LocalFileSystem.getInstance() + .refreshAndFindFileByPath(baseDir.getPath() + "/" + workspaceRoot + "/" + myDependantModulePath); } } ); if (file != null) { - model.addContentEntry(file); - } else { - model.dispose(); + PsiTestUtil.addContentRoot(getModule(), file); + } + else { Assert.assertTrue("File not found", false); } - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run(){ - model.commit(); - } - }); } public void setDependantModulePath(String dependantModulePath) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java index f8992644e1e5..61cbb2593255 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java @@ -89,7 +89,7 @@ public class MvcModuleStructureUtil { sourceRoots.put(folder.getFile(), folder.isTestSource()); } } - + root.refresh(false, true); final List> actions = CollectionFactory.arrayList(); @@ -139,7 +139,9 @@ public class MvcModuleStructureUtil { }; } - public static void removeSrcFolderFromRoots(final VirtualFile file, List> actions, Map sourceRoots) { + public static void removeSrcFolderFromRoots(final VirtualFile file, + List> actions, + Map sourceRoots) { if (sourceRoots.containsKey(file)) { actions.add(new Consumer() { public void consume(ContentEntry contentEntry) { @@ -198,7 +200,10 @@ public class MvcModuleStructureUtil { return library.getModifiableModel(); } - public static void addSourceFolder(@NotNull VirtualFile root, @NotNull String relativePath, final boolean isTest, List> actions, + public static void addSourceFolder(@NotNull VirtualFile root, + @NotNull String relativePath, + final boolean isTest, + List> actions, Map sourceRoots) { final VirtualFile src = root.findFileByRelativePath(relativePath); if (src == null) { @@ -412,7 +417,7 @@ public class MvcModuleStructureUtil { public static List getAllModulesWithSupport(Project project, MvcFramework framework) { List modules = new ArrayList(); - for (Module module : ModuleManager.getInstance(project).getModules()){ + for (Module module : ModuleManager.getInstance(project).getModules()) { if (framework.hasSupport(module)) { modules.add(module); } @@ -576,10 +581,7 @@ public class MvcModuleStructureUtil { public static void ensureDependency(@NotNull Module from, @NotNull Module to, boolean exported) { if (!from.equals(to) && !hasDependency(from, to)) { - final ModifiableRootModel fromModel = ModuleRootManager.getInstance(from).getModifiableModel(); - ModuleOrderEntry entry = fromModel.addModuleOrderEntry(to); - entry.setExported(exported); - fromModel.commit(); + ModuleRootModificationUtil.addDependency(from, to, DependencyScope.COMPILE, exported); } } @@ -613,7 +615,8 @@ public class MvcModuleStructureUtil { public static void copySdk(ModuleRootModel from, ModifiableRootModel to) { if (from.isSdkInherited()) { to.inheritSdk(); - } else { + } + else { to.setSdk(from.getSdk()); } } @@ -670,7 +673,7 @@ public class MvcModuleStructureUtil { if (userLibraryTo == null) { if (userLibraryFrom == null) return; - userLibraryTo = to.getModuleLibraryTable().createLibrary(framework.getUserLibraryName() + " (" +to.getModule().getName() + ')'); + userLibraryTo = to.getModuleLibraryTable().createLibrary(framework.getUserLibraryName() + " (" + to.getModule().getName() + ')'); } else { OrderEntry[] orderEntries = to.getOrderEntries().clone(); @@ -812,7 +815,8 @@ public class MvcModuleStructureUtil { for (VirtualFile virtualFile : map.keySet()) { if (!globalAuxModules.containsKey(virtualFile)) { Module appModule = map.get(virtualFile).iterator().next(); - Module module = createAuxiliaryModule(appModule, generateUniqueModuleName(project, framework.getGlobalPluginsModuleName()), framework); + Module module = + createAuxiliaryModule(appModule, generateUniqueModuleName(project, framework.getGlobalPluginsModuleName()), framework); globalAuxModules.put(virtualFile, module); } } @@ -853,7 +857,8 @@ public class MvcModuleStructureUtil { i++; if (manager.findModuleByName(res) == null) return res; - } while (true); + } + while (true); } @Nullable diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy index e32f2c8ebf4b..03d25ca15a1c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy @@ -26,8 +26,9 @@ import com.intellij.openapi.module.Module import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiFile -import com.intellij.testFramework.PsiTestUtil + import junit.framework.AssertionFailedError +import com.intellij.openapi.roots.ModuleRootModificationUtil /** * @author peter @@ -134,9 +135,9 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase { public void testTransitiveJavaDependencyThroughGroovy() throws Throwable { myFixture.addClass("public class IFoo { void foo() {} }").getContainingFile().getVirtualFile(); myFixture.addFileToProject("Foo.groovy", "class Foo {\n" + - " static IFoo f\n" + - " public int foo() { return 239; }\n" + - "}"); + " static IFoo f\n" + + " public int foo() { return 239; }\n" + + "}"); final PsiFile bar = myFixture.addFileToProject("Bar.groovy", "class Bar extends Foo {" + "public static void main(String[] args) { " + " System.out.println(new Foo().foo());" + @@ -216,11 +217,11 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase { assertEmpty(make()); myFixture.addFileToProject("tests/Sub.groovy", "class Sub {\n" + - " Super xxx() {}\n" + - " static void main(String[] args) {" + - " println 'hello'" + - " }" + - "}"); + " Super xxx() {}\n" + + " static void main(String[] args) {" + + " println 'hello'" + + " }" + + "}"); myFixture.addFileToProject("tests/Java.java", "public class Java {}"); assertEmpty(make()); assertOutput("Sub", "hello"); @@ -231,9 +232,9 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase { myFixture.addFileToProject("src/com/Bar.groovy", "package com\n" + "class Bar {}"); myFixture.addFileToProject("src/com/ToGenerateStubs.java", "package com;\n" + - "public class ToGenerateStubs {}"); + "public class ToGenerateStubs {}"); myFixture.addFileToProject("tests/com/BarTest.groovy", "package com\n" + - "class BarTest extends Bar {}"); + "class BarTest extends Bar {}"); assertEmpty(make()); } @@ -307,8 +308,8 @@ public class Transf implements ASTTransformation { Module dep1 = addModule('dependent1') Module dep2 = addModule('dependent2') - PsiTestUtil.addDependency dep2, dep1 - PsiTestUtil.addDependency myModule, dep2 + ModuleRootModificationUtil.addDependency dep2, dep1 + ModuleRootModificationUtil.addDependency myModule, dep2 addGroovyLibrary(dep1); addGroovyLibrary(dep2); @@ -335,7 +336,7 @@ class Foo { }""" def javaFile = myFixture.addFileToProject("AJava.java", "public class AJava extends Foo.Bar {}") assertEmpty make() - + touch(javaFile.virtualFile) assertEmpty make() } @@ -516,7 +517,7 @@ class Indirect { assertEmpty compileModule(myModule) assertEmpty compileModule(myModule) - + setFileText(used, 'class Used2 {}') shouldFail { make() } assert findClassFile('Used') == null @@ -569,7 +570,7 @@ class Main { public void "test module cycle"() { def dep = addDependentModule() - PsiTestUtil.addDependency(myModule, dep) + ModuleRootModificationUtil.addDependency(myModule, dep) addGroovyLibrary(dep) myFixture.addFileToProject('Foo.groovy', 'class Foo extends Bar { static void main(String[] args) { println "Hello from Foo" } }') @@ -734,7 +735,5 @@ string } } } - } - } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java index d3109934d310..e17b4fc68070 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java @@ -99,9 +99,7 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC JavaAwareProjectJdkTableImpl jdkTable = JavaAwareProjectJdkTableImpl.getInstanceEx(); Sdk internalJdk = jdkTable.getInternalJdk(); jdkTable.addJdk(internalJdk); - final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(myModule).getModifiableModel(); - modifiableModel.setSdk(internalJdk); - modifiableModel.commit(); + ModuleRootModificationUtil.setModuleSdk(myModule, internalJdk); } } }.execute(); @@ -166,7 +164,7 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC protected Module addDependentModule() { Module module = addModule("dependent"); - PsiTestUtil.addDependency(module, myModule); + ModuleRootModificationUtil.addDependency(module, myModule); return module; } @@ -181,12 +179,8 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC moduleModel.commit(); final Module dep = ModuleManager.getInstance(getProject()).findModuleByName(moduleName); - final ModifiableRootModel model = ModuleRootManager.getInstance(dep).getModifiableModel(); - final ContentEntry entry = model.addContentEntry(depRoot); - entry.addSourceFolder(depRoot, false); - model.setSdk(ModuleRootManager.getInstance(myModule).getSdk()); - model.commit(); - + ModuleRootModificationUtil.setModuleSdk(dep, ModuleRootManager.getInstance(myModule).getSdk()); + PsiTestUtil.addSourceRoot(dep, depRoot); IdeaTestUtil.setModuleLanguageLevel(dep, LanguageLevelModuleExtension.getInstance(myModule).getLanguageLevel()); result.setResult(dep); @@ -200,7 +194,8 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC if (useJps()) { //noinspection ConstantConditions touch(JavaPsiFacade.getInstance(getProject()).findClass(className).getContainingFile().getVirtualFile()); - } else { + } + else { //noinspection ConstantConditions findClassFile(className).delete(this); } @@ -210,10 +205,13 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC } } - @Nullable protected VirtualFile findClassFile(String className) { + @Nullable + protected VirtualFile findClassFile(String className) { return findClassFile(className, myModule); } - @Nullable protected VirtualFile findClassFile(String className, Module module) { + + @Nullable + protected VirtualFile findClassFile(String className, Module module) { //noinspection ConstantConditions VirtualFile path = ModuleRootManager.getInstance(module).getModuleExtension(CompilerModuleExtension.class).getCompilerOutputPath(); path.getChildren(); @@ -344,7 +342,8 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC Module module, final Class executorClass, final ProcessListener listener, final ProgramRunner runner) throws ExecutionException { - final ApplicationConfiguration configuration = new ApplicationConfiguration("app", getProject(), ApplicationConfigurationType.getInstance()); + final ApplicationConfiguration configuration = + new ApplicationConfiguration("app", getProject(), ApplicationConfigurationType.getInstance()); configuration.setModule(module); configuration.setMainClassName(className); final Executor executor = Executor.EXECUTOR_EXTENSION_NAME.findExtension(executorClass); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java index 714e4e6e5be0..9d32c7109ef1 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java @@ -492,14 +492,7 @@ public abstract class MavenImportingTestCase extends MavenTestCase { protected Sdk setupJdkForModule(final String moduleName) { final Sdk sdk = createJdk("Java 1.5"); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - final ModifiableRootModel m = ModuleRootManager.getInstance(getModule(moduleName)).getModifiableModel(); - m.setSdk(sdk); - m.commit(); - } - }); - + ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk); return sdk; } @@ -524,7 +517,8 @@ public abstract class MavenImportingTestCase extends MavenTestCase { CompilerManagerImpl.testSetup(); List roots = Arrays.asList(ProjectRootManager.getInstance(myProject).getContentRoots()); - TranslatingCompilerFilesMonitor.getInstance().scanSourceContent(new TranslatingCompilerFilesMonitor.ProjectRef(myProject), roots, roots.size(), true); + TranslatingCompilerFilesMonitor.getInstance() + .scanSourceContent(new TranslatingCompilerFilesMonitor.ProjectRef(myProject), roots, roots.size(), true); final CompileScope scope = new ModuleCompileScope(myProject, modules.toArray(new Module[modules.size()]), false); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java index de2dce2defd0..007908d9c015 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/DependenciesImportingTest.java @@ -26,7 +26,6 @@ import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.PsiTestUtil; import org.jetbrains.idea.maven.MavenCustomRepositoryHelper; import org.jetbrains.idea.maven.MavenImportingTestCase; import org.jetbrains.idea.maven.model.MavenId; @@ -1507,7 +1506,7 @@ public class DependenciesImportingTest extends MavenImportingTestCase { final Module module = createModule("my-module"); - PsiTestUtil.addDependency(getModule("m1"), module); + ModuleRootModificationUtil.addDependency(getModule("m1"), module); assertModuleModuleDeps("m1", "m2", "my-module"); @@ -2055,9 +2054,7 @@ public class DependenciesImportingTest extends MavenImportingTestCase { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { Library lib = createProjectLibrary(libraryName); - ModifiableRootModel model = ModuleRootManager.getInstance(getModule(moduleName)).getModifiableModel(); - model.addLibraryEntry(lib); - model.commit(); + ModuleRootModificationUtil.addDependency(getModule(moduleName), lib); } }); } @@ -2121,9 +2118,7 @@ public class DependenciesImportingTest extends MavenImportingTestCase { public void run() { LibraryTable appTable = LibraryTablesRegistrar.getInstance().getLibraryTable(); Library lib = appTable.createLibrary("foo"); - ModifiableRootModel model = ModuleRootManager.getInstance(getModule("project")).getModifiableModel(); - model.addLibraryEntry(lib); - model.commit(); + ModuleRootModificationUtil.addDependency(getModule("project"), lib); appTable.removeLibrary(lib); } }); diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/InsertComponentProcessor.java b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/InsertComponentProcessor.java index 1fc39ad60d47..be7f2468010f 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/InsertComponentProcessor.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/designSurface/InsertComponentProcessor.java @@ -72,6 +72,7 @@ public final class InsertComponentProcessor extends EventProcessor { private ComponentDropLocation myLastLocation; private static final Map myComponentClassMap = new HashMap(); + static { myComponentClassMap.put(JScrollPane.class.getName(), new RadScrollPane.Factory()); myComponentClassMap.put(JPanel.class.getName(), new RadContainer.Factory()); @@ -158,11 +159,11 @@ public final class InsertComponentProcessor extends EventProcessor { // Here is euristic. Chop first 'J' letter for standard Swing classes. // Without 'J' bindings look better. - if( + if ( shortClassName.length() > 1 && Character.isUpperCase(shortClassName.charAt(1)) && componentClassName.startsWith("javax.swing.") && StringUtil.startsWithChar(shortClassName, 'J') - ){ + ) { shortClassName = shortClassName.substring(1); } shortClassName = StringUtil.decapitalize(shortClassName); @@ -172,7 +173,7 @@ public final class InsertComponentProcessor extends EventProcessor { public static String getUniqueBinding(RadRootContainer root, final String baseName) { // Generate member name based on current code style //noinspection ForLoopThatDoesntUseLoopVariable - for(int i = 0; true; i++){ + for (int i = 0; true; i++) { final String nameCandidate = baseName + (i + 1); final String binding = JavaCodeStyleManager.getInstance(root.getProject()).propertyNameToVariableName( nameCandidate, @@ -187,6 +188,7 @@ public final class InsertComponentProcessor extends EventProcessor { /** * Tries to create binding for {@link #myInsertedComponent} + * * @param editor * @param insertedComponent * @param forceBinding @@ -210,9 +212,9 @@ public final class InsertComponentProcessor extends EventProcessor { public static void createBindingField(final GuiEditor editor, final RadComponent insertedComponent) { // Try to create field in the corresponding bound class final String classToBind = editor.getRootContainer().getClassToBind(); - if(classToBind != null){ + if (classToBind != null) { final PsiClass aClass = FormEditingUtil.findClassToBind(editor.getModule(), classToBind); - if(aClass != null && aClass.findFieldByName(insertedComponent.getBinding(), true) == null) { + if (aClass != null && aClass.findFieldByName(insertedComponent.getBinding(), true) == null) { if (!CodeInsightUtilBase.preparePsiElementForWrite(aClass)) { return; } @@ -233,7 +235,7 @@ public final class InsertComponentProcessor extends EventProcessor { } } - protected void processMouseEvent(final MouseEvent e){ + protected void processMouseEvent(final MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_PRESSED) { final ComponentItem componentItem = getComponentToInsert(); if (componentItem != null) { @@ -302,8 +304,8 @@ public final class InsertComponentProcessor extends EventProcessor { if (location.canDrop(dragObject)) { CommandProcessor.getInstance().executeCommand( myEditor.getProject(), - new Runnable(){ - public void run(){ + new Runnable() { + public void run() { createBindingWhenDrop(myEditor, myInsertedComponent, forceBinding); final RadComponent[] components = new RadComponent[]{myInsertedComponent}; @@ -331,7 +333,6 @@ public final class InsertComponentProcessor extends EventProcessor { myEditor.refreshAndSave(false); } - }, UIDesignerBundle.message("command.insert.component"), null); } myComponentToInsert = null; @@ -351,10 +352,10 @@ public final class InsertComponentProcessor extends EventProcessor { List entries = fileIndex.getOrderEntriesForFile(componentClass.getContainingFile().getVirtualFile()); if (entries.size() > 0) { if (entries.get(0) instanceof ModuleSourceOrderEntry) { - if (!checkAddModuleDependency(item, (ModuleSourceOrderEntry) entries.get(0))) return false; + if (!checkAddModuleDependency(item, (ModuleSourceOrderEntry)entries.get(0))) return false; } else if (entries.get(0) instanceof LibraryOrderEntry) { - if (!checkAddLibraryDependency(item, (LibraryOrderEntry) entries.get(0))) return false; + if (!checkAddLibraryDependency(item, (LibraryOrderEntry)entries.get(0))) return false; } } } @@ -370,13 +371,7 @@ public final class InsertComponentProcessor extends EventProcessor { Messages.getQuestionIcon()); if (rc == 2) return false; if (rc == 0) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - final ModifiableRootModel model = ModuleRootManager.getInstance(myEditor.getModule()).getModifiableModel(); - model.addModuleOrderEntry(ownerModule); - model.commit(); - } - }); + ModuleRootModificationUtil.addDependency(myEditor.getModule(), ownerModule); } return true; } @@ -384,7 +379,8 @@ public final class InsertComponentProcessor extends EventProcessor { private boolean checkAddLibraryDependency(final ComponentItem item, final LibraryOrderEntry libraryOrderEntry) { int rc = Messages.showYesNoCancelDialog( myEditor, - UIDesignerBundle.message("add.library.dependency.prompt", item.getClassName(), libraryOrderEntry.getPresentableName(), myEditor.getModule().getName()), + UIDesignerBundle.message("add.library.dependency.prompt", item.getClassName(), libraryOrderEntry.getPresentableName(), + myEditor.getModule().getName()), UIDesignerBundle.message("add.library.dependency.title"), Messages.getQuestionIcon()); if (rc == 2) return false; @@ -409,8 +405,8 @@ public final class InsertComponentProcessor extends EventProcessor { final LibraryTable.ModifiableModel libraryTableModel = toModel.getModuleLibraryTable().getModifiableModel(); Library library = libraryTableModel.createLibrary(null); final Library.ModifiableModel libraryModel = library.getModifiableModel(); - for(OrderRootType rootType: OrderRootType.getAllTypes()) { - for(String url: fromLibrary.getUrls(rootType)) { + for (OrderRootType rootType : OrderRootType.getAllTypes()) { + for (String url : fromLibrary.getUrls(rootType)) { libraryModel.addRoot(url, rootType); } } @@ -426,7 +422,7 @@ public final class InsertComponentProcessor extends EventProcessor { final String targetForm = FormEditingUtil.buildResourceName(myEditor.getPsiFile()); Utils.validateNestedFormLoop(formName, new PsiNestedFormLoader(myEditor.getModule()), targetForm); } - catch(Exception ex) { + catch (Exception ex) { Messages.showErrorDialog(myEditor, ex.getMessage(), CommonBundle.getErrorTitle()); return false; } @@ -437,7 +433,7 @@ public final class InsertComponentProcessor extends EventProcessor { public static RadContainer createPanelComponent(GuiEditor editor) { RadComponent c = createInsertedComponent(editor, Palette.getInstance(editor.getProject()).getPanelItem()); LOG.assertTrue(c != null); - return (RadContainer) c; + return (RadContainer)c; } @Nullable @@ -447,7 +443,7 @@ public final class InsertComponentProcessor extends EventProcessor { ComponentItemDialog dlg = new ComponentItemDialog(editor.getProject(), editor, newItem, true); dlg.setTitle(title); dlg.show(); - if(!dlg.isOK()) { + if (!dlg.isOK()) { return null; } @@ -479,9 +475,9 @@ public final class InsertComponentProcessor extends EventProcessor { try { result = new RadNestedForm(editor, formFileName, id); } - catch(Exception ex) { + catch (Exception ex) { String errorMessage = UIDesignerBundle.message("error.instantiating.nested.form", formFileName, - (ex.getMessage() != null ? ex.getMessage() : ex.toString())); + (ex.getMessage() != null ? ex.getMessage() : ex.toString())); result = RadErrorComponent.create( editor, id, @@ -502,9 +498,9 @@ public final class InsertComponentProcessor extends EventProcessor { result = new RadAtomicComponent(editor, aClass, id); } } - catch(final UnsupportedClassVersionError ucve) { + catch (final UnsupportedClassVersionError ucve) { result = RadErrorComponent.create(editor, id, item.getClassName(), null, - UIDesignerBundle.message("unsupported.component.class.version") + UIDesignerBundle.message("unsupported.component.class.version") ); } catch (final Exception exc) { @@ -551,7 +547,7 @@ public final class InsertComponentProcessor extends EventProcessor { @Nullable public static RadComponentFactory getRadComponentFactory(Class componentClass) { - while(componentClass != null) { + while (componentClass != null) { RadComponentFactory c = myComponentClassMap.get(componentClass.getName()); if (c != null) return c; componentClass = componentClass.getSuperclass(); @@ -567,7 +563,7 @@ public final class InsertComponentProcessor extends EventProcessor { final RadComponent component = myEditor.getRootContainer().getComponent(0); if (component.getBinding() == null) { if (component == myInsertedComponent || - (component instanceof RadContainer && ((RadContainer) component).getComponentCount() == 1 && + (component instanceof RadContainer && ((RadContainer)component).getComponentCount() == 1 && component == myInsertedComponent.getParent())) { doCreateBindingWhenDrop(myEditor, component); } @@ -589,7 +585,8 @@ public final class InsertComponentProcessor extends EventProcessor { return FormEditingUtil.getMoveNoDropCursor(); } - @Override public boolean needMousePressed() { + @Override + public boolean needMousePressed() { return true; } } From 6128f059784017949ef17cc2397127576f576000 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Jun 2012 07:53:53 +0400 Subject: [PATCH 080/100] sort profiles (IDEA-87366) --- .../intellij/codeInspection/actions/CodeInspectionAction.java | 3 ++- .../profile/codeInspection/ui/InspectionToolsConfigurable.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java index ec6ebedcd3e2..63d6ee958051 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CodeInspectionAction.java @@ -42,6 +42,7 @@ import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Collection; +import java.util.TreeSet; public class CodeInspectionAction extends BaseAnalysisAction { private GlobalInspectionContextImpl myGlobalInspectionContext = null; @@ -147,7 +148,7 @@ public class CodeInspectionAction extends BaseAnalysisAction { } private static void fillModel(final ProfileManager inspectionProfileManager, final DefaultComboBoxModel model) { - Collection profiles = inspectionProfileManager.getProfiles(); + Collection profiles = new TreeSet(inspectionProfileManager.getProfiles()); for (Profile profile : profiles) { model.addElement(profile); } diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java index fe306e537246..ba11f15f772b 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java @@ -418,7 +418,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple protected Collection getProfiles() { final Collection result = new ArrayList(); - result.addAll(myProfileManager.getProfiles()); + result.addAll(new TreeSet(myProfileManager.getProfiles())); result.addAll(myProjectProfileManager.getProfiles()); return result; } From c51ed9a33fe8b215677f7ba5ba1e3e27894b2d8a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Jun 2012 09:21:07 +0400 Subject: [PATCH 081/100] EA-36695 - NPE: InplaceRefactoring.getVariable --- .../rename/inplace/InplaceRefactoring.java | 11 +++++++---- .../rename/inplace/MemberInplaceRenamer.java | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java index b7e94bc7f93d..f678387ef376 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java @@ -448,11 +448,14 @@ public abstract class InplaceRefactoring { protected PsiNamedElement getVariable() { if (myElementToRename != null && myElementToRename.isValid()) { if (Comparing.strEqual(myOldName, myElementToRename.getName())) return myElementToRename; - return PsiTreeUtil.getParentOfType(myElementToRename.getContainingFile().findElementAt(myRenameOffset.getStartOffset()), PsiNameIdentifierOwner.class); + if (myRenameOffset != null) return PsiTreeUtil.getParentOfType(myElementToRename.getContainingFile().findElementAt(myRenameOffset.getStartOffset()), PsiNameIdentifierOwner.class); } - final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument()); - if (psiFile != null) { - return PsiTreeUtil.getParentOfType(psiFile.findElementAt(myRenameOffset.getStartOffset()), PsiNameIdentifierOwner.class); + + if (myRenameOffset != null) { + final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(myEditor.getDocument()); + if (psiFile != null) { + return PsiTreeUtil.getParentOfType(psiFile.findElementAt(myRenameOffset.getStartOffset()), PsiNameIdentifierOwner.class); + } } return myElementToRename; } diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java index 6d5477e406f2..caf14daadbf3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java @@ -262,7 +262,7 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer { if (Comparing.strEqual(myOldName, ((PsiNameIdentifierOwner)mySubstituted).getName())) return mySubstituted; final RangeMarker rangeMarker = mySubstitutedRange != null ? mySubstitutedRange : myRenameOffset; - return PsiTreeUtil.getParentOfType(mySubstituted.getContainingFile().findElementAt(rangeMarker.getStartOffset()), PsiNameIdentifierOwner.class); + if (rangeMarker != null) return PsiTreeUtil.getParentOfType(mySubstituted.getContainingFile().findElementAt(rangeMarker.getStartOffset()), PsiNameIdentifierOwner.class); } return mySubstituted; } From 40e35d7a60ad6b897db9905b1bc084ee43b01c61 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Jun 2012 12:05:52 +0400 Subject: [PATCH 082/100] enable fix all for file for annotator problems, should work for localQuickFixes only (IDEA-87100) --- .../quickFix/fixAllAnnotator/after1.java | 7 + .../quickFix/fixAllAnnotator/before1.java | 7 + .../quickFix/FixAllAnnotatorQuickfixTest.java | 124 ++++++++++++++++++ .../daemon/impl/HighlightInfo.java | 15 ++- ...efaultHighlightVisitorBasedInspection.java | 5 +- .../codeInspection/InspectionRunningUtil.java | 28 +++- .../actions/CleanupInspectionIntention.java | 27 ++-- 7 files changed, 189 insertions(+), 24 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java new file mode 100644 index 000000000000..1a0aba5d40ef --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/after1.java @@ -0,0 +1,7 @@ +// "Fix all 'Annotator' problems" "true" +public class Test { + void fooF() { + } + + void barF(){} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java new file mode 100644 index 000000000000..8006731dbe32 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator/before1.java @@ -0,0 +1,7 @@ +// "Fix all 'Annotator' problems" "true" +public class Test { + void foo() { + } + + void bar(){} +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java new file mode 100644 index 000000000000..001bb3764f4c --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/FixAllAnnotatorQuickfixTest.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * User: anna + * Date: 17-Jun-2007 + */ +package com.intellij.codeInsight.daemon.quickFix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.*; +import com.intellij.codeInspection.dataFlow.DataFlowInspection; +import com.intellij.lang.Language; +import com.intellij.lang.LanguageAnnotators; +import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.CodeInsightColors; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class FixAllAnnotatorQuickfixTest extends LightQuickFixTestCase { + public void testAnnotator() throws Exception { + Annotator annotator = new MyAnnotator(); + Language javaLanguage = StdFileTypes.JAVA.getLanguage(); + LanguageAnnotators.INSTANCE.addExplicitExtension(javaLanguage, annotator); + enableInspectionTool(new DefaultHighlightVisitorBasedInspection.AnnotatorBasedInspection()); + try { + doAllTests(); + } + finally { + LanguageAnnotators.INSTANCE.removeExplicitExtension(javaLanguage, annotator); + } + } + + @Override + protected boolean shouldBeAvailableAfterExecution() { + return true; + } + + @Override + @NonNls + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/fixAllAnnotator"; + } + + public static class MyAnnotator implements Annotator { + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + if (element instanceof PsiMethod) { + Annotation annotation = holder.createErrorAnnotation(((PsiMethod)element).getNameIdentifier(), null); + annotation.registerFix(new MyFix()); + annotation.setTextAttributes(CodeInsightColors.DOC_COMMENT_TAG_VALUE); + } + } + + static class MyFix implements IntentionAction, LocalQuickFix { + + @NotNull + @Override + public String getText() { + return getName(); + } + + @NotNull + @Override + public String getName() { + return "MyFix"; + } + + @NotNull + @Override + public String getFamilyName() { + return getName(); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (element != null) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiMethod) { + ((PsiMethod)parent).setName(((PsiMethod)parent).getName() + "F"); + } + } + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + fail(); + } + + @Override + public boolean startInWriteAction() { + return true; + } + } + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index 7255f18995cf..6039146ee2ce 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -20,10 +20,7 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.IntentionManager; -import com.intellij.codeInspection.CustomSuppressableInspectionTool; -import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.InspectionProfileEntry; -import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.*; import com.intellij.codeInspection.actions.CleanupInspectionIntention; import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper; import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; @@ -405,7 +402,8 @@ public class HighlightInfo implements Segment { List fixes = annotation.getQuickFixes(); if (fixes != null) { for (final Annotation.QuickFixInfo quickFixInfo : fixes) { - QuickFixAction.registerQuickFixAction(info, fixedRange != null? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix, quickFixInfo.key); + QuickFixAction.registerQuickFixAction(info, fixedRange != null ? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix, + quickFixInfo.key != null ? quickFixInfo.key : HighlightDisplayKey.find(DefaultHighlightVisitorBasedInspection.AnnotatorBasedInspection.ANNOTATOR_SHORT_NAME)); } } return info; @@ -524,6 +522,13 @@ public class HighlightInfo implements Segment { newOptions.add(new CleanupInspectionIntention((LocalInspectionToolWrapper)tool, aClass)); } else if (tool instanceof GlobalInspectionToolWrapper) { wrappedTool = ((GlobalInspectionToolWrapper)tool).getTool(); + if (wrappedTool instanceof GlobalSimpleInspectionTool && (myAction instanceof LocalQuickFix || myAction instanceof QuickFixWrapper)) { + Class aClass = myAction.getClass(); + if (myAction instanceof QuickFixWrapper) { + aClass = ((QuickFixWrapper)myAction).getFix().getClass(); + } + newOptions.add(new CleanupInspectionIntention((GlobalInspectionToolWrapper)tool, aClass)); + } } if (wrappedTool instanceof CustomSuppressableInspectionTool) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java index 3fb18d97b96c..c7eeb50809c3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java @@ -49,6 +49,9 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl } public static class AnnotatorBasedInspection extends DefaultHighlightVisitorBasedInspection { + + public static final String ANNOTATOR_SHORT_NAME = "Annotator"; + public AnnotatorBasedInspection() { super(false, true); } @@ -62,7 +65,7 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl @NotNull @Override public String getShortName() { - return "Annotator"; + return ANNOTATOR_SHORT_NAME; } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java b/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java index e940b4944649..c9a887d59d5a 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/InspectionRunningUtil.java @@ -15,13 +15,13 @@ */ package com.intellij.codeInspection; -import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; -import com.intellij.codeInspection.ex.InspectionManagerEx; -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; +import com.intellij.codeInspection.ex.*; import com.intellij.codeInspection.reference.RefManagerImpl; import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -31,17 +31,33 @@ import java.util.List; public class InspectionRunningUtil { public static List runInspectionOnFile(final PsiFile file, final LocalInspectionTool inspectionTool) { + return runInspectionOnFile(file, new LocalInspectionToolWrapper(inspectionTool)); + } + + public static List runInspectionOnFile(final PsiFile file, final InspectionTool tool) { final InspectionManagerEx managerEx = (InspectionManagerEx)InspectionManager.getInstance(file.getProject()); final GlobalInspectionContextImpl context = managerEx.createNewGlobalContext(false); - final LocalInspectionToolWrapper tool = new LocalInspectionToolWrapper(inspectionTool); tool.initialize(context); ((RefManagerImpl)context.getRefManager()).inspectionReadActionStarted(); try { - tool.processFile(file, true, managerEx, true); - return new ArrayList(tool.getProblemDescriptors()); + if (tool instanceof LocalInspectionToolWrapper) { + ((LocalInspectionToolWrapper)tool).processFile(file, true, managerEx, true); + return new ArrayList(((LocalInspectionToolWrapper)tool).getProblemDescriptors()); + } + else if (tool instanceof GlobalInspectionToolWrapper) { + final GlobalInspectionTool globalInspectionTool = ((GlobalInspectionToolWrapper)tool).getTool(); + if (globalInspectionTool instanceof GlobalSimpleInspectionTool) { + ProblemsHolder problemsHolder = new ProblemsHolder(managerEx, file, false); + ((GlobalSimpleInspectionTool)globalInspectionTool) + .checkFile(file, managerEx, problemsHolder, context, (GlobalInspectionToolWrapper)tool); + return new ArrayList(((GlobalInspectionToolWrapper)tool).getProblemDescriptors()); + } + } + return Collections.emptyList(); } finally { ((RefManagerImpl)context.getRefManager()).inspectionReadActionFinished(); + tool.cleanup(); context.cleanup(managerEx); } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java index 664c700be1f4..326e9d0ccae2 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java @@ -21,9 +21,7 @@ import com.intellij.codeInsight.intention.EmptyIntentionAction; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.*; -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; -import com.intellij.codeInspection.ex.ProblemDescriptorImpl; -import com.intellij.codeInspection.ex.UnfairLocalInspectionTool; +import com.intellij.codeInspection.ex.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -44,10 +42,10 @@ import java.util.List; * Date: 21-Feb-2006 */ public class CleanupInspectionIntention implements IntentionAction, HighPriorityAction { - private final LocalInspectionToolWrapper myTool; + private final InspectionToolWrapper myTool; private final Class myQuickfixClass; - public CleanupInspectionIntention(final LocalInspectionToolWrapper tool, Class quickFixClass) { + public CleanupInspectionIntention(final InspectionToolWrapper tool, Class quickFixClass) { myTool = tool; myQuickfixClass = quickFixClass; } @@ -64,12 +62,13 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) return; - final List descriptions = ProgressManager.getInstance().runProcess(new Computable>() { - @Override - public List compute() { - return InspectionRunningUtil.runInspectionOnFile(file, myTool.getTool()); - } - }, new EmptyProgressIndicator()); + final List descriptions = + ProgressManager.getInstance().runProcess(new Computable>() { + @Override + public List compute() { + return InspectionRunningUtil.runInspectionOnFile(file, myTool); + } + }, new EmptyProgressIndicator()); Collections.sort(descriptions, new Comparator() { public int compare(final CommonProblemDescriptor o1, final CommonProblemDescriptor o2) { @@ -95,8 +94,12 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority } } + + + public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) { - return myQuickfixClass != null && myQuickfixClass != EmptyIntentionAction.class && !(myTool.isUnfair()); + return myQuickfixClass != null && myQuickfixClass != EmptyIntentionAction.class && !(myTool instanceof LocalInspectionToolWrapper && + ((LocalInspectionToolWrapper)myTool).isUnfair()); } public boolean startInWriteAction() { From d3f19de485ffa279551d78c2cc4bb000689e26fd Mon Sep 17 00:00:00 2001 From: "andrey.zaytsev" Date: Mon, 18 Jun 2012 12:17:37 +0400 Subject: [PATCH 083/100] breakpoints-ui. breakpoints tree nodes sorting. --- .../debugger/ui/XBreakpointCategoryGroup.java | 22 ++++++++++++++++ .../BreakpointPropertiesPanel.java | 10 ++++++++ .../ui/breakpoints/JavaBreakpointItem.java | 10 ++++++++ .../breakpoints/ui/BreakpointItem.java | 5 ++-- .../breakpoints/ui/XBreakpointTypeGroup.java | 12 ++++----- .../impl/actions/ViewBreakpointsAction.java | 3 ++- .../impl/breakpoints/XBreakpointBase.java | 7 +++++- .../impl/breakpoints/XBreakpointItem.java | 15 +++++++++++ .../BreakpointsMasterDetailPopupFactory.java | 5 ++-- .../tree/BreakpointItemsTreeController.java | 25 ++++++------------- 10 files changed, 84 insertions(+), 30 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java index bfb59e0a412b..6f6dcc45e808 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java @@ -19,6 +19,7 @@ import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.breakpoints.BreakpointFactory; import com.intellij.openapi.util.Key; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointTypeGroup; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -56,4 +57,25 @@ public class XBreakpointCategoryGroup extends XBreakpointGroup { public String getName() { return myName; } + + @Override + public int compareTo(XBreakpointGroup o) { + if (o instanceof XBreakpointTypeGroup) { + return -1; + } + if (o instanceof XBreakpointCategoryGroup) { + return getFactoryIndex() - ((XBreakpointCategoryGroup)o).getFactoryIndex(); + } + return super.compareTo(o); + } + + private int getFactoryIndex() { + BreakpointFactory[] breakpointFactories = BreakpointFactory.getBreakpointFactories(); + for (int i = 0; i < breakpointFactories.length; ++i) { + if (breakpointFactories[i].getBreakpointCategory().equals(myCategory)) { + return i; + } + } + return -1; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java index c4dee4bc0638..0182e6fa4d6f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java @@ -389,6 +389,11 @@ public abstract class BreakpointPropertiesPanel { //To change body of implemented methods use File | Settings | File Templates. } + @Override + public boolean isDefaultBreakpoint() { + return true; + } + @Override protected void setupGenericRenderer(SimpleColoredComponent renderer, boolean plainView) { renderer.clear(); @@ -434,6 +439,11 @@ public abstract class BreakpointPropertiesPanel { public void removed(Project project) { //To change body of implemented methods use File | Settings | File Templates. } + + @Override + public int compareTo(BreakpointItem breakpointItem) { + return 1; + } }); return items; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java index e46e7103fd45..aab563e1d658 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java @@ -133,4 +133,14 @@ class JavaBreakpointItem extends BreakpointItem { public void setEnabled(boolean state) { myBreakpoint.ENABLED = state; } + + @Override + public boolean isDefaultBreakpoint() { + return myBreakpoint.getCategory().equals(AnyExceptionBreakpoint.CATEGORY); + } + + @Override + public int compareTo(BreakpointItem breakpointItem) { + return getDisplayText().compareTo(breakpointItem.getDisplayText()); + } } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java index c9067e4425ef..0c7b33913d13 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/BreakpointItem.java @@ -41,8 +41,7 @@ import javax.swing.*; * Time: 4:48 AM * To change this template use File | Settings | File Templates. */ -public abstract class BreakpointItem extends ItemWrapper { - protected static final Key BREAKPOINT_ITEM = Key.create("BreakpointItem"); +public abstract class BreakpointItem extends ItemWrapper implements Comparable { public static final Key EDITOR_ONLY = Key.create("EditorOnly"); public abstract Object getBreakpoint(); @@ -51,6 +50,8 @@ public abstract class BreakpointItem extends ItemWrapper { public abstract void setEnabled(boolean state); + public abstract boolean isDefaultBreakpoint(); + protected boolean showInEditor(DetailView panel, VirtualFile virtualFile, int line) { TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java index aa4879ef1781..79631599b871 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java @@ -20,13 +20,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; -/** - * Created with IntelliJ IDEA. - * User: zajac - * Date: 23.05.12 - * Time: 15:55 - * To change this template use File | Settings | File Templates. - */ public class XBreakpointTypeGroup extends XBreakpointGroup { private XBreakpointType myBreakpointType; @@ -49,4 +42,9 @@ public class XBreakpointTypeGroup extends XBreakpointGroup { public Icon getIcon(boolean isOpen) { return myBreakpointType.getEnabledIcon(); } + + @Override + public int compareTo(XBreakpointGroup o) { + return -o.compareTo(this); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ViewBreakpointsAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ViewBreakpointsAction.java index 14b21b5834ec..38b52f648b8b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ViewBreakpointsAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ViewBreakpointsAction.java @@ -23,6 +23,7 @@ package com.intellij.xdebugger.impl.actions; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.registry.Registry; @@ -30,7 +31,7 @@ import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsConfigurationDialogFactory; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsMasterDetailPopupFactory; -public class ViewBreakpointsAction extends AnAction implements AnAction.TransparentUpdate { +public class ViewBreakpointsAction extends AnAction implements AnAction.TransparentUpdate, DumbAware { private Object myInitialBreakpoint; public ViewBreakpointsAction(){ diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java index aa77773d5e53..a655c5d0dd42 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java @@ -57,7 +57,7 @@ import java.util.List; /** * @author nik */ -public class XBreakpointBase, P extends XBreakpointProperties, S extends BreakpointState> extends UserDataHolderBase implements XBreakpoint

    { +public class XBreakpointBase, P extends XBreakpointProperties, S extends BreakpointState> extends UserDataHolderBase implements XBreakpoint

    , Comparable { private static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTERS = new SkipDefaultValuesSerializationFilters(); @NonNls private static final String BR_NBSP = "
     "; private final XBreakpointType myType; @@ -347,6 +347,11 @@ public class XBreakpointBase, P extends XBreakpointP myIcon = null; } + @Override + public int compareTo(Self self) { + return myType.getBreakpointComparator().compare((Self)this, self); + } + protected class BreakpointGutterIconRenderer extends GutterIconRenderer { @NotNull public Icon getIcon() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java index 8440fa919956..394202313bb2 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java @@ -147,4 +147,19 @@ class XBreakpointItem extends BreakpointItem { public void setEnabled(boolean state) { myBreakpoint.setEnabled(state); } + + @Override + public boolean isDefaultBreakpoint() { + return getManager().isDefaultBreakpoint(myBreakpoint); + } + + @Override + public int compareTo(BreakpointItem breakpointItem) { + if (breakpointItem.getBreakpoint() instanceof XBreakpointBase) { + return ((XBreakpointBase)myBreakpoint).compareTo((XBreakpoint)breakpointItem.getBreakpoint()); + } + else { + return 0; + } + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java index 3debf7781db0..9b0c0bc3c94f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java @@ -38,7 +38,6 @@ public class BreakpointsMasterDetailPopupFactory { public BreakpointsMasterDetailPopupFactory(Project project) { myProject = project; - collectPanelProviders(); } public static List collectPanelProviders() { @@ -84,7 +83,9 @@ public class BreakpointsMasterDetailPopupFactory { @Override public void onClosed(LightweightWindowEvent event) { - //To change body of implemented methods use File | Settings | File Templates. + for (BreakpointPanelProvider provider : collectPanelProviders()) { + provider.onDialogClosed(myProject); + } } }); return popup; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java index b94ec8b72ed8..16b60d8b7121 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/tree/BreakpointItemsTreeController.java @@ -38,7 +38,7 @@ import java.util.*; * @author nik, zajac */ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.Delegate { - //private final TreeNodeComparator myComparator; + private final TreeNodeComparator myComparator = new TreeNodeComparator(); private final CheckedTreeNode myRoot; private final Map myNodes = new HashMap(); private List myGroupingRules; @@ -52,7 +52,6 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De public BreakpointItemsTreeController(Collection groupingRules) { myRoot = new CheckedTreeNode("root"); - //myComparator = new TreeNodeComparator(type, breakpointManager); setGroupingRulesInternal(groupingRules); } @@ -84,7 +83,7 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De parent.add(node); myNodes.put(breakpoint, node); } - //TreeUtil.sort(myRoot, myComparator); + TreeUtil.sort(myRoot, myComparator); ((DefaultTreeModel)(myTreeView.getModel())).nodeStructureChanged(myRoot); state.applyTo(myTreeView, myRoot); TreeUtil.expandAll(myTreeView); @@ -204,26 +203,18 @@ public class BreakpointItemsTreeController implements BreakpointsCheckboxTree.De return myRoot; } - private static class TreeNodeComparator> implements Comparator { - private final Comparator myBreakpointComparator; - private final XBreakpointManager myBreakpointManager; - - public TreeNodeComparator(final XBreakpointType type, XBreakpointManager breakpointManager) { - myBreakpointManager = breakpointManager; - myBreakpointComparator = type.getBreakpointComparator(); - } - + private static class TreeNodeComparator implements Comparator { public int compare(final TreeNode o1, final TreeNode o2) { if (o1 instanceof BreakpointItemNode && o2 instanceof BreakpointItemNode) { //noinspection unchecked - B b1 = (B)((BreakpointItemNode)o1).getBreakpointItem(); + BreakpointItem b1 = ((BreakpointItemNode)o1).getBreakpointItem(); //noinspection unchecked - B b2 = (B)((BreakpointItemNode)o2).getBreakpointItem(); - boolean default1 = myBreakpointManager.isDefaultBreakpoint(b1); - boolean default2 = myBreakpointManager.isDefaultBreakpoint(b2); + BreakpointItem b2 = ((BreakpointItemNode)o2).getBreakpointItem(); + boolean default1 = b1.isDefaultBreakpoint(); + boolean default2 = b2.isDefaultBreakpoint(); if (default1 && !default2) return -1; if (!default1 && default2) return 1; - return myBreakpointComparator.compare(b1, b2); + return b1.compareTo(b2); } if (o1 instanceof BreakpointsGroupNode && o2 instanceof BreakpointsGroupNode) { final BreakpointsGroupNode group1 = (BreakpointsGroupNode)o1; From 47411f9ae5f38a6dae60f83c0585ba99cded850b Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 18 Jun 2012 12:53:25 +0400 Subject: [PATCH 084/100] close ServerSocket instance in finally block --- .../src/com/intellij/util/net/NetUtils.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/net/NetUtils.java b/platform/platform-api/src/com/intellij/util/net/NetUtils.java index cc36bd8264af..8f92fe6e52db 100644 --- a/platform/platform-api/src/com/intellij/util/net/NetUtils.java +++ b/platform/platform-api/src/com/intellij/util/net/NetUtils.java @@ -40,19 +40,22 @@ public class NetUtils { public static int findAvailableSocketPort() throws IOException { final ServerSocket serverSocket = new ServerSocket(0); - int port = serverSocket.getLocalPort(); - //workaround for linux : calling close() immediately after opening socket - //may result that socket is not closed - synchronized(serverSocket) { - try { - serverSocket.wait(1); - } - catch (InterruptedException e) { - LOG.error(e); + try { + int port = serverSocket.getLocalPort(); + //workaround for linux : calling close() immediately after opening socket + //may result that socket is not closed + synchronized (serverSocket) { + try { + serverSocket.wait(1); + } + catch (InterruptedException e) { + LOG.error(e); + } } + return port; + } finally { + serverSocket.close(); } - serverSocket.close(); - return port; } public static int[] findAvailableSocketPorts(int capacity) throws IOException { From e3f929558abcc96c2261a3e9714d7a51dad471a1 Mon Sep 17 00:00:00 2001 From: "andrey.zaytsev" Date: Mon, 18 Jun 2012 13:25:04 +0400 Subject: [PATCH 085/100] breakpoints-ui. infinite recursive fixed --- .../debugger/ui/XBreakpointCategoryGroup.java | 2 +- .../impl/breakpoints/XBreakpointPanelProvider.java | 2 +- .../ui/grouping}/XBreakpointGroupingByTypeRule.java | 3 ++- .../ui/grouping}/XBreakpointTypeGroup.java | 12 +++++++++++- 4 files changed, 15 insertions(+), 4 deletions(-) rename platform/{xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui => xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping}/XBreakpointGroupingByTypeRule.java (92%) rename platform/{xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui => xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping}/XBreakpointTypeGroup.java (71%) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java index 6f6dcc45e808..032b480c5584 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointCategoryGroup.java @@ -19,7 +19,7 @@ import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.breakpoints.BreakpointFactory; import com.intellij.openapi.util.Key; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointTypeGroup; +import com.intellij.xdebugger.impl.breakpoints.ui.grouping.XBreakpointTypeGroup; import org.jetbrains.annotations.NotNull; import javax.swing.*; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java index 877871da0451..62cf777b3f1f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java @@ -29,7 +29,7 @@ import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XDebuggerUtil; import com.intellij.xdebugger.breakpoints.*; import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingByTypeRule; +import com.intellij.xdebugger.impl.breakpoints.ui.grouping.XBreakpointGroupingByTypeRule; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import com.intellij.xdebugger.impl.breakpoints.ui.AbstractBreakpointPanel; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider; diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java similarity index 92% rename from platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java rename to platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java index d843b375833c..a646979fff9b 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointGroupingByTypeRule.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.xdebugger.breakpoints.ui; +package com.intellij.xdebugger.impl.breakpoints.ui.grouping; import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; import org.jetbrains.annotations.NotNull; import java.util.Collection; diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java similarity index 71% rename from platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java rename to platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java index 79631599b871..d00e27418edc 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointTypeGroup.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointTypeGroup.java @@ -13,9 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.xdebugger.breakpoints.ui; +package com.intellij.xdebugger.impl.breakpoints.ui.grouping; +import com.intellij.util.ArrayUtil; import com.intellij.xdebugger.breakpoints.XBreakpointType; +import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup; +import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -45,6 +48,13 @@ public class XBreakpointTypeGroup extends XBreakpointGroup { @Override public int compareTo(XBreakpointGroup o) { + if (o instanceof XBreakpointTypeGroup) { + return indexOfType(myBreakpointType) - indexOfType(((XBreakpointTypeGroup)o).getBreakpointType()); + } return -o.compareTo(this); } + + private static int indexOfType(XBreakpointType type) { + return ArrayUtil.find(XBreakpointUtil.getBreakpointTypes(), type); + } } From 730a1337eb31c971a79f8ae9c12cabb0fbdf905b Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 18 Jun 2012 13:55:25 +0400 Subject: [PATCH 086/100] don't save states if they set automatically after speed search --- .../src/com/intellij/ide/util/FileStructurePopup.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java index 162f52d21834..747cb5dbbe3b 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -111,6 +111,7 @@ public class FileStructurePopup implements Disposable { private final FilteringTreeStructure myFilteringStructure; private PsiElement myInitialPsiElement; private Map myCheckBoxes = new HashMap(); + private List myAutoClicked = new ArrayList(); private String myTestSearchFilter; private final ActionCallback myTreeHasBuilt = new ActionCallback(); private boolean myInitialNodeIsLeaf; @@ -312,6 +313,7 @@ public class FileStructurePopup implements Disposable { if (myFilteringStructure.getRootElement().getChildren().length == 0) { for (JCheckBox box : myCheckBoxes.values()) { if (!box.isSelected()) { + myAutoClicked.add(box); box.doClick(); filter = ""; break; @@ -586,7 +588,9 @@ public class FileStructurePopup implements Disposable { chkFilter.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final boolean state = chkFilter.isSelected(); - saveState(action, state); + if (!myAutoClicked.contains(chkFilter)) { + saveState(action, state); + } myTreeActionsOwner.setActionIncluded(action, action instanceof FileStructureFilter ? !state : state); //final String filter = mySpeedSearch.isPopupActive() ? mySpeedSearch.getEnteredPrefix() : null; //mySpeedSearch.hidePopup(); From 414c215384fbfaf2cb174ef4b9e9ddbf40a40313 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Mon, 18 Jun 2012 14:02:23 +0400 Subject: [PATCH 087/100] Palette --- .../android/designer/model/views-meta-model.xml | 16 ++++++++-------- .../editors/StringsComboEditor.java | 1 + .../propertyTable/editors/ComboEditor.java | 4 +++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml index 7e004335d2e4..b96ccfa8d7b1 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml +++ b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml @@ -743,6 +743,8 @@ + + - @@ -929,8 +931,7 @@ - + - @@ -1398,8 +1399,8 @@ class="android.widget.GridLayout" tag="GridLayout"> - @@ -1424,8 +1425,7 @@ class="android.widget.RelativeLayout" tag="RelativeLayout"> - + diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java index 949b97356e1a..c01367b5cc40 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java +++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/StringsComboEditor.java @@ -59,6 +59,7 @@ public class StringsComboEditor extends ComboEditor { Object value, @Nullable InplaceContext inplaceContext) { myCombo.setSelectedItem(value); + myCombo.setBorder(inplaceContext == null ? null : myComboBorder); return myCombo; } } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java index f19eb16efed7..d7f493b2c4dd 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/propertyTable/editors/ComboEditor.java @@ -19,6 +19,7 @@ import com.intellij.designer.propertyTable.PropertyEditor; import com.intellij.openapi.ui.ComboBox; import javax.swing.*; +import javax.swing.border.Border; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import java.awt.event.ActionEvent; @@ -30,10 +31,11 @@ import java.awt.event.KeyEvent; */ public abstract class ComboEditor extends PropertyEditor { protected final ComboBox myCombo; + protected final Border myComboBorder; public ComboEditor() { myCombo = new ComboBox(-1); - myCombo.setBorder(null); + myComboBorder = myCombo.getBorder(); addEditorSupport(this, myCombo); } From 8d8309c532a611f91ee916edfec270055d2a2bad Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 18 Jun 2012 14:25:43 +0400 Subject: [PATCH 088/100] stop daemon while showing file structure --- .../intellij/ide/util/FileStructurePopup.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java index 747cb5dbbe3b..08246d11fa90 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -15,6 +15,8 @@ */ package com.intellij.ide.util; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; import com.intellij.ide.DataManager; import com.intellij.ide.IdeBundle; import com.intellij.ide.structureView.StructureViewModel; @@ -115,6 +117,7 @@ public class FileStructurePopup implements Disposable { private String myTestSearchFilter; private final ActionCallback myTreeHasBuilt = new ActionCallback(); private boolean myInitialNodeIsLeaf; + private final boolean myDaemonUpdateEnabled; public FileStructurePopup(StructureViewModel structureViewModel, @Nullable Editor editor, @@ -123,6 +126,16 @@ public class FileStructurePopup implements Disposable { final boolean applySortAndFilter) { myProject = project; myEditor = editor; + + //Stop code analyzer to speedup EDT + final DaemonCodeAnalyzer analyzer = DaemonCodeAnalyzer.getInstance(myProject); + if (analyzer != null) { + myDaemonUpdateEnabled = ((DaemonCodeAnalyzerImpl)analyzer).isUpdateByTimerEnabled(); + analyzer.setUpdateByTimerEnabled(false); + } else { + myDaemonUpdateEnabled = false; + } + IdeFocusManager.getInstance(myProject).typeAheadUntil(myTreeHasBuilt); myBaseTreeModel = structureViewModel; Disposer.register(this, auxDisposable); @@ -398,6 +411,10 @@ public class FileStructurePopup implements Disposable { } public void dispose() { + final DaemonCodeAnalyzer analyzer = DaemonCodeAnalyzer.getInstance(myProject); + if (analyzer != null) { + analyzer.setUpdateByTimerEnabled(myDaemonUpdateEnabled); + } } protected static String getDimensionServiceKey() { From b7edeb92b5a2db7175d7a6cc18354a1555cc6410 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 18 Jun 2012 11:47:37 +0200 Subject: [PATCH 089/100] expected type is sometimes more important than prefix-variant case mismatch --- .../completion/JavaCompletionSorting.java | 4 +++- .../ExpectedTypeIsMoreImportantThanCase.java | 9 +++++++++ .../completion/CompletionSortingTestCase.java | 2 ++ .../completion/NormalCompletionOrderingTest.groovy | 14 +++++++------- .../completion/PrefixMatchingWeigher.java | 12 ++++-------- .../completion/impl/CompletionServiceImpl.java | 6 +++--- 6 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/ExpectedTypeIsMoreImportantThanCase.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java index 50b06728eaa6..2aabcdd1c2d8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java @@ -62,7 +62,9 @@ public class JavaCompletionSorting { if (!smart) { ContainerUtil.addIfNotNull(afterNegativeStats, preferStatics(position, expectedTypes)); } - afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type, position)); + if (!JavaCompletionData.START_FOR.accepts(position)) { + afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type, position)); + } ContainerUtil.addIfNotNull(afterNegativeStats, recursion(parameters, expectedTypes)); if (!smart && !afterNew) { afterNegativeStats.add(new PreferExpected(false, expectedTypes)); diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/ExpectedTypeIsMoreImportantThanCase.java b/java/java-tests/testData/codeInsight/completion/normalSorting/ExpectedTypeIsMoreImportantThanCase.java new file mode 100644 index 000000000000..95e9cc36bf6e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/ExpectedTypeIsMoreImportantThanCase.java @@ -0,0 +1,9 @@ +class Foo { + boolean ENABLED; + void enable() {} + + { + if (!en) + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionSortingTestCase.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionSortingTestCase.java index 940a4b40dbbf..c33a5945ab3b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionSortingTestCase.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/CompletionSortingTestCase.java @@ -4,6 +4,7 @@ */ package com.intellij.codeInsight.completion; +import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CompletionServiceImpl; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupManager; @@ -28,6 +29,7 @@ public abstract class CompletionSortingTestCase extends LightFixtureCompletionTe protected void tearDown() throws Exception { LookupManager.getInstance(getProject()).hideActiveLookup(); UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = false; + CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER; super.tearDown(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy index f7bd4bab66a5..b693da11333b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -202,7 +202,7 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { } public void testLocalVarsOverMethods() { - checkPreferredItems(0, "value"); + checkPreferredItems(0, "value", "valueOf"); } public void testCurrentClassBest() { @@ -329,12 +329,12 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { public void testCaseInsensitivePrefixMatch() { CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE; - try { - checkPreferredItems(1, "Foo", "foo1", "foo2"); - } - finally { - CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.FIRST_LETTER; - } + checkPreferredItems(1, "Foo", "foo1", "foo2"); + } + + public void testExpectedTypeIsMoreImportantThanCase() { + CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE; + checkPreferredItems(0, "ENABLED", "enable"); } public void testPreferKeywordsToVoidMethodsInExpectedTypeContext() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java index f298603491f0..8c9b887c278a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java @@ -54,8 +54,7 @@ public class PrefixMatchingWeigher extends CompletionWeigher { return new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); } - public static StartMatchingDegree getStartMatchingDegree(LookupElement element, CompletionLocation location) { - StartMatchingDegree result = StartMatchingDegree.middleMatch; + public static boolean isMiddleMatch(LookupElement element, CompletionLocation location) { String prefix = location.getCompletionParameters().getLookup().itemPattern(element); if (StringUtil.isNotEmpty(prefix)) { MinusculeMatcher matcher = getMinusculeMatcher(prefix); @@ -64,18 +63,15 @@ public class PrefixMatchingWeigher extends CompletionWeigher { if (fragments != null) { Iterator iterator = fragments.iterator(); if (!ls.isEmpty() && prefix.charAt(0) == ls.charAt(0)) { - return StartMatchingDegree.startMatchSameCase; + return false; } if (iterator.hasNext() && iterator.next().contains(0)) { - result = StartMatchingDegree.startMatchDifferentCase; + return false; } } } } - return result; + return true; } - public enum StartMatchingDegree { - startMatchSameCase, startMatchDifferentCase, middleMatch - } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 2a1b20d70737..2d8c4eb47a3f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -237,14 +237,14 @@ public class CompletionServiceImpl extends CompletionService{ final CompletionLocation location = new CompletionLocation(parameters); CompletionSorterImpl sorter = emptySorter(); - sorter = sorter.withClassifier(new ClassifierFactory("prefixHumps") { + sorter = sorter.withClassifier(new ClassifierFactory("startMatching") { @Override public Classifier createClassifier(Classifier next) { - return new ComparingClassifier(next, "prefixHumps") { + return new ComparingClassifier(next, "startMatching") { @NotNull @Override public Comparable getWeight(LookupElement element) { - return PrefixMatchingWeigher.getStartMatchingDegree(element, location); + return PrefixMatchingWeigher.isMiddleMatch(element, location); } }; } From b1142a5755d6368fb6e1e7e00f52172304315088 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 18 Jun 2012 12:05:56 +0200 Subject: [PATCH 090/100] save some memory --- .../lang/psi/controlFlow/impl/InstructionImpl.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java index 20492c9d24fb..a979fe46c19d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/impl/InstructionImpl.java @@ -23,6 +23,7 @@ import org.jetbrains.plugins.groovy.lang.psi.controlFlow.CallInstruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.NegatingGotoInstruction; +import java.util.Collections; import java.util.Deque; import java.util.LinkedHashSet; @@ -30,9 +31,9 @@ import java.util.LinkedHashSet; * @author ven */ public class InstructionImpl implements Instruction { - private final LinkedHashSet myPredecessors = new LinkedHashSet(); - private final LinkedHashSet mySuccessors = new LinkedHashSet(); - private final LinkedHashSet myNegations = new LinkedHashSet(); + private final LinkedHashSet myPredecessors = new LinkedHashSet(1); + private final LinkedHashSet mySuccessors = new LinkedHashSet(1); + private LinkedHashSet myNegations; PsiElement myPsiElement; private int myNumber = -1; @@ -97,6 +98,9 @@ public class InstructionImpl implements Instruction { @NotNull @Override public Iterable getNegatingGotoInstruction() { + if (myNegations == null) { + return Collections.emptyList(); + } return myNegations; } @@ -109,6 +113,9 @@ public class InstructionImpl implements Instruction { } void addNegationsFrom(Instruction instruction) { + if (myNegations == null) { + myNegations = new LinkedHashSet(1); + } for (NegatingGotoInstruction negation : instruction.getNegatingGotoInstruction()) { myNegations.add(negation); } From df59af1c8aa257dc577afd6d06250299d98604fc Mon Sep 17 00:00:00 2001 From: "Nadya.Zabrodina" Date: Mon, 18 Jun 2012 14:21:22 +0400 Subject: [PATCH 091/100] initialize PsiViewer blockTree, if only checkBox is selected; PsiViewer assertion comment --- .../src/com/intellij/internal/psiView/PsiViewerDialog.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java index 2d2e929b8967..d1de1c60312c 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java @@ -735,6 +735,9 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp myPsiTree.expandRow(0); myPsiTree.setRootVisible(false); + if (!myShowBlocksCheckBox.isSelected()) { + return; + } Block rootBlock = rootElement == null ? null : buildBlocks(rootElement); if (rootBlock == null) { myBlockTreeBuilder = null; @@ -823,7 +826,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp myPsiToBlockMap.put(currentElem, rootBlockNode); //nested PSI elements with same ranges will be mapped to one blockNode - assert currentElem != null; +// assert currentElem != null; //for Scala-language plugin etc it can be null, because formatterBlocks is not instance of ASTBlock TextRange curTextRange = currentElem.getTextRange(); PsiElement parentElem = currentElem.getParent(); while (parentElem != null && parentElem.getTextRange().equals(curTextRange)) { From d30542fa784435be6335d76aee2c1a79f679ee76 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 13:40:55 +0400 Subject: [PATCH 092/100] EA-36623 --- .../lang-api/src/com/intellij/lang/annotation/Annotation.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java b/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java index 882ad555d758..c6c7097609d3 100644 --- a/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java +++ b/platform/lang-api/src/com/intellij/lang/annotation/Annotation.java @@ -99,6 +99,7 @@ public final class Annotation implements Segment { */ public Annotation(final int startOffset, final int endOffset, final HighlightSeverity severity, final String message, String tooltip) { assert startOffset <= endOffset : startOffset + ":" + endOffset; + assert startOffset >= 0 : "Start offset must not be negative: " +startOffset; myStartOffset = startOffset; myEndOffset = endOffset; myMessage = message; @@ -186,6 +187,7 @@ public final class Annotation implements Segment { * * @return the annotation start offset. */ + @Override public int getStartOffset() { return myStartOffset; } @@ -195,6 +197,7 @@ public final class Annotation implements Segment { * * @return the annotation end offset. */ + @Override public int getEndOffset() { return myEndOffset; } From ace84254f0d41d19ee09b614b3115b37bceebc3d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 13:45:19 +0400 Subject: [PATCH 093/100] EA-36637 assertion --- .../src/com/intellij/psi/impl/source/PsiFileImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 5ba93fd8b982..51a8a104a481 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -305,9 +305,10 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF return; } - final PsiElement psi = stub.getPsi(); + PsiElement psi = stub.getPsi(); + assert psi != null : "Stub " + stub + " (" + stub.getClass() + ") has returned null PSI"; ((CompositeElement)tree).setPsi(psi); - final StubBasedPsiElementBase base = (StubBasedPsiElementBase)psi; + StubBasedPsiElementBase base = (StubBasedPsiElementBase)psi; base.setNode(tree); base.setStub(null); } From 421c5772c1076fc8b32ed798cc4041f114101874 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 13:47:19 +0400 Subject: [PATCH 094/100] EA-36658 --- .../highlighting/HighlightOverridingMethodsHandler.java | 7 +++++-- .../highlighting/HighlightUsagesHandlerBase.java | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandler.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandler.java index 5b19711089da..894de11323fe 100644 --- a/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/HighlightOverridingMethodsHandler.java @@ -66,8 +66,11 @@ public class HighlightOverridingMethodsHandler extends HighlightUsagesHandlerBas if (containingClass == null) continue; for (PsiClass classToAnalyze : classes) { if (InheritanceUtil.isInheritorOrSelf(classToAnalyze, containingClass, true)) { - addOccurrence(method.getNameIdentifier()); - break; + PsiIdentifier identifier = method.getNameIdentifier(); + if (identifier != null) { + addOccurrence(identifier); + break; + } } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerBase.java index 46562622f23d..a6816f273d37 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerBase.java @@ -28,6 +28,7 @@ import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -102,7 +103,7 @@ public abstract class HighlightUsagesHandlerBase { public abstract void computeUsages(List targets); - protected void addOccurrence(PsiElement element) { + protected void addOccurrence(@NotNull PsiElement element) { TextRange range = element.getTextRange(); range = InjectedLanguageManager.getInstance(element.getProject()).injectedToHost(element, range); myReadUsages.add(range); From 6e26e2c27aa6eeac22daac78d74df26046fca677 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 13:50:23 +0400 Subject: [PATCH 095/100] EA-36666 --- .../vfs/impl/VirtualFilePointerManagerImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java index e92039ec2039..5b905620ae69 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/VirtualFilePointerManagerImpl.java @@ -375,9 +375,9 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp return virtualFilePointerContainer; } - @Nullable private List myEvents = null; - @Nullable private List myPointersToUpdateUrl = null; - @Nullable private List myPointersToFire = null; + @Nullable private List myEvents = Collections.emptyList(); + @Nullable private List myPointersToUpdateUrl = Collections.emptyList(); + @Nullable private List myPointersToFire = Collections.emptyList(); @Override public void before(@NotNull final List events) { @@ -501,9 +501,9 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(pointersToFireArray); } - myPointersToUpdateUrl = null; - myEvents = null; - myPointersToFire = null; + myPointersToUpdateUrl = Collections.emptyList(); + myEvents = Collections.emptyList(); + myPointersToFire = Collections.emptyList(); for (FilePointerPartNode root : myPointers.values()) { root.checkStructure(); } From 03d179b990a501902986cc762053e1bf6e57d108 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 14:01:43 +0400 Subject: [PATCH 096/100] EA-36671 diag --- .../com/intellij/codeInsight/navigation/MethodUpDownUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/MethodUpDownUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/MethodUpDownUtil.java index a4b2e80d854c..77469a9b1be4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/MethodUpDownUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/MethodUpDownUtil.java @@ -52,7 +52,7 @@ public class MethodUpDownUtil { TIntArrayList offsets = new TIntArrayList(array.size()); for (PsiElement element : array) { int offset = element.getTextOffset(); - assert offset >= 0 : element + "; offset: " + offset; + assert offset >= 0 : element + " ("+element.getClass()+"); offset: " + offset; offsets.add(offset); } offsets.sort(); From 06c7132f838943e3ab6df5be6af5d79dd5ccb59b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Jun 2012 17:00:12 +0400 Subject: [PATCH 097/100] avoid induced error --- .../psi/impl/source/tree/java/PsiReferenceExpressionImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index 36dd50972386..7f537205fc30 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -317,7 +317,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple final PsiManagerEx manager = getManager(); if (manager == null) { LOG.error("getManager() == null!"); - return null; + return JavaResolveResult.EMPTY_ARRAY; } ResolveResult[] results = ResolveCache.getInstance(getProject()).resolveWithCaching(this, OurGenericsResolver.INSTANCE, true, incompleteCode); return results.length == 0 ? JavaResolveResult.EMPTY_ARRAY : (JavaResolveResult[])results; From 3f263b707728d5f405b95be28369bc0feca54464 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 18 Jun 2012 13:40:02 +0400 Subject: [PATCH 098/100] kill highlights on the fly: fix nested psi element ranges case --- .../daemon/impl/GeneralHighlightingPass.java | 38 +++++++++++++++---- .../daemon/impl/HighlightInfo.java | 2 +- ...efaultHighlightVisitorBasedInspection.java | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java index 2d991fff0e72..c46689ceb342 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java @@ -66,6 +66,7 @@ import com.intellij.psi.search.TodoItem; import com.intellij.psi.tree.IElementType; import com.intellij.util.Processor; import com.intellij.util.SmartList; +import com.intellij.util.containers.Stack; import com.intellij.util.containers.TransferToEDTQueue; import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; @@ -595,9 +596,11 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP final Runnable action = new Runnable() { @Override public void run() { + Stack>> nested = new Stack>>(); boolean failed = false; //noinspection unchecked for (List elements : new List[]{elements1, elements2}) { + nested.clear(); int nextLimit = chunkSize; for (int i = 0; i < elements.size(); i++) { PsiElement element = elements.get(i); @@ -641,7 +644,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP } TextRange elementRange = element.getTextRange(); - //noinspection ForLoopReplaceableByForEach + List infosForThisRange = holder.size() == 0 ? null : new ArrayList(holder.size()); for (int j = 0; j < holder.size(); j++) { final HighlightInfo info = holder.get(j); assert info != null; @@ -659,9 +662,28 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP info.bijective = elementRange.equalsToRange(info.startOffset, info.endOffset); myTransferToEDTQueue.offer(info); + infosForThisRange.add(info); } + // include infos which we got while visiting nested elements with the same range + while (true) { + if (!nested.isEmpty() && elementRange.contains(nested.peek().first)) { + Pair> old = nested.pop(); + if (elementRange.equals(old.first)) { + if (infosForThisRange == null) { + infosForThisRange = old.second; + } + else if (old.second != null){ + infosForThisRange.addAll(old.second); + } + } + } + else { + break; + } + } + nested.push(Pair.create(elementRange, infosForThisRange)); if (parent == null || !Comparing.equal(elementRange, parent.getTextRange())) { - killAbandonedHighlightsUnder(elementRange, holder, progress); + killAbandonedHighlightsUnder(elementRange, infosForThisRange, progress); } } advanceProgress(elements.size() - (nextLimit-chunkSize)); @@ -674,7 +696,7 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP } protected void killAbandonedHighlightsUnder(@NotNull final TextRange range, - @NotNull final HighlightInfoHolder holder, + @Nullable final List holder, @NotNull final ProgressIndicator progress) { DaemonCodeAnalyzerImpl.processHighlights(getDocument(), myProject, null, range.getStartOffset(), range.getEndOffset(), new Processor() { @Override @@ -682,9 +704,10 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP if (existing.bijective && existing.group == Pass.UPDATE_ALL && range.equalsToRange(existing.getActualStartOffset(), existing.getActualEndOffset())) { - for (int j = 0; j < holder.size(); j++) { - HighlightInfo created = holder.get(j); - if (existing.equalsByActualOffset(created)) return true; + if (holder != null) { + for (HighlightInfo created : holder) { + if (existing.equalsByActualOffset(created)) return true; + } } // seems that highlight info "existing" is going to disappear // remove it earlier @@ -706,7 +729,8 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP private void analyzeByVisitors(@NotNull final ProgressIndicator progress, @NotNull final HighlightVisitor[] visitors, @NotNull final HighlightInfoHolder holder, - final int i, @NotNull final Runnable action) { + final int i, + @NotNull final Runnable action) { if (i == visitors.length) { action.run(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index 6039146ee2ce..997e08fc62af 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -93,7 +93,7 @@ public class HighlightInfo implements Segment { private GutterIconRenderer gutterIconRenderer; private String myProblemGroup; - public boolean bijective; + public volatile boolean bijective; public HighlightSeverity getSeverity() { return severity; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java index c7eeb50809c3..c7debd891dca 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/DefaultHighlightVisitorBasedInspection.java @@ -188,7 +188,7 @@ public abstract class DefaultHighlightVisitorBasedInspection extends GlobalSimpl @Override protected void killAbandonedHighlightsUnder(@NotNull TextRange range, - @NotNull HighlightInfoHolder holder, + @Nullable List holder, @NotNull ProgressIndicator progress) { // do not mess with real editor highlights } From 22ec1696fe271c8b668c06259300ffd5a79f5c9d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Jun 2012 14:04:42 +0400 Subject: [PATCH 099/100] conflicts for duplicated type parameter name (IDEA-87473) --- .../ChangeClassSignatureDialog.java | 14 ++++++++++++- .../ChangeClassSignatureProcessor.java | 20 +++++++++++++++++++ .../rename/RenameJavaClassProcessor.java | 18 +++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java index c35b0b4420b7..d6b4b601f4c6 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java @@ -25,6 +25,7 @@ import com.intellij.refactoring.ui.JavaCodeFragmentTableCellEditor; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.ui.StringTableCellEditor; import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.ui.*; import com.intellij.ui.table.JBTable; import com.intellij.usageView.UsageViewUtil; @@ -39,7 +40,9 @@ import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; import java.awt.*; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author dsl @@ -153,10 +156,19 @@ public class ChangeClassSignatureDialog extends RefactoringDialog { } private String validateAndCommitData() { + final PsiTypeParameter[] parameters = myClass.getTypeParameters(); + final Map infos = new HashMap(); for (final TypeParameterInfo info : myTypeParameterInfos) { - if (!info.isForExistingParameter() && !JavaPsiFacade.getInstance(myClass.getProject()).getNameHelper().isIdentifier(info.getNewName())) { + if (!info.isForExistingParameter() && + !JavaPsiFacade.getInstance(myClass.getProject()).getNameHelper().isIdentifier(info.getNewName())) { return RefactoringBundle.message("error.wrong.name.input", info.getNewName()); } + final String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName(); + TypeParameterInfo existing = infos.get(newName); + if (existing != null) { + return myClass.getName() + " already contains type parameter " + newName; + } + infos.put(newName, info); } LOG.assertTrue(myTypeCodeFragments.size() == myTypeParameterInfos.size()); for (int i = 0; i < myTypeCodeFragments.size(); i++) { diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java index 477369902638..6026d8f33b76 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java @@ -19,16 +19,19 @@ import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.changeSignature.ChangeSignatureUtil; +import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -62,6 +65,23 @@ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor { return new ChangeClassSigntaureViewDescriptor(myClass); } + @Override + protected boolean preprocessUsages(Ref refUsages) { + final MultiMap conflicts = new MultiMap(); + + final PsiTypeParameter[] parameters = myClass.getTypeParameters(); + final Map infos = new HashMap(); + for (TypeParameterInfo info : myNewSignature) { + final String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName(); + TypeParameterInfo existing = infos.get(newName); + if (existing != null) { + conflicts.putValue(myClass, RefactoringUIUtil.getDescription(myClass, false) + " already contains type parameter " + newName); + } + infos.put(newName, info); + } + return showConflicts(conflicts, refUsages.get()); + } + @NotNull protected UsageInfo[] findUsages() { GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java index d98870a493f6..d651777f0106 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java @@ -34,7 +34,9 @@ import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.util.ConflictsUtil; import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.usageView.UsageInfo; import com.intellij.util.ArrayUtil; @@ -153,6 +155,22 @@ public class RenameJavaClassProcessor extends RenamePsiElementProcessor { } } findSubmemberHidesMemberCollisions(aClass, newName, result); + + if (aClass instanceof PsiTypeParameter) { + final PsiTypeParameterListOwner owner = ((PsiTypeParameter)aClass).getOwner(); + if (owner != null) { + for (PsiTypeParameter typeParameter : owner.getTypeParameters()) { + if (Comparing.equal(newName, typeParameter.getName())) { + result.add(new UnresolvableCollisionUsageInfo(aClass, typeParameter) { + @Override + public String getDescription() { + return "There is already type parameter in " + RefactoringUIUtil.getDescription(aClass, false) + " with name " + newName; + } + }); + } + } + } + } } public static void findSubmemberHidesMemberCollisions(final PsiClass aClass, final String newName, final List result) { From c3450589303764e965bfd143e1ef80cd58972fa9 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 18 Jun 2012 15:06:20 +0400 Subject: [PATCH 100/100] dialog with macros check should be shown over loading project progress (IDEA-87165) --- .../project/impl/ProjectMacrosUtil.java | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java index c81e4d1b050b..77baf2a6b98c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java @@ -22,12 +22,16 @@ package com.intellij.openapi.project.impl; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathMacros; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.WaitForProgressToShow; import org.jetbrains.annotations.NonNls; import javax.swing.*; @@ -89,26 +93,13 @@ public class ProjectMacrosUtil { // there are undefined macros, need to define them before loading components final boolean[] result = new boolean[1]; - try { - final Runnable r = new Runnable() { - public void run() { - result[0] = showMacrosConfigurationDialog(project, usedMacros); - } - }; + final Runnable r = new Runnable() { + public void run() { + result[0] = showMacrosConfigurationDialog(project, usedMacros); + } + }; - if (!ApplicationManager.getApplication().isDispatchThread()) { - SwingUtilities.invokeAndWait(r); - } - else { - r.run(); - } - } - catch (InterruptedException e) { - LOG.error(e); - } - catch (InvocationTargetException e) { - LOG.error(e); - } + WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(r, ModalityState.NON_MODAL); return result[0]; }