From 7165d85e3c3f726efe8bbaae931f97a1540a74a7 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 14 Mar 2013 18:52:57 +0400 Subject: [PATCH 01/18] RUBY-12276: reverting callback API refactoring --- platform/core-api/src/com/intellij/lang/PsiBuilder.java | 4 +--- .../src/com/intellij/lang/impl/PsiBuilderAdapter.java | 5 ++--- .../core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java | 5 +---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/platform/core-api/src/com/intellij/lang/PsiBuilder.java b/platform/core-api/src/com/intellij/lang/PsiBuilder.java index 2000064136be..0b234c084161 100644 --- a/platform/core-api/src/com/intellij/lang/PsiBuilder.java +++ b/platform/core-api/src/com/intellij/lang/PsiBuilder.java @@ -76,10 +76,8 @@ public interface PsiBuilder extends UserDataHolder, UserDataHolderUnprotected { /** * Subscribe for notification on default whitespace and comments skipped events. * @param callback an implementation for the callback - * @return previously registered callback */ - @Nullable - WhitespaceSkippedCallback setWhitespaceSkippedCallback(@Nullable WhitespaceSkippedCallback callback); + void setWhitespaceSkippedCallback(@Nullable WhitespaceSkippedCallback callback); /** * See what token type is in steps ahead diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java index 6f7b36a3bdfa..051da297750a 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderAdapter.java @@ -62,9 +62,8 @@ public class PsiBuilderAdapter implements PsiBuilder { } @Override - @Nullable - public WhitespaceSkippedCallback setWhitespaceSkippedCallback(@Nullable final WhitespaceSkippedCallback callback) { - return myDelegate.setWhitespaceSkippedCallback(callback); + public void setWhitespaceSkippedCallback(@Nullable final WhitespaceSkippedCallback callback) { + myDelegate.setWhitespaceSkippedCallback(callback); } @Override diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index 53c7ed371520..4dfb8a1cb2bd 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -734,11 +734,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { } @Override - @Nullable - public WhitespaceSkippedCallback setWhitespaceSkippedCallback(@Nullable final WhitespaceSkippedCallback callback) { - final WhitespaceSkippedCallback oldCallback = myWhitespaceSkippedCallback; + public void setWhitespaceSkippedCallback(@Nullable final WhitespaceSkippedCallback callback) { myWhitespaceSkippedCallback = callback; - return oldCallback; } @Override From 334da0a30cf0b3b48c33efaba7a8faaca69b4651 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Thu, 14 Mar 2013 19:13:19 +0400 Subject: [PATCH 02/18] EA-44844 - assert: FlexmojosImporter.getFlexmojosPlugin configure all facets in one write action. --- .../maven/importing/MavenModuleImporter.java | 68 +++++++++---------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index 05c5d58551ae..65e5392fd34b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -81,52 +81,48 @@ public class MavenModuleImporter { } public void preConfigFacets() { - if (myModule.isDisposed()) return; + MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { + public void run() { + if (myModule.isDisposed()) return; - final ModuleType moduleType = ModuleType.get(myModule); + final ModuleType moduleType = ModuleType.get(myModule); - for (final MavenImporter importer : getSuitableImporters()) { - final MavenProjectChanges changes; - if (myMavenProjectChanges == null) { - if (importer.processChangedModulesOnly()) continue; - changes = MavenProjectChanges.NONE; - } - else { - changes = myMavenProjectChanges; - } + for (final MavenImporter importer : getSuitableImporters()) { + final MavenProjectChanges changes; + if (myMavenProjectChanges == null) { + if (importer.processChangedModulesOnly()) continue; + changes = MavenProjectChanges.NONE; + } + else { + changes = myMavenProjectChanges; + } - if (importer.getModuleType() == moduleType) { - // facets use FacetConfiguration and like that do not have modifiable models, - // therefore we have to take write lock - MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { - public void run() { + if (importer.getModuleType() == moduleType) { importer.preProcess(myModule, myMavenProject, changes, myModifiableModelsProvider); } - }); + } } - } + }); } public void configFacets(final List postTasks) { - if (myModule.isDisposed()) return; + MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { + public void run() { + if (myModule.isDisposed()) return; - final ModuleType moduleType = ModuleType.get(myModule); + final ModuleType moduleType = ModuleType.get(myModule); - for (final MavenImporter importer : getSuitableImporters()) { - final MavenProjectChanges changes; - if (myMavenProjectChanges == null) { - if (importer.processChangedModulesOnly()) continue; - changes = MavenProjectChanges.NONE; - } - else { - changes = myMavenProjectChanges; - } + for (final MavenImporter importer : getSuitableImporters()) { + final MavenProjectChanges changes; + if (myMavenProjectChanges == null) { + if (importer.processChangedModulesOnly()) continue; + changes = MavenProjectChanges.NONE; + } + else { + changes = myMavenProjectChanges; + } - if (importer.getModuleType() == moduleType) { - // facets use FacetConfiguration and like that do not have modifiable models, - // therefore we have to take write lock - MavenUtil.invokeAndWaitWriteAction(myModule.getProject(), new Runnable() { - public void run() { + if (importer.getModuleType() == moduleType) { importer.process(myModifiableModelsProvider, myModule, myRootModelAdapter, @@ -136,9 +132,9 @@ public class MavenModuleImporter { myMavenProjectToModuleName, postTasks); } - }); + } } - } + }); } private List getSuitableImporters() { From d71740130271d06175a68e99477d49ec8b6a4e69 Mon Sep 17 00:00:00 2001 From: Alexander Kirillin Date: Thu, 14 Mar 2013 19:38:42 +0400 Subject: [PATCH 03/18] right keymap for "inspect code" in xcode keymap --- platform/platform-resources/src/idea/Keymap_Xcode.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources/src/idea/Keymap_Xcode.xml b/platform/platform-resources/src/idea/Keymap_Xcode.xml index c0cfb66e8a12..461206add912 100644 --- a/platform/platform-resources/src/idea/Keymap_Xcode.xml +++ b/platform/platform-resources/src/idea/Keymap_Xcode.xml @@ -238,7 +238,7 @@ - + From b09ba0f86d200f97030fb94bf269aaa51929edcf Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 14 Mar 2013 21:29:14 +0400 Subject: [PATCH 04/18] jps: fix loading project when project directory is named '.idea' (ZD-62) --- .../jps/model/serialization/JpsProjectLoader.java | 11 ++++++----- .../testData/matryoshka/.idea/.idea/misc.xml | 7 +++++++ .../testData/matryoshka/.idea/.idea/modules.xml | 8 ++++++++ .../serialization/JpsProjectSerializationTest.java | 12 ++++++++---- 4 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 jps/model-serialization/testData/matryoshka/.idea/.idea/misc.xml create mode 100644 jps/model-serialization/testData/matryoshka/.idea/.idea/modules.xml diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index 28863f900152..23fb427f9660 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -83,15 +83,16 @@ public class JpsProjectLoader extends JpsLoaderBase { new JpsProjectLoader(project, pathVariables, file.getParentFile()).loadFromIpr(file); } else { + File dotIdea = new File(file, PathMacroUtil.DIRECTORY_STORE_NAME); File directory; - if (file.isDirectory() && file.getName().equals(PathMacroUtil.DIRECTORY_STORE_NAME)) { + if (dotIdea.isDirectory()) { + directory = dotIdea; + } + else if (file.isDirectory() && file.getName().equals(PathMacroUtil.DIRECTORY_STORE_NAME)) { directory = file; } else { - directory = new File(file, PathMacroUtil.DIRECTORY_STORE_NAME); - if (!directory.isDirectory()) { - throw new IOException("Cannot find IntelliJ IDEA project files at " + projectPath); - } + throw new IOException("Cannot find IntelliJ IDEA project files at " + projectPath); } new JpsProjectLoader(project, pathVariables, directory.getParentFile()).loadFromDirectory(directory); } diff --git a/jps/model-serialization/testData/matryoshka/.idea/.idea/misc.xml b/jps/model-serialization/testData/matryoshka/.idea/.idea/misc.xml new file mode 100644 index 000000000000..dc7535439d30 --- /dev/null +++ b/jps/model-serialization/testData/matryoshka/.idea/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/jps/model-serialization/testData/matryoshka/.idea/.idea/modules.xml b/jps/model-serialization/testData/matryoshka/.idea/.idea/modules.xml new file mode 100644 index 000000000000..e1042fc80c7a --- /dev/null +++ b/jps/model-serialization/testData/matryoshka/.idea/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java index 3ed4336709c4..2567927c87e9 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java @@ -23,10 +23,7 @@ import org.jetbrains.jps.model.JpsDummyElement; import org.jetbrains.jps.model.JpsEncodingConfigurationService; import org.jetbrains.jps.model.JpsEncodingProjectConfiguration; import org.jetbrains.jps.model.artifact.JpsArtifactService; -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.java.JpsJavaSdkType; +import org.jetbrains.jps.model.java.*; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.library.sdk.JpsSdkReference; @@ -135,6 +132,13 @@ public class JpsProjectSerializationTest extends JpsSerializationTestCase { assertSameElements(lib2.getRootUrls(JpsOrderRootType.COMPILED), getUrl("data/lib2")); } + public void testDotIdeaUnderDotIdea() { + loadProject("/jps/model-serialization/testData/matryoshka/.idea"); + JpsJavaProjectExtension extension = JpsJavaExtensionService.getInstance().getProjectExtension(myProject); + assertNotNull(extension); + assertEquals(getUrl("out"), extension.getOutputUrl()); + } + public void testLoadEncoding() { loadProject(SAMPLE_PROJECT_PATH); JpsEncodingConfigurationService service = JpsEncodingConfigurationService.getInstance(); From e5bfb079fecff864978399a5701d0132098efe01 Mon Sep 17 00:00:00 2001 From: Fedor Korotkov Date: Thu, 14 Mar 2013 22:01:20 +0400 Subject: [PATCH 05/18] WEB-7126 $FileNameWithoutExtension$ needed to remove all extensions --- .../macro/FileNameWithoutAllExtensions.java | 41 +++++++++++++++++++ .../com/intellij/ide/macro/MacroManager.java | 1 + .../src/messages/IdeBundle.properties | 1 + .../application/options/PathMacrosImpl.java | 1 + 4 files changed, 44 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutAllExtensions.java diff --git a/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutAllExtensions.java b/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutAllExtensions.java new file mode 100644 index 000000000000..423fb438cf63 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/macro/FileNameWithoutAllExtensions.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2013 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.ide.macro; + +import com.intellij.ide.IdeBundle; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.vfs.VirtualFile; + +public class FileNameWithoutAllExtensions extends FileNameMacro { + public String getName() { + return "FileNameWithoutAllExtensions"; + } + + public String getDescription() { + return IdeBundle.message("macro.file.name.without.all.extensions"); + } + + public String expand(DataContext dataContext) { + VirtualFile file = PlatformDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file == null) { + return null; + } + String fileName = file.getName(); + int index = fileName.indexOf('.'); + return index > 0 ? fileName.substring(0, index) : fileName; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java index e7f6674e69ea..9c29fa2171b8 100644 --- a/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java +++ b/platform/lang-impl/src/com/intellij/ide/macro/MacroManager.java @@ -54,6 +54,7 @@ public final class MacroManager { registerMacro(new FileExtMacro()); registerMacro(new FileNameMacro()); registerMacro(new FileNameWithoutExtension()); + registerMacro(new FileNameWithoutAllExtensions()); registerMacro(new FilePathMacro()); registerMacro(new FileEncodingMacro()); registerMacro(new FileDirRelativeToProjectRootMacro()); diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index cc37db2094b3..fd809e11d239 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -446,6 +446,7 @@ macro.file.extension=File extension macro.file.fully.qualified.package=File fully qualified package macro.file.name=File name macro.file.name.without.extension=File name without extension +macro.file.name.without.all.extensions=File name without all extensions macro.file.package=File package macro.file.path=File path macro.file.path.relative.to.root=File path relative to the module content root the file belongs to diff --git a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java index cbac00107c3b..4c36cdfccd01 100644 --- a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java +++ b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java @@ -91,6 +91,7 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, "FileFQPackage", "FileName", "FileNameWithoutExtension", + "FileNameWithoutAllExtensions", "FilePackage", "FilePath", "FilePathRelativeToProjectRoot", From 8a92a59f89b761c4d8c503b47ecd4b3b0f94117e Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Thu, 14 Mar 2013 22:37:56 +0400 Subject: [PATCH 06/18] Smart menu for full screen mode (MS Windows) After review http://crucible.labs.intellij.net/cru/CR-IC-241 --- .../intellij/openapi/wm/impl/IdeMenuBar.java | 122 ++++++++++++++---- .../intellij/openapi/wm/impl/IdeRootPane.java | 118 ++++++++++++++++- 2 files changed, 210 insertions(+), 30 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeMenuBar.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeMenuBar.java index 387caa553b5d..d619a2b2d74b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeMenuBar.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeMenuBar.java @@ -38,6 +38,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.AWTEventListener; import java.awt.event.ActionEvent; @@ -55,6 +56,7 @@ import java.util.ArrayList; public class IdeMenuBar extends JMenuBar { private static final int COLLAPSED_HEIGHT = 2; + private IdeMenuBar.MyBorderDelegator myBorderDelegator; private enum State { EXPANDED, COLLAPSING, COLLAPSED, EXPANDING, TEMPORARY_EXPANDED; @@ -88,7 +90,7 @@ public class IdeMenuBar extends JMenuBar { myPresentationFactory = new MenuItemPresentationFactory(); myDataManager = dataManager; if (SystemInfo.isWindows) { - myAnimator = new Animator("MenuBarAnimator", 8, 300, false) { + myAnimator = new Animator("MenuBarAnimator", 16, 300, false) { @Override public void paintNow(int frame, int totalFrames, int cycle) { myProgress = (1 - Math.cos(Math.PI * ((float)frame / totalFrames))) / 2; @@ -116,11 +118,7 @@ public class IdeMenuBar extends JMenuBar { @Override public void eventDispatched(AWTEvent event) { MouseEvent mouseEvent = (MouseEvent)event; - Component component = mouseEvent.getComponent(); - Component deepestComponent = SwingUtilities.getDeepestComponentAt(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); - if (deepestComponent != null) { - component = deepestComponent; - } + Component component = findActualComponent(mouseEvent); if (myState != State.EXPANDED && !myState.isInProgress()) { myMouseInside = myActivated || isDescendingFrom(component, IdeMenuBar.this); @@ -134,20 +132,39 @@ public class IdeMenuBar extends JMenuBar { } } } + + private Component findActualComponent(MouseEvent mouseEvent) { + Component component = mouseEvent.getComponent(); + Component deepestComponent; + if (myState != State.EXPANDED && + !myState.isInProgress() && + contains(SwingUtilities.convertPoint(component, mouseEvent.getPoint(), IdeMenuBar.this))) { + deepestComponent = IdeMenuBar.this; + } + else { + deepestComponent = SwingUtilities.getDeepestComponentAt(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); + } + if (deepestComponent != null) { + component = deepestComponent; + } + return component; + } }, AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK); myActivationWatcher = new Timer(100, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if (myState == State.EXPANDED || myState == State.EXPANDING) + if (myState == State.EXPANDED || myState == State.EXPANDING) { return; + } boolean activated = isActivated(); if (myActivated && !activated && myState == State.TEMPORARY_EXPANDED) { myActivated = false; setState(State.COLLAPSING); restartAnimator(); } - if (activated) + if (activated) { myActivated = true; + } } }); } @@ -157,6 +174,24 @@ public class IdeMenuBar extends JMenuBar { } } + @Override + public void setBorder(Border border) { + if (border == null || !SystemInfo.isWindows) { + super.setBorder(border); + myBorderDelegator = null; + return; + } + + if (myBorderDelegator == null) { + myBorderDelegator = new MyBorderDelegator(border); + } + else { + myBorderDelegator.setSource(border); + } + + super.setBorder(myBorderDelegator); + } + private static boolean isDescendingFrom(@Nullable Component a, @NotNull Component b) { while (a != null) { if (a == b) { @@ -165,7 +200,8 @@ public class IdeMenuBar extends JMenuBar { if (a instanceof JPopupMenu) { a = ((JPopupMenu)a).getInvoker(); - } else { + } + else { a = a.getParent(); } } @@ -174,8 +210,9 @@ public class IdeMenuBar extends JMenuBar { private boolean isActivated() { int index = getSelectionModel().getSelectedIndex(); - if (index ==-1) + if (index == -1) { return false; + } return getMenu(index).isPopupMenuVisible(); } @@ -211,23 +248,19 @@ public class IdeMenuBar extends JMenuBar { public void addNotify() { super.addNotify(); updateMenuActions(); - if (!ScreenUtil.isStandardAddRemoveNotify(this)) { - Window window = SwingUtilities.getWindowAncestor(this); - if (window instanceof IdeFrameImpl) { - boolean fullScreen = WindowManagerEx.getInstanceEx().isFullScreen((IdeFrameImpl)window); - if (fullScreen) { - setState(State.COLLAPSING); - restartAnimator(); - } else { - if (myAnimator != null) { - myAnimator.suspend(); - } - setState(State.EXPANDED); - revalidate(); - repaint(); + Window window = SwingUtilities.getWindowAncestor(this); + if (SystemInfo.isWindows && window instanceof IdeFrameImpl) { + boolean fullScreen = WindowManagerEx.getInstanceEx().isFullScreen((IdeFrameImpl)window); + if (fullScreen) { + setState(State.COLLAPSING); + restartAnimator(); + } + else { + if (myAnimator != null) { + myAnimator.suspend(); } + setState(State.EXPANDED); } - return; } // Add updater for menus myActionManager.addTimerListener(1000, new WeakTimerListener(myActionManager, myTimerListener)); @@ -308,12 +341,15 @@ public class IdeMenuBar extends JMenuBar { super.paintComponent(g); if (UIUtil.isUnderDarcula()) { g.setColor(UIManager.getColor("MenuItem.background")); - g.fillRect(0,0,getWidth(), getHeight()); + g.fillRect(0, 0, getWidth(), getHeight()); } } @Override protected void paintChildren(Graphics g) { + if (SystemInfo.isWindows && myState == State.COLLAPSED) { + return; + } if (SystemInfo.isWindows && myState.isInProgress()) { Graphics2D g2 = (Graphics2D)g; AffineTransform oldTransform = g2.getTransform(); @@ -322,7 +358,8 @@ public class IdeMenuBar extends JMenuBar { g2.setTransform(newTransform); super.paintChildren(g2); g2.setTransform(oldTransform); - } else { + } + else { super.paintChildren(g); } } @@ -411,4 +448,35 @@ public class IdeMenuBar extends JMenuBar { } } } + + private class MyBorderDelegator implements Border { + @NotNull private Border mySource; + + private MyBorderDelegator(@NotNull Border source) { + setSource(source); + } + + void setSource(@NotNull Border source) { + mySource = source; + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + mySource.paintBorder(c, g, x, y, width, height); + } + + @Override + public Insets getBorderInsets(Component c) { + Insets insets = mySource.getBorderInsets(c); + if (myState != State.EXPANDED) { + insets.top = 0;//get rid of "passive top pixel" in fullscreen mode + } + return insets; + } + + @Override + public boolean isBorderOpaque() { + return mySource.isBorderOpaque(); + } + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java index 45b4782c11dc..139c11ebf874 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeRootPane.java @@ -39,6 +39,7 @@ import com.intellij.openapi.wm.impl.status.IdeStatusBarImpl; import com.intellij.openapi.wm.impl.status.MemoryUsagePanel; import com.intellij.ui.JBColor; import com.intellij.ui.PopupHandler; +import com.intellij.ui.ScreenUtil; import com.intellij.ui.components.JBLayeredPane; import com.intellij.ui.components.JBPanel; import com.intellij.util.IconUtil; @@ -49,6 +50,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; @@ -87,9 +90,10 @@ public class IdeRootPane extends JRootPane implements UISettingsListener { private final Disposable myDisposable= Disposer.newDisposable(); private static final Icon BG = IconLoader.getIcon("/frame_background.png"); + private boolean myFullScreen; public IdeRootPane(ActionManagerEx actionManager, UISettings uiSettings, DataManager dataManager, - final Application application, IdeFrame frame){ + final Application application, final IdeFrame frame){ myActionManager = actionManager; myUISettings = uiSettings; @@ -106,8 +110,24 @@ public class IdeRootPane extends JRootPane implements UISettingsListener { myContentPane.add(myStatusBar, BorderLayout.SOUTH); myUISettingsListener=new MyUISettingsListenerImpl(); - setJMenuBar(new IdeMenuBar(actionManager, dataManager)); - + if (SystemInfo.isWindows) { + menuBar = new IdeMenuBar(actionManager, dataManager); + getLayeredPane().add(menuBar, new Integer(1)); + if (frame instanceof IdeFrameImpl) { + final PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getNewValue() == null) {//fullscreen state has been just changed + myFullScreen = ((IdeFrameImpl)frame).isInFullScreen(); + } + } + }; + addPropertyChangeListener(ScreenUtil.DISPOSE_TEMPORARY, propertyChangeListener); + } + } + else { + setJMenuBar(new IdeMenuBar(actionManager, dataManager)); + } myGlassPane = new IdeGlassPaneImpl(this); setGlassPane(myGlassPane); @@ -117,6 +137,12 @@ public class IdeRootPane extends JRootPane implements UISettingsListener { Disposer.register(application, myDisposable); } + @Override + protected LayoutManager createRootLayout() { + return SystemInfo.isWindows ? new MyRootLayout() : super.createRootLayout(); + } + + public void setGlassPane(final Component glass) { if (myGlassPaneInitialized) throw new IllegalStateException("Setting of glass pane for IdeFrame is prohibited"); super.setGlassPane(glass); @@ -329,4 +355,90 @@ public class IdeRootPane extends JRootPane implements UISettingsListener { public ToolWindowsPane getToolWindowsPane() { return myToolWindowsPane; } + + private class MyRootLayout extends RootLayout { + public Dimension preferredLayoutSize(Container parent) { + Dimension rd, mbd; + Insets i = getInsets(); + + if (contentPane != null) { + rd = contentPane.getPreferredSize(); + } + else { + rd = parent.getSize(); + } + if (menuBar != null && menuBar.isVisible() && !myFullScreen) { + mbd = menuBar.getPreferredSize(); + } + else { + mbd = new Dimension(0, 0); + } + return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right, + rd.height + mbd.height + i.top + i.bottom); + } + + public Dimension minimumLayoutSize(Container parent) { + Dimension rd, mbd; + Insets i = getInsets(); + if (contentPane != null) { + rd = contentPane.getMinimumSize(); + } + else { + rd = parent.getSize(); + } + if (menuBar != null && menuBar.isVisible() && !myFullScreen) { + mbd = menuBar.getMinimumSize(); + } + else { + mbd = new Dimension(0, 0); + } + return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right, + rd.height + mbd.height + i.top + i.bottom); + } + + public Dimension maximumLayoutSize(Container target) { + Dimension rd, mbd; + Insets i = getInsets(); + if (menuBar != null && menuBar.isVisible() && !myFullScreen) { + mbd = menuBar.getMaximumSize(); + } + else { + mbd = new Dimension(0, 0); + } + if (contentPane != null) { + rd = contentPane.getMaximumSize(); + } + else { + rd = new Dimension(Integer.MAX_VALUE, + Integer.MAX_VALUE - i.top - i.bottom - mbd.height - 1); + } + return new Dimension(Math.min(rd.width, mbd.width) + i.left + i.right, + rd.height + mbd.height + i.top + i.bottom); + } + + public void layoutContainer(Container parent) { + Rectangle b = parent.getBounds(); + Insets i = getInsets(); + int contentY = 0; + int w = b.width - i.right - i.left; + int h = b.height - i.top - i.bottom; + + if (layeredPane != null) { + layeredPane.setBounds(i.left, i.top, w, h); + } + if (glassPane != null) { + glassPane.setBounds(i.left, i.top, w, h); + } + if (menuBar != null && menuBar.isVisible()) { + Dimension mbd = menuBar.getPreferredSize(); + menuBar.setBounds(0, 0, w, mbd.height); + if (!myFullScreen) { + contentY += mbd.height; + } + } + if (contentPane != null) { + contentPane.setBounds(0, contentY, w, h - contentY); + } + } + } } From d1fd12dd42eda5104d1936a29efa41915d472b1d Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Thu, 14 Mar 2013 22:45:37 +0400 Subject: [PATCH 07/18] IDEA-82284 is here again --- .../src/com/intellij/openapi/actionSystem/impl/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java index b3aaf5bb71c8..c3f2509afb25 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.java @@ -258,7 +258,7 @@ public class Utils{ @Override protected void paintComponent(Graphics g) { - if (UIUtil.isUnderWindowsClassicLookAndFeel() || UIUtil.isUnderDarcula()) { + if (UIUtil.isUnderWindowsClassicLookAndFeel() || UIUtil.isUnderDarcula() || UIUtil.isUnderWindowsLookAndFeel()) { g.setColor(component.getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); } From 238483108b67aa86c0997d3f4da7fc3cc2e22262 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 14 Mar 2013 20:54:46 +0100 Subject: [PATCH 08/18] Unneeded exceptions --- .../daemon/quickFix/LightQuickFix15TestCase.java | 6 +++--- .../codeInsight/daemon/quickFix/LightQuickFixTestCase.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java index 457d783a7bb4..63e01f34f60a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -22,8 +22,8 @@ import com.intellij.pom.java.LanguageLevel; */ public abstract class LightQuickFix15TestCase extends LightQuickFixTestCase { @Override - protected void doAllTests() throws Exception { - setLanguageLevel(LanguageLevel.JDK_1_5); + protected void doAllTests() { + setLanguageLevel(LanguageLevel.JDK_1_5); super.doAllTests(); } } diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java index cf95fb2560e4..d5d35cf60ff7 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java @@ -121,7 +121,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase if (comment == null) { comment = commenter.getBlockCommentPrefix(); } - + // "quick fix action text to perform" "should be available" assert comment != null : commenter; Pattern pattern = Pattern.compile("^" + comment.replace("*", "\\*") + actionPattern, Pattern.DOTALL); @@ -197,7 +197,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase return null; } - public static void doAllTests(QuickFixTestCase testCase) throws Exception { + public static void doAllTests(QuickFixTestCase testCase) { assertNotNull("getBasePath() should not return null!", testCase.getBasePath()); final String testDirPath = testCase.getTestDataPath().replace(File.separatorChar, '/') + testCase.getBasePath(); @@ -224,7 +224,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase doTestFor(fileSuffix, createWrapper()); } - protected void doAllTests() throws Exception { + protected void doAllTests() { doAllTests(createWrapper()); } From 75f112bc0d7eb1760a0cd453026416d526929e83 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 14 Mar 2013 21:03:14 +0100 Subject: [PATCH 09/18] IDEA-54393 (type element tree generation reworked) Fixes: marking of generated elements, annotated types --- .../impl/source/tree/JavaTreeGenerator.java | 103 +++++------------- .../src/com/intellij/psi/PsiArrayType.java | 8 +- .../src/com/intellij/psi/PsiEllipsisType.java | 10 +- .../com/intellij/psi/PsiIntersectionType.java | 11 +- .../com/intellij/psi/PsiPrimitiveType.java | 6 +- .../src/com/intellij/psi/PsiType.java | 71 ++++++++---- .../impl/source/PsiImmediateClassType.java | 8 +- .../addTypeCast/afterTypeAnnoArray.java | 12 ++ .../addTypeCast/afterTypeAnnoPrimitive.java | 12 ++ .../addTypeCast/afterTypeAnnoRefType.java | 12 ++ .../addTypeCast/afterTypeAnnoTypeParam.java | 13 +++ .../addTypeCast/afterTypeAnnoWildcard.java | 13 +++ .../addTypeCast/beforeTypeAnnoArray.java | 12 ++ .../addTypeCast/beforeTypeAnnoPrimitive.java | 12 ++ .../addTypeCast/beforeTypeAnnoRefType.java | 12 ++ .../addTypeCast/beforeTypeAnnoTypeParam.java | 13 +++ .../addTypeCast/beforeTypeAnnoWildcard.java | 13 +++ .../daemon/quickFix/AddTypeCastTest.java | 27 +++-- 18 files changed, 240 insertions(+), 128 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoArray.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoPrimitive.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoRefType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoTypeParam.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoWildcard.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoArray.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoPrimitive.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoRefType.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoTypeParam.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoWildcard.java diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java index a2df081217de..30e55c110153 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,31 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.psi.impl.source.tree; -import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; import com.intellij.lang.PsiBuilder; import com.intellij.lang.java.parser.JavaParser; import com.intellij.lang.java.parser.JavaParserUtil; -import com.intellij.lexer.JavaLexer; -import com.intellij.lexer.Lexer; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.impl.GeneratedMarkerVisitor; -import com.intellij.psi.impl.light.LightTypeElement; import com.intellij.psi.impl.source.*; import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; -import com.intellij.psi.impl.source.parsing.ParseUtilBase; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiUtil; import com.intellij.util.CharTable; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -61,15 +54,16 @@ public class JavaTreeGenerator implements TreeGenerator { final String text = original.getText(); return createLeafFromText(text, table, manager, original, ((PsiJavaToken)original).getTokenType()); } + if (original instanceof PsiModifierList) { final String text = original.getText(); assert text != null : "Text is null for " + original + "; " + original.getClass(); final LanguageLevel level = PsiUtil.getLanguageLevel(original); final DummyHolder holder = DummyHolderFactory.createHolder(original.getManager(), new JavaDummyElement(text, MOD_LIST, level), null); final TreeElement modifierListElement = holder.getTreeElement().getFirstChildNode(); - if (CodeEditUtil.isNodeGenerated(original.getNode())) modifierListElement.acceptTree(new GeneratedMarkerVisitor()); - return modifierListElement; + return markGeneratedIfNeeded(original, modifierListElement); } + if (original instanceof PsiReferenceExpression) { TreeElement element = createReferenceExpression(original.getProject(), original.getText(), original); PsiElement refElement = ((PsiJavaCodeReferenceElement)original).resolve(); @@ -78,6 +72,7 @@ public class JavaTreeGenerator implements TreeGenerator { } return element; } + if (original instanceof PsiJavaCodeReferenceElement) { PsiElement refElement = ((PsiJavaCodeReferenceElement)original).resolve(); final boolean generated = refElement != null && CodeEditUtil.isNodeGenerated(refElement.getNode()); @@ -115,6 +110,7 @@ public class JavaTreeGenerator implements TreeGenerator { } return createReference(original.getProject(), original.getText(), generated); } + if (original instanceof PsiCompiledElement) { PsiElement sourceVersion = original.getNavigationElement(); if (sourceVersion != original) { @@ -123,84 +119,44 @@ public class JavaTreeGenerator implements TreeGenerator { ASTNode mirror = SourceTreeToPsiMap.psiElementToTree(((PsiCompiledElement)original).getMirror()); return ChangeUtil.generateTreeElement(SourceTreeToPsiMap.treeElementToPsi(mirror), table,manager); } + if (original instanceof PsiTypeElement) { - final boolean generated = CodeEditUtil.isNodeGenerated(original.getNode()); PsiTypeElement typeElement = (PsiTypeElement)original; PsiType type = typeElement.getType(); - if (type instanceof PsiEllipsisType) { - TreeElement componentTypeCopy = ChangeUtil.generateTreeElement( - new LightTypeElement(original.getManager(), ((PsiEllipsisType)type).getComponentType()), - table, - manager); - if (componentTypeCopy == null) return null; - CompositeElement element = ASTFactory.composite(JavaElementType.TYPE); - CodeEditUtil.setNodeGenerated(element, generated); - element.rawAddChildren(componentTypeCopy); - element.rawAddChildren(createLeafFromText("...", table, manager, original, JavaTokenType.ELLIPSIS)); - return element; - } - if (type instanceof PsiArrayType) { - TreeElement componentTypeCopy = ChangeUtil.generateTreeElement( - new LightTypeElement(original.getManager(), ((PsiArrayType)type).getComponentType()), - table, - manager); - if (componentTypeCopy == null) return null; - CompositeElement element = ASTFactory.composite(JavaElementType.TYPE); - CodeEditUtil.setNodeGenerated(element, generated); - element.rawAddChildren(componentTypeCopy); - element.rawAddChildren(createLeafFromText("[", table, manager, original, JavaTokenType.LBRACKET)); - element.rawAddChildren(createLeafFromText("]", table, manager, original, JavaTokenType.RBRACKET)); - return element; - } - if (type instanceof PsiPrimitiveType) { - @NonNls String text = typeElement.getText(); - if (text.equals("null")) return null; - Lexer lexer = new JavaLexer(LanguageLevel.JDK_1_3); - lexer.start(text); - TreeElement keyword = ParseUtilBase.createTokenElement(lexer, table); - CodeEditUtil.setNodeGenerated(keyword, generated); - CompositeElement element = ASTFactory.composite(JavaElementType.TYPE); - CodeEditUtil.setNodeGenerated(element, generated); - element.rawAddChildren(keyword); - return element; - } - if (type instanceof PsiWildcardType || type instanceof PsiCapturedWildcardType || type instanceof PsiDisjunctionType) { - final String originalText = original.getText(); - return createType(original.getProject(), originalText, null, generated); - } + if (type instanceof PsiIntersectionType) { - LightTypeElement te = new LightTypeElement(original.getManager(), ((PsiIntersectionType)type).getRepresentative()); - return ChangeUtil.generateTreeElement(te, table, manager); + type = ((PsiIntersectionType)type).getRepresentative(); } - if (type instanceof PsiMethodReferenceType || type instanceof PsiLambdaExpressionType) { + else if (type instanceof PsiMethodReferenceType || type instanceof PsiLambdaExpressionType) { type = PsiType.getJavaLangObject(manager, GlobalSearchScope.projectScope(manager.getProject())); } - PsiClassType classType = (PsiClassType)type; + String text = type.getPresentableText(); + PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(original.getProject()).getParserFacade(); + TreeElement element = (TreeElement)parserFacade.createTypeElementFromText(text, original).getNode(); - String text = classType.getPresentableText(); - final TreeElement element = createType(original.getProject(), text, original, false); - PsiTypeElementImpl result = SourceTreeToPsiMap.treeToPsiNotNull(element); - - CodeEditUtil.setNodeGenerated(result, generated); - if (generated) { - PsiJavaCodeReferenceElement ref = result.getInnermostComponentReferenceElement(); - if (ref != null) ((CompositeElement)ref.getNode()).acceptTree(new GeneratedMarkerVisitor()); + PsiTypeElementImpl result = (PsiTypeElementImpl)element.getPsi(); + markGeneratedIfNeeded(original, result); + if (type instanceof PsiClassType) { + encodeInfoInTypeElement(result, type); } - encodeInfoInTypeElement(result, classType); return result; } + return null; } - private static LeafElement createLeafFromText(final String text, - final CharTable table, - final PsiManager manager, - final PsiElement original, - final IElementType type) { + private static LeafElement createLeafFromText(String text, CharTable table, PsiManager manager, PsiElement original, IElementType type) { return Factory.createSingleLeafElement(type, text, 0, text.length(), table, manager, CodeEditUtil.isNodeGenerated(original.getNode())); } + private static TreeElement markGeneratedIfNeeded(PsiElement original, TreeElement copy) { + if (CodeEditUtil.isNodeGenerated(original.getNode())) { + copy.acceptTree(new GeneratedMarkerVisitor()); + } + return copy; + } + private static TreeElement createReference(final Project project, final String text, boolean mark) { final PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(project).getParserFacade(); final TreeElement element = (TreeElement)parserFacade.createReferenceFromText(text, null).getNode(); @@ -214,13 +170,6 @@ public class JavaTreeGenerator implements TreeGenerator { return (TreeElement)expression.getNode(); } - private static TreeElement createType(final Project project, final String text, final PsiElement context, final boolean mark) { - final PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(project).getParserFacade(); - final TreeElement element = (TreeElement)parserFacade.createTypeElementFromText(text, context).getNode(); - if (mark) element.acceptTree(new GeneratedMarkerVisitor()); - return element; - } - private static void encodeInfoInTypeElement(ASTNode typeElement, PsiType type) { if (type instanceof PsiPrimitiveType) return; LOG.assertTrue(typeElement.getElementType() == JavaElementType.TYPE); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java index 1c6ed36d97bd..ce0167c90a30 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -36,14 +36,14 @@ public class PsiArrayType extends PsiType { this(componentType, PsiAnnotation.EMPTY_ARRAY); } - public PsiArrayType(@NotNull PsiType componentType, PsiAnnotation[] annotations) { + public PsiArrayType(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) { super(annotations); myComponentType = componentType; } @Override public String getPresentableText() { - return StringUtil.joinOrNull(myComponentType.getPresentableText(), "[]"); + return StringUtil.joinOrNull(myComponentType.getPresentableText(), getAnnotationsTextPrefix(true, true), "[]"); } @Override @@ -53,7 +53,7 @@ public class PsiArrayType extends PsiType { @Override public String getInternalCanonicalText() { - return StringUtil.joinOrNull(myComponentType.getInternalCanonicalText(), "[]"); + return StringUtil.joinOrNull(myComponentType.getInternalCanonicalText(), getAnnotationsTextPrefix(true, true), "[]"); } @Override diff --git a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java index f295375f9403..07e3a6f707c4 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -36,7 +36,7 @@ public class PsiEllipsisType extends PsiArrayType { @Override public String getPresentableText() { - return StringUtil.joinOrNull(getComponentType().getPresentableText(), "..."); + return StringUtil.joinOrNull(getComponentType().getPresentableText(), getAnnotationsTextPrefix(true, true), "..."); } @Override @@ -46,13 +46,13 @@ public class PsiEllipsisType extends PsiArrayType { @Override public String getInternalCanonicalText() { - return StringUtil.joinOrNull(getComponentType().getInternalCanonicalText(), "..."); + return StringUtil.joinOrNull(getComponentType().getInternalCanonicalText(), getAnnotationsTextPrefix(true, true), "..."); } @Override public boolean equalsToText(String text) { - return text.endsWith("...") && getComponentType().equalsToText(text.substring(0, text.length() - 3)) - || super.equalsToText(text); + return text.endsWith("...") && getComponentType().equalsToText(text.substring(0, text.length() - 3)) || + super.equalsToText(text); } /** diff --git a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java index 8c13cd7582c6..8bc973444dfd 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -169,10 +169,11 @@ public class PsiIntersectionType extends PsiType { @Override public String toString() { - String s = "PsiIntersectionType: "; - for (PsiType conjunct : myConjuncts) { - s += conjunct.getPresentableText() +", "; + StringBuilder sb = new StringBuilder("PsiIntersectionType: "); + for (int i = 0; i < myConjuncts.length; i++) { + if (i > 0) sb.append(", "); + sb.append(myConjuncts[i].getPresentableText()); } - return s; + return sb.toString(); } } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java index acbbfdfdb014..ee40f077ed2c 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -53,7 +53,7 @@ public class PsiPrimitiveType extends PsiType { @Override public String getPresentableText() { - return myName; + return getAnnotationsTextPrefix() + myName; } @Override @@ -63,7 +63,7 @@ public class PsiPrimitiveType extends PsiType { @Override public String getInternalCanonicalText() { - return getAnnotationsTextPrefix() + getCanonicalText(); + return getAnnotationsTextPrefix() + myName; } /** diff --git a/java/java-psi-api/src/com/intellij/psi/PsiType.java b/java/java-psi-api/src/com/intellij/psi/PsiType.java index 5ed21bd5fdd0..84ba85e54ed0 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,6 @@ package com.intellij.psi; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.Function; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,6 +39,7 @@ public abstract class PsiType implements PsiAnnotationOwner { public static final PsiType[] EMPTY_ARRAY = new PsiType[0]; private final PsiAnnotation[] myAnnotations; + protected PsiType(@NotNull PsiAnnotation[] annotations) { myAnnotations = annotations; } @@ -52,22 +51,31 @@ public abstract class PsiType implements PsiAnnotationOwner { public PsiArrayType createArrayType() { return new PsiArrayType(this); } + /** * Creates array type with this type as a component. */ @NotNull public PsiArrayType createArrayType(PsiAnnotation... annotations) { - return new PsiArrayType(this,annotations); + return new PsiArrayType(this, annotations); } /** - * @return text of this type that can be presented to user. + * @return text of the type that can be presented to a user (non-qualified references, with annotations). */ + @NonNls public abstract String getPresentableText(); + /** + * @return text of the type (fully-qualified references, no annotations). + */ @NonNls public abstract String getCanonicalText(); + /** + * @return text of the type (fully-qualified references, with annotations). + */ + @NonNls public abstract String getInternalCanonicalText(); /** @@ -109,7 +117,8 @@ public abstract class PsiType implements PsiAnnotationOwner { */ @NotNull public static PsiClassType getJavaLangObject(@NotNull PsiManager manager, @NotNull GlobalSearchScope resolveScope) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, resolveScope); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, resolveScope); } /** @@ -120,7 +129,8 @@ public abstract class PsiType implements PsiAnnotationOwner { * @return the class instance. */ public static PsiClassType getJavaLangClass(PsiManager manager, GlobalSearchScope resolveScope) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_CLASS, resolveScope); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_CLASS, resolveScope); } /** @@ -131,7 +141,8 @@ public abstract class PsiType implements PsiAnnotationOwner { * @return the class instance. */ public static PsiClassType getJavaLangThrowable(PsiManager manager, GlobalSearchScope resolveScope) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE, resolveScope); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE, resolveScope); } /** @@ -143,7 +154,8 @@ public abstract class PsiType implements PsiAnnotationOwner { */ @NotNull public static PsiClassType getJavaLangString(PsiManager manager, GlobalSearchScope resolveScope) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, resolveScope); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, resolveScope); } /** @@ -154,7 +166,8 @@ public abstract class PsiType implements PsiAnnotationOwner { * @return the class instance. */ public static PsiClassType getJavaLangError(PsiManager manager, GlobalSearchScope resolveScope) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_ERROR, resolveScope); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_ERROR, resolveScope); } /** @@ -165,7 +178,8 @@ public abstract class PsiType implements PsiAnnotationOwner { * @return the class instance. */ public static PsiClassType getJavaLangRuntimeException(PsiManager manager, GlobalSearchScope resolveScope) { - return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, resolveScope); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, resolveScope); } /** @@ -195,7 +209,7 @@ public abstract class PsiType implements PsiAnnotationOwner { * Returns the innermost component type for an array type. * * @return the innermost (non-array) component of the type, or this if the type is not - * an array type. + * an array type. */ @NotNull public final PsiType getDeepComponentType() { @@ -214,11 +228,6 @@ public abstract class PsiType implements PsiAnnotationOwner { @Nullable public abstract GlobalSearchScope getResolveScope(); - public String toString() { - //noinspection HardCodedStringLiteral - return "PsiType:" + getPresentableText(); - } - /** * Returns the list of superclass types for a class type. * @@ -251,13 +260,27 @@ public abstract class PsiType implements PsiAnnotationOwner { } protected String getAnnotationsTextPrefix() { - PsiAnnotation[] annotations = getAnnotations(); - return StringUtil.join(annotations, new Function() { - @Override - public String fun(PsiAnnotation annotation) { - return "@"+annotation.getQualifiedName(); - } - }, " ") + (annotations.length == 0 ? "" : " "); + return getAnnotationsTextPrefix(false, true); } + @NotNull + protected String getAnnotationsTextPrefix(boolean leadingSpace, boolean trailingSpace) { + PsiAnnotation[] annotations = getAnnotations(); + if (annotations.length == 0) return ""; + + StringBuilder sb = new StringBuilder(); + if (leadingSpace) sb.append(' '); + for (int i = 0; i < annotations.length; i++) { + if (i > 0) sb.append(' '); + sb.append('@').append(annotations[i].getQualifiedName()); + } + if (trailingSpace) sb.append(' '); + return sb.toString(); + } + + @Override + public String toString() { + //noinspection HardCodedStringLiteral + return "PsiType:" + getPresentableText(); + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java index d815bab4235f..5844bd796ae5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -180,7 +180,9 @@ public class PsiImmediateClassType extends PsiClassType { enclosingClass = (PsiClass)parent; } } - buffer.append(getAnnotationsTextPrefix()); + if (canonical == internal) { + buffer.append(getAnnotationsTextPrefix()); + } if (enclosingClass != null) { buildText(enclosingClass, substitutor, buffer, canonical, false); buffer.append('.'); @@ -203,7 +205,7 @@ public class PsiImmediateClassType extends PsiClassType { buffer.append(name); } - final PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); + PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); if (typeParameters.length > 0) { StringBuilder pineBuffer = new StringBuilder(); pineBuffer.append('<'); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoArray.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoArray.java new file mode 100644 index 000000000000..4d69c363e6eb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoArray.java @@ -0,0 +1,12 @@ +// "Cast to 'int[]'" "true" +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA int @TA [] a = (@TA int[]) o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoPrimitive.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoPrimitive.java new file mode 100644 index 000000000000..8cd2a01d46e8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoPrimitive.java @@ -0,0 +1,12 @@ +// "Cast to 'int'" "true" +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA int i = (@TA int) o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoRefType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoRefType.java new file mode 100644 index 000000000000..28420d1f46ea --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoRefType.java @@ -0,0 +1,12 @@ +// "Cast to 'java.lang.Integer'" "true" +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA Integer i = (@TA Integer) o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoTypeParam.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoTypeParam.java new file mode 100644 index 000000000000..6fa421e10993 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoTypeParam.java @@ -0,0 +1,13 @@ +// "Cast to 'java.util.List'" "true" +import java.lang.annotation.*; +import java.util.List; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA List<@TA String> l = (@TA List<@TA String>) o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoWildcard.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoWildcard.java new file mode 100644 index 000000000000..f13704e3c443 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterTypeAnnoWildcard.java @@ -0,0 +1,13 @@ +// "Cast to 'java.util.List'" "true" +import java.lang.annotation.*; +import java.util.List; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA List<@TA ? extends @TA String> l = (@TA List) o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoArray.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoArray.java new file mode 100644 index 000000000000..9540221fa4ff --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoArray.java @@ -0,0 +1,12 @@ +// "Cast to 'int[]'" "true" +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA int @TA [] a = o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoPrimitive.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoPrimitive.java new file mode 100644 index 000000000000..5d17c26ca97a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoPrimitive.java @@ -0,0 +1,12 @@ +// "Cast to 'int'" "true" +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA int i = o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoRefType.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoRefType.java new file mode 100644 index 000000000000..7948738bb264 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoRefType.java @@ -0,0 +1,12 @@ +// "Cast to 'java.lang.Integer'" "true" +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA Integer i = o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoTypeParam.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoTypeParam.java new file mode 100644 index 000000000000..33b2d0be44da --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoTypeParam.java @@ -0,0 +1,13 @@ +// "Cast to 'java.util.List'" "true" +import java.lang.annotation.*; +import java.util.List; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA List<@TA String> l = o; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoWildcard.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoWildcard.java new file mode 100644 index 000000000000..84a9df6fad0a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeTypeAnnoWildcard.java @@ -0,0 +1,13 @@ +// "Cast to 'java.util.List'" "true" +import java.lang.annotation.*; +import java.util.List; +import static java.lang.annotation.ElementType.*; + +@Target({TYPE_USE}) @interface TA { } + +class C { + { + Object o = null; + @TA List<@TA ? extends @TA String> l = o; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddTypeCastTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddTypeCastTest.java index 7e24823d8036..578885dab2e0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddTypeCastTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AddTypeCastTest.java @@ -1,16 +1,29 @@ - +/* + * Copyright 2000-2013 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 AddTypeCastTest extends LightQuickFixTestCase { + public void test() { + doAllTests(); - -public class AddTypeCastTest extends LightQuickFix15TestCase { - - public void test() throws Exception { doAllTests(); } + Object o = null; + } @Override protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast"; } - } - From aa8e0e8c789471012c6c602aee036646cd85d737 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 15 Mar 2013 01:42:12 +0400 Subject: [PATCH 10/18] similar replacements handling fix --- .../intellij/codeInsight/intention/impl/QuickEditHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java index dbc06d177713..d40bd5fbcf5b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java @@ -406,9 +406,10 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable { String newText = myNewDocument.getText(); // prepare guarded blocks LinkedHashMap replacementMap = new LinkedHashMap(); + int count = 0; for (RangeMarker o : ContainerUtil.reverse(((DocumentEx)myNewDocument).getGuardedBlocks())) { String replacement = o.getUserData(REPLACEMENT_KEY); - String tempText = "REPLACE"+Long.toHexString(StringHash.calc(replacement)); + String tempText = "REPLACE"+(count++)+Long.toHexString(StringHash.calc(replacement)); newText = newText.substring(0, o.getStartOffset()) + tempText + newText.substring(o.getEndOffset()); replacementMap.put(tempText, replacement); } From c7a4149ce51f3e9c88cb60c395d33fec2cbfc121 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Fri, 15 Mar 2013 12:06:59 +0400 Subject: [PATCH 11/18] WEB-7134 Settings/JavaScript/Libraries: 'Configure' button should open selected library settings --- .../ui/configuration/IdeaProjectSettingsService.java | 12 ++++++++++++ .../ui/configuration/ProjectSettingsService.java | 3 +++ 2 files changed, 15 insertions(+) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/IdeaProjectSettingsService.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/IdeaProjectSettingsService.java index 926c62846cb6..e654eab22bcd 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/IdeaProjectSettingsService.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/IdeaProjectSettingsService.java @@ -25,6 +25,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.JdkOrderEntry; import com.intellij.openapi.roots.LibraryOrderEntry; import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable; import com.intellij.packaging.artifacts.Artifact; import org.jetbrains.annotations.NotNull; @@ -62,6 +63,17 @@ public class IdeaProjectSettingsService extends ProjectSettingsService implement }); } + @Override + public void openLibrary(@NotNull final Library library) { + final ProjectStructureConfigurable config = ProjectStructureConfigurable.getInstance(myProject); + ShowSettingsUtil.getInstance().editConfigurable(myProject, config, new Runnable() { + @Override + public void run() { + config.selectProjectOrGlobalLibrary(library, true); + } + }); + } + @Override public boolean canOpenModuleSettings() { return true; diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java index c8bee89f66e9..aaada40f33cf 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ProjectSettingsService.java @@ -45,6 +45,9 @@ public class ProjectSettingsService { public void openGlobalLibraries() { } + public void openLibrary(@NotNull Library library) { + } + public void openModuleSettings(final Module module) { } From 34c98ce2449919a2a3295e8dadcb587a4e0b30f0 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Fri, 15 Mar 2013 15:10:39 +0400 Subject: [PATCH 12/18] max timeout for EDT blocking --- .../PathEnvironmentVariableUtil.java | 59 ++++++++++++------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java index 9e7068c5ddb3..36b31fb595a7 100644 --- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java +++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java @@ -1,6 +1,7 @@ package com.intellij.execution.configurations; import com.intellij.execution.process.UnixProcessManager; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; @@ -14,6 +15,9 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; /** * @author Sergey Simonchik @@ -22,40 +26,55 @@ public class PathEnvironmentVariableUtil { public static final String PATH_ENV_VAR_NAME = "PATH"; private static final Logger LOG = Logger.getInstance(PathEnvironmentVariableUtil.class); - private static final String FIXED_MAC_PATH_VALUE; - - static { - String fixedPathValue = null; - try { - fixedPathValue = calcFixedMacPathEnvVarValue(); - } - catch (Throwable t) { - LOG.error("Can't initialize class " + PathEnvironmentVariableUtil.class.getName(), t); - } - FIXED_MAC_PATH_VALUE = fixedPathValue; - } + private static final int MAX_BLOCKING_TIMEOUT_MILLIS = 1000; + private static final AtomicBoolean INITIALIZED = new AtomicBoolean(false); + private static volatile String FIXED_MAC_PATH_VALUE; private PathEnvironmentVariableUtil() { } /** - * Tries to return a real value for PATH environment variable. + * Tries to return a real value for PATH environment variable on OSX. * Workaround for http://youtrack.jetbrains.com/issue/IDEA-99154 + * + * @return null, if the platform isn't OSX, any troubles were encountered or time limit exceeded, + * otherwise returns String instance - PATH env var value */ @Nullable public static String getFixedPathEnvVarValueOnMac() { + if (INITIALIZED.compareAndSet(false, true)) { + final Semaphore semaphore = new Semaphore(0, true); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") + @Override + public void run() { + try { + FIXED_MAC_PATH_VALUE = calcFixedMacPathEnvVarValue(); + } + catch (Throwable t) { + LOG.error("Can't calculate proper value for PATH environment variable", t); + } + finally { + semaphore.release(); + } + } + }); + try { + semaphore.tryAcquire(MAX_BLOCKING_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + } + catch (InterruptedException e) { + LOG.info("Thread interrupted", e); + } + } return FIXED_MAC_PATH_VALUE; } @Nullable private static String calcFixedMacPathEnvVarValue() { - if (SystemInfo.isMac) { - final String originalPath = getOriginalPathEnvVarValue(); - Map envVars = UnixProcessManager.getOrLoadConsoleEnvironment(); - String consolePath = envVars.get(PATH_ENV_VAR_NAME); - return mergePaths(ContainerUtil.newArrayList(originalPath, consolePath)); - } - return null; + final String originalPath = getOriginalPathEnvVarValue(); + Map envVars = UnixProcessManager.getOrLoadConsoleEnvironment(); + String consolePath = envVars.get(PATH_ENV_VAR_NAME); + return mergePaths(ContainerUtil.newArrayList(originalPath, consolePath)); } @Nullable From 543702f855bb67b172af0e6f4d01ce28203b11bc Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 15 Mar 2013 15:28:28 +0400 Subject: [PATCH 13/18] [git] Don't scan for roots in tests --- plugins/git4idea/src/git4idea/roots/GitRootScanner.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java index 226f8932b603..c14f276a4c22 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java @@ -17,6 +17,7 @@ package git4idea.roots; import com.intellij.ProjectTopics; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; @@ -111,6 +112,11 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis } private void scheduleScan() { + if (ApplicationManager.getApplication().isUnitTestMode()) { + // don't scan in tests + return; + } + myAlarm.cancelAllRequests(); // one scan is enough, no need to queue, they all do the same myAlarm.addRequest(new Runnable() { @Override From 670602159abba9ee298faac8f6d3945fa128b0ba Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Fri, 15 Mar 2013 15:29:42 +0400 Subject: [PATCH 14/18] [git] Cancel all pending root scan requests on dispose. --- plugins/git4idea/src/git4idea/roots/GitRootScanner.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java index c14f276a4c22..87f7d197edb8 100644 --- a/plugins/git4idea/src/git4idea/roots/GitRootScanner.java +++ b/plugins/git4idea/src/git4idea/roots/GitRootScanner.java @@ -70,6 +70,7 @@ public class GitRootScanner implements BulkFileListener, ModuleRootListener, Dis @Override public void dispose() { + myAlarm.cancelAllRequests(); } @Override From c8bd368fe6c2360bb8922523178252886ff3310b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 15 Mar 2013 12:38:34 +0100 Subject: [PATCH 15/18] enlarge intention's availability scope to include catch parameter --- .../siyeh/ipp/exceptions/MulticatchPredicate.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java index 878df78fed76..5866835ccd43 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/MulticatchPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 Bas Leijdekkers + * Copyright 2011-2013 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,15 @@ package com.siyeh.ipp.exceptions; import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; import com.siyeh.ipp.base.PsiElementPredicate; class MulticatchPredicate implements PsiElementPredicate { public boolean satisfiedBy(PsiElement element) { - if (!(element instanceof PsiKeyword)) { + if (element instanceof PsiCodeBlock) { return false; } - final PsiJavaToken javaToken = (PsiJavaToken)element; - final IElementType tokenType = javaToken.getTokenType(); - if (!tokenType.equals(JavaTokenType.CATCH_KEYWORD)) { - return false; - } - final PsiElement parent = javaToken.getParent(); + final PsiElement parent = element.getParent(); if (!(parent instanceof PsiCatchSection)) { return false; } From b3ea9a74bffdc08867b07818e64eb1743418bd5b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 14 Mar 2013 18:58:07 +0400 Subject: [PATCH 16/18] update excluded status regardless the collapsed state --- .../intellij/usages/impl/UsageViewImpl.java | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index fd16d670394a..d48540d91382 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -861,24 +861,28 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra @Override public void includeUsages(@NotNull Usage[] usages) { + List nodes = new ArrayList(usages.length); for (Usage usage : usages) { final UsageNode node = myUsageNodes.get(usage); if (node != NULL_NODE && node != null) { node.setUsageExcluded(false); + nodes.add(node); } } - updateImmediately(); + updateImmediatelyNodesUpToRoot(nodes); } @Override public void excludeUsages(@NotNull Usage[] usages) { + List nodes = new ArrayList(usages.length); for (Usage usage : usages) { final UsageNode node = myUsageNodes.get(usage); if (node != NULL_NODE && node != null) { node.setUsageExcluded(true); + nodes.add(node); } } - updateImmediately(); + updateImmediatelyNodesUpToRoot(nodes); } @Override @@ -920,6 +924,24 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra updateOnSelectionChanged(); } + private void updateImmediatelyNodesUpToRoot(@NotNull List nodes) { + if (myProject.isDisposed()) return; + TreeNode root = (TreeNode)myTree.getModel().getRoot(); + + for (int i=0; i infos = getSelectedUsageInfos(); if (myCurrentUsageContextPanel != null) { From 946a4c2f7726d10fedb3e8bcfc7481a66e2e8fd3 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 15 Mar 2013 15:37:13 +0400 Subject: [PATCH 17/18] more correct fix of the invalid root children attributes --- .../openapi/vfs/impl/local/LocalFileSystemBase.java | 3 ++- .../vfs/newvfs/persistent/PersistentFSImpl.java | 13 ------------- .../com/intellij/util/io/PersistentFSTest.java | 12 +++++++++++- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java index 61928b69ddc8..1d0d0b471a94 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java @@ -688,7 +688,8 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { @Override public FileAttributes getAttributes(@NotNull final VirtualFile file) { - final String path = file.getPath(); + String path = normalize(file.getPath()); + if (path == null) return null; if (StringUtil.isEmpty(path) || file.getParent() == null && path.startsWith("//")) { return FAKE_ROOT_ATTRIBUTES; // fake Windows roots } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index 7f633c8e5d3d..150c05df3ab8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -380,19 +380,6 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone public int getId(@NotNull final VirtualFile parent, @NotNull final String childName, @NotNull final NewVirtualFileSystem fs) { int parentId = getFileId(parent); - if (parent == myFakeRoot) { - // children of the fake root must be the FS roots only - myRootsLock.readLock().lock(); - try { - String rootUrl = fs.getProtocol() + "://" + VfsImplUtil.normalize(fs, childName); - VirtualFileSystemEntry root = myRoots.get(rootUrl); - return root == null ? 0 : root.getId(); - } - finally { - myRootsLock.readLock().unlock(); - } - } - int[] children = FSRecords.list(parentId); if (children.length > 0) { diff --git a/platform/platform-tests/testSrc/com/intellij/util/io/PersistentFSTest.java b/platform/platform-tests/testSrc/com/intellij/util/io/PersistentFSTest.java index f48e2470808e..7e0479e15632 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/io/PersistentFSTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/io/PersistentFSTest.java @@ -18,6 +18,7 @@ package com.intellij.util.io; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWithId; +import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.testFramework.PlatformTestCase; @@ -48,7 +49,7 @@ public class PersistentFSTest extends PlatformTestCase { public void testListChildrenOfTheRootOfTheRoot() { PersistentFS fs = PersistentFS.getInstance(); - VirtualFile fakeRoot = fs.findRoot("", LocalFileSystem.getInstance()); + NewVirtualFile fakeRoot = fs.findRoot("", LocalFileSystem.getInstance()); int users = fs.getId(fakeRoot, "Users", LocalFileSystem.getInstance()); assertEquals(0, users); int win = fs.getId(fakeRoot, "Windows", LocalFileSystem.getInstance()); @@ -59,5 +60,14 @@ public class PersistentFSTest extends PlatformTestCase { int rid = fs.getId(fakeRoot, root.getName(), LocalFileSystem.getInstance()); assertTrue(0 != rid); } + + NewVirtualFile c = fakeRoot.refreshAndFindChild("Users"); + assertNull(c); + c = fakeRoot.refreshAndFindChild("Users"); + assertNull(c); + c = fakeRoot.refreshAndFindChild("Windows"); + assertNull(c); + c = fakeRoot.refreshAndFindChild("Windows"); + assertNull(c); } } From a7272edc9dcc9cc66cb3d5043dfe746769bf3df3 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Fri, 15 Mar 2013 16:04:29 +0400 Subject: [PATCH 18/18] Fix a problem with JSPX code style settings preview (as discussed with D.Avdeev) --- .../application/options/TabbedLanguageCodeStylePanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java index e4719e673f89..06e9cd9ce2ac 100644 --- a/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java @@ -586,7 +586,7 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane @Override protected int getRightMargin() { - return getSettings().RIGHT_MARGIN; + return myProvider.getRightMargin(LanguageCodeStyleSettingsProvider.SettingsType.INDENT_SETTINGS); } @Override